diff options
author | Paul Berry <[email protected]> | 2012-12-05 07:17:07 -0800 |
---|---|---|
committer | Paul Berry <[email protected]> | 2012-12-14 10:48:35 -0800 |
commit | 50895d443ae7b96cb7de6b41857393d4e129d6eb (patch) | |
tree | a95d8f1e6693dbb62d13924c2c848f9bebf4288e /src/glsl/linker.cpp | |
parent | 18392443d448e083187d085965375e7de910b18a (diff) |
glsl/linker: Always invalidate shader ins/outs, even in corner cases.
Previously, link_invalidate_variable_locations() was only called
during assign_attribute_or_color_locations() and
assign_varying_locations(). This meant that in the corner case when
there was only a vertex shader, and varyings were being captured by
transform feedback, link_invalidate_variable_locations() wasn't being
called for the varyings.
This patch migrates the calls to link_invalidate_variable_locations()
to link_shaders(), so that they will be called in all circumstances.
In addition, it modifies the call semantics so that
link_invalidate_variable_locations() need only be called once per
shader stage (rather than once for inputs and once for outputs).
Reviewed-by: Eric Anholt <[email protected]>
Reviewed-by: Ian Romanick <[email protected]>
Diffstat (limited to 'src/glsl/linker.cpp')
-rw-r--r-- | src/glsl/linker.cpp | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 802323e32f0..2523dc99d6f 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -200,19 +200,31 @@ linker_warning(gl_shader_program *prog, const char *fmt, ...) void -link_invalidate_variable_locations(gl_shader *sh, enum ir_variable_mode mode, - int generic_base) +link_invalidate_variable_locations(gl_shader *sh, int input_base, + int output_base) { foreach_list(node, sh->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); - if ((var == NULL) || (var->mode != (unsigned) mode)) - continue; + if (var == NULL) + continue; + + int base; + switch (var->mode) { + case ir_var_in: + base = input_base; + break; + case ir_var_out: + base = output_base; + break; + default: + continue; + } /* Only assign locations for generic attributes / varyings / etc. */ - if ((var->location >= generic_base) && !var->explicit_location) - var->location = -1; + if ((var->location >= base) && !var->explicit_location) + var->location = -1; } } @@ -1309,8 +1321,6 @@ assign_attribute_or_color_locations(gl_shader_program *prog, (target_index == MESA_SHADER_VERTEX) ? ir_var_in : ir_var_out; - link_invalidate_variable_locations(sh, direction, generic_base); - /* Temporary storage for the set of attributes that need locations assigned. */ struct temp_attr { @@ -2072,10 +2082,6 @@ assign_varying_locations(struct gl_context *ctx, * not being inputs. This lets the optimizer eliminate them. */ - link_invalidate_variable_locations(producer, ir_var_out, VERT_RESULT_VAR0); - if (consumer) - link_invalidate_variable_locations(consumer, ir_var_in, FRAG_ATTRIB_VAR0); - foreach_list(node, producer->ir) { ir_variable *const output_var = ((ir_instruction *) node)->as_variable(); @@ -2578,6 +2584,19 @@ 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], + VERT_ATTRIB_GENERIC0, VERT_RESULT_VAR0); + } + /* FINISHME: Geometry shaders not implemented yet */ + if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) { + link_invalidate_variable_locations( + prog->_LinkedShaders[MESA_SHADER_FRAGMENT], + FRAG_ATTRIB_VAR0, FRAG_RESULT_DATA0); + } + /* FINISHME: The value of the max_attribute_index parameter is * FINISHME: implementation dependent based on the value of * FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be |