diff options
author | Iago Toral Quiroga <[email protected]> | 2015-04-24 12:34:00 +0200 |
---|---|---|
committer | Samuel Iglesias Gonsalvez <[email protected]> | 2015-09-25 08:39:23 +0200 |
commit | a07d0c26574203415da343718d906375accf95b3 (patch) | |
tree | 97127fb312744ea1c61efef4089a0ce03fb395cb /src/glsl | |
parent | 5ef169034c77ede86546d8dc42f7f22abcd6faa0 (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.cpp | 42 |
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; } |