glsl: be more strict when validating shader inputs
authorIlia Mirkin <imirkin@alum.mit.edu>
Fri, 13 May 2016 04:26:44 +0000 (00:26 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Fri, 13 May 2016 23:17:26 +0000 (19:17 -0400)
interpolateAt* can only take input variables or an element of an input
variable array. No structs.

Further, GLSL 4.40 relaxes the requirement to allow swizzles, so enable
that as well.

This fixes the following dEQP tests:

dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_sample.negative.interpolate_struct_member
dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_centroid.negative.interpolate_struct_member
dEQP-GLES31.functional.shaders.multisample_interpolation.interpolate_at_offset.negative.interpolate_struct_member

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/glsl/ast_function.cpp

index 4db3dd0384bbac8648439b2addae6e75acbc46b4..6c12565b08467424b966bfde678cc8b628745106 100644 (file)
@@ -208,17 +208,27 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
 
       /* Verify that shader_in parameters are shader inputs */
       if (formal->data.must_be_shader_input) {
-         ir_variable *var = actual->variable_referenced();
-         if (!var || var->data.mode != ir_var_shader_in) {
-            _mesa_glsl_error(&loc, state,
-                             "parameter `%s` must be a shader input",
-                             formal->name);
-            return false;
+         const ir_rvalue *val = actual;
+
+         // GLSL 4.40 allows swizzles, while earlier GLSL versions do not.
+         if (val->ir_type == ir_type_swizzle) {
+            if (!state->is_version(440, 0)) {
+               _mesa_glsl_error(&loc, state,
+                                "parameter `%s` must not be swizzled",
+                                formal->name);
+               return false;
+            }
+            val = ((ir_swizzle *)val)->val;
+         }
+
+         while (val->ir_type == ir_type_dereference_array) {
+            val = ((ir_dereference_array *)val)->array;
          }
 
-         if (actual->ir_type == ir_type_swizzle) {
+         if (!val->as_dereference_variable() ||
+             val->variable_referenced()->data.mode != ir_var_shader_in) {
             _mesa_glsl_error(&loc, state,
-                             "parameter `%s` must not be swizzled",
+                             "parameter `%s` must be a shader input",
                              formal->name);
             return false;
          }