Mesa (master): linker: Assign varying locations for separable programs

Ian Romanick idr at kemper.freedesktop.org
Fri May 2 14:31:43 UTC 2014


Module: Mesa
Branch: master
Commit: 1ff5a2b1ba2148b772f5e5c86d64c3cb18e1ce97
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1ff5a2b1ba2148b772f5e5c86d64c3cb18e1ce97

Author: Ian Romanick <ian.d.romanick at intel.com>
Date:   Fri Feb 14 12:10:27 2014 -0800

linker: Assign varying locations for separable programs

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>

---

 src/glsl/link_varyings.cpp |   17 +++++++++++++++++
 src/glsl/linker.cpp        |   16 +++++++++++++---
 2 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp
index 8982332..85a8b90 100644
--- a/src/glsl/link_varyings.cpp
+++ b/src/glsl/link_varyings.cpp
@@ -1198,6 +1198,23 @@ assign_varying_locations(struct gl_context *ctx,
             matches.record(output_var, input_var);
          }
       }
+   } else {
+      /* If there's no producer stage, then this must be a separable program.
+       * For example, we may have a program that has just a fragment shader.
+       * Later this program will be used with some arbitrary vertex (or
+       * geometry) shader program.  This means that locations must be assigned
+       * for all the inputs.
+       */
+      foreach_list(node, consumer->ir) {
+         ir_variable *const input_var =
+            ((ir_instruction *) node)->as_variable();
+
+         if ((input_var == NULL) ||
+             (input_var->data.mode != ir_var_shader_in))
+            continue;
+
+         matches.record(NULL, input_var);
+      }
    }
 
    for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index a1bae29..de7e3cd 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -2502,7 +2502,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
    if (last >= 0 && last < MESA_SHADER_FRAGMENT) {
       gl_shader *const sh = prog->_LinkedShaders[last];
 
-      if (num_tfeedback_decls != 0) {
+      if (num_tfeedback_decls != 0 || prog->SeparateShader) {
          /* There was no fragment shader, but we still have to assign varying
           * locations for use by transform feedback.
           */
@@ -2516,7 +2516,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       do_dead_builtin_varyings(ctx, sh, NULL,
                                num_tfeedback_decls, tfeedback_decls);
 
-      demote_shader_inputs_and_outputs(sh, ir_var_shader_out);
+      if (!prog->SeparateShader)
+         demote_shader_inputs_and_outputs(sh, ir_var_shader_out);
 
       /* Eliminate code that is now dead due to unused outputs being demoted.
        */
@@ -2531,7 +2532,16 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       do_dead_builtin_varyings(ctx, NULL, sh,
                                num_tfeedback_decls, tfeedback_decls);
 
-      demote_shader_inputs_and_outputs(sh, ir_var_shader_in);
+      if (prog->SeparateShader) {
+         if (!assign_varying_locations(ctx, mem_ctx, prog,
+                                       NULL /* producer */,
+                                       sh /* consumer */,
+                                       0 /* num_tfeedback_decls */,
+                                       NULL /* tfeedback_decls */,
+                                       0 /* gs_input_vertices */))
+            goto done;
+      } else
+         demote_shader_inputs_and_outputs(sh, ir_var_shader_in);
 
       while (do_dead_code(sh->ir, false))
          ;




More information about the mesa-commit mailing list