From: Caio Marcelo de Oliveira Filho Date: Wed, 5 Jun 2019 08:25:24 +0000 (-0700) Subject: glsl: Check order and uniqueness of interlock functions X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2cb5907508662b46ad4d15b44f3e786f400ee087;p=mesa.git glsl: Check order and uniqueness of interlock functions With this commit all remaining compilation tests in Piglit for ARB_fragment_shader_interlock will pass. Reviewed-by: Tapani Pälli Reviewed-by: Plamena Manolova --- diff --git a/src/compiler/glsl/ast_function.cpp b/src/compiler/glsl/ast_function.cpp index a35bd63fa41..80cbb582b0e 100644 --- a/src/compiler/glsl/ast_function.cpp +++ b/src/compiler/glsl/ast_function.cpp @@ -2387,13 +2387,19 @@ ast_function_expression::hir(exec_list *instructions, new(ctx) ir_dereference_variable(mvp), new(ctx) ir_dereference_variable(vtx)); } else { + bool is_begin_interlock = false; + bool is_end_interlock = false; + if (sig->is_builtin() && + state->stage == MESA_SHADER_FRAGMENT && + state->ARB_fragment_shader_interlock_enable) { + is_begin_interlock = strcmp(func_name, "beginInvocationInterlockARB") == 0; + is_end_interlock = strcmp(func_name, "endInvocationInterlockARB") == 0; + } + if (sig->is_builtin() && ((state->stage == MESA_SHADER_TESS_CTRL && strcmp(func_name, "barrier") == 0) || - (state->stage == MESA_SHADER_FRAGMENT && - state->ARB_fragment_shader_interlock_enable && - (strcmp(func_name, "beginInvocationInterlockARB") == 0 || - strcmp(func_name, "endInvocationInterlockARB") == 0)))) { + is_begin_interlock || is_end_interlock)) { if (state->current_function == NULL || strcmp(state->current_function->function_name(), "main") != 0) { _mesa_glsl_error(&loc, state, @@ -2411,6 +2417,23 @@ ast_function_expression::hir(exec_list *instructions, } } + /* There can be only one begin/end interlock pair in the function. */ + if (is_begin_interlock) { + if (state->found_begin_interlock) + _mesa_glsl_error(&loc, state, + "beginInvocationInterlockARB may not be used twice"); + state->found_begin_interlock = true; + } else if (is_end_interlock) { + if (!state->found_begin_interlock) + _mesa_glsl_error(&loc, state, + "endInvocationInterlockARB may not be used " + "before beginInvocationInterlockARB"); + if (state->found_end_interlock) + _mesa_glsl_error(&loc, state, + "endInvocationInterlockARB may not be used twice"); + state->found_end_interlock = true; + } + value = generate_call(instructions, sig, &actual_parameters, sub_var, array_idx, state); if (!value) { diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index a3a24810012..4f062ba1543 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -6195,6 +6195,8 @@ ast_function_definition::hir(exec_list *instructions, assert(state->current_function == NULL); state->current_function = signature; state->found_return = false; + state->found_begin_interlock = false; + state->found_end_interlock = false; /* Duplicate parameters declared in the prototype as concrete variables. * Add these to the symbol table. diff --git a/src/compiler/glsl/glsl_parser_extras.cpp b/src/compiler/glsl/glsl_parser_extras.cpp index 41f2a97dfff..a2127f49936 100644 --- a/src/compiler/glsl/glsl_parser_extras.cpp +++ b/src/compiler/glsl/glsl_parser_extras.cpp @@ -197,6 +197,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, this->current_function = NULL; this->toplevel_ir = NULL; this->found_return = false; + this->found_begin_interlock = false; + this->found_end_interlock = false; this->all_invariant = false; this->user_structures = NULL; this->num_user_structures = 0; diff --git a/src/compiler/glsl/glsl_parser_extras.h b/src/compiler/glsl/glsl_parser_extras.h index dad73e924d8..b82b35da5af 100644 --- a/src/compiler/glsl/glsl_parser_extras.h +++ b/src/compiler/glsl/glsl_parser_extras.h @@ -605,6 +605,10 @@ struct _mesa_glsl_parse_state { /** Have we found a return statement in this function? */ bool found_return; + /** Have we found the interlock builtins in this function? */ + bool found_begin_interlock; + bool found_end_interlock; + /** Was there an error during compilation? */ bool error;