[Mesa-dev] [PATCH 6/6] glsl: Simplify the interface to link_invalidate_variable_locations
Paul Berry
stereotype441 at gmail.com
Wed Oct 23 16:54:57 CEST 2013
On 18 October 2013 13:40, Paul Berry <stereotype441 at gmail.com> wrote:
> On 11 October 2013 11:18, Ian Romanick <idr at freedesktop.org> wrote:
>
>> From: Ian Romanick <ian.d.romanick at intel.com>
>>
>> The unit tests added in the previous commits prove some things about the
>> state of some internal data structures. The most important of these is
>> that all built-in input and output variables have explicit_location
>> set. This means that link_invalidate_variable_locations doesn't need to
>> know the range of non-generic shader inputs or outputs. It can simply
>> reset location state depending on whether explicit_location is set.
>>
>> There are two additional assumptions that were already implicit in the
>> code that comments now document.
>>
>> - ir_variable::is_unmatched_generic_inout is only used by the linker
>> when connecting outputs from one shader stage to inputs of another
>> shader stage.
>>
>> - Any varying that has explicit_location set must be a built-in. This
>> will be true until GL_ARB_separate_shader_objects is supported.
>>
>> As a result, the input_base and output_base parameters to
>> link_invalidate_variable_locations are no longer necessary, and the code
>> for resetting locations and setting is_unmatched_generic_inout can be
>> simplified.
>>
>> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>> Cc: Paul Berry <stereotype441 at gmail.com>
>> ---
>> src/glsl/linker.cpp | 48 ++++++++++-----------
>> src/glsl/linker.h | 3 +-
>> src/glsl/tests/invalidate_locations_test.cpp | 62
>> ++++++++++++++--------------
>> 3 files changed, 55 insertions(+), 58 deletions(-)
>>
>> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
>> index 02eb4e1..acc3039 100644
>> --- a/src/glsl/linker.cpp
>> +++ b/src/glsl/linker.cpp
>> @@ -366,8 +366,7 @@ parse_program_resource_name(const GLchar *name,
>>
>>
>> void
>> -link_invalidate_variable_locations(exec_list *ir, int input_base,
>> - int output_base)
>> +link_invalidate_variable_locations(exec_list *ir)
>> {
>> foreach_list(node, ir) {
>> ir_variable *const var = ((ir_instruction *) node)->as_variable();
>> @@ -375,26 +374,30 @@ link_invalidate_variable_locations(exec_list *ir,
>> int input_base,
>> if (var == NULL)
>> continue;
>>
>> - int base;
>> - switch (var->mode) {
>> - case ir_var_shader_in:
>> - base = input_base;
>> - break;
>> - case ir_var_shader_out:
>> - base = output_base;
>> - break;
>> - default:
>> - continue;
>> - }
>> -
>> - /* Only assign locations for generic attributes / varyings / etc.
>> + /* Only assign locations for variables that lack an explicit
>> location.
>> + * Explicit locations are set for all built-in variables, generic
>> vertex
>> + * shader inputs (via layout(location=...)), and generic fragment
>> shader
>> + * outputs (also via layout(location=...)).
>> */
>> - if ((var->location >= base) && !var->explicit_location)
>> + if (!var->explicit_location) {
>> var->location = -1;
>> + var->location_frac = 0;
>> + }
>>
>> - if ((var->location == -1) && !var->explicit_location) {
>> + /* ir_variable::is_unmatched_generic_inout is used by the linker
>> while
>> + * connecting outputs from one stage to inputs of the next stage.
>> + *
>> + * There are two implicit assumptions here. First, we assume that
>> any
>> + * built-in variable (i.e., non-generic in or out) will have
>> + * explicit_location set. Second, we assume that any generic in
>> or out
>> + * will not have explicit_location set.
>> + *
>> + * This second assumption will only be valid until
>> + * GL_ARB_separate_shader_objects is supported. When that
>> extension is
>> + * implemented, this function will need some modifications.
>> + */
>> + if (!var->explicit_location) {
>> var->is_unmatched_generic_inout = 1;
>> - var->location_frac = 0;
>> } else {
>> var->is_unmatched_generic_inout = 0;
>> }
>> @@ -2221,18 +2224,15 @@ link_shaders(struct gl_context *ctx, struct
>> gl_shader_program *prog)
>> /* Mark all generic shader inputs and outputs as unpaired. */
>> if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
>> link_invalidate_variable_locations(
>> - prog->_LinkedShaders[MESA_SHADER_VERTEX]->ir,
>> - VERT_ATTRIB_GENERIC0, VARYING_SLOT_VAR0);
>> + prog->_LinkedShaders[MESA_SHADER_VERTEX]->ir);
>> }
>> if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
>> link_invalidate_variable_locations(
>> - prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir,
>> - VARYING_SLOT_VAR0, VARYING_SLOT_VAR0);
>> + prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir);
>> }
>> if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {
>> link_invalidate_variable_locations(
>> - prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir,
>> - VARYING_SLOT_VAR0, FRAG_RESULT_DATA0);
>> + prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir);
>> }
>>
>> /* FINISHME: The value of the max_attribute_index parameter is
>> diff --git a/src/glsl/linker.h b/src/glsl/linker.h
>> index 9915c38..887cd33 100644
>> --- a/src/glsl/linker.h
>> +++ b/src/glsl/linker.h
>> @@ -31,8 +31,7 @@ link_function_calls(gl_shader_program *prog, gl_shader
>> *main,
>> gl_shader **shader_list, unsigned num_shaders);
>>
>> extern void
>> -link_invalidate_variable_locations(exec_list *ir, int input_base,
>> - int output_base);
>> +link_invalidate_variable_locations(exec_list *ir);
>>
>> extern void
>> link_assign_uniform_locations(struct gl_shader_program *prog);
>> diff --git a/src/glsl/tests/invalidate_locations_test.cpp
>> b/src/glsl/tests/invalidate_locations_test.cpp
>> index 958acec..b26d825 100644
>> --- a/src/glsl/tests/invalidate_locations_test.cpp
>> +++ b/src/glsl/tests/invalidate_locations_test.cpp
>> @@ -72,9 +72,7 @@ TEST_F(invalidate_locations, simple_vertex_in_generic)
>>
>> ir.push_tail(var);
>>
>> - link_invalidate_variable_locations(&ir,
>> - VERT_ATTRIB_GENERIC0,
>> - VARYING_SLOT_VAR0);
>> + link_invalidate_variable_locations(&ir);
>>
>> EXPECT_EQ(-1, var->location);
>> EXPECT_EQ(0u, var->location_frac);
>> @@ -97,9 +95,7 @@ TEST_F(invalidate_locations,
>> explicit_location_vertex_in_generic)
>>
>> ir.push_tail(var);
>>
>> - link_invalidate_variable_locations(&ir,
>> - VERT_ATTRIB_GENERIC0,
>> - VARYING_SLOT_VAR0);
>> + link_invalidate_variable_locations(&ir);
>>
>> EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->location);
>> EXPECT_EQ(0u, var->location_frac);
>> @@ -123,9 +119,7 @@ TEST_F(invalidate_locations,
>> explicit_location_frac_vertex_in_generic)
>>
>> ir.push_tail(var);
>>
>> - link_invalidate_variable_locations(&ir,
>> - VERT_ATTRIB_GENERIC0,
>> - VARYING_SLOT_VAR0);
>> + link_invalidate_variable_locations(&ir);
>>
>> EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->location);
>> EXPECT_EQ(2u, var->location_frac);
>> @@ -148,9 +142,7 @@ TEST_F(invalidate_locations, vertex_in_builtin)
>>
>> ir.push_tail(var);
>>
>> - link_invalidate_variable_locations(&ir,
>> - VERT_ATTRIB_GENERIC0,
>> - VARYING_SLOT_VAR0);
>> + link_invalidate_variable_locations(&ir);
>>
>> EXPECT_EQ(VERT_ATTRIB_POS, var->location);
>> EXPECT_EQ(0u, var->location_frac);
>> @@ -162,8 +154,15 @@ TEST_F(invalidate_locations,
>> vertex_in_builtin_without_explicit)
>> {
>> /* This test is almost identical to vertex_in_builtin. However,
>> * ir_variable::explicit_location is not.
>> - * link_invalidate_variable_locations has the behavior that
>> non-generic
>> - * inputs (or outputs) are not modified.
>> + *
>> + * At one point in time, link_invalidate_variable_locations would not
>> + * modify any non-generic inputs (or outputs). However, the
>> + * vertex_builtin::inputs_have_explicit_location et al. test cases
>> prove
>> + * that all built-in variables have explicit_location set.
>> + * link_invalidate_variable_locations will reset the locations of any
>> + * variable that does not have explicit_location set.
>> + *
>> + * In addition, is_unmatch_generic_inout depend only on
>> explicit_location.
>>
>
> 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.
>
> With that changed, this patch is:
>
> Reviewed-by: Paul Berry <stereotype441 at gmail.com>
>
> I've made comments on all the other patches in the series except for patch
> 4. That patch is:
>
> Reviewed-by: Paul Berry <stereotype441 at gmail.com>
>
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 :)
The tests that now fail are those that use built-in geometry shader inputs:
- clip-distance-bulk-copy
- clip-distance-in-bulk-read
- clip-distance-in-explicitly-sized
- clip-distance-in-param
- clip-distance-in-values
- core-inputs
- gs-redeclares-both-pervertex-blocks
- gs-redeclares-pervertex-in-only
- gs-redeclares-pervertex-out-only
- redeclare-pervertex-subset-vs-to-gs
- unsized-in-named-interface-block-gs
- unsized-in-named-interface-block-multiple
- unsized-in-unnamed-interface-block-gs
- unsized-in-unnamed-interface-block-multiple
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 :)
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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20131023/06bdd808/attachment-0001.html>
More information about the mesa-dev
mailing list