<div dir="ltr">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 class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Ian Romanick <<a href="mailto:ian.d.romanick@intel.com">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">ian.d.romanick@intel.com</a>><br>
Cc: Paul Berry <<a href="mailto:stereotype441@gmail.com">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>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">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">stereotype441@gmail.com</a>><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

     */<br>
    ir_variable *const var =<br>
       new(mem_ctx) ir_variable(glsl_type::vec(4),<br>
@@ -177,14 +176,12 @@ TEST_F(invalidate_locations, vertex_in_builtin_without_explicit)<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(-1, var->location);<br>
    EXPECT_EQ(0u, var->location_frac);<br>
    EXPECT_FALSE(var->explicit_location);<br>
-   EXPECT_FALSE(var->is_unmatched_generic_inout);<br>
+   EXPECT_TRUE(var->is_unmatched_generic_inout);<br>
 }<br>
<br>
 TEST_F(invalidate_locations, simple_vertex_out_generic)<br>
@@ -201,9 +198,7 @@ TEST_F(invalidate_locations, simple_vertex_out_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>
@@ -226,9 +221,7 @@ TEST_F(invalidate_locations, vertex_out_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(VARYING_SLOT_COL0, var->location);<br>
    EXPECT_EQ(0u, var->location_frac);<br>
@@ -240,8 +233,15 @@ TEST_F(invalidate_locations, vertex_out_builtin_without_explicit)<br>
 {<br>
    /* This test is almost identical to vertex_out_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>
     */<br>
    ir_variable *const var =<br>
       new(mem_ctx) ir_variable(glsl_type::vec(4),<br>
@@ -255,12 +255,10 @@ TEST_F(invalidate_locations, vertex_out_builtin_without_explicit)<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(VARYING_SLOT_COL0, var->location);<br>
+   EXPECT_EQ(-1, var->location);<br>
    EXPECT_EQ(0u, var->location_frac);<br>
    EXPECT_FALSE(var->explicit_location);<br>
-   EXPECT_FALSE(var->is_unmatched_generic_inout);<br>
+   EXPECT_TRUE(var->is_unmatched_generic_inout);<br>
 }<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.1.4<br>
<br>
</font></span></blockquote></div><br></div></div>