Mesa (7.9): linker: Improve handling of unread/unwritten shader inputs/ outputs

Ian Romanick idr at kemper.freedesktop.org
Tue Dec 14 21:13:04 UTC 2010


Module: Mesa
Branch: 7.9
Commit: 2f398485f26237b7596d63d457d61aebf909fe3f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2f398485f26237b7596d63d457d61aebf909fe3f

Author: Ian Romanick <ian.d.romanick at intel.com>
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:




More information about the mesa-commit mailing list