From 63974c0f5b26e369a790505af6820d4bbcf451b2 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Fri, 4 Oct 2013 10:46:29 -0700 Subject: [PATCH] glsl: Simplify the interface to link_invalidate_variable_locations 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 Reviewed-by: Paul Berry --- src/glsl/linker.cpp | 48 ++++++++++---------- src/glsl/linker.h | 3 +- src/glsl/tests/invalidate_locations_test.cpp | 24 +++------- 3 files changed, 31 insertions(+), 44 deletions(-) diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index bf96d606488..b23c31a166b 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; } @@ -2217,18 +2220,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 9915c38b01e..887cd33d1cd 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 cded1d5e8c7..f70dc6f2626 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); @@ -172,9 +164,7 @@ TEST_F(invalidate_locations, simple_vertex_out_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); @@ -197,9 +187,7 @@ TEST_F(invalidate_locations, vertex_out_builtin) ir.push_tail(var); - link_invalidate_variable_locations(&ir, - VERT_ATTRIB_GENERIC0, - VARYING_SLOT_VAR0); + link_invalidate_variable_locations(&ir); EXPECT_EQ(VARYING_SLOT_COL0, var->location); EXPECT_EQ(0u, var->location_frac); -- 2.30.2