<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>
This required fixing the out-of-date prototype in linker.h.  While<br>
making that change, further change the prototype to make unit testing a<br>
bit easier.<br></blockquote><div><br></div><div>I'd prefer to see this split into two patches: one to change the signature of the function, and a second one to add the unit test.  But I won't be a stickler about it.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Validates:<br>
<br>
  - ir_variable::explicit_location should not be modified.<br>
<br>
  - If ir_variable::location is not a generic location (i.e., it's a<br>
    location for a built-in), ir_variable::location is not modified.<br>
    ir_variable::location_frac must be reset to 0.<br>
    ir_variable::is_unmatched_generic_inout must be reset to 1.<br>
<br>
  - If ir_variable::explicit_location is not set, ir_variable::location,<br>
    ir_variable::location_frac, and<br>
    ir_variable::is_unmatched_generic_inout must be reset to 0.<br>
<br>
  - If ir_variable::explicit_location is set, ir_variable::location<br>
    should not be modified.  ir_variable::location_frac, and<br>
    ir_variable::is_unmatched_generic_inout must be reset to 0.<br>
<br>
Signed-off-by: Ian Romanick <<a href="mailto:ian.d.romanick@intel.com">ian.d.romanick@intel.com</a>><br>
---<br>
 src/glsl/Makefile.am                         |   1 +<br>
 src/glsl/linker.cpp                          |  10 +-<br>
 src/glsl/linker.h                            |   4 +-<br>
 src/glsl/tests/invalidate_locations_test.cpp | 266 +++++++++++++++++++++++++++<br>
 4 files changed, 274 insertions(+), 7 deletions(-)<br>
 create mode 100644 src/glsl/tests/invalidate_locations_test.cpp<br>
<br>
diff --git a/src/glsl/Makefile.am b/src/glsl/Makefile.am<br>
index 80949fb..b9ed5b6 100644<br>
--- a/src/glsl/Makefile.am<br>
+++ b/src/glsl/Makefile.am<br>
@@ -60,6 +60,7 @@ tests_general_ir_test_SOURCES =               \<br>
        $(top_srcdir)/src/mesa/program/symbol_table.c   \<br>
        $(GLSL_SRCDIR)/standalone_scaffolding.cpp \<br>
        tests/builtin_variable_test.cpp                 \<br>
+       tests/invalidate_locations_test.cpp             \<br>
        tests/general_ir_test.cpp<br>
 tests_general_ir_test_CFLAGS =                         \<br>
        $(PTHREAD_CFLAGS)<br>
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp<br>
index 9095a40..02eb4e1 100644<br>
--- a/src/glsl/linker.cpp<br>
+++ b/src/glsl/linker.cpp<br>
@@ -366,10 +366,10 @@ parse_program_resource_name(const GLchar *name,<br>
<br>
<br>
 void<br>
-link_invalidate_variable_locations(gl_shader *sh, int input_base,<br>
+link_invalidate_variable_locations(exec_list *ir, int input_base,<br>
                                    int output_base)<br>
 {<br>
-   foreach_list(node, sh->ir) {<br>
+   foreach_list(node, ir) {<br>
       ir_variable *const var = ((ir_instruction *) node)->as_variable();<br>
<br>
       if (var == NULL)<br>
@@ -2221,17 +2221,17 @@ 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],<br>
+            prog->_LinkedShaders[MESA_SHADER_VERTEX]->ir,<br>
             VERT_ATTRIB_GENERIC0, VARYING_SLOT_VAR0);<br>
    }<br>
    if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {<br>
       link_invalidate_variable_locations(<br>
-            prog->_LinkedShaders[MESA_SHADER_GEOMETRY],<br>
+            prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir,<br>
             VARYING_SLOT_VAR0, VARYING_SLOT_VAR0);<br>
    }<br>
    if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {<br>
       link_invalidate_variable_locations(<br>
-            prog->_LinkedShaders[MESA_SHADER_FRAGMENT],<br>
+            prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir,<br>
             VARYING_SLOT_VAR0, FRAG_RESULT_DATA0);<br>
    }<br>
<br>
diff --git a/src/glsl/linker.h b/src/glsl/linker.h<br>
index 8a0027d..9915c38 100644<br>
--- a/src/glsl/linker.h<br>
+++ b/src/glsl/linker.h<br>
@@ -31,8 +31,8 @@ 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(gl_shader *sh, enum ir_variable_mode mode,<br>
-                                  int generic_base);<br>
+link_invalidate_variable_locations(exec_list *ir, int input_base,<br>
+                                   int output_base);<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>
new file mode 100644<br>
index 0000000..958acec<br>
--- /dev/null<br>
+++ b/src/glsl/tests/invalidate_locations_test.cpp<br>
@@ -0,0 +1,266 @@<br>
+/*<br>
+ * Copyright © 2013 Intel Corporation<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice (including the next<br>
+ * paragraph) shall be included in all copies or substantial portions of the<br>
+ * Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER<br>
+ * DEALINGS IN THE SOFTWARE.<br>
+ */<br>
+#include <gtest/gtest.h><br>
+#include "main/compiler.h"<br>
+#include "main/mtypes.h"<br>
+#include "main/macros.h"<br>
+#include "ralloc.h"<br>
+#include "ir.h"<br>
+#include "linker.h"<br>
+<br>
+/**<br>
+ * \file varyings_test.cpp<br>
+ *<br>
+ * Test various aspects of linking shader stage inputs and outputs.<br>
+ */<br>
+<br>
+class invalidate_locations : public ::testing::Test {<br>
+public:<br>
+   virtual void SetUp();<br>
+   virtual void TearDown();<br>
+<br>
+   void *mem_ctx;<br>
+   exec_list ir;<br>
+};<br>
+<br>
+void<br>
+invalidate_locations::SetUp()<br>
+{<br>
+   this->mem_ctx = ralloc_context(NULL);<br>
+   this->ir.make_empty();<br>
+}<br>
+<br>
+void<br>
+invalidate_locations::TearDown()<br>
+{<br>
+   ralloc_free(this->mem_ctx);<br>
+   this->mem_ctx = NULL;<br>
+}<br>
+<br>
+TEST_F(invalidate_locations, simple_vertex_in_generic)<br>
+{<br>
+   ir_variable *const var =<br>
+      new(mem_ctx) ir_variable(glsl_type::vec(4),<br>
+                               "a",<br>
+                               ir_var_shader_in);<br>
+<br>
+   EXPECT_FALSE(var->explicit_location);<br>
+   EXPECT_EQ(-1, var->location);<br>
+<br>
+   var->location = VERT_ATTRIB_GENERIC0;<br>
+   var->location_frac = 2;<br>
+<br>
+   ir.push_tail(var);<br>
+<br>
+   link_invalidate_variable_locations(&ir,<br>
+                                      VERT_ATTRIB_GENERIC0,<br>
+                                      VARYING_SLOT_VAR0);<br>
+<br>
+   EXPECT_EQ(-1, var->location);<br>
+   EXPECT_EQ(0u, var->location_frac);<br>
+   EXPECT_FALSE(var->explicit_location);<br>
+   EXPECT_TRUE(var->is_unmatched_generic_inout);<br>
+}<br>
+<br>
+TEST_F(invalidate_locations, explicit_location_vertex_in_generic)<br>
+{<br>
+   ir_variable *const var =<br>
+      new(mem_ctx) ir_variable(glsl_type::vec(4),<br>
+                               "a",<br>
+                               ir_var_shader_in);<br>
+<br>
+   EXPECT_FALSE(var->explicit_location);<br>
+   EXPECT_EQ(-1, var->location);<br>
+<br>
+   var->location = VERT_ATTRIB_GENERIC0;<br>
+   var->explicit_location = true;<br>
+<br>
+   ir.push_tail(var);<br>
+<br>
+   link_invalidate_variable_locations(&ir,<br>
+                                      VERT_ATTRIB_GENERIC0,<br>
+                                      VARYING_SLOT_VAR0);<br>
+<br>
+   EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->location);<br>
+   EXPECT_EQ(0u, var->location_frac);<br>
+   EXPECT_TRUE(var->explicit_location);<br>
+   EXPECT_FALSE(var->is_unmatched_generic_inout);<br>
+}<br>
+<br>
+TEST_F(invalidate_locations, explicit_location_frac_vertex_in_generic)<br>
+{<br>
+   ir_variable *const var =<br>
+      new(mem_ctx) ir_variable(glsl_type::vec(4),<br>
+                               "a",<br>
+                               ir_var_shader_in);<br>
+<br>
+   EXPECT_FALSE(var->explicit_location);<br>
+   EXPECT_EQ(-1, var->location);<br>
+<br>
+   var->location = VERT_ATTRIB_GENERIC0;<br>
+   var->location_frac = 2;<br>
+   var->explicit_location = true;<br>
+<br>
+   ir.push_tail(var);<br>
+<br>
+   link_invalidate_variable_locations(&ir,<br>
+                                      VERT_ATTRIB_GENERIC0,<br>
+                                      VARYING_SLOT_VAR0);<br>
+<br>
+   EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->location);<br>
+   EXPECT_EQ(2u, var->location_frac);<br>
+   EXPECT_TRUE(var->explicit_location);<br>
+   EXPECT_FALSE(var->is_unmatched_generic_inout);<br>
+}<br>
+<br>
+TEST_F(invalidate_locations, vertex_in_builtin)<br>
+{<br>
+   ir_variable *const var =<br>
+      new(mem_ctx) ir_variable(glsl_type::vec(4),<br>
+                               "gl_Vertex",<br>
+                               ir_var_shader_in);<br>
+<br>
+   EXPECT_FALSE(var->explicit_location);<br>
+   EXPECT_EQ(-1, var->location);<br>
+<br>
+   var->location = VERT_ATTRIB_POS;<br>
+   var->explicit_location = true;<br>
+<br>
+   ir.push_tail(var);<br>
+<br>
+   link_invalidate_variable_locations(&ir,<br>
+                                      VERT_ATTRIB_GENERIC0,<br>
+                                      VARYING_SLOT_VAR0);<br>
+<br>
+   EXPECT_EQ(VERT_ATTRIB_POS, var->location);<br>
+   EXPECT_EQ(0u, var->location_frac);<br>
+   EXPECT_TRUE(var->explicit_location);<br>
+   EXPECT_FALSE(var->is_unmatched_generic_inout);<br>
+}<br>
+<br>
+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></blockquote><div><br></div><div>Did you mean to say "...is not set"?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+    * link_invalidate_variable_locations has the behavior that non-generic<br>
+    * inputs (or outputs) are not modified.<br>
+    */<br></blockquote><div><br></div><div>It seems a little weird to be testing this case, since as I understand it, non-generic (i.e. built-in) inputs and outputs always have explicit_location set to true.  Are you really meaning to test a corner case that we know never happens?  My temptation would be to delete this test.<br>
<br></div><div>If you really think we should keep it, I think at the very least the comment above should be updated to say something like "Although non-generic inputs/outputs always have explicit_location set to true, the contract of link_invalidate_variable_locations() is that it should not modify non-generic inputs or outputs regardless of the setting of explicit_location."<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+   ir_variable *const var =<br>
+      new(mem_ctx) ir_variable(glsl_type::vec(4),<br>
+                               "gl_Vertex",<br>
+                               ir_var_shader_in);<br>
+<br>
+   EXPECT_FALSE(var->explicit_location);<br>
+   EXPECT_EQ(-1, var->location);<br>
+<br>
+   var->location = VERT_ATTRIB_POS;<br>
+<br>
+   ir.push_tail(var);<br>
+<br>
+   link_invalidate_variable_locations(&ir,<br>
+                                      VERT_ATTRIB_GENERIC0,<br>
+                                      VARYING_SLOT_VAR0);<br>
+<br>
+   EXPECT_EQ(VERT_ATTRIB_POS, var->location);<br>
+   EXPECT_EQ(0u, var->location_frac);<br>
+   EXPECT_FALSE(var->explicit_location);<br>
+   EXPECT_FALSE(var->is_unmatched_generic_inout);<br>
+}<br>
+<br>
+TEST_F(invalidate_locations, simple_vertex_out_generic)<br>
+{<br>
+   ir_variable *const var =<br>
+      new(mem_ctx) ir_variable(glsl_type::vec(4),<br>
+                               "a",<br>
+                               ir_var_shader_out);<br>
+<br>
+   EXPECT_FALSE(var->explicit_location);<br>
+   EXPECT_EQ(-1, var->location);<br>
+<br>
+   var->location = VARYING_SLOT_VAR0;<br>
+<br>
+   ir.push_tail(var);<br>
+<br>
+   link_invalidate_variable_locations(&ir,<br>
+                                      VERT_ATTRIB_GENERIC0,<br>
+                                      VARYING_SLOT_VAR0);<br>
+<br>
+   EXPECT_EQ(-1, var->location);<br>
+   EXPECT_EQ(0u, var->location_frac);<br>
+   EXPECT_FALSE(var->explicit_location);<br>
+   EXPECT_TRUE(var->is_unmatched_generic_inout);<br>
+}<br>
+<br>
+TEST_F(invalidate_locations, vertex_out_builtin)<br>
+{<br>
+   ir_variable *const var =<br>
+      new(mem_ctx) ir_variable(glsl_type::vec(4),<br>
+                               "gl_FrontColor",<br>
+                               ir_var_shader_out);<br>
+<br>
+   EXPECT_FALSE(var->explicit_location);<br>
+   EXPECT_EQ(-1, var->location);<br>
+<br>
+   var->location = VARYING_SLOT_COL0;<br>
+   var->explicit_location = true;<br>
+<br>
+   ir.push_tail(var);<br>
+<br>
+   link_invalidate_variable_locations(&ir,<br>
+                                      VERT_ATTRIB_GENERIC0,<br>
+                                      VARYING_SLOT_VAR0);<br>
+<br>
+   EXPECT_EQ(VARYING_SLOT_COL0, var->location);<br>
+   EXPECT_EQ(0u, var->location_frac);<br>
+   EXPECT_TRUE(var->explicit_location);<br>
+   EXPECT_FALSE(var->is_unmatched_generic_inout);<br>
+}<br>
+<br>
+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></blockquote><div><br></div><div>I have similar feelings about this test.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+   ir_variable *const var =<br>
+      new(mem_ctx) ir_variable(glsl_type::vec(4),<br>
+                               "gl_FrontColor",<br>
+                               ir_var_shader_out);<br>
+<br>
+   EXPECT_FALSE(var->explicit_location);<br>
+   EXPECT_EQ(-1, var->location);<br>
+<br>
+   var->location = VARYING_SLOT_COL0;<br>
+<br>
+   ir.push_tail(var);<br>
+<br>
+   link_invalidate_variable_locations(&ir,<br>
+                                      VERT_ATTRIB_GENERIC0,<br>
+                                      VARYING_SLOT_VAR0);<br>
+<br>
+   EXPECT_EQ(VARYING_SLOT_COL0, var->location);<br>
+   EXPECT_EQ(0u, var->location_frac);<br>
+   EXPECT_FALSE(var->explicit_location);<br>
+   EXPECT_FALSE(var->is_unmatched_generic_inout);<br>
+}<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.1.4<br></font></span></blockquote><div><br></div><div>With the *_builtin_without_explicit issues resolved, this patch is:<br><br>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>><br>
</div></div></div></div>