<div dir="ltr">On 18 October 2013 13:40, Paul Berry <span dir="ltr"><<a href="mailto:stereotype441@gmail.com" target="_blank">stereotype441@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div class="h5">On 11 October 2013 11:18, Ian Romanick <span dir="ltr"><<a href="mailto:idr@freedesktop.org" target="_blank">idr@freedesktop.org</a>></span> wrote:<br>
</div></div><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">From: Ian Romanick <<a href="mailto:ian.d.romanick@intel.com" target="_blank">ian.d.romanick@intel.com</a>><br>

<br>
The unit tests added in the previous commits prove some things about the<br>
state of some internal data structures.  The most important of these is<br>
that all built-in input and output variables have explicit_location<br>
set.  This means that link_invalidate_variable_locations doesn't need to<br>
know the range of non-generic shader inputs or outputs.  It can simply<br>
reset location state depending on whether explicit_location is set.<br>
<br>
There are two additional assumptions that were already implicit in the<br>
code that comments now document.<br>
<br>
  - ir_variable::is_unmatched_generic_inout is only used by the linker<br>
    when connecting outputs from one shader stage to inputs of another<br>
    shader stage.<br>
<br>
  - Any varying that has explicit_location set must be a built-in.  This<br>
    will be true until GL_ARB_separate_shader_objects is supported.<br>
<br>
As a result, the input_base and output_base parameters to<br>
link_invalidate_variable_locations are no longer necessary, and the code<br>
for resetting locations and setting is_unmatched_generic_inout can be<br>
simplified.<br>
<br>
Signed-off-by: Ian Romanick <<a href="mailto:ian.d.romanick@intel.com" target="_blank">ian.d.romanick@intel.com</a>><br>
Cc: Paul Berry <<a href="mailto:stereotype441@gmail.com" target="_blank">stereotype441@gmail.com</a>><br>
---<br>
 src/glsl/linker.cpp                          | 48 ++++++++++-----------<br>
 src/glsl/linker.h                            |  3 +-<br>
 src/glsl/tests/invalidate_locations_test.cpp | 62 ++++++++++++++--------------<br>
 3 files changed, 55 insertions(+), 58 deletions(-)<br>
<br>
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp<br>
index 02eb4e1..acc3039 100644<br>
--- a/src/glsl/linker.cpp<br>
+++ b/src/glsl/linker.cpp<br>
@@ -366,8 +366,7 @@ parse_program_resource_name(const GLchar *name,<br>
<br>
<br>
 void<br>
-link_invalidate_variable_locations(exec_list *ir, int input_base,<br>
-                                   int output_base)<br>
+link_invalidate_variable_locations(exec_list *ir)<br>
 {<br>
    foreach_list(node, ir) {<br>
       ir_variable *const var = ((ir_instruction *) node)->as_variable();<br>
@@ -375,26 +374,30 @@ link_invalidate_variable_locations(exec_list *ir, int input_base,<br>
       if (var == NULL)<br>
          continue;<br>
<br>
-      int base;<br>
-      switch (var->mode) {<br>
-      case ir_var_shader_in:<br>
-         base = input_base;<br>
-         break;<br>
-      case ir_var_shader_out:<br>
-         base = output_base;<br>
-         break;<br>
-      default:<br>
-         continue;<br>
-      }<br>
-<br>
-      /* Only assign locations for generic attributes / varyings / etc.<br>
+      /* Only assign locations for variables that lack an explicit location.<br>
+       * Explicit locations are set for all built-in variables, generic vertex<br>
+       * shader inputs (via layout(location=...)), and generic fragment shader<br>
+       * outputs (also via layout(location=...)).<br>
        */<br>
-      if ((var->location >= base) && !var->explicit_location)<br>
+      if (!var->explicit_location) {<br>
          var->location = -1;<br>
+         var->location_frac = 0;<br>
+      }<br>
<br>
-      if ((var->location == -1) && !var->explicit_location) {<br>
+      /* ir_variable::is_unmatched_generic_inout is used by the linker while<br>
+       * connecting outputs from one stage to inputs of the next stage.<br>
+       *<br>
+       * There are two implicit assumptions here.  First, we assume that any<br>
+       * built-in variable (i.e., non-generic in or out) will have<br>
+       * explicit_location set.  Second, we assume that any generic in or out<br>
+       * will not have explicit_location set.<br>
+       *<br>
+       * This second assumption will only be valid until<br>
+       * GL_ARB_separate_shader_objects is supported.  When that extension is<br>
+       * implemented, this function will need some modifications.<br>
+       */<br>
+      if (!var->explicit_location) {<br>
          var->is_unmatched_generic_inout = 1;<br>
-         var->location_frac = 0;<br>
       } else {<br>
          var->is_unmatched_generic_inout = 0;<br>
       }<br>
@@ -2221,18 +2224,15 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)<br>
    /* Mark all generic shader inputs and outputs as unpaired. */<br>
    if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {<br>
       link_invalidate_variable_locations(<br>
-            prog->_LinkedShaders[MESA_SHADER_VERTEX]->ir,<br>
-            VERT_ATTRIB_GENERIC0, VARYING_SLOT_VAR0);<br>
+            prog->_LinkedShaders[MESA_SHADER_VERTEX]->ir);<br>
    }<br>
    if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {<br>
       link_invalidate_variable_locations(<br>
-            prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir,<br>
-            VARYING_SLOT_VAR0, VARYING_SLOT_VAR0);<br>
+            prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir);<br>
    }<br>
    if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {<br>
       link_invalidate_variable_locations(<br>
-            prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir,<br>
-            VARYING_SLOT_VAR0, FRAG_RESULT_DATA0);<br>
+            prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir);<br>
    }<br>
<br>
    /* FINISHME: The value of the max_attribute_index parameter is<br>
diff --git a/src/glsl/linker.h b/src/glsl/linker.h<br>
index 9915c38..887cd33 100644<br>
--- a/src/glsl/linker.h<br>
+++ b/src/glsl/linker.h<br>
@@ -31,8 +31,7 @@ link_function_calls(gl_shader_program *prog, gl_shader *main,<br>
                    gl_shader **shader_list, unsigned num_shaders);<br>
<br>
 extern void<br>
-link_invalidate_variable_locations(exec_list *ir, int input_base,<br>
-                                   int output_base);<br>
+link_invalidate_variable_locations(exec_list *ir);<br>
<br>
 extern void<br>
 link_assign_uniform_locations(struct gl_shader_program *prog);<br>
diff --git a/src/glsl/tests/invalidate_locations_test.cpp b/src/glsl/tests/invalidate_locations_test.cpp<br>
index 958acec..b26d825 100644<br>
--- a/src/glsl/tests/invalidate_locations_test.cpp<br>
+++ b/src/glsl/tests/invalidate_locations_test.cpp<br>
@@ -72,9 +72,7 @@ TEST_F(invalidate_locations, simple_vertex_in_generic)<br>
<br>
    ir.push_tail(var);<br>
<br>
-   link_invalidate_variable_locations(&ir,<br>
-                                      VERT_ATTRIB_GENERIC0,<br>
-                                      VARYING_SLOT_VAR0);<br>
+   link_invalidate_variable_locations(&ir);<br>
<br>
    EXPECT_EQ(-1, var->location);<br>
    EXPECT_EQ(0u, var->location_frac);<br>
@@ -97,9 +95,7 @@ TEST_F(invalidate_locations, explicit_location_vertex_in_generic)<br>
<br>
    ir.push_tail(var);<br>
<br>
-   link_invalidate_variable_locations(&ir,<br>
-                                      VERT_ATTRIB_GENERIC0,<br>
-                                      VARYING_SLOT_VAR0);<br>
+   link_invalidate_variable_locations(&ir);<br>
<br>
    EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->location);<br>
    EXPECT_EQ(0u, var->location_frac);<br>
@@ -123,9 +119,7 @@ TEST_F(invalidate_locations, explicit_location_frac_vertex_in_generic)<br>
<br>
    ir.push_tail(var);<br>
<br>
-   link_invalidate_variable_locations(&ir,<br>
-                                      VERT_ATTRIB_GENERIC0,<br>
-                                      VARYING_SLOT_VAR0);<br>
+   link_invalidate_variable_locations(&ir);<br>
<br>
    EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->location);<br>
    EXPECT_EQ(2u, var->location_frac);<br>
@@ -148,9 +142,7 @@ TEST_F(invalidate_locations, vertex_in_builtin)<br>
<br>
    ir.push_tail(var);<br>
<br>
-   link_invalidate_variable_locations(&ir,<br>
-                                      VERT_ATTRIB_GENERIC0,<br>
-                                      VARYING_SLOT_VAR0);<br>
+   link_invalidate_variable_locations(&ir);<br>
<br>
    EXPECT_EQ(VERT_ATTRIB_POS, var->location);<br>
    EXPECT_EQ(0u, var->location_frac);<br>
@@ -162,8 +154,15 @@ TEST_F(invalidate_locations, vertex_in_builtin_without_explicit)<br>
 {<br>
    /* This test is almost identical to vertex_in_builtin.  However,<br>
     * ir_variable::explicit_location is not.<br>
-    * link_invalidate_variable_locations has the behavior that non-generic<br>
-    * inputs (or outputs) are not modified.<br>
+    *<br>
+    * At one point in time, link_invalidate_variable_locations would not<br>
+    * modify any non-generic inputs (or outputs).  However, the<br>
+    * vertex_builtin::inputs_have_explicit_location et al. test cases prove<br>
+    * that all built-in variables have explicit_location set.<br>
+    * link_invalidate_variable_locations will reset the locations of any<br>
+    * variable that does not have explicit_location set.<br>
+    *<br>
+    * In addition, is_unmatch_generic_inout depend only on explicit_location.<br></blockquote><div><br></div></div></div><div>Basically what you're saying here is "this corner case that never happens now has different behaviour, so we have to change the test."  As I mentioned in my comments on patch 5, I would prefer to just see the *_builtin_without_explicit tests go away--there's no point in testing a case that cannot occur, especially when there are other tests to verify that the case cannot occur.  That would make this patch a lot simpler, since we wouldn't have to contort ourselves to explain why we need to change a test when the functionality is preserved.<br>

<br></div><div>With that changed, this patch is:<br><br></div><div>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com" target="_blank">stereotype441@gmail.com</a>><br><br></div><div>I've made comments on all the other patches in the series except for patch 4.  That patch is:<br>

<br></div><div>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com" target="_blank">stereotype441@gmail.com</a>><br></div></div></div></div></blockquote><div><br></div><div>This morning I pulled down the latest master (with this patch landed) and ran the "glsl-1.50" subset of piglit (this is what I've been using as a smoke test during my geometry shader development).  It turns out that some tests regressed.  Since I was encouraging you to do less testing, I wonder if I'm going to have to eat some of my words :)<br>
<br></div><div>The tests that now fail are those that use built-in geometry shader inputs:<br>    - clip-distance-bulk-copy<br>    - clip-distance-in-bulk-read<br>    - clip-distance-in-explicitly-sized<br>    - clip-distance-in-param<br>
    - clip-distance-in-values<br>    - core-inputs<br>    - gs-redeclares-both-pervertex-blocks<br>    - gs-redeclares-pervertex-in-only<br>    - gs-redeclares-pervertex-out-only<br>    - redeclare-pervertex-subset-vs-to-gs<br>
    - unsized-in-named-interface-block-gs<br>    - unsized-in-named-interface-block-multiple<br>    - unsized-in-unnamed-interface-block-gs<br>    - unsized-in-unnamed-interface-block-multiple<br><br></div><div>It seems that we both missed a mechanism by which built-in variables could be created which have explicit_location set to false: when a built-in variable is created by lower_named_interface_blocks.  The test I encouraged you to remove wouldn't have caught this problem, and I'm having trouble thinking of a unit test or assertion that would have caught it.  Fortunately piglit caught it :)<br>
<br></div><div>I'll post a patch in a few minutes which fixes the regression by causing lower_named_interface_blocks to set explicit_location = true whenever it's creating a variable with a location >= 0.<br></div>
</div></div></div>