<div dir="ltr">That was supposed to be 119/133<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jan 7, 2015 at 6:03 PM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Reviewed-by: Chris Forbes <<a href="mailto:chrisf@ijw.co.nz">chrisf@ijw.co.nz</a>><br>
<br>
v2 Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>>:<br>
- Use the nir_tex_src_sampler_offset source type instead of the<br>
sampler_indirect thing that I cooked up before.<br>
---<br>
src/glsl/nir/nir_lower_samplers.cpp | 153 ++++++++++++++++++------------------<br>
1 file changed, 78 insertions(+), 75 deletions(-)<br>
<br>
diff --git a/src/glsl/nir/nir_lower_samplers.cpp b/src/glsl/nir/nir_lower_samplers.cpp<br>
index d94183c..5e90a4c 100644<br>
--- a/src/glsl/nir/nir_lower_samplers.cpp<br>
+++ b/src/glsl/nir/nir_lower_samplers.cpp<br>
@@ -36,67 +36,9 @@ extern "C" {<br>
}<br>
<br>
static unsigned<br>
-get_deref_name_offset(nir_deref_var *deref_var,<br>
- gl_shader_program *shader_program, char **name,<br>
- void *mem_ctx)<br>
-{<br>
- nir_deref *deref = &deref_var->deref;<br>
- nir_deref_array *deref_array;<br>
- nir_deref_struct *deref_struct;<br>
-<br>
- *name = ralloc_strdup(mem_ctx, deref_var->var->name);<br>
-<br>
- while (deref->child != NULL) {<br>
- switch (deref->child->deref_type) {<br>
- case nir_deref_type_array:<br>
- deref_array = nir_deref_as_array(deref->child);<br>
- if (deref_array->deref_array_type == nir_deref_array_type_indirect) {<br>
- /* GLSL 1.10 and 1.20 allowed variable sampler array indices,<br>
- * while GLSL 1.30 requires that the array indices be<br>
- * constant integer expressions. We don't expect any driver<br>
- * to actually work with a really variable array index, so<br>
- * all that would work would be an unrolled loop counter that<br>
- * ends up being constant.<br>
- */<br>
- ralloc_strcat(&shader_program->InfoLog,<br>
- "warning: Variable sampler array index unsupported.\n"<br>
- "This feature of the language was removed in GLSL 1.20 "<br>
- "and is unlikely to be supported for 1.10 in Mesa.\n");<br>
- }<br>
- if (deref_array->deref.child == NULL) {<br>
- return deref_array->base_offset;<br>
- }<br>
- ralloc_asprintf_append(name, "[%u]", deref_array->base_offset);<br>
- break;<br>
-<br>
- case nir_deref_type_struct: {<br>
- deref_struct = nir_deref_as_struct(deref->child);<br>
- const char *field = glsl_get_struct_elem_name(deref->type,<br>
- deref_struct->index);<br>
- ralloc_asprintf_append(name, ".%s", field);<br>
- break;<br>
- }<br>
-<br>
- default:<br>
- assert(0);<br>
- break;<br>
- }<br>
- deref = deref->child;<br>
- }<br>
-<br>
- return 0;<br>
-}<br>
-<br>
-static unsigned<br>
-get_sampler_index(nir_deref_var *sampler,<br>
- struct gl_shader_program *shader_program,<br>
+get_sampler_index(struct gl_shader_program *shader_program, const char *name,<br>
const struct gl_program *prog)<br>
{<br>
- void *mem_ctx = ralloc_context(NULL);<br>
- char *name;<br>
- unsigned offset = get_deref_name_offset(sampler, shader_program, &name,<br>
- mem_ctx);<br>
-<br>
GLuint shader = _mesa_program_enum_to_shader_stage(prog->Target);<br>
<br>
unsigned location;<br>
@@ -115,33 +57,90 @@ get_sampler_index(nir_deref_var *sampler,<br>
return 0;<br>
}<br>
<br>
- ralloc_free(mem_ctx);<br>
-<br>
- return shader_program->UniformStorage[location].sampler[shader].index +<br>
- offset;<br>
+ return shader_program->UniformStorage[location].sampler[shader].index;<br>
}<br>
<br>
static void<br>
lower_sampler(nir_tex_instr *instr, struct gl_shader_program *shader_program,<br>
- const struct gl_program *prog)<br>
+ const struct gl_program *prog, void *mem_ctx)<br>
{<br>
- if (instr->sampler) {<br>
- instr->sampler_index = get_sampler_index(instr->sampler, shader_program,<br>
- prog);<br>
- nir_src empty_src;<br>
- memset(&empty_src, 0, sizeof empty_src);<br>
- for (nir_deref *deref = &instr->sampler->deref; deref; deref = deref->child) {<br>
- if (deref->deref_type == nir_deref_type_array) {<br>
- nir_deref_array *arr = nir_deref_as_array(deref);<br>
- nir_instr_rewrite_src(&instr->instr, &arr->indirect, empty_src);<br>
+ if (instr->sampler == NULL)<br>
+ return;<br>
+<br>
+ /* Get the name and the offset */<br>
+ instr->sampler_index = 0;<br>
+ bool has_indirect = false;<br>
+ char *name = ralloc_strdup(mem_ctx, instr->sampler->var->name);<br>
+<br>
+ for (nir_deref *deref = &instr->sampler->deref;<br>
+ deref->child; deref = deref->child) {<br>
+ switch (deref->child->deref_type) {<br>
+ case nir_deref_type_array: {<br>
+ nir_deref_array *deref_array = nir_deref_as_array(deref->child);<br>
+<br>
+ /* XXX: We're assuming here that the indirect is the last array<br>
+ * thing we have. This should be ok for now as we don't support<br>
+ * arrays_of_arrays yet.<br>
+ */<br>
+ assert(!has_indirect);<br>
+<br>
+ instr->sampler_index *= glsl_get_length(deref->type);<br>
+ switch (deref_array->deref_array_type) {<br>
+ case nir_deref_array_type_direct:<br>
+ instr->sampler_index += deref_array->base_offset;<br>
+ if (deref_array->deref.child)<br>
+ ralloc_asprintf_append(&name, "[%u]", deref_array->base_offset);<br>
+ break;<br>
+ case nir_deref_array_type_indirect: {<br>
+ assert(!has_indirect);<br>
+<br>
+ assert(instr->num_srcs < 4);<br>
+<br>
+ nir_instr_rewrite_src(&instr->instr, &instr->src[instr->num_srcs],<br>
+ nir_src_copy(deref_array->indirect, mem_ctx));<br>
+ instr->src_type[instr->num_srcs] = nir_tex_src_sampler_offset;<br>
+ instr->num_srcs++;<br>
+<br>
+ instr->sampler_array_size = glsl_get_length(deref->type);<br>
+<br>
+ nir_src empty;<br>
+ memset(&empty, 0, sizeof empty);<br>
+ nir_instr_rewrite_src(&instr->instr, &deref_array->indirect, empty);<br>
+<br>
+ if (deref_array->deref.child)<br>
+ ralloc_strcat(&name, "[0]");<br>
+ break;<br>
}<br>
+<br>
+ case nir_deref_array_type_wildcard:<br>
+ unreachable("Cannot copy samplers");<br>
+ default:<br>
+ unreachable("Invalid deref array type");<br>
+ }<br>
+ break;<br>
}<br>
<br>
- instr->sampler = NULL;<br>
+ case nir_deref_type_struct: {<br>
+ nir_deref_struct *deref_struct = nir_deref_as_struct(deref->child);<br>
+ const char *field = glsl_get_struct_elem_name(deref->type,<br>
+ deref_struct->index);<br>
+ ralloc_asprintf_append(&name, ".%s", field);<br>
+ break;<br>
+ }<br>
+<br>
+ default:<br>
+ unreachable("Invalid deref type");<br>
+ break;<br>
+ }<br>
}<br>
+<br>
+ instr->sampler_index += get_sampler_index(shader_program, name, prog);<br>
+<br>
+ instr->sampler = NULL;<br>
}<br>
<br>
typedef struct {<br>
+ void *mem_ctx;<br>
struct gl_shader_program *shader_program;<br>
struct gl_program *prog;<br>
} lower_state;<br>
@@ -154,7 +153,8 @@ lower_block_cb(nir_block *block, void *_state)<br>
nir_foreach_instr(block, instr) {<br>
if (instr->type == nir_instr_type_tex) {<br>
nir_tex_instr *tex_instr = nir_instr_as_tex(instr);<br>
- lower_sampler(tex_instr, state->shader_program, state->prog);<br>
+ lower_sampler(tex_instr, state->shader_program, state->prog,<br>
+ state->mem_ctx);<br>
}<br>
}<br>
<br>
@@ -166,8 +166,11 @@ lower_impl(nir_function_impl *impl, struct gl_shader_program *shader_program,<br>
struct gl_program *prog)<br>
{<br>
lower_state state;<br>
+<br>
+ state.mem_ctx = ralloc_parent(impl);<br>
state.shader_program = shader_program;<br>
state.prog = prog;<br>
+<br>
nir_foreach_block(impl, lower_block_cb, &state);<br>
}<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
2.2.0<br>
<br>
</font></span></blockquote></div><br></div>