<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>