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 <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
This commit is contained in:
Ian Romanick 2013-10-04 10:46:29 -07:00
parent 1eee0a9f01
commit 63974c0f5b
3 changed files with 31 additions and 44 deletions

View file

@ -366,8 +366,7 @@ parse_program_resource_name(const GLchar *name,
void void
link_invalidate_variable_locations(exec_list *ir, int input_base, link_invalidate_variable_locations(exec_list *ir)
int output_base)
{ {
foreach_list(node, ir) { foreach_list(node, ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable(); 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) if (var == NULL)
continue; continue;
int base; /* Only assign locations for variables that lack an explicit location.
switch (var->mode) { * Explicit locations are set for all built-in variables, generic vertex
case ir_var_shader_in: * shader inputs (via layout(location=...)), and generic fragment shader
base = input_base; * outputs (also via layout(location=...)).
break; */
case ir_var_shader_out: if (!var->explicit_location) {
base = output_base; var->location = -1;
break; var->location_frac = 0;
default:
continue;
} }
/* Only assign locations for generic attributes / varyings / etc. /* 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->location >= base) && !var->explicit_location) if (!var->explicit_location) {
var->location = -1;
if ((var->location == -1) && !var->explicit_location) {
var->is_unmatched_generic_inout = 1; var->is_unmatched_generic_inout = 1;
var->location_frac = 0;
} else { } else {
var->is_unmatched_generic_inout = 0; 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. */ /* Mark all generic shader inputs and outputs as unpaired. */
if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) { if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
link_invalidate_variable_locations( link_invalidate_variable_locations(
prog->_LinkedShaders[MESA_SHADER_VERTEX]->ir, prog->_LinkedShaders[MESA_SHADER_VERTEX]->ir);
VERT_ATTRIB_GENERIC0, VARYING_SLOT_VAR0);
} }
if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) { if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
link_invalidate_variable_locations( link_invalidate_variable_locations(
prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir, prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir);
VARYING_SLOT_VAR0, VARYING_SLOT_VAR0);
} }
if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) { if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {
link_invalidate_variable_locations( link_invalidate_variable_locations(
prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir, prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir);
VARYING_SLOT_VAR0, FRAG_RESULT_DATA0);
} }
/* FINISHME: The value of the max_attribute_index parameter is /* FINISHME: The value of the max_attribute_index parameter is

View file

@ -31,8 +31,7 @@ link_function_calls(gl_shader_program *prog, gl_shader *main,
gl_shader **shader_list, unsigned num_shaders); gl_shader **shader_list, unsigned num_shaders);
extern void extern void
link_invalidate_variable_locations(exec_list *ir, int input_base, link_invalidate_variable_locations(exec_list *ir);
int output_base);
extern void extern void
link_assign_uniform_locations(struct gl_shader_program *prog); link_assign_uniform_locations(struct gl_shader_program *prog);

View file

@ -72,9 +72,7 @@ TEST_F(invalidate_locations, simple_vertex_in_generic)
ir.push_tail(var); ir.push_tail(var);
link_invalidate_variable_locations(&ir, link_invalidate_variable_locations(&ir);
VERT_ATTRIB_GENERIC0,
VARYING_SLOT_VAR0);
EXPECT_EQ(-1, var->location); EXPECT_EQ(-1, var->location);
EXPECT_EQ(0u, var->location_frac); EXPECT_EQ(0u, var->location_frac);
@ -97,9 +95,7 @@ TEST_F(invalidate_locations, explicit_location_vertex_in_generic)
ir.push_tail(var); ir.push_tail(var);
link_invalidate_variable_locations(&ir, link_invalidate_variable_locations(&ir);
VERT_ATTRIB_GENERIC0,
VARYING_SLOT_VAR0);
EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->location); EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->location);
EXPECT_EQ(0u, var->location_frac); EXPECT_EQ(0u, var->location_frac);
@ -123,9 +119,7 @@ TEST_F(invalidate_locations, explicit_location_frac_vertex_in_generic)
ir.push_tail(var); ir.push_tail(var);
link_invalidate_variable_locations(&ir, link_invalidate_variable_locations(&ir);
VERT_ATTRIB_GENERIC0,
VARYING_SLOT_VAR0);
EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->location); EXPECT_EQ(VERT_ATTRIB_GENERIC0, var->location);
EXPECT_EQ(2u, var->location_frac); EXPECT_EQ(2u, var->location_frac);
@ -148,9 +142,7 @@ TEST_F(invalidate_locations, vertex_in_builtin)
ir.push_tail(var); ir.push_tail(var);
link_invalidate_variable_locations(&ir, link_invalidate_variable_locations(&ir);
VERT_ATTRIB_GENERIC0,
VARYING_SLOT_VAR0);
EXPECT_EQ(VERT_ATTRIB_POS, var->location); EXPECT_EQ(VERT_ATTRIB_POS, var->location);
EXPECT_EQ(0u, var->location_frac); EXPECT_EQ(0u, var->location_frac);
@ -172,9 +164,7 @@ TEST_F(invalidate_locations, simple_vertex_out_generic)
ir.push_tail(var); ir.push_tail(var);
link_invalidate_variable_locations(&ir, link_invalidate_variable_locations(&ir);
VERT_ATTRIB_GENERIC0,
VARYING_SLOT_VAR0);
EXPECT_EQ(-1, var->location); EXPECT_EQ(-1, var->location);
EXPECT_EQ(0u, var->location_frac); EXPECT_EQ(0u, var->location_frac);
@ -197,9 +187,7 @@ TEST_F(invalidate_locations, vertex_out_builtin)
ir.push_tail(var); ir.push_tail(var);
link_invalidate_variable_locations(&ir, link_invalidate_variable_locations(&ir);
VERT_ATTRIB_GENERIC0,
VARYING_SLOT_VAR0);
EXPECT_EQ(VARYING_SLOT_COL0, var->location); EXPECT_EQ(VARYING_SLOT_COL0, var->location);
EXPECT_EQ(0u, var->location_frac); EXPECT_EQ(0u, var->location_frac);