Module: Mesa Branch: 7.9 Commit: 2f398485f26237b7596d63d457d61aebf909fe3f URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=2f398485f26237b7596d63d457d61aebf909fe3f
Author: Ian Romanick <[email protected]> Date: Tue Oct 19 17:59:10 2010 -0700 linker: Improve handling of unread/unwritten shader inputs/outputs Previously some shader input or outputs that hadn't received location assignments could slip through. This could happen when a shader contained user-defined varyings and was used with either fixed-function or assembly shaders. See the piglit tests glsl-[fv]s-user-varying-ff and sso-user-varying-0[12]. NOTE: this is a candidate for the 7.9 branch. (cherry picked from commit cc90e62d70d91fb16abcd66c61c211c0fd573339) --- src/glsl/linker.cpp | 36 +++++++++++++++++++++++++----------- 1 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 63ec4fd..7f0695f 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -1259,19 +1259,20 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index /** - * Demote shader outputs that are not read to being just plain global variables + * Demote shader inputs and outputs that are not used in other stages */ void -demote_unread_shader_outputs(gl_shader *sh) +demote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode) { foreach_list(node, sh->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); - if ((var == NULL) || (var->mode != ir_var_out)) + if ((var == NULL) || (var->mode != int(mode))) continue; - /* An 'out' variable is only really a shader output if its value is read - * by the following stage. + /* A shader 'in' or 'out' variable is only really an input or output if + * its value is used by other shader stages. This will cause the variable + * to have a location assigned. */ if (var->location == -1) { var->mode = ir_var_auto; @@ -1337,8 +1338,6 @@ assign_varying_locations(struct gl_shader_program *prog, } } - demote_unread_shader_outputs(producer); - foreach_list(node, consumer->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); @@ -1525,10 +1524,6 @@ link_shaders(GLcontext *ctx, struct gl_shader_program *prog) */ if (!assign_attribute_locations(prog, 16)) goto done; - - if ((prog->_LinkedShaders[MESA_SHADER_GEOMETRY] == NULL) - && (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)) - demote_unread_shader_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX]); } unsigned prev; @@ -1547,6 +1542,25 @@ link_shaders(GLcontext *ctx, struct gl_shader_program *prog) prev = i; } + if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) { + demote_shader_inputs_and_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX], + ir_var_out); + } + + if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) { + gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_GEOMETRY]; + + demote_shader_inputs_and_outputs(sh, ir_var_in); + demote_shader_inputs_and_outputs(sh, ir_var_inout); + demote_shader_inputs_and_outputs(sh, ir_var_out); + } + + if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) { + gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; + + demote_shader_inputs_and_outputs(sh, ir_var_in); + } + /* FINISHME: Assign fragment shader output locations. */ done: _______________________________________________ mesa-commit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-commit
