summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2013-10-04 10:46:29 -0700
committerIan Romanick <ian.d.romanick@intel.com>2013-10-22 15:23:30 -0700
commit63974c0f5b26e369a790505af6820d4bbcf451b2 (patch)
tree227b453fc6e459d5cb04ae6a5baad96c5454134f
parent1eee0a9f016a1049869f4677f5919186ee3785a2 (diff)
downloadexternal_mesa3d-63974c0f5b26e369a790505af6820d4bbcf451b2.zip
external_mesa3d-63974c0f5b26e369a790505af6820d4bbcf451b2.tar.gz
external_mesa3d-63974c0f5b26e369a790505af6820d4bbcf451b2.tar.bz2
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>
-rw-r--r--src/glsl/linker.cpp48
-rw-r--r--src/glsl/linker.h3
-rw-r--r--src/glsl/tests/invalidate_locations_test.cpp24
3 files changed, 31 insertions, 44 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index bf96d60..b23c31a 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 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 cded1d5..f70dc6f 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);