diff options
author | Iago Toral Quiroga <itoral@igalia.com> | 2015-04-24 12:34:00 +0200 |
---|---|---|
committer | Samuel Iglesias Gonsalvez <siglesias@igalia.com> | 2015-07-09 12:53:53 +0200 |
commit | 5c868b003ddc97369bfbbc6ba6e0305ed72f9d52 (patch) | |
tree | 221e88e537f96030f4921c8271760c998eadae1f | |
parent | 83a648329499dbcc69f99d38338c10c6a8c91e86 (diff) |
glsl: First argument to atomic functions must be a buffer variable
-rw-r--r-- | src/glsl/ast_function.cpp | 37 |
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) { |