glsl: don't allow non-flat integral types in varying structs/arrays.
authorPaul Berry <stereotype441@gmail.com>
Thu, 7 Feb 2013 00:09:39 +0000 (16:09 -0800)
committerPaul Berry <stereotype441@gmail.com>
Wed, 13 Feb 2013 15:58:01 +0000 (07:58 -0800)
In the GLSL 1.30 spec, section 4.3.6 ("Outputs") says:

    "If a vertex output is a signed or unsigned integer or integer
    vector, then it must be qualified with the interpolation qualifier
    flat."

The GLSL ES 3.00 spec further clarifies, in section 4.3.6 ("Output
Variables"):

    "Vertex shader outputs that are, *or contain*, signed or unsigned
    integers or integer vectors must be qualified with the
    interpolation qualifier flat."

(Emphasis mine.)

The language in the GLSL ES 3.00 spec is clearly correct and should be
applied to all shading language versions, since varyings that contain
ints can't be interpolated, regardless of which shading language
version is in use.

(Note that in GLSL 1.50 the restriction is changed to apply to
fragment shader inputs rather than vertex shader outputs, to
accommodate the fact that in the presence of geometry shaders, vertex
shader outputs are not necessarily interpolated.  That will be
addressed by a future patch).

NOTE: This is a candidate for stable branches.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com>
src/glsl/ast_to_hir.cpp
src/glsl/glsl_types.cpp
src/glsl/glsl_types.h

index 668973d4c2a12ef00592f814ef4d66a968b87b9f..2ff44ada777afffb96fee9bcb6c0c28336a0900f 100644 (file)
@@ -2829,9 +2829,9 @@ ast_declarator_list::hir(exec_list *instructions,
        *    flat."
        *
        * From section 4.3.4 of the GLSL 3.00 ES spec:
-       *    "Fragment shader inputs that are signed or unsigned integers or
-       *    integer vectors must be qualified with the interpolation qualifier
-       *    flat."
+       *    "Fragment shader inputs that are, or contain, signed or unsigned
+       *    integers or integer vectors must be qualified with the
+       *    interpolation qualifier flat."
        *
        * Since vertex outputs and fragment inputs must have matching
        * qualifiers, these two requirements are equivalent.
@@ -2839,12 +2839,12 @@ ast_declarator_list::hir(exec_list *instructions,
       if (state->is_version(130, 300)
           && state->target == vertex_shader
           && state->current_function == NULL
-          && var->type->is_integer()
+          && var->type->contains_integer()
           && var->mode == ir_var_shader_out
           && var->interpolation != INTERP_QUALIFIER_FLAT) {
 
-         _mesa_glsl_error(&loc, state, "If a vertex output is an integer, "
-                          "then it must be qualified with 'flat'");
+         _mesa_glsl_error(&loc, state, "If a vertex output is (or contains) "
+                          "an integer, then it must be qualified with 'flat'");
       }
 
 
index 3b066d0991e1be9671712ca8c466587d7cd985bf..82aeb84edb4304a69956dd38b017c111cef4ddd0 100644 (file)
@@ -158,6 +158,24 @@ glsl_type::contains_sampler() const
    }
 }
 
+
+bool
+glsl_type::contains_integer() const
+{
+   if (this->is_array()) {
+      return this->fields.array->contains_integer();
+   } else if (this->is_record()) {
+      for (unsigned int i = 0; i < this->length; i++) {
+        if (this->fields.structure[i].type->contains_integer())
+           return true;
+      }
+      return false;
+   } else {
+      return this->is_integer();
+   }
+}
+
+
 gl_texture_index
 glsl_type::sampler_index() const
 {
index b0db2bf11ceb9a72ffc924f18aa8968791ce01e9..8cfd8dd021d50eed5065e61f23a262df084d454f 100644 (file)
@@ -359,6 +359,12 @@ struct glsl_type {
       return (base_type == GLSL_TYPE_UINT) || (base_type == GLSL_TYPE_INT);
    }
 
+   /**
+    * Query whether or not type is an integral type, or for struct and array
+    * types, contains an integral type.
+    */
+   bool contains_integer() const;
+
    /**
     * Query whether or not a type is a float type
     */