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 <tapani.palli@intel.com>
Reviewed-by: Plamena Manolova <plamena.manolova@intel.com>
This commit is contained in:
Caio Marcelo de Oliveira Filho 2019-06-05 01:25:24 -07:00
parent b7c9fc72fd
commit 2cb5907508
4 changed files with 35 additions and 4 deletions

View file

@ -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) {

View file

@ -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.

View file

@ -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;

View file

@ -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;