aboutsummaryrefslogtreecommitdiffstats
path: root/src/glsl
diff options
context:
space:
mode:
authorIago Toral Quiroga <[email protected]>2015-04-24 12:34:00 +0200
committerSamuel Iglesias Gonsalvez <[email protected]>2015-09-25 08:39:23 +0200
commita07d0c26574203415da343718d906375accf95b3 (patch)
tree97127fb312744ea1c61efef4089a0ce03fb395cb /src/glsl
parent5ef169034c77ede86546d8dc42f7f22abcd6faa0 (diff)
glsl: First argument to atomic functions must be a buffer variable
v2: - Add ssbo_in the names of the static functions so it is clear that this is specific to SSBO atomics. v3: - Move the check after the loop (Kristian Høgsberg) Reviewed-by: Kristian Høgsberg <[email protected]>
Diffstat (limited to 'src/glsl')
-rw-r--r--src/glsl/ast_function.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
index ff5ecb954f0..26d4c62ce36 100644
--- a/src/glsl/ast_function.cpp
+++ b/src/glsl/ast_function.cpp
@@ -142,6 +142,31 @@ verify_image_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state,
return true;
}
+static bool
+verify_first_atomic_ssbo_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_ssbo_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
@@ -256,6 +281,23 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
actual_ir_node = actual_ir_node->next;
actual_ast_node = actual_ast_node->next;
}
+
+ /* The first parameter of atomic functions must be a buffer variable */
+ const char *func_name = sig->function_name();
+ bool is_atomic_ssbo = is_atomic_ssbo_function(func_name);
+ if (is_atomic_ssbo) {
+ const ir_rvalue *const actual = (ir_rvalue *) actual_ir_parameters.head;
+
+ const ast_expression *const actual_ast =
+ exec_node_data(ast_expression, actual_ast_parameters.head, link);
+ YYLTYPE loc = actual_ast->get_location();
+
+ if (!verify_first_atomic_ssbo_parameter(&loc, state,
+ actual->variable_referenced())) {
+ return false;
+ }
+ }
+
return true;
}