summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIago Toral Quiroga <itoral@igalia.com>2015-04-24 12:34:00 +0200
committerSamuel Iglesias Gonsalvez <siglesias@igalia.com>2015-07-09 12:53:53 +0200
commit5c868b003ddc97369bfbbc6ba6e0305ed72f9d52 (patch)
tree221e88e537f96030f4921c8271760c998eadae1f
parent83a648329499dbcc69f99d38338c10c6a8c91e86 (diff)
glsl: First argument to atomic functions must be a buffer variable
-rw-r--r--src/glsl/ast_function.cpp37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
index 92e26bf241..be6aba673d 100644
--- a/src/glsl/ast_function.cpp
+++ b/src/glsl/ast_function.cpp
@@ -141,6 +141,31 @@ verify_image_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state,
return true;
}
+static bool
+verify_first_atomic_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state,
+ ir_variable *var)
+{
+ if (!var || !var->is_in_shader_storage_block()) {
+ _mesa_glsl_error(loc, state, "First argument to atomic function"
+ " must be a buffer variable");
+ return false;
+ }
+ return true;
+}
+
+static bool
+is_atomic_function(const char *func_name)
+{
+ return !strcmp(func_name, "atomicAdd") ||
+ !strcmp(func_name, "atomicMin") ||
+ !strcmp(func_name, "atomicMax") ||
+ !strcmp(func_name, "atomicAnd") ||
+ !strcmp(func_name, "atomicOr") ||
+ !strcmp(func_name, "atomicXor") ||
+ !strcmp(func_name, "atomicExchange") ||
+ !strcmp(func_name, "atomicCompSwap");
+}
+
/**
* Verify that 'out' and 'inout' actual parameters are lvalues. Also, verify
* that 'const_in' formal parameters (an extension in our IR) correspond to
@@ -155,6 +180,10 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
exec_node *actual_ir_node = actual_ir_parameters.head;
exec_node *actual_ast_node = actual_ast_parameters.head;
+ const char *func_name = sig->function_name();
+ bool is_atomic = is_atomic_function(func_name);
+
+ bool first_param = true;
foreach_in_list(const ir_variable, formal, &sig->parameters) {
/* The lists must be the same length. */
assert(!actual_ir_node->is_tail_sentinel());
@@ -169,6 +198,14 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
*/
YYLTYPE loc = actual_ast->get_location();
+ /* The first parameter of atomic functions must be a buffer variable */
+ if (is_atomic && first_param) {
+ first_param = false;
+ if (!verify_first_atomic_parameter(&loc, state,
+ actual->variable_referenced()))
+ return false;
+ }
+
/* Verify that 'const_in' parameters are ir_constants. */
if (formal->data.mode == ir_var_const_in &&
actual->ir_type != ir_type_constant) {