glsl: Refactor a bunch of the code out of cross_validate_outputs_to_inputs
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 30 Aug 2013 22:41:53 +0000 (15:41 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Wed, 4 Sep 2013 15:08:15 +0000 (08:08 -0700)
The new function, cross_validate_types_and_qualifiers, will have
multiple callers from this file in future commits.

v2: Don't pass the names of the producer / consumer stages to
cross_validate_types_and_qualifiers.  Instead, pass the types and get
the names only in the error paths.  Suggested by Paul.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
src/glsl/link_varyings.cpp

index 4ceb1d33e926e71ada0246e8583fd17f1102b431..0368de9d5756a9d6aec9682f2a6c0be71acef413 100644 (file)
 #include "program.h"
 
 
+/**
+ * Validate the types and qualifiers of an output from one stage against the
+ * matching input to another stage.
+ */
+static void
+cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
+                                    const ir_variable *input,
+                                    const ir_variable *output,
+                                    GLenum consumer_type,
+                                    GLenum producer_type)
+{
+   /* Check that the types match between stages.
+    */
+   const glsl_type *type_to_match = input->type;
+   if (consumer_type == GL_GEOMETRY_SHADER) {
+      assert(type_to_match->is_array()); /* Enforced by ast_to_hir */
+      type_to_match = type_to_match->element_type();
+   }
+   if (type_to_match != output->type) {
+      /* There is a bit of a special case for gl_TexCoord.  This
+       * built-in is unsized by default.  Applications that variable
+       * access it must redeclare it with a size.  There is some
+       * language in the GLSL spec that implies the fragment shader
+       * and vertex shader do not have to agree on this size.  Other
+       * driver behave this way, and one or two applications seem to
+       * rely on it.
+       *
+       * Neither declaration needs to be modified here because the array
+       * sizes are fixed later when update_array_sizes is called.
+       *
+       * From page 48 (page 54 of the PDF) of the GLSL 1.10 spec:
+       *
+       *     "Unlike user-defined varying variables, the built-in
+       *     varying variables don't have a strict one-to-one
+       *     correspondence between the vertex language and the
+       *     fragment language."
+       */
+      if (!output->type->is_array()
+          || (strncmp("gl_", output->name, 3) != 0)) {
+         linker_error(prog,
+                      "%s shader output `%s' declared as type `%s', "
+                      "but %s shader input declared as type `%s'\n",
+                      _mesa_glsl_shader_target_name(producer_type),
+                      output->name,
+                      output->type->name,
+                      _mesa_glsl_shader_target_name(consumer_type),
+                      input->type->name);
+         return;
+      }
+   }
+
+   /* Check that all of the qualifiers match between stages.
+    */
+   if (input->centroid != output->centroid) {
+      linker_error(prog,
+                   "%s shader output `%s' %s centroid qualifier, "
+                   "but %s shader input %s centroid qualifier\n",
+                   _mesa_glsl_shader_target_name(producer_type),
+                   output->name,
+                   (output->centroid) ? "has" : "lacks",
+                   _mesa_glsl_shader_target_name(consumer_type),
+                   (input->centroid) ? "has" : "lacks");
+      return;
+   }
+
+   if (input->invariant != output->invariant) {
+      linker_error(prog,
+                   "%s shader output `%s' %s invariant qualifier, "
+                   "but %s shader input %s invariant qualifier\n",
+                   _mesa_glsl_shader_target_name(producer_type),
+                   output->name,
+                   (output->invariant) ? "has" : "lacks",
+                   _mesa_glsl_shader_target_name(consumer_type),
+                   (input->invariant) ? "has" : "lacks");
+      return;
+   }
+
+   if (input->interpolation != output->interpolation) {
+      linker_error(prog,
+                   "%s shader output `%s' specifies %s "
+                   "interpolation qualifier, "
+                   "but %s shader input specifies %s "
+                   "interpolation qualifier\n",
+                   _mesa_glsl_shader_target_name(producer_type),
+                   output->name,
+                   output->interpolation_string(),
+                   _mesa_glsl_shader_target_name(consumer_type),
+                   input->interpolation_string());
+      return;
+   }
+}
+
 /**
  * Validate that outputs from one stage match inputs of another
  */
@@ -48,10 +140,6 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
                                 gl_shader *producer, gl_shader *consumer)
 {
    glsl_symbol_table parameters;
-   const char *const producer_stage =
-      _mesa_glsl_shader_target_name(producer->Type);
-   const char *const consumer_stage =
-      _mesa_glsl_shader_target_name(consumer->Type);
 
    /* Find all shader outputs in the "producer" stage.
     */
@@ -81,83 +169,8 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
 
       ir_variable *const output = parameters.get_variable(input->name);
       if (output != NULL) {
-        /* Check that the types match between stages.
-         */
-         const glsl_type *type_to_match = input->type;
-         if (consumer->Type == GL_GEOMETRY_SHADER) {
-            assert(type_to_match->is_array()); /* Enforced by ast_to_hir */
-            type_to_match = type_to_match->element_type();
-         }
-        if (type_to_match != output->type) {
-           /* There is a bit of a special case for gl_TexCoord.  This
-            * built-in is unsized by default.  Applications that variable
-            * access it must redeclare it with a size.  There is some
-            * language in the GLSL spec that implies the fragment shader
-            * and vertex shader do not have to agree on this size.  Other
-            * driver behave this way, and one or two applications seem to
-            * rely on it.
-            *
-            * Neither declaration needs to be modified here because the array
-            * sizes are fixed later when update_array_sizes is called.
-            *
-            * From page 48 (page 54 of the PDF) of the GLSL 1.10 spec:
-            *
-            *     "Unlike user-defined varying variables, the built-in
-            *     varying variables don't have a strict one-to-one
-            *     correspondence between the vertex language and the
-            *     fragment language."
-            */
-           if (!output->type->is_array()
-               || (strncmp("gl_", output->name, 3) != 0)) {
-              linker_error(prog,
-                           "%s shader output `%s' declared as type `%s', "
-                           "but %s shader input declared as type `%s'\n",
-                           producer_stage, output->name,
-                           output->type->name,
-                           consumer_stage, input->type->name);
-              return;
-           }
-        }
-
-        /* Check that all of the qualifiers match between stages.
-         */
-        if (input->centroid != output->centroid) {
-           linker_error(prog,
-                        "%s shader output `%s' %s centroid qualifier, "
-                        "but %s shader input %s centroid qualifier\n",
-                        producer_stage,
-                        output->name,
-                        (output->centroid) ? "has" : "lacks",
-                        consumer_stage,
-                        (input->centroid) ? "has" : "lacks");
-           return;
-        }
-
-        if (input->invariant != output->invariant) {
-           linker_error(prog,
-                        "%s shader output `%s' %s invariant qualifier, "
-                        "but %s shader input %s invariant qualifier\n",
-                        producer_stage,
-                        output->name,
-                        (output->invariant) ? "has" : "lacks",
-                        consumer_stage,
-                        (input->invariant) ? "has" : "lacks");
-           return;
-        }
-
-        if (input->interpolation != output->interpolation) {
-           linker_error(prog,
-                        "%s shader output `%s' specifies %s "
-                        "interpolation qualifier, "
-                        "but %s shader input specifies %s "
-                        "interpolation qualifier\n",
-                        producer_stage,
-                        output->name,
-                        output->interpolation_string(),
-                        consumer_stage,
-                        input->interpolation_string());
-           return;
-        }
+         cross_validate_types_and_qualifiers(prog, input, output,
+                                             consumer->Type, producer->Type);
       }
    }
 }