[Mesa-dev] [PATCH 1/2] mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.

Samuel Pitoiset samuel.pitoiset at gmail.com
Tue Apr 18 09:52:05 UTC 2017



On 04/18/2017 04:10 AM, Timothy Arceri wrote:
> 
> 
> On 18/04/17 11:25, Plamena Manolova wrote:
>> This extension provides new GLSL built-in functions
>> beginInvocationInterlockARB() and endInvocationInterlockARB()
>> that delimit a critical section of fragment shader code. For
>> pairs of shader invocations with "overlapping" coverage in a
>> given pixel, the OpenGL implementation will guarantee that the
>> critical section of the fragment shader will be executed for
>> only one fragment at a time.
>>
>> Signed-off-by: Plamena Manolova <plamena.manolova at intel.com>
>> ---
>>  src/compiler/glsl/ast.h                  |  10 +++
>>  src/compiler/glsl/ast_to_hir.cpp         |  21 ++++++
>>  src/compiler/glsl/ast_type.cpp           |  90 ++++++++++++++++++++++++-
>>  src/compiler/glsl/builtin_functions.cpp  |  79 ++++++++++++++++++++++
>>  src/compiler/glsl/glsl_parser.yy         | 109 
>> +++++++++++++++++++++++++++++++
>>  src/compiler/glsl/glsl_parser_extras.cpp |  13 ++++
>>  src/compiler/glsl/glsl_parser_extras.h   |   7 ++
>>  src/compiler/glsl/glsl_to_nir.cpp        |  12 ++++
>>  src/compiler/glsl/ir.h                   |   2 +
>>  src/compiler/glsl/linker.cpp             |   8 +++
>>  src/compiler/nir/nir_intrinsics.h        |   2 +
>>  src/compiler/shader_info.h               |   5 ++
>>  src/mesa/main/extensions_table.h         |   1 +
>>  src/mesa/main/mtypes.h                   |   5 ++
>>  14 files changed, 363 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h
>> index 455cb81..f2f7e9e 100644
>> --- a/src/compiler/glsl/ast.h
>> +++ b/src/compiler/glsl/ast.h
>> @@ -617,6 +617,16 @@ struct ast_type_qualifier {
>>            * Flag set if GL_ARB_post_depth_coverage layout qualifier 
>> is used.
>>            */
>>           unsigned post_depth_coverage:1;
>> +
>> +         /**
>> +          * Flags for the layout qualifers added by 
>> ARB_fragment_shader_interlock
>> +          */
>> +
>> +         unsigned pixel_interlock_ordered:1;
>> +         unsigned pixel_interlock_unordered:1;
>> +         unsigned sample_interlock_ordered:1;
>> +         unsigned sample_interlock_unordered:1;
> 
> 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.

That's true. Not sure if you noticed, but there is exactly 4 free bits 
in this flags... which is just enough for ARB_bindless_texture.

In terms of priority, bindless is going to be mandatory for some new 
apps. And it looks like complicated to free more bits in that area.

Would be very nice if we can give the priority to bindless.

> 
> 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?
> 
>> +
>>           /**
>>            * Flag set if GL_INTEL_conservartive_rasterization layout 
>> qualifier
>>            * is used.
>> diff --git a/src/compiler/glsl/ast_to_hir.cpp 
>> b/src/compiler/glsl/ast_to_hir.cpp
>> index 9ea37f4..71c52ad 100644
>> --- a/src/compiler/glsl/ast_to_hir.cpp
>> +++ b/src/compiler/glsl/ast_to_hir.cpp
>> @@ -3717,6 +3717,27 @@ apply_layout_qualifier_to_variable(const struct 
>> ast_type_qualifier *qual,
>>        _mesa_glsl_error(loc, state, "post_depth_coverage layout 
>> qualifier only "
>>                         "valid in fragment shader input layout 
>> declaration.");
>>     }
>> +
>> +   if (qual->flags.q.pixel_interlock_ordered) {
>> +      _mesa_glsl_error(loc, state, "pixel_interlock_ordered layout 
>> qualifier only "
>> +                       "valid in fragment shader input layout 
>> declaration.");
>> +   }
>> +
>> +   if (qual->flags.q.pixel_interlock_unordered) {
>> +      _mesa_glsl_error(loc, state, "pixel_interlock_unordered layout 
>> qualifier only "
>> +                       "valid in fragment shader input layout 
>> declaration.");
>> +   }
>> +
>> +
>> +   if (qual->flags.q.pixel_interlock_ordered) {
>> +      _mesa_glsl_error(loc, state, "sample_interlock_ordered layout 
>> qualifier only "
>> +                       "valid in fragment shader input layout 
>> declaration.");
>> +   }
>> +
>> +   if (qual->flags.q.pixel_interlock_unordered) {
>> +      _mesa_glsl_error(loc, state, "sample_interlock_unordered layout 
>> qualifier only "
>> +                       "valid in fragment shader input layout 
>> declaration.");
>> +   }
> 
> Here and below we duplicated the validation done in glsl_parser.yy. Does 
> the parser validation not catch everything?
> 
> 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.
> 
> Do you have any piglit tests to go with this series?
> 
>>  }
>>
>>  static void
>> diff --git a/src/compiler/glsl/ast_type.cpp 
>> b/src/compiler/glsl/ast_type.cpp
>> index d302fc4..0e74253 100644
>> --- a/src/compiler/glsl/ast_type.cpp
>> +++ b/src/compiler/glsl/ast_type.cpp
>> @@ -580,6 +580,10 @@ ast_type_qualifier::validate_in_qualifier(YYLTYPE 
>> *loc,
>>        valid_in_mask.flags.q.early_fragment_tests = 1;
>>        valid_in_mask.flags.q.inner_coverage = 1;
>>        valid_in_mask.flags.q.post_depth_coverage = 1;
>> +      valid_in_mask.flags.q.pixel_interlock_ordered = 1;
>> +      valid_in_mask.flags.q.pixel_interlock_unordered = 1;
>> +      valid_in_mask.flags.q.sample_interlock_ordered = 1;
>> +      valid_in_mask.flags.q.sample_interlock_unordered = 1;
>>        break;
>>     case MESA_SHADER_COMPUTE:
>>        valid_in_mask.flags.q.local_size = 7;
>> @@ -651,6 +655,86 @@ 
>> ast_type_qualifier::merge_into_in_qualifier(YYLTYPE *loc,
>>        r = false;
>>     }
>>
>> +   if (state->in_qualifier->flags.q.pixel_interlock_ordered) {
>> +      if (state->in_qualifier->flags.q.pixel_interlock_unordered ||
>> +          state->in_qualifier->flags.q.sample_interlock_ordered ||
>> +          state->in_qualifier->flags.q.sample_interlock_unordered) {
>> +         _mesa_glsl_error(loc, state, "only one interlock mode can be 
>> used at "
>> +                          "any time.");
>> +         r = false;
>> +      } else {
>> +         if (!state->ctx->Multisample.Enabled) {
>> +            state->fs_pixel_interlock_ordered = true;
>> +            state->in_qualifier->flags.q.pixel_interlock_ordered = 
>> false;
>> +         } else {
>> +            _mesa_glsl_error(loc, state,
>> +                             "pixel_interlock_ordered can only be 
>> used when "
>> +                             "multisampling is disabled.");
>> +            r = false;
>> +         }
>> +      }
>> +   }
>> +
>> +   if (state->in_qualifier->flags.q.pixel_interlock_unordered) {
>> +      if (state->in_qualifier->flags.q.pixel_interlock_ordered ||
>> +          state->in_qualifier->flags.q.sample_interlock_ordered ||
>> +          state->in_qualifier->flags.q.sample_interlock_unordered) {
>> +         _mesa_glsl_error(loc, state, "only one interlock mode can be 
>> used at "
>> +                          "any time.");
>> +         r = false;
>> +      } else {
>> +         if (!state->ctx->Multisample.Enabled) {
>> +            state->fs_pixel_interlock_unordered = true;
>> +            state->in_qualifier->flags.q.pixel_interlock_unordered = 
>> false;
>> +         } else {
>> +            _mesa_glsl_error(loc, state,
>> +                             "pixel_interlock_unordered can only be 
>> used when "
>> +                             "multisampling is disabled.");
>> +            r = false;
>> +         }
>> +      }
>> +   }
>> +
>> +   if (state->in_qualifier->flags.q.sample_interlock_ordered) {
>> +      if (state->in_qualifier->flags.q.pixel_interlock_ordered ||
>> +          state->in_qualifier->flags.q.pixel_interlock_unordered ||
>> +          state->in_qualifier->flags.q.sample_interlock_unordered) {
>> +         _mesa_glsl_error(loc, state, "only one interlock mode can be 
>> used at "
>> +                          "any time.");
>> +         r = false;
>> +      } else {
>> +         if (state->ctx->Multisample.Enabled) {
>> +            state->fs_sample_interlock_ordered = true;
>> +            state->in_qualifier->flags.q.sample_interlock_ordered = 
>> false;
>> +         } else {
>> +            _mesa_glsl_error(loc, state,
>> +                             "sample_interlock_ordered can only be 
>> used when "
>> +                              "multisampling is enabled.");
>> +            r = false;
>> +         }
>> +      }
>> +   }
>> +
>> +   if (state->in_qualifier->flags.q.sample_interlock_unordered) {
>> +      if (state->in_qualifier->flags.q.pixel_interlock_ordered ||
>> +          state->in_qualifier->flags.q.pixel_interlock_unordered ||
>> +          state->in_qualifier->flags.q.sample_interlock_ordered) {
>> +         _mesa_glsl_error(loc, state, "only one interlock mode can be 
>> used at "
>> +                          "any time.");
>> +         r = false;
>> +      } else {
>> +         if (state->ctx->Multisample.Enabled) {
>> +            state->fs_sample_interlock_unordered = true;
>> +            state->in_qualifier->flags.q.sample_interlock_unordered = 
>> false;
>> +         } else {
>> +            _mesa_glsl_error(loc, state,
>> +                             "sample_interlock_unordered can only be 
>> used when "
>> +                             "multisampling is enabled.\n");
>> +            r = false;
>> +         }
>> +      }
>> +   }
>> +
>>     /* We allow the creation of multiple cs_input_layout nodes. 
>> Coherence among
>>      * all existing nodes is checked later, when the AST node is 
>> transformed
>>      * into HIR.
>> @@ -778,7 +862,11 @@ ast_type_qualifier::validate_flags(YYLTYPE *loc,
>>                      bad.flags.q.subroutine ? " subroutine" : "",
>>                      bad.flags.q.blend_support ? " blend_support" : "",
>>                      bad.flags.q.inner_coverage ? " inner_coverage" : "",
>> -                    bad.flags.q.post_depth_coverage ? " 
>> post_depth_coverage" : "");
>> +                    bad.flags.q.post_depth_coverage ? " 
>> post_depth_coverage" : "",
>> +                    bad.flags.q.pixel_interlock_ordered ? " 
>> pixel_interlock_ordered" : "",
>> +                    bad.flags.q.pixel_interlock_unordered ? " 
>> pixel_interlock_unordered": "",
>> +                    bad.flags.q.sample_interlock_ordered ? " 
>> sample_interlock_ordered": "",
>> +                    bad.flags.q.sample_interlock_unordered ? " 
>> sample_interlock_unordered": "");
>>     return false;
>>  }
>>
>> diff --git a/src/compiler/glsl/builtin_functions.cpp 
>> b/src/compiler/glsl/builtin_functions.cpp
>> index 5d62d9f..43adf00 100644
>> --- a/src/compiler/glsl/builtin_functions.cpp
>> +++ b/src/compiler/glsl/builtin_functions.cpp
>> @@ -493,6 +493,12 @@ shader_ballot(const _mesa_glsl_parse_state *state)
>>  }
>>
>>  static bool
>> +supports_arb_fragment_shader_interlock(const _mesa_glsl_parse_state 
>> *state)
>> +{
>> +   return state->ARB_fragment_shader_interlock_enable;
>> +}
>> +
>> +static bool
>>  shader_clock(const _mesa_glsl_parse_state *state)
>>  {
>>     return state->ARB_shader_clock_enable;
>> @@ -952,6 +958,21 @@ private:
>>     ir_function_signature *_read_first_invocation(const glsl_type *type);
>>     ir_function_signature *_read_invocation(const glsl_type *type);
>>
>> +
>> +   ir_function_signature *_begin_invocation_interlock_ARB_intrinsic(
>> +      builtin_available_predicate avail,
>> +      enum ir_intrinsic_id id);
>> +   ir_function_signature *_begin_invocation_interlock_ARB(
>> +      const char *intrinsic_name,
>> +      builtin_available_predicate avail);
>> +
>> +   ir_function_signature *_end_invocation_interlock_ARB_intrinsic(
>> +      builtin_available_predicate avail,
>> +      enum ir_intrinsic_id id);
>> +   ir_function_signature *_end_invocation_interlock_ARB(
>> +      const char *intrinsic_name,
>> +      builtin_available_predicate avail);
>> +
>>     ir_function_signature 
>> *_shader_clock_intrinsic(builtin_available_predicate avail,
>>                                                    const glsl_type 
>> *type);
>>     ir_function_signature *_shader_clock(builtin_available_predicate 
>> avail,
>> @@ -1186,6 +1207,16 @@ builtin_builder::create_intrinsics()
>>                                            
>> ir_intrinsic_memory_barrier_shared),
>>                  NULL);
>>
>> +   add_function("__intrinsic_begin_invocation_interlock_ARB",
>> +                _begin_invocation_interlock_ARB_intrinsic(
>> +                   supports_arb_fragment_shader_interlock,
>> +                   ir_intrinsic_begin_invocation_interlock_ARB), NULL);
>> +
>> +   add_function("__intrinsic_end_invocation_interlock_ARB",
>> +                _end_invocation_interlock_ARB_intrinsic(
>> +                   supports_arb_fragment_shader_interlock,
>> +                   ir_intrinsic_end_invocation_interlock_ARB), NULL);
>> +
>>     add_function("__intrinsic_shader_clock",
>>                  _shader_clock_intrinsic(shader_clock,
>>                                          glsl_type::uvec2_type),
>> @@ -3168,6 +3199,18 @@ builtin_builder::create_builtins()
>>                                glsl_type::uint64_t_type),
>>                  NULL);
>>
>> +   add_function("beginInvocationInterlockARB",
>> +                _begin_invocation_interlock_ARB(
>> +                   "__intrinsic_begin_invocation_interlock_ARB",
>> +                   supports_arb_fragment_shader_interlock),
>> +                NULL);
>> +
>> +   add_function("endInvocationInterlockARB",
>> +                _end_invocation_interlock_ARB(
>> +                   "__intrinsic_end_invocation_interlock_ARB",
>> +                   supports_arb_fragment_shader_interlock),
>> +                NULL);
>> +
>>     add_function("anyInvocationARB", _vote(ir_unop_vote_any), NULL);
>>     add_function("allInvocationsARB", _vote(ir_unop_vote_all), NULL);
>>     add_function("allInvocationsEqualARB", _vote(ir_unop_vote_eq), NULL);
>> @@ -6034,6 +6077,42 @@ builtin_builder::_read_invocation(const 
>> glsl_type *type)
>>  }
>>
>>  ir_function_signature *
>> +builtin_builder::_begin_invocation_interlock_ARB_intrinsic(builtin_available_predicate 
>> avail,
>> +                                                           enum 
>> ir_intrinsic_id id)
>> +{
>> +   MAKE_INTRINSIC(glsl_type::void_type, id, avail, 0);
>> +   return sig;
>> +}
>> +
>> +ir_function_signature *
>> +builtin_builder::_begin_invocation_interlock_ARB(const char 
>> *intrinsic_name,
>> +                                                 
>> builtin_available_predicate avail)
>> +{
>> +   MAKE_SIG(glsl_type::void_type, avail, 0);
>> +   body.emit(call(shader->symbols->get_function(intrinsic_name),
>> +                  NULL, sig->parameters));
>> +   return sig;
>> +}
>> +
>> +ir_function_signature *
>> +builtin_builder::_end_invocation_interlock_ARB_intrinsic(builtin_available_predicate 
>> avail,
>> +                                                         enum 
>> ir_intrinsic_id id)
>> +{
>> +   MAKE_INTRINSIC(glsl_type::void_type, id, avail, 0);
>> +   return sig;
>> +}
>> +
>> +ir_function_signature *
>> +builtin_builder::_end_invocation_interlock_ARB(const char 
>> *intrinsic_name,
>> +                                               
>> builtin_available_predicate avail)
>> +{
>> +   MAKE_SIG(glsl_type::void_type, avail, 0);
>> +   body.emit(call(shader->symbols->get_function(intrinsic_name),
>> +                  NULL, sig->parameters));
>> +   return sig;
>> +}
>> +
>> +ir_function_signature *
>>  builtin_builder::_shader_clock_intrinsic(builtin_available_predicate 
>> avail,
>>                                           const glsl_type *type)
>>  {
>> diff --git a/src/compiler/glsl/glsl_parser.yy 
>> b/src/compiler/glsl/glsl_parser.yy
>> index e703073..1e23fd2 100644
>> --- a/src/compiler/glsl/glsl_parser.yy
>> +++ b/src/compiler/glsl/glsl_parser.yy
>> @@ -1456,6 +1456,115 @@ layout_qualifier_id:
>>           }
>>        }
>>
>> +      $$.flags.q.pixel_interlock_ordered = match_layout_qualifier($1,
>> +         "pixel_interlock_ordered", state) == 0 ? 1 : 0;
>> +      $$.flags.q.pixel_interlock_unordered = match_layout_qualifier($1,
>> +            "pixel_interlock_unordered", state) == 0 ? 1 : 0;
>> +      $$.flags.q.sample_interlock_ordered = match_layout_qualifier($1,
>> +            "sample_interlock_ordered", state) == 0 ? 1 : 0;
>> +      $$.flags.q.sample_interlock_unordered = match_layout_qualifier($1,
>> +            "sample_interlock_unordered", state) == 0 ? 1 : 0;
>> +
>> +      if ($$.flags.q.pixel_interlock_ordered == 1) {
>> +         if (state->stage != MESA_SHADER_FRAGMENT) {
>> +            _mesa_glsl_error(& @1, state,
>> +                             "pixel_interlock_ordered layout 
>> qualifier only "
>> +                             "valid in fragment shaders.");
>> +            $$.flags.q.pixel_interlock_ordered = 0;
>> +         }
>> +
>> +         if ($$.flags.q.pixel_interlock_unordered == 1 ||
>> +             $$.flags.q.sample_interlock_ordered == 1 ||
>> +             $$.flags.q.sample_interlock_unordered == 1) {
>> +            _mesa_glsl_error(& @1, state,
>> +                             "only one interlock mode can be used at 
>> any "
>> +                             "time.");
>> +            $$.flags.q.pixel_interlock_ordered = 0;
>> +         }
>> +
>> +         if (state->ctx->Multisample.Enabled) {
>> +            _mesa_glsl_error(& @1, state,
>> +                             "pixel_interlock_ordered can only be 
>> used when "
>> +                             "multisampling is disabled.");
>> +            $$.flags.q.pixel_interlock_ordered = 0;
>> +         }
>> +      }
>> +
>> +      if ($$.flags.q.pixel_interlock_unordered == 1) {
>> +         if (state->stage != MESA_SHADER_FRAGMENT) {
>> +            _mesa_glsl_error(& @1, state,
>> +                             "pixel_interlock_unordered layout 
>> qualifier only "
>> +                             "valid in fragment shaders.");
>> +            $$.flags.q.pixel_interlock_unordered = 0;
>> +         }
>> +
>> +         if ($$.flags.q.pixel_interlock_ordered == 1 ||
>> +             $$.flags.q.sample_interlock_ordered == 1 ||
>> +             $$.flags.q.sample_interlock_unordered == 1) {
>> +            _mesa_glsl_error(& @1, state,
>> +                             "only one interlock mode can be used at 
>> any "
>> +                             "time.");
>> +            $$.flags.q.pixel_interlock_unordered = 0;
>> +         }
>> +
>> +         if (state->ctx->Multisample.Enabled) {
>> +            _mesa_glsl_error(& @1, state,
>> +                             "pixel_interlock_unordered can only be 
>> used when "
>> +                             "multisampling is disabled.");
>> +            $$.flags.q.pixel_interlock_unordered = 0;
>> +         }
>> +      }
>> +
>> +      if ($$.flags.q.sample_interlock_ordered == 1) {
>> +         if (state->stage != MESA_SHADER_FRAGMENT) {
>> +            _mesa_glsl_error(& @1, state,
>> +                             "sample_interlock_ordered layout 
>> qualifier only "
>> +                             "valid in fragment shaders.");
>> +            $$.flags.q.sample_interlock_ordered = 0;
>> +         }
>> +
>> +         if ($$.flags.q.pixel_interlock_ordered == 1 ||
>> +             $$.flags.q.pixel_interlock_unordered == 1 ||
>> +             $$.flags.q.sample_interlock_unordered == 1) {
>> +            _mesa_glsl_error(& @1, state,
>> +                             "only one interlock mode can be used at 
>> any "
>> +                             "time.");
>> +            $$.flags.q.sample_interlock_ordered = 0;
>> +         }
>> +
>> +         if (!state->ctx->Multisample.Enabled) {
>> +            _mesa_glsl_error(& @1, state,
>> +                             "sample_interlock_ordered can only be 
>> used when "
>> +                             "multisampling is enabled.");
>> +            $$.flags.q.sample_interlock_ordered = 0;
>> +         }
>> +      }
>> +
>> +      if ($$.flags.q.sample_interlock_unordered == 1) {
>> +         if (state->stage != MESA_SHADER_FRAGMENT) {
>> +            _mesa_glsl_error(& @1, state,
>> +                             "sample_interlock_unordered layout 
>> qualifier only "
>> +                             "valid in fragment shaders.");
>> +            $$.flags.q.sample_interlock_unordered = 0;
>> +         }
>> +
>> +         if ($$.flags.q.pixel_interlock_ordered == 1 ||
>> +             $$.flags.q.pixel_interlock_unordered == 1 ||
>> +             $$.flags.q.sample_interlock_ordered == 1) {
>> +            _mesa_glsl_error(& @1, state,
>> +                             "only one interlock mode can be used at 
>> any "
>> +                             "time.");
>> +            $$.flags.q.sample_interlock_unordered = 0;
>> +         }
>> +
>> +         if (!state->ctx->Multisample.Enabled) {
>> +            _mesa_glsl_error(& @1, state,
>> +                             "sample_interlock_unordered can only be 
>> used when "
>> +                             "multisampling is enabled.");
>> +            $$.flags.q.sample_interlock_unordered = 0;
>> +         }
>> +      }
>> +
>>        /* Layout qualifiers for tessellation evaluation shaders. */
>>        if (!$$.flags.i) {
>>           static const struct {
>> diff --git a/src/compiler/glsl/glsl_parser_extras.cpp 
>> b/src/compiler/glsl/glsl_parser_extras.cpp
>> index eb12eff..68ebd5c 100644
>> --- a/src/compiler/glsl/glsl_parser_extras.cpp
>> +++ b/src/compiler/glsl/glsl_parser_extras.cpp
>> @@ -300,6 +300,10 @@ 
>> _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
>>     this->fs_early_fragment_tests = false;
>>     this->fs_inner_coverage = false;
>>     this->fs_post_depth_coverage = false;
>> +   this->fs_pixel_interlock_ordered = false;
>> +   this->fs_pixel_interlock_unordered = false;
>> +   this->fs_sample_interlock_ordered = false;
>> +   this->fs_sample_interlock_unordered = false;
>>     this->fs_blend_support = 0;
>>     memset(this->atomic_counter_offsets, 0,
>>            sizeof(this->atomic_counter_offsets));
>> @@ -619,6 +623,7 @@ static const _mesa_glsl_extension 
>> _mesa_glsl_supported_extensions[] = {
>>     EXT(ARB_explicit_uniform_location),
>>     EXT(ARB_fragment_coord_conventions),
>>     EXT(ARB_fragment_layer_viewport),
>> +   EXT(ARB_fragment_shader_interlock),
>>     EXT(ARB_gpu_shader5),
>>     EXT(ARB_gpu_shader_fp64),
>>     EXT(ARB_gpu_shader_int64),
>> @@ -1720,6 +1725,10 @@ set_shader_inout_layout(struct gl_shader *shader,
>>        assert(!state->fs_early_fragment_tests);
>>        assert(!state->fs_inner_coverage);
>>        assert(!state->fs_post_depth_coverage);
>> +      assert(!state->fs_pixel_interlock_ordered);
>> +      assert(!state->fs_pixel_interlock_unordered);
>> +      assert(!state->fs_sample_interlock_ordered);
>> +      assert(!state->fs_sample_interlock_unordered);
>>     }
>>
>>     for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) {
>> @@ -1841,6 +1850,10 @@ set_shader_inout_layout(struct gl_shader *shader,
>>        shader->EarlyFragmentTests = state->fs_early_fragment_tests;
>>        shader->InnerCoverage = state->fs_inner_coverage;
>>        shader->PostDepthCoverage = state->fs_post_depth_coverage;
>> +      shader->PixelInterlockOrdered = state->fs_pixel_interlock_ordered;
>> +      shader->PixelInterlockUnordered = 
>> state->fs_pixel_interlock_unordered;
>> +      shader->SampleInterlockOrdered = 
>> state->fs_sample_interlock_ordered;
>> +      shader->SampleInterlockUnordered = 
>> state->fs_sample_interlock_unordered;
>>        shader->BlendSupport = state->fs_blend_support;
>>        break;
>>
>> diff --git a/src/compiler/glsl/glsl_parser_extras.h 
>> b/src/compiler/glsl/glsl_parser_extras.h
>> index 6c3bc8a..56218cc 100644
>> --- a/src/compiler/glsl/glsl_parser_extras.h
>> +++ b/src/compiler/glsl/glsl_parser_extras.h
>> @@ -616,6 +616,8 @@ struct _mesa_glsl_parse_state {
>>     bool ARB_fragment_coord_conventions_warn;
>>     bool ARB_fragment_layer_viewport_enable;
>>     bool ARB_fragment_layer_viewport_warn;
>> +   bool ARB_fragment_shader_interlock_enable;
>> +   bool ARB_fragment_shader_interlock_warn;
>>     bool ARB_gpu_shader5_enable;
>>     bool ARB_gpu_shader5_warn;
>>     bool ARB_gpu_shader_fp64_enable;
>> @@ -810,6 +812,11 @@ struct _mesa_glsl_parse_state {
>>
>>     bool fs_post_depth_coverage;
>>
>> +   bool fs_pixel_interlock_ordered;
>> +   bool fs_pixel_interlock_unordered;
>> +   bool fs_sample_interlock_ordered;
>> +   bool fs_sample_interlock_unordered;
>> +
>>     unsigned fs_blend_support;
>>
>>     /**
>> diff --git a/src/compiler/glsl/glsl_to_nir.cpp 
>> b/src/compiler/glsl/glsl_to_nir.cpp
>> index 870d457..82b872c 100644
>> --- a/src/compiler/glsl/glsl_to_nir.cpp
>> +++ b/src/compiler/glsl/glsl_to_nir.cpp
>> @@ -734,6 +734,12 @@ nir_visitor::visit(ir_call *ir)
>>        case ir_intrinsic_shader_clock:
>>           op = nir_intrinsic_shader_clock;
>>           break;
>> +      case ir_intrinsic_begin_invocation_interlock_ARB:
>> +         op = nir_intrinsic_begin_invocation_interlock_ARB;
>> +         break;
>> +      case ir_intrinsic_end_invocation_interlock_ARB:
>> +         op = nir_intrinsic_end_invocation_interlock_ARB;
>> +         break;
>>        case ir_intrinsic_group_memory_barrier:
>>           op = nir_intrinsic_group_memory_barrier;
>>           break;
>> @@ -934,6 +940,12 @@ nir_visitor::visit(ir_call *ir)
>>           instr->num_components = 2;
>>           nir_builder_instr_insert(&b, &instr->instr);
>>           break;
>> +      case nir_intrinsic_begin_invocation_interlock_ARB:
>> +         nir_builder_instr_insert(&b, &instr->instr);
>> +         break;
>> +      case nir_intrinsic_end_invocation_interlock_ARB:
>> +         nir_builder_instr_insert(&b, &instr->instr);
>> +         break;
>>        case nir_intrinsic_store_ssbo: {
>>           exec_node *param = ir->actual_parameters.get_head();
>>           ir_rvalue *block = ((ir_instruction *)param)->as_rvalue();
>> diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h
>> index d7a81c5..a404d00 100644
>> --- a/src/compiler/glsl/ir.h
>> +++ b/src/compiler/glsl/ir.h
>> @@ -1097,6 +1097,8 @@ enum ir_intrinsic_id {
>>     ir_intrinsic_memory_barrier_buffer,
>>     ir_intrinsic_memory_barrier_image,
>>     ir_intrinsic_memory_barrier_shared,
>> +   ir_intrinsic_begin_invocation_interlock_ARB,
>> +   ir_intrinsic_end_invocation_interlock_ARB,
>>
>>     ir_intrinsic_shared_load,
>>     ir_intrinsic_shared_store = MAKE_INTRINSIC_FOR_TYPE(store, shared),
>> diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
>> index 7ace01d..f06eaf7 100644
>> --- a/src/compiler/glsl/linker.cpp
>> +++ b/src/compiler/glsl/linker.cpp
>> @@ -1895,6 +1895,14 @@ link_fs_inout_layout_qualifiers(struct 
>> gl_shader_program *prog,
>>        linked_shader->Program->info.fs.inner_coverage |= 
>> shader->InnerCoverage;
>>        linked_shader->Program->info.fs.post_depth_coverage |=
>>           shader->PostDepthCoverage;
>> +      linked_shader->Program->info.fs.pixel_interlock_ordered |=
>> +         shader->PixelInterlockOrdered;
>> +      linked_shader->Program->info.fs.pixel_interlock_unordered |=
>> +         shader->PixelInterlockUnordered;
>> +      linked_shader->Program->info.fs.sample_interlock_ordered |=
>> +         shader->SampleInterlockOrdered;
>> +      linked_shader->Program->info.fs.sample_interlock_unordered |=
>> +         shader->SampleInterlockUnordered;
>>
>>        linked_shader->Program->sh.fs.BlendSupport |= 
>> shader->BlendSupport;
>>     }
>> diff --git a/src/compiler/nir/nir_intrinsics.h 
>> b/src/compiler/nir/nir_intrinsics.h
>> index 3a519a7..82dac3d 100644
>> --- a/src/compiler/nir/nir_intrinsics.h
>> +++ b/src/compiler/nir/nir_intrinsics.h
>> @@ -104,6 +104,8 @@ BARRIER(memory_barrier_buffer)
>>  BARRIER(memory_barrier_image)
>>  BARRIER(memory_barrier_shared)
>>
>> +BARRIER(begin_invocation_interlock_ARB)
>> +BARRIER(end_invocation_interlock_ARB)
>>  /** A conditional discard, with a single boolean source. */
>>  INTRINSIC(discard_if, 1, ARR(1), false, 0, 0, 0, xx, xx, xx, 0)
>>
>> diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h
>> index a670841..3d7282f 100644
>> --- a/src/compiler/shader_info.h
>> +++ b/src/compiler/shader_info.h
>> @@ -127,6 +127,11 @@ typedef struct shader_info {
>>
>>           bool post_depth_coverage;
>>
>> +         bool pixel_interlock_ordered;
>> +         bool pixel_interlock_unordered;
>> +         bool sample_interlock_ordered;
>> +         bool sample_interlock_unordered;
>> +
>>           /** gl_FragDepth layout for ARB_conservative_depth. */
>>           enum gl_frag_depth_layout depth_layout;
>>        } fs;
>> diff --git a/src/mesa/main/extensions_table.h 
>> b/src/mesa/main/extensions_table.h
>> index d11cb0f..e64a88a 100644
>> --- a/src/mesa/main/extensions_table.h
>> +++ b/src/mesa/main/extensions_table.h
>> @@ -67,6 +67,7 @@ EXT(ARB_fragment_layer_viewport             , 
>> ARB_fragment_layer_viewport
>>  EXT(ARB_fragment_program                    , 
>> ARB_fragment_program                   , GLL,  x ,  x ,  x , 2002)
>>  EXT(ARB_fragment_program_shadow             , 
>> ARB_fragment_program_shadow            , GLL,  x ,  x ,  x , 2003)
>>  EXT(ARB_fragment_shader                     , 
>> ARB_fragment_shader                    , GLL, GLC,  x ,  x , 2002)
>> +EXT(ARB_fragment_shader_interlock           , 
>> ARB_fragment_shader_interlock          , GLL, GLC,  x ,  x , 2015)
>>  EXT(ARB_framebuffer_no_attachments          , 
>> ARB_framebuffer_no_attachments         , GLL, GLC,  x ,  x , 2012)
>>  EXT(ARB_framebuffer_object                  , 
>> ARB_framebuffer_object                 , GLL, GLC,  x ,  x , 2005)
>>  EXT(ARB_framebuffer_sRGB                    , 
>> EXT_framebuffer_sRGB                   , GLL, GLC,  x ,  x , 1998)
>> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
>> index c4fab9d..608345d 100644
>> --- a/src/mesa/main/mtypes.h
>> +++ b/src/mesa/main/mtypes.h
>> @@ -2558,6 +2558,10 @@ struct gl_shader
>>     bool uses_gl_fragcoord;
>>
>>     bool PostDepthCoverage;
>> +   bool PixelInterlockOrdered;
>> +   bool PixelInterlockUnordered;
>> +   bool SampleInterlockOrdered;
>> +   bool SampleInterlockUnordered;
>>     bool InnerCoverage;
>>
>>     /**
>> @@ -3967,6 +3971,7 @@ struct gl_extensions
>>     GLboolean ARB_fragment_shader;
>>     GLboolean ARB_framebuffer_no_attachments;
>>     GLboolean ARB_framebuffer_object;
>> +   GLboolean ARB_fragment_shader_interlock;
>>     GLboolean ARB_enhanced_layouts;
>>     GLboolean ARB_explicit_attrib_location;
>>     GLboolean ARB_explicit_uniform_location;
>> -- 
>> 2.9.3
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list