glsl: Check order and uniqueness of interlock functions
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Wed, 5 Jun 2019 08:25:24 +0000 (01:25 -0700)
committerCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Mon, 10 Jun 2019 21:29:32 +0000 (14:29 -0700)
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>
src/compiler/glsl/ast_function.cpp
src/compiler/glsl/ast_to_hir.cpp
src/compiler/glsl/glsl_parser_extras.cpp
src/compiler/glsl/glsl_parser_extras.h

index a35bd63fa41ef638d419ad476b5b83f49279d997..80cbb582b0e849fbdf150a4937db0d3cb7ff8e17 100644 (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) {
index a3a24810012abf704ef2499acd3dd742d4412397..4f062ba15435cee7ce517ffff85894a972e76b80 100644 (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.
index 41f2a97dfff960aa577cca25465150cce3c990fb..a2127f49936087bfb03620ef11192079b84c6589 100644 (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;
index dad73e924d81ef969ea1878140843b256b5c6964..b82b35da5afcc769bea3ffe9a03d0b64f2ea33f8 100644 (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;