glsl/ast: Verify that function calls don't discard image format qualifiers.
authorFrancisco Jerez <currojerez@riseup.net>
Fri, 22 Nov 2013 23:11:50 +0000 (15:11 -0800)
committerFrancisco Jerez <currojerez@riseup.net>
Wed, 12 Feb 2014 17:44:05 +0000 (18:44 +0100)
Reviewed-by: Paul Berry <stereotype441@gmail.com>
src/glsl/ast_function.cpp

index 4c5b0e4aa90ae932960ad8ad6666ffb8e1747601..8fa03dc2d4c2b955459c59914c834c5352d58257 100644 (file)
@@ -93,6 +93,57 @@ prototype_string(const glsl_type *return_type, const char *name,
    return str;
 }
 
+static bool
+verify_image_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state,
+                       const ir_variable *formal, const ir_variable *actual)
+{
+   /**
+    * From the ARB_shader_image_load_store specification:
+    *
+    * "The values of image variables qualified with coherent,
+    *  volatile, restrict, readonly, or writeonly may not be passed
+    *  to functions whose formal parameters lack such
+    *  qualifiers. [...] It is legal to have additional qualifiers
+    *  on a formal parameter, but not to have fewer."
+    */
+   if (actual->data.image.coherent && !formal->data.image.coherent) {
+      _mesa_glsl_error(loc, state,
+                       "function call parameter `%s' drops "
+                       "`coherent' qualifier", formal->name);
+      return false;
+   }
+
+   if (actual->data.image._volatile && !formal->data.image._volatile) {
+      _mesa_glsl_error(loc, state,
+                       "function call parameter `%s' drops "
+                       "`volatile' qualifier", formal->name);
+      return false;
+   }
+
+   if (actual->data.image._restrict && !formal->data.image._restrict) {
+      _mesa_glsl_error(loc, state,
+                       "function call parameter `%s' drops "
+                       "`restrict' qualifier", formal->name);
+      return false;
+   }
+
+   if (actual->data.image.read_only && !formal->data.image.read_only) {
+      _mesa_glsl_error(loc, state,
+                       "function call parameter `%s' drops "
+                       "`readonly' qualifier", formal->name);
+      return false;
+   }
+
+   if (actual->data.image.write_only && !formal->data.image.write_only) {
+      _mesa_glsl_error(loc, state,
+                       "function call parameter `%s' drops "
+                       "`writeonly' qualifier", formal->name);
+      return false;
+   }
+
+   return true;
+}
+
 /**
  * Verify that 'out' and 'inout' actual parameters are lvalues.  Also, verify
  * that 'const_in' formal parameters (an extension in our IR) correspond to
@@ -180,6 +231,13 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
         }
       }
 
+      if (formal->type->is_image() &&
+          actual->variable_referenced()) {
+         if (!verify_image_parameter(&loc, state, formal,
+                                     actual->variable_referenced()))
+            return false;
+      }
+
       actual_ir_node  = actual_ir_node->next;
       actual_ast_node = actual_ast_node->next;
    }