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