<div dir="ltr">Not sure how reviews work in Mesa, but this patch LGTM. I also tested that it fixes the relevant tests failures it is supposed to address.</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jul 6, 2016 at 7:40 PM, Ilia Mirkin <span dir="ltr"><<a href="mailto:imirkin@alum.mit.edu" target="_blank">imirkin@alum.mit.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The GL spec is very unclear on this point. Apparently this is discussed<br>
without resolution in the closed Khronos bugtracker at<br>
<a href="https://cvs.khronos.org/bugzilla/show_bug.cgi?id=7829" rel="noreferrer" target="_blank">https://cvs.khronos.org/bugzilla/show_bug.cgi?id=7829</a> . The<br>
recommendation is to allow dropping the [0] for looking up the bindings.<br>
<br>
The approach taken in this patch is to instead tack on [0]'s for each<br>
arrayness level of the output's type, and doing the lookup again. That<br>
way, for<br>
<br>
out vec4 foo[2][2][2]<br>
<br>
we will end up looking for bindings for foo, foo[0], foo[0][0], and<br>
foo[0][0][0], in that order of preference.<br>
<br>
Bugzilla: <a href="https://bugs.freedesktop.org/show_bug.cgi?id=96765" rel="noreferrer" target="_blank">https://bugs.freedesktop.org/show_bug.cgi?id=96765</a><br>
Signed-off-by: Ilia Mirkin <<a href="mailto:imirkin@alum.mit.edu">imirkin@alum.mit.edu</a>><br>
---<br>
 src/compiler/glsl/linker.cpp | 39 ++++++++++++++++++++++++++++-----------<br>
 1 file changed, 28 insertions(+), 11 deletions(-)<br>
<br>
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp<br>
index d963f54..9d54c2f 100644<br>
--- a/src/compiler/glsl/linker.cpp<br>
+++ b/src/compiler/glsl/linker.cpp<br>
@@ -2566,6 +2566,7 @@ find_available_slots(unsigned used_mask, unsigned needed_count)<br>
 /**<br>
  * Assign locations for either VS inputs or FS outputs<br>
  *<br>
+ * \param mem_ctx       Temporary ralloc context used for linking<br>
  * \param prog          Shader program whose variables need locations assigned<br>
  * \param constants     Driver specific constant values for the program.<br>
  * \param target_index  Selector for the program target to receive location<br>
@@ -2577,7 +2578,8 @@ find_available_slots(unsigned used_mask, unsigned needed_count)<br>
  * error is emitted to the shader link log and false is returned.<br>
  */<br>
 bool<br>
-assign_attribute_or_color_locations(gl_shader_program *prog,<br>
+assign_attribute_or_color_locations(void *mem_ctx,<br>
+                                    gl_shader_program *prog,<br>
                                     struct gl_constants *constants,<br>
                                     unsigned target_index)<br>
 {<br>
@@ -2680,16 +2682,31 @@ assign_attribute_or_color_locations(gl_shader_program *prog,<br>
       } else if (target_index == MESA_SHADER_FRAGMENT) {<br>
         unsigned binding;<br>
         unsigned index;<br>
+         const char *name = var->name;<br>
+         const glsl_type *type = var->type;<br>
+<br>
+         while (type) {<br>
+            /* Check if there's a binding for the variable name */<br>
+            if (prog->FragDataBindings->get(binding, name)) {<br>
+               assert(binding >= FRAG_RESULT_DATA0);<br>
+               var->data.location = binding;<br>
+               var->data.is_unmatched_generic_inout = 0;<br>
+<br>
+               if (prog->FragDataIndexBindings->get(index, name)) {<br>
+                  var->data.index = index;<br>
+               }<br>
+               break;<br>
+            }<br>
<br>
-        if (prog->FragDataBindings->get(binding, var->name)) {<br>
-           assert(binding >= FRAG_RESULT_DATA0);<br>
-           var->data.location = binding;<br>
-            var->data.is_unmatched_generic_inout = 0;<br>
+            /* If not, but it's an array type, look for name[0] */<br>
+            if (type->is_array()) {<br>
+               name = ralloc_asprintf(mem_ctx, "%s[0]", name);<br>
+               type = type->fields.array;<br>
+               continue;<br>
+            }<br>
<br>
-           if (prog->FragDataIndexBindings->get(index, var->name)) {<br>
-              var->data.index = index;<br>
-           }<br>
-        }<br>
+            break;<br>
+         }<br>
       }<br>
<br>
       /* From GL4.5 core spec, section 15.2 (Shader Execution):<br>
@@ -4816,12 +4833,12 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)<br>
       prev = i;<br>
    }<br>
<br>
-   if (!assign_attribute_or_color_locations(prog, &ctx->Const,<br>
+   if (!assign_attribute_or_color_locations(mem_ctx, prog, &ctx->Const,<br>
                                             MESA_SHADER_VERTEX)) {<br>
       goto done;<br>
    }<br>
<br>
-   if (!assign_attribute_or_color_locations(prog, &ctx->Const,<br>
+   if (!assign_attribute_or_color_locations(mem_ctx, prog, &ctx->Const,<br>
                                             MESA_SHADER_FRAGMENT)) {<br>
       goto done;<br>
    }<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.7.3<br>
<br>
</font></span></blockquote></div><br></div>