glsl/linker: check against varying limit after unused varyings are eliminated
authorMarek Olšák <maraeo@gmail.com>
Thu, 13 Jun 2013 01:17:22 +0000 (03:17 +0200)
committerMarek Olšák <maraeo@gmail.com>
Tue, 2 Jul 2013 15:02:14 +0000 (17:02 +0200)
We counted even the varyings which were later eliminated, which was
suboptimal.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/link_varyings.cpp
src/glsl/link_varyings.h
src/glsl/linker.cpp

index 4fdbdc1994268b8fd3357322af8b5a7c6acfdba7..5abc61293ae5c56a02326e7bfc8c8e23664604df 100644 (file)
@@ -1113,16 +1113,12 @@ assign_varying_locations(struct gl_context *ctx,
       }
    }
 
-   unsigned varying_vectors = 0;
-
    if (consumer) {
       foreach_list(node, consumer->ir) {
          ir_variable *const var = ((ir_instruction *) node)->as_variable();
 
-         if ((var == NULL) || (var->mode != ir_var_shader_in))
-            continue;
-
-         if (var->is_unmatched_generic_inout) {
+         if (var && var->mode == ir_var_shader_in &&
+             var->is_unmatched_generic_inout) {
             if (prog->Version <= 120) {
                /* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec:
                 *
@@ -1148,15 +1144,32 @@ assign_varying_locations(struct gl_context *ctx,
              * value is written by the previous stage.
              */
             var->mode = ir_var_auto;
-         } else if (is_varying_var(consumer->Type, var)) {
-            /* The packing rules are used for vertex shader inputs are also
-             * used for fragment shader inputs.
-             */
-            varying_vectors += count_attribute_slots(var->type);
          }
       }
    }
 
+   return true;
+}
+
+bool
+check_against_varying_limit(struct gl_context *ctx,
+                            struct gl_shader_program *prog,
+                            gl_shader *consumer)
+{
+   unsigned varying_vectors = 0;
+
+   foreach_list(node, consumer->ir) {
+      ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+      if (var && var->mode == ir_var_shader_in &&
+          is_varying_var(consumer->Type, var)) {
+         /* The packing rules used for vertex shader inputs are also
+          * used for fragment shader inputs.
+          */
+         varying_vectors += count_attribute_slots(var->type);
+      }
+   }
+
    if (ctx->API == API_OPENGLES2 || prog->IsES) {
       if (varying_vectors > ctx->Const.MaxVarying) {
          if (ctx->Const.GLSLSkipStrictMaxVaryingLimitCheck) {
index ee1010a7b7d42a4e69e06ac35e1b317eda242403..daa9d79c94f133a33c5728989ef79bd55e96d1c8 100644 (file)
@@ -232,4 +232,9 @@ assign_varying_locations(struct gl_context *ctx,
                          unsigned num_tfeedback_decls,
                          tfeedback_decl *tfeedback_decls);
 
+bool
+check_against_varying_limit(struct gl_context *ctx,
+                            struct gl_shader_program *prog,
+                            gl_shader *consumer);
+
 #endif /* GLSL_LINK_VARYINGS_H */
index 3adcddd16b6b8e4d2e8bf293864685a8eb38a4d2..6d7357820c9fad69849d51cb1f03eb0ce36a88ae 100644 (file)
@@ -1929,6 +1929,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       while (do_dead_code(sh_next->ir, false))
          ;
 
+      /* This must be done after all dead varyings are eliminated. */
+      if (!check_against_varying_limit(ctx, prog, sh_next))
+         goto done;
+
       next = i;
    }