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

Manolova, Plamena plamena.manolova at intel.com
Wed Apr 19 01:12:34 UTC 2017


Thank you for reviewing Timothy!

On Mon, Apr 17, 2017 at 7:10 PM, Timothy Arceri <tarceri at itsqueeze.com>
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.
>
> 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?
>

I think it should be possible to split them out, I can have a go at that.

+
>>           /**
>>            * 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?
>

Yes there's a test here: https://patchwork.freedesktop.org/patch/151133
 I'll look into whether we actually need validation in both glsl_parser.yy
and ast_type.cpp


>
>  }
>>
>>  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_s
>> hared),
>>                  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_unor
>> dered;
>> +      shader->SampleInterlockOrdered = state->fs_sample_interlock_ord
>> ered;
>> +      shader->SampleInterlockUnordered = state->fs_sample_interlock_uno
>> rdered;
>>        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
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170418/9edabb52/attachment-0001.html>


More information about the mesa-dev mailing list