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