From 50895d443ae7b96cb7de6b41857393d4e129d6eb Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Wed, 5 Dec 2012 07:17:07 -0800 Subject: [PATCH] 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 Reviewed-by: Ian Romanick --- src/glsl/linker.cpp | 43 +++++++++++++++++++++++++++++++------------ 1 file 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 -- 2.30.2