<div dir="ltr">Thank you for reviewing Timothy!<br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 17, 2017 at 7:10 PM, Timothy Arceri <span dir="ltr"><<a href="mailto:tarceri@itsqueeze.com" target="_blank">tarceri@itsqueeze.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="gmail-HOEnZb"><div class="gmail-h5"><br>
<br>
On 18/04/17 11:25, Plamena Manolova wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
This extension provides new GLSL built-in functions<br>
beginInvocationInterlockARB() and endInvocationInterlockARB()<br>
that delimit a critical section of fragment shader code. For<br>
pairs of shader invocations with "overlapping" coverage in a<br>
given pixel, the OpenGL implementation will guarantee that the<br>
critical section of the fragment shader will be executed for<br>
only one fragment at a time.<br>
<br>
Signed-off-by: Plamena Manolova <<a href="mailto:plamena.manolova@intel.com" target="_blank">plamena.manolova@intel.com</a>><br>
---<br>
 src/compiler/glsl/ast.h                  |  10 +++<br>
 src/compiler/glsl/ast_to_hir.<wbr>cpp         |  21 ++++++<br>
 src/compiler/glsl/ast_type.<wbr>cpp           |  90 ++++++++++++++++++++++++-<br>
 src/compiler/glsl/builtin_fun<wbr>ctions.cpp  |  79 ++++++++++++++++++++++<br>
 src/compiler/glsl/glsl_<wbr>parser.yy         | 109 ++++++++++++++++++++++++++++++<wbr>+<br>
 src/compiler/glsl/glsl_<wbr>parser_extras.cpp |  13 ++++<br>
 src/compiler/glsl/glsl_<wbr>parser_extras.h   |   7 ++<br>
 src/compiler/glsl/glsl_to_<wbr>nir.cpp        |  12 ++++<br>
 src/compiler/glsl/ir.h                   |   2 +<br>
 src/compiler/glsl/linker.cpp             |   8 +++<br>
 src/compiler/nir/nir_intrinsi<wbr>cs.h        |   2 +<br>
 src/compiler/shader_info.h               |   5 ++<br>
 src/mesa/main/extensions_tabl<wbr>e.h         |   1 +<br>
 src/mesa/main/mtypes.h                   |   5 ++<br>
 14 files changed, 363 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h<br>
index 455cb81..f2f7e9e 100644<br>
--- a/src/compiler/glsl/ast.h<br>
+++ b/src/compiler/glsl/ast.h<br>
@@ -617,6 +617,16 @@ struct ast_type_qualifier {<br>
           * Flag set if GL_ARB_post_depth_coverage layout qualifier is used.<br>
           */<br>
          unsigned post_depth_coverage:1;<br>
+<br>
+         /**<br>
+          * Flags for the layout qualifers added by ARB_fragment_shader_interlock<br>
+          */<br>
+<br>
+         unsigned pixel_interlock_ordered:1;<br>
+         unsigned pixel_interlock_unordered:1;<br>
+         unsigned sample_interlock_ordered:1;<br>
+         unsigned sample_interlock_unordered:1;<br>
</blockquote>
<br></div></div>
Samuel spent a bunch of time freeing up 4 bits of this flag to be able to implement ARB_bindless_texture. This change will use up all those free bits.<br>
<br>
These only apply to the default in right? I wonder if it's possible to split those qualifiers off from the layout qualifiers applied to varyings?<div><div class="gmail-h5"><font color="#000000"></font></div></div></blockquote><div> </div><div><span style="color:rgb(0,0,0)">I think it should be possible to split them out, I can have a go at that.</span></div><div><span style="color:rgb(0,0,0)"><br></span></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div class="gmail-h5"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
          /**<br>
           * Flag set if GL_INTEL_conservartive_rasteri<wbr>zation layout qualifier<br>
           * is used.<br>
diff --git a/src/compiler/glsl/ast_to_hir<wbr>.cpp b/src/compiler/glsl/ast_to_hir<wbr>.cpp<br>
index 9ea37f4..71c52ad 100644<br>
--- a/src/compiler/glsl/ast_to_hir<wbr>.cpp<br>
+++ b/src/compiler/glsl/ast_to_hir<wbr>.cpp<br>
@@ -3717,6 +3717,27 @@ apply_layout_qualifier_to_vari<wbr>able(const struct ast_type_qualifier *qual,<br>
       _mesa_glsl_error(loc, state, "post_depth_coverage layout qualifier only "<br>
                        "valid in fragment shader input layout declaration.");<br>
    }<br>
+<br>
+   if (qual->flags.q.pixel_interlock<wbr>_ordered) {<br>
+      _mesa_glsl_error(loc, state, "pixel_interlock_ordered layout qualifier only "<br>
+                       "valid in fragment shader input layout declaration.");<br>
+   }<br>
+<br>
+   if (qual->flags.q.pixel_interlock<wbr>_unordered) {<br>
+      _mesa_glsl_error(loc, state, "pixel_interlock_unordered layout qualifier only "<br>
+                       "valid in fragment shader input layout declaration.");<br>
+   }<br>
+<br>
+<br>
+   if (qual->flags.q.pixel_interlock<wbr>_ordered) {<br>
+      _mesa_glsl_error(loc, state, "sample_interlock_ordered layout qualifier only "<br>
+                       "valid in fragment shader input layout declaration.");<br>
+   }<br>
+<br>
+   if (qual->flags.q.pixel_interlock<wbr>_unordered) {<br>
+      _mesa_glsl_error(loc, state, "sample_interlock_unordered layout qualifier only "<br>
+                       "valid in fragment shader input layout declaration.");<br>
+   }<br>
</blockquote>
</div></div>Here and below we duplicated the validation done in glsl_parser.yy. Does the parser validation not catch everything?<br>
<br>
Also there seems to be no link time validation to check that "only one interlock mode can be used at any time" when we are compiling a program that contains multiple fragment shaders. </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Do you have any piglit tests to go with this series?<br></blockquote><div><br></div><div>Yes there's a test here: <a href="https://patchwork.freedesktop.org/patch/151133">https://patchwork.freedesktop.org/patch/151133</a><br></div><div> I'll look into whether we actually need validation in both glsl_parser.yy and ast_type.c<wbr>pp</div><div>    </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div class="gmail-h5">
 }<br>
<br>
 static void<br>
diff --git a/src/compiler/glsl/ast_type.c<wbr>pp b/src/compiler/glsl/ast_type.c<wbr>pp<br>
index d302fc4..0e74253 100644<br>
--- a/src/compiler/glsl/ast_type.c<wbr>pp<br>
+++ b/src/compiler/glsl/ast_type.c<wbr>pp<br>
@@ -580,6 +580,10 @@ ast_type_qualifier::validate_i<wbr>n_qualifier(YYLTYPE *loc,<br>
       valid_in_mask.flags.q.early_f<wbr>ragment_tests = 1;<br>
       valid_in_mask.flags.q.inner_c<wbr>overage = 1;<br>
       valid_in_mask.flags.q.post_de<wbr>pth_coverage = 1;<br>
+      valid_in_mask.flags.q.pixel_in<wbr>terlock_ordered = 1;<br>
+      valid_in_mask.flags.q.pixel_in<wbr>terlock_unordered = 1;<br>
+      valid_in_mask.flags.q.sample_i<wbr>nterlock_ordered = 1;<br>
+      valid_in_mask.flags.q.sample_i<wbr>nterlock_unordered = 1;<br>
       break;<br>
    case MESA_SHADER_COMPUTE:<br>
       valid_in_mask.flags.q.local_s<wbr>ize = 7;<br>
@@ -651,6 +655,86 @@ ast_type_qualifier::merge_into<wbr>_in_qualifier(YYLTYPE *loc,<br>
       r = false;<br>
    }<br>
<br>
+   if (state->in_qualifier->flags.q.<wbr>pixel_interlock_ordered) {<br>
+      if (state->in_qualifier->flags.q.<wbr>pixel_interlock_unordered ||<br>
+          state->in_qualifier->flags.q.s<wbr>ample_interlock_ordered ||<br>
+          state->in_qualifier->flags.q.s<wbr>ample_interlock_unordered) {<br>
+         _mesa_glsl_error(loc, state, "only one interlock mode can be used at "<br>
+                          "any time.");<br>
+         r = false;<br>
+      } else {<br>
+         if (!state->ctx->Multisample.Enab<wbr>led) {<br>
+            state->fs_pixel_interlock_orde<wbr>red = true;<br>
+            state->in_qualifier->flags.q.p<wbr>ixel_interlock_ordered = false;<br>
+         } else {<br>
+            _mesa_glsl_error(loc, state,<br>
+                             "pixel_interlock_ordered can only be used when "<br>
+                             "multisampling is disabled.");<br>
+            r = false;<br>
+         }<br>
+      }<br>
+   }<br>
+<br>
+   if (state->in_qualifier->flags.q.<wbr>pixel_interlock_unordered) {<br>
+      if (state->in_qualifier->flags.q.<wbr>pixel_interlock_ordered ||<br>
+          state->in_qualifier->flags.q.s<wbr>ample_interlock_ordered ||<br>
+          state->in_qualifier->flags.q.s<wbr>ample_interlock_unordered) {<br>
+         _mesa_glsl_error(loc, state, "only one interlock mode can be used at "<br>
+                          "any time.");<br>
+         r = false;<br>
+      } else {<br>
+         if (!state->ctx->Multisample.Enab<wbr>led) {<br>
+            state->fs_pixel_interlock_unor<wbr>dered = true;<br>
+            state->in_qualifier->flags.q.p<wbr>ixel_interlock_unordered = false;<br>
+         } else {<br>
+            _mesa_glsl_error(loc, state,<br>
+                             "pixel_interlock_unordered can only be used when "<br>
+                             "multisampling is disabled.");<br>
+            r = false;<br>
+         }<br>
+      }<br>
+   }<br>
+<br>
+   if (state->in_qualifier->flags.q.<wbr>sample_interlock_ordered) {<br>
+      if (state->in_qualifier->flags.q.<wbr>pixel_interlock_ordered ||<br>
+          state->in_qualifier->flags.q.p<wbr>ixel_interlock_unordered ||<br>
+          state->in_qualifier->flags.q.s<wbr>ample_interlock_unordered) {<br>
+         _mesa_glsl_error(loc, state, "only one interlock mode can be used at "<br>
+                          "any time.");<br>
+         r = false;<br>
+      } else {<br>
+         if (state->ctx->Multisample.Enabl<wbr>ed) {<br>
+            state->fs_sample_interlock_ord<wbr>ered = true;<br>
+            state->in_qualifier->flags.q.s<wbr>ample_interlock_ordered = false;<br>
+         } else {<br>
+            _mesa_glsl_error(loc, state,<br>
+                             "sample_interlock_ordered can only be used when "<br>
+                              "multisampling is enabled.");<br>
+            r = false;<br>
+         }<br>
+      }<br>
+   }<br>
+<br>
+   if (state->in_qualifier->flags.q.<wbr>sample_interlock_unordered) {<br>
+      if (state->in_qualifier->flags.q.<wbr>pixel_interlock_ordered ||<br>
+          state->in_qualifier->flags.q.p<wbr>ixel_interlock_unordered ||<br>
+          state->in_qualifier->flags.q.s<wbr>ample_interlock_ordered) {<br>
+         _mesa_glsl_error(loc, state, "only one interlock mode can be used at "<br>
+                          "any time.");<br>
+         r = false;<br>
+      } else {<br>
+         if (state->ctx->Multisample.Enabl<wbr>ed) {<br>
+            state->fs_sample_interlock_uno<wbr>rdered = true;<br>
+            state->in_qualifier->flags.q.s<wbr>ample_interlock_unordered = false;<br>
+         } else {<br>
+            _mesa_glsl_error(loc, state,<br>
+                             "sample_interlock_unordered can only be used when "<br>
+                             "multisampling is enabled.\n");<br>
+            r = false;<br>
+         }<br>
+      }<br>
+   }<br>
+<br>
    /* We allow the creation of multiple cs_input_layout nodes. Coherence among<br>
     * all existing nodes is checked later, when the AST node is transformed<br>
     * into HIR.<br>
@@ -778,7 +862,11 @@ ast_type_qualifier::validate_f<wbr>lags(YYLTYPE *loc,<br>
                     bad.flags.q.subroutine ? " subroutine" : "",<br>
                     bad.flags.q.blend_support ? " blend_support" : "",<br>
                     bad.flags.q.inner_coverage ? " inner_coverage" : "",<br>
-                    bad.flags.q.post_depth_coverag<wbr>e ? " post_depth_coverage" : "");<br>
+                    bad.flags.q.post_depth_coverag<wbr>e ? " post_depth_coverage" : "",<br>
+                    bad.flags.q.pixel_interlock_or<wbr>dered ? " pixel_interlock_ordered" : "",<br>
+                    bad.flags.q.pixel_interlock_un<wbr>ordered ? " pixel_interlock_unordered": "",<br>
+                    bad.flags.q.sample_interlock_o<wbr>rdered ? " sample_interlock_ordered": "",<br>
+                    bad.flags.q.sample_interlock_u<wbr>nordered ? " sample_interlock_unordered": "");<br>
    return false;<br>
 }<br>
<br>
diff --git a/src/compiler/glsl/builtin_fu<wbr>nctions.cpp b/src/compiler/glsl/builtin_fu<wbr>nctions.cpp<br>
index 5d62d9f..43adf00 100644<br>
--- a/src/compiler/glsl/builtin_fu<wbr>nctions.cpp<br>
+++ b/src/compiler/glsl/builtin_fu<wbr>nctions.cpp<br>
@@ -493,6 +493,12 @@ shader_ballot(const _mesa_glsl_parse_state *state)<br>
 }<br>
<br>
 static bool<br>
+supports_arb_fragment_shader_<wbr>interlock(const _mesa_glsl_parse_state *state)<br>
+{<br>
+   return state->ARB_fragment_shader_int<wbr>erlock_enable;<br>
+}<br>
+<br>
+static bool<br>
 shader_clock(const _mesa_glsl_parse_state *state)<br>
 {<br>
    return state->ARB_shader_clock_enable<wbr>;<br>
@@ -952,6 +958,21 @@ private:<br>
    ir_function_signature *_read_first_invocation(const glsl_type *type);<br>
    ir_function_signature *_read_invocation(const glsl_type *type);<br>
<br>
+<br>
+   ir_function_signature *_begin_invocation_interlock_A<wbr>RB_intrinsic(<br>
+      builtin_available_predicate avail,<br>
+      enum ir_intrinsic_id id);<br>
+   ir_function_signature *_begin_invocation_interlock_A<wbr>RB(<br>
+      const char *intrinsic_name,<br>
+      builtin_available_predicate avail);<br>
+<br>
+   ir_function_signature *_end_invocation_interlock_ARB<wbr>_intrinsic(<br>
+      builtin_available_predicate avail,<br>
+      enum ir_intrinsic_id id);<br>
+   ir_function_signature *_end_invocation_interlock_ARB<wbr>(<br>
+      const char *intrinsic_name,<br>
+      builtin_available_predicate avail);<br>
+<br>
    ir_function_signature *_shader_clock_intrinsic(built<wbr>in_available_predicate avail,<br>
                                                   const glsl_type *type);<br>
    ir_function_signature *_shader_clock(builtin_availab<wbr>le_predicate avail,<br>
@@ -1186,6 +1207,16 @@ builtin_builder::create_intrin<wbr>sics()<br>
                                           ir_intrinsic_memory_barrier_s<wbr>hared),<br>
                 NULL);<br>
<br>
+   add_function("__intrinsic_beg<wbr>in_invocation_interlock_ARB",<br>
+                _begin_invocation_interlock_AR<wbr>B_intrinsic(<br>
+                   supports_arb_fragment_shader_<wbr>interlock,<br>
+                   ir_intrinsic_begin_<wbr>invocation_interlock_ARB), NULL);<br>
+<br>
+   add_function("__intrinsic_<wbr>end_invocation_interlock_ARB",<br>
+                _end_invocation_interlock_ARB_<wbr>intrinsic(<br>
+                   supports_arb_fragment_shader_<wbr>interlock,<br>
+                   ir_intrinsic_end_invocation_i<wbr>nterlock_ARB), NULL);<br>
+<br>
    add_function("__intrinsic_shad<wbr>er_clock",<br>
                 _shader_clock_intrinsic(shade<wbr>r_clock,<br>
                                         glsl_type::uvec2_type),<br>
@@ -3168,6 +3199,18 @@ builtin_builder::create_builti<wbr>ns()<br>
                               glsl_type::uint64_t_type),<br>
                 NULL);<br>
<br>
+   add_function("beginInvocation<wbr>InterlockARB",<br>
+                _begin_invocation_interlock_AR<wbr>B(<br>
+                   "__intrinsic_begin_<wbr>invocation_interlock_ARB",<br>
+                   supports_arb_fragment_shader_<wbr>interlock),<br>
+                NULL);<br>
+<br>
+   add_function("endInvocationIn<wbr>terlockARB",<br>
+                _end_invocation_interlock_ARB(<br>
+                   "__intrinsic_end_invocation_i<wbr>nterlock_ARB",<br>
+                   supports_arb_fragment_shader_<wbr>interlock),<br>
+                NULL);<br>
+<br>
    add_function("anyInvocationARB<wbr>", _vote(ir_unop_vote_any), NULL);<br>
    add_function("allInvocationsAR<wbr>B", _vote(ir_unop_vote_all), NULL);<br>
    add_function("allInvocationsEq<wbr>ualARB", _vote(ir_unop_vote_eq), NULL);<br>
@@ -6034,6 +6077,42 @@ builtin_builder::_read_invocat<wbr>ion(const glsl_type *type)<br>
 }<br>
<br>
 ir_function_signature *<br>
+builtin_builder::_begin_invoc<wbr>ation_interlock_ARB_intrinsic(<wbr>builtin_available_predicate avail,<br>
+                                                           enum ir_intrinsic_id id)<br>
+{<br>
+   MAKE_INTRINSIC(glsl_type::voi<wbr>d_type, id, avail, 0);<br>
+   return sig;<br>
+}<br>
+<br>
+ir_function_signature *<br>
+builtin_builder::_begin_invoc<wbr>ation_interlock_ARB(const char *intrinsic_name,<br>
+                                                 builtin_available_predicate avail)<br>
+{<br>
+   MAKE_SIG(glsl_type::void_<wbr>type, avail, 0);<br>
+   body.emit(call(shader->symbol<wbr>s->get_function(intrinsic_<wbr>name),<br>
+                  NULL, sig->parameters));<br>
+   return sig;<br>
+}<br>
+<br>
+ir_function_signature *<br>
+builtin_builder::_end_invocat<wbr>ion_interlock_ARB_intrinsic(<wbr>builtin_available_predicate avail,<br>
+                                                         enum ir_intrinsic_id id)<br>
+{<br>
+   MAKE_INTRINSIC(glsl_type::voi<wbr>d_type, id, avail, 0);<br>
+   return sig;<br>
+}<br>
+<br>
+ir_function_signature *<br>
+builtin_builder::_end_invocat<wbr>ion_interlock_ARB(const char *intrinsic_name,<br>
+                                               builtin_available_predicate avail)<br>
+{<br>
+   MAKE_SIG(glsl_type::void_<wbr>type, avail, 0);<br>
+   body.emit(call(shader->symbol<wbr>s->get_function(intrinsic_<wbr>name),<br>
+                  NULL, sig->parameters));<br>
+   return sig;<br>
+}<br>
+<br>
+ir_function_signature *<br>
 builtin_builder::_shader_cloc<wbr>k_intrinsic(builtin_available_<wbr>predicate avail,<br>
                                          const glsl_type *type)<br>
 {<br>
diff --git a/src/compiler/glsl/glsl_parse<wbr>r.yy b/src/compiler/glsl/glsl_parse<wbr>r.yy<br>
index e703073..1e23fd2 100644<br>
--- a/src/compiler/glsl/glsl_parse<wbr>r.yy<br>
+++ b/src/compiler/glsl/glsl_parse<wbr>r.yy<br>
@@ -1456,6 +1456,115 @@ layout_qualifier_id:<br>
          }<br>
       }<br>
<br>
+      $$.flags.q.pixel_interlock_ord<wbr>ered = match_layout_qualifier($1,<br>
+         "pixel_interlock_ordered", state) == 0 ? 1 : 0;<br>
+      $$.flags.q.pixel_interlock_uno<wbr>rdered = match_layout_qualifier($1,<br>
+            "pixel_interlock_unordered", state) == 0 ? 1 : 0;<br>
+      $$.flags.q.sample_interlock_or<wbr>dered = match_layout_qualifier($1,<br>
+            "sample_interlock_ordered", state) == 0 ? 1 : 0;<br>
+      $$.flags.q.sample_interlock_un<wbr>ordered = match_layout_qualifier($1,<br>
+            "sample_interlock_unordered", state) == 0 ? 1 : 0;<br>
+<br>
+      if ($$.flags.q.pixel_interlock_or<wbr>dered == 1) {<br>
+         if (state->stage != MESA_SHADER_FRAGMENT) {<br>
+            _mesa_glsl_error(& @1, state,<br>
+                             "pixel_interlock_ordered layout qualifier only "<br>
+                             "valid in fragment shaders.");<br>
+            $$.flags.q.pixel_interlock_ord<wbr>ered = 0;<br>
+         }<br>
+<br>
+         if ($$.flags.q.pixel_interlock_un<wbr>ordered == 1 ||<br>
+             $$.flags.q.sample_interlock_o<wbr>rdered == 1 ||<br>
+             $$.flags.q.sample_interlock_u<wbr>nordered == 1) {<br>
+            _mesa_glsl_error(& @1, state,<br>
+                             "only one interlock mode can be used at any "<br>
+                             "time.");<br>
+            $$.flags.q.pixel_interlock_ord<wbr>ered = 0;<br>
+         }<br>
+<br>
+         if (state->ctx->Multisample.Enabl<wbr>ed) {<br>
+            _mesa_glsl_error(& @1, state,<br>
+                             "pixel_interlock_ordered can only be used when "<br>
+                             "multisampling is disabled.");<br>
+            $$.flags.q.pixel_interlock_ord<wbr>ered = 0;<br>
+         }<br>
+      }<br>
+<br>
+      if ($$.flags.q.pixel_interlock_un<wbr>ordered == 1) {<br>
+         if (state->stage != MESA_SHADER_FRAGMENT) {<br>
+            _mesa_glsl_error(& @1, state,<br>
+                             "pixel_interlock_unordered layout qualifier only "<br>
+                             "valid in fragment shaders.");<br>
+            $$.flags.q.pixel_interlock_uno<wbr>rdered = 0;<br>
+         }<br>
+<br>
+         if ($$.flags.q.pixel_interlock_or<wbr>dered == 1 ||<br>
+             $$.flags.q.sample_interlock_o<wbr>rdered == 1 ||<br>
+             $$.flags.q.sample_interlock_u<wbr>nordered == 1) {<br>
+            _mesa_glsl_error(& @1, state,<br>
+                             "only one interlock mode can be used at any "<br>
+                             "time.");<br>
+            $$.flags.q.pixel_interlock_uno<wbr>rdered = 0;<br>
+         }<br>
+<br>
+         if (state->ctx->Multisample.Enabl<wbr>ed) {<br>
+            _mesa_glsl_error(& @1, state,<br>
+                             "pixel_interlock_unordered can only be used when "<br>
+                             "multisampling is disabled.");<br>
+            $$.flags.q.pixel_interlock_uno<wbr>rdered = 0;<br>
+         }<br>
+      }<br>
+<br>
+      if ($$.flags.q.sample_interlock_o<wbr>rdered == 1) {<br>
+         if (state->stage != MESA_SHADER_FRAGMENT) {<br>
+            _mesa_glsl_error(& @1, state,<br>
+                             "sample_interlock_ordered layout qualifier only "<br>
+                             "valid in fragment shaders.");<br>
+            $$.flags.q.sample_interlock_or<wbr>dered = 0;<br>
+         }<br>
+<br>
+         if ($$.flags.q.pixel_interlock_or<wbr>dered == 1 ||<br>
+             $$.flags.q.pixel_interlock_un<wbr>ordered == 1 ||<br>
+             $$.flags.q.sample_interlock_u<wbr>nordered == 1) {<br>
+            _mesa_glsl_error(& @1, state,<br>
+                             "only one interlock mode can be used at any "<br>
+                             "time.");<br>
+            $$.flags.q.sample_interlock_or<wbr>dered = 0;<br>
+         }<br>
+<br>
+         if (!state->ctx->Multisample.Enab<wbr>led) {<br>
+            _mesa_glsl_error(& @1, state,<br>
+                             "sample_interlock_ordered can only be used when "<br>
+                             "multisampling is enabled.");<br>
+            $$.flags.q.sample_interlock_or<wbr>dered = 0;<br>
+         }<br>
+      }<br>
+<br>
+      if ($$.flags.q.sample_interlock_u<wbr>nordered == 1) {<br>
+         if (state->stage != MESA_SHADER_FRAGMENT) {<br>
+            _mesa_glsl_error(& @1, state,<br>
+                             "sample_interlock_unordered layout qualifier only "<br>
+                             "valid in fragment shaders.");<br>
+            $$.flags.q.sample_interlock_un<wbr>ordered = 0;<br>
+         }<br>
+<br>
+         if ($$.flags.q.pixel_interlock_or<wbr>dered == 1 ||<br>
+             $$.flags.q.pixel_interlock_un<wbr>ordered == 1 ||<br>
+             $$.flags.q.sample_interlock_o<wbr>rdered == 1) {<br>
+            _mesa_glsl_error(& @1, state,<br>
+                             "only one interlock mode can be used at any "<br>
+                             "time.");<br>
+            $$.flags.q.sample_interlock_un<wbr>ordered = 0;<br>
+         }<br>
+<br>
+         if (!state->ctx->Multisample.Enab<wbr>led) {<br>
+            _mesa_glsl_error(& @1, state,<br>
+                             "sample_interlock_unordered can only be used when "<br>
+                             "multisampling is enabled.");<br>
+            $$.flags.q.sample_interlock_un<wbr>ordered = 0;<br>
+         }<br>
+      }<br>
+<br>
       /* Layout qualifiers for tessellation evaluation shaders. */<br>
       if (!$$.flags.i) {<br>
          static const struct {<br>
diff --git a/src/compiler/glsl/glsl_parse<wbr>r_extras.cpp b/src/compiler/glsl/glsl_parse<wbr>r_extras.cpp<br>
index eb12eff..68ebd5c 100644<br>
--- a/src/compiler/glsl/glsl_parse<wbr>r_extras.cpp<br>
+++ b/src/compiler/glsl/glsl_parse<wbr>r_extras.cpp<br>
@@ -300,6 +300,10 @@ _mesa_glsl_parse_state::_mesa_<wbr>glsl_parse_state(struct gl_context *_ctx,<br>
    this->fs_early_fragment_tests = false;<br>
    this->fs_inner_coverage = false;<br>
    this->fs_post_depth_coverage = false;<br>
+   this->fs_pixel_interlock_orde<wbr>red = false;<br>
+   this->fs_pixel_interlock_unor<wbr>dered = false;<br>
+   this->fs_sample_interlock_ord<wbr>ered = false;<br>
+   this->fs_sample_interlock_uno<wbr>rdered = false;<br>
    this->fs_blend_support = 0;<br>
    memset(this->atomic_counter_of<wbr>fsets, 0,<br>
           sizeof(this->atomic_counter_o<wbr>ffsets));<br>
@@ -619,6 +623,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extension<wbr>s[] = {<br>
    EXT(ARB_explicit_uniform_locat<wbr>ion),<br>
    EXT(ARB_fragment_coord_convent<wbr>ions),<br>
    EXT(ARB_fragment_layer_viewpor<wbr>t),<br>
+   EXT(ARB_fragment_shader_inter<wbr>lock),<br>
    EXT(ARB_gpu_shader5),<br>
    EXT(ARB_gpu_shader_fp64),<br>
    EXT(ARB_gpu_shader_int64),<br>
@@ -1720,6 +1725,10 @@ set_shader_inout_layout(struct gl_shader *shader,<br>
       assert(!state->fs_early_fragm<wbr>ent_tests);<br>
       assert(!state->fs_inner_cover<wbr>age);<br>
       assert(!state->fs_post_depth_<wbr>coverage);<br>
+      assert(!state->fs_pixel_interl<wbr>ock_ordered);<br>
+      assert(!state->fs_pixel_interl<wbr>ock_unordered);<br>
+      assert(!state->fs_sample_inter<wbr>lock_ordered);<br>
+      assert(!state->fs_sample_inter<wbr>lock_unordered);<br>
    }<br>
<br>
    for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) {<br>
@@ -1841,6 +1850,10 @@ set_shader_inout_layout(struct gl_shader *shader,<br>
       shader->EarlyFragmentTests = state->fs_early_fragment_tests<wbr>;<br>
       shader->InnerCoverage = state->fs_inner_coverage;<br>
       shader->PostDepthCoverage = state->fs_post_depth_coverage;<br>
+      shader->PixelInterlockOrdered = state->fs_pixel_interlock_orde<wbr>red;<br>
+      shader->PixelInterlockUnordere<wbr>d = state->fs_pixel_interlock_unor<wbr>dered;<br>
+      shader->SampleInterlockOrdered = state->fs_sample_interlock_ord<wbr>ered;<br>
+      shader->SampleInterlockUnorder<wbr>ed = state->fs_sample_interlock_uno<wbr>rdered;<br>
       shader->BlendSupport = state->fs_blend_support;<br>
       break;<br>
<br>
diff --git a/src/compiler/glsl/glsl_parse<wbr>r_extras.h b/src/compiler/glsl/glsl_parse<wbr>r_extras.h<br>
index 6c3bc8a..56218cc 100644<br>
--- a/src/compiler/glsl/glsl_parse<wbr>r_extras.h<br>
+++ b/src/compiler/glsl/glsl_parse<wbr>r_extras.h<br>
@@ -616,6 +616,8 @@ struct _mesa_glsl_parse_state {<br>
    bool ARB_fragment_coord_conventions<wbr>_warn;<br>
    bool ARB_fragment_layer_viewport_en<wbr>able;<br>
    bool ARB_fragment_layer_viewport_wa<wbr>rn;<br>
+   bool ARB_fragment_shader_interlock_<wbr>enable;<br>
+   bool ARB_fragment_shader_interlock_<wbr>warn;<br>
    bool ARB_gpu_shader5_enable;<br>
    bool ARB_gpu_shader5_warn;<br>
    bool ARB_gpu_shader_fp64_enable;<br>
@@ -810,6 +812,11 @@ struct _mesa_glsl_parse_state {<br>
<br>
    bool fs_post_depth_coverage;<br>
<br>
+   bool fs_pixel_interlock_ordered;<br>
+   bool fs_pixel_interlock_unordered;<br>
+   bool fs_sample_interlock_ordered;<br>
+   bool fs_sample_interlock_unordered;<br>
+<br>
    unsigned fs_blend_support;<br>
<br>
    /**<br>
diff --git a/src/compiler/glsl/glsl_to_ni<wbr>r.cpp b/src/compiler/glsl/glsl_to_ni<wbr>r.cpp<br>
index 870d457..82b872c 100644<br>
--- a/src/compiler/glsl/glsl_to_ni<wbr>r.cpp<br>
+++ b/src/compiler/glsl/glsl_to_ni<wbr>r.cpp<br>
@@ -734,6 +734,12 @@ nir_visitor::visit(ir_call *ir)<br>
       case ir_intrinsic_shader_clock:<br>
          op = nir_intrinsic_shader_clock;<br>
          break;<br>
+      case ir_intrinsic_begin_invocation_<wbr>interlock_ARB:<br>
+         op = nir_intrinsic_begin_invocation<wbr>_interlock_ARB;<br>
+         break;<br>
+      case ir_intrinsic_end_invocation_in<wbr>terlock_ARB:<br>
+         op = nir_intrinsic_end_invocation_i<wbr>nterlock_ARB;<br>
+         break;<br>
       case ir_intrinsic_group_memory_barr<wbr>ier:<br>
          op = nir_intrinsic_group_memory_bar<wbr>rier;<br>
          break;<br>
@@ -934,6 +940,12 @@ nir_visitor::visit(ir_call *ir)<br>
          instr->num_components = 2;<br>
          nir_builder_instr_insert(&b, &instr->instr);<br>
          break;<br>
+      case nir_intrinsic_begin_invocation<wbr>_interlock_ARB:<br>
+         nir_builder_instr_insert(&b, &instr->instr);<br>
+         break;<br>
+      case nir_intrinsic_end_invocation_i<wbr>nterlock_ARB:<br>
+         nir_builder_instr_insert(&b, &instr->instr);<br>
+         break;<br>
       case nir_intrinsic_store_ssbo: {<br>
          exec_node *param = ir->actual_parameters.get_head<wbr>();<br>
          ir_rvalue *block = ((ir_instruction *)param)->as_rvalue();<br>
diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h<br>
index d7a81c5..a404d00 100644<br>
--- a/src/compiler/glsl/ir.h<br>
+++ b/src/compiler/glsl/ir.h<br>
@@ -1097,6 +1097,8 @@ enum ir_intrinsic_id {<br>
    ir_intrinsic_memory_barrier_bu<wbr>ffer,<br>
    ir_intrinsic_memory_barrier_im<wbr>age,<br>
    ir_intrinsic_memory_barrier_sh<wbr>ared,<br>
+   ir_intrinsic_begin_<wbr>invocation_interlock_ARB,<br>
+   ir_intrinsic_end_invocation_i<wbr>nterlock_ARB,<br>
<br>
    ir_intrinsic_shared_load,<br>
    ir_intrinsic_shared_store = MAKE_INTRINSIC_FOR_TYPE(store, shared),<br>
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp<br>
index 7ace01d..f06eaf7 100644<br>
--- a/src/compiler/glsl/linker.cpp<br>
+++ b/src/compiler/glsl/linker.cpp<br>
@@ -1895,6 +1895,14 @@ link_fs_inout_layout_qualifier<wbr>s(struct gl_shader_program *prog,<br>
       linked_shader->Program->info.<wbr>fs.inner_coverage |= shader->InnerCoverage;<br>
       linked_shader->Program->info.<wbr>fs.post_depth_coverage |=<br>
          shader->PostDepthCoverage;<br>
+      linked_shader->Program->info.f<wbr>s.pixel_interlock_ordered |=<br>
+         shader-><wbr>PixelInterlockOrdered;<br>
+      linked_shader->Program->info.f<wbr>s.pixel_interlock_unordered |=<br>
+         shader->PixelInterlockUnorder<wbr>ed;<br>
+      linked_shader->Program->info.f<wbr>s.sample_interlock_ordered |=<br>
+         shader->SampleInterlockOrdere<wbr>d;<br>
+      linked_shader->Program->info.f<wbr>s.sample_interlock_unordered |=<br>
+         shader->SampleInterlockUnorde<wbr>red;<br>
<br>
       linked_shader->Program->sh.<wbr>fs.BlendSupport |= shader->BlendSupport;<br>
    }<br>
diff --git a/src/compiler/nir/nir_intrins<wbr>ics.h b/src/compiler/nir/nir_intrins<wbr>ics.h<br>
index 3a519a7..82dac3d 100644<br>
--- a/src/compiler/nir/nir_intrins<wbr>ics.h<br>
+++ b/src/compiler/nir/nir_intrins<wbr>ics.h<br>
@@ -104,6 +104,8 @@ BARRIER(memory_barrier_buffer)<br>
 BARRIER(memory_barrier_image)<br>
 BARRIER(memory_barrier_<wbr>shared)<br>
<br>
+BARRIER(begin_invocation_inte<wbr>rlock_ARB)<br>
+BARRIER(end_invocation_interl<wbr>ock_ARB)<br>
 /** A conditional discard, with a single boolean source. */<br>
 INTRINSIC(discard_if, 1, ARR(1), false, 0, 0, 0, xx, xx, xx, 0)<br>
<br>
diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h<br>
index a670841..3d7282f 100644<br>
--- a/src/compiler/shader_info.h<br>
+++ b/src/compiler/shader_info.h<br>
@@ -127,6 +127,11 @@ typedef struct shader_info {<br>
<br>
          bool post_depth_coverage;<br>
<br>
+         bool pixel_interlock_ordered;<br>
+         bool pixel_interlock_unordered;<br>
+         bool sample_interlock_ordered;<br>
+         bool sample_interlock_unordered;<br>
+<br>
          /** gl_FragDepth layout for ARB_conservative_depth. */<br>
          enum gl_frag_depth_layout depth_layout;<br>
       } fs;<br>
diff --git a/src/mesa/main/extensions_tab<wbr>le.h b/src/mesa/main/extensions_tab<wbr>le.h<br>
index d11cb0f..e64a88a 100644<br>
--- a/src/mesa/main/extensions_tab<wbr>le.h<br>
+++ b/src/mesa/main/extensions_tab<wbr>le.h<br>
@@ -67,6 +67,7 @@ EXT(ARB_fragment_layer_viewpor<wbr>t             , ARB_fragment_layer_viewport<br>
 EXT(ARB_fragment_program                    , ARB_fragment_program                   , GLL,  x ,  x ,  x , 2002)<br>
 EXT(ARB_fragment_program_shad<wbr>ow             , ARB_fragment_program_shadow            , GLL,  x ,  x ,  x , 2003)<br>
 EXT(ARB_fragment_shader                     , ARB_fragment_shader                    , GLL, GLC,  x ,  x , 2002)<br>
+EXT(ARB_fragment_shader_inter<wbr>lock           , ARB_fragment_shader_interlock          , GLL, GLC,  x ,  x , 2015)<br>
 EXT(ARB_framebuffer_no_attach<wbr>ments          , ARB_framebuffer_no_<wbr>attachments         , GLL, GLC,  x ,  x , 2012)<br>
 EXT(ARB_framebuffer_object                  , ARB_framebuffer_object                 , GLL, GLC,  x ,  x , 2005)<br>
 EXT(ARB_framebuffer_sRGB                    , EXT_framebuffer_sRGB                   , GLL, GLC,  x ,  x , 1998)<br>
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h<br>
index c4fab9d..608345d 100644<br>
--- a/src/mesa/main/mtypes.h<br>
+++ b/src/mesa/main/mtypes.h<br>
@@ -2558,6 +2558,10 @@ struct gl_shader<br>
    bool uses_gl_fragcoord;<br>
<br>
    bool PostDepthCoverage;<br>
+   bool PixelInterlockOrdered;<br>
+   bool PixelInterlockUnordered;<br>
+   bool SampleInterlockOrdered;<br>
+   bool SampleInterlockUnordered;<br>
    bool InnerCoverage;<br>
<br>
    /**<br>
@@ -3967,6 +3971,7 @@ struct gl_extensions<br>
    GLboolean ARB_fragment_shader;<br>
    GLboolean ARB_framebuffer_no_attachments<wbr>;<br>
    GLboolean ARB_framebuffer_object;<br>
+   GLboolean ARB_fragment_shader_interlock;<br>
    GLboolean ARB_enhanced_layouts;<br>
    GLboolean ARB_explicit_attrib_location;<br>
    GLboolean ARB_explicit_uniform_location;<br>
--<br>
2.9.3<br></div></div>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
<br>
</blockquote>
</blockquote></div><br></div></div>