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

Francisco Jerez currojerez at riseup.net
Thu Apr 5 17:07:52 UTC 2018


Plamena Manolova <plamena.n.manolova at gmail.com> writes:

> 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.n.manolova at gmail.com>
> ---
>  src/compiler/glsl/ast.h                  | 10 ++++
>  src/compiler/glsl/ast_to_hir.cpp         | 10 ++++
>  src/compiler/glsl/ast_type.cpp           | 30 +++++++++++-
>  src/compiler/glsl/builtin_functions.cpp  | 79 ++++++++++++++++++++++++++++++++
>  src/compiler/glsl/glsl_parser.yy         | 46 +++++++++++++++++++
>  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, 229 insertions(+), 1 deletion(-)
>
> diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h
> index a1ec0d566f..319a6a82c1 100644
> --- a/src/compiler/glsl/ast.h
> +++ b/src/compiler/glsl/ast.h
> @@ -620,6 +620,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;
> +
>           /**
>            * 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 badfbe6816..2358153c5f 100644
> --- a/src/compiler/glsl/ast_to_hir.cpp
> +++ b/src/compiler/glsl/ast_to_hir.cpp
> @@ -3897,6 +3897,16 @@ apply_layout_qualifier_to_variable(const struct ast_type_qualifier *qual,
>  
>     if (state->has_bindless())
>        apply_bindless_qualifier_to_variable(qual, var, state, loc);
> +
> +   if (qual->flags.q.pixel_interlock_ordered ||
> +       qual->flags.q.pixel_interlock_unordered ||
> +       qual->flags.q.sample_interlock_ordered ||
> +       qual->flags.q.sample_interlock_unordered) {
> +      _mesa_glsl_error(loc, state, "interlock layout qualifiers: "
> +                       "pixel_interlock_ordered, pixel_interlock_unordered, "
> +                       "sample_interlock_ordered and sample_interlock_unordered, "
> +                       "only valid in fragment shader input layout declaration.");
> +   }
>  }
>  
>  static void
> diff --git a/src/compiler/glsl/ast_type.cpp b/src/compiler/glsl/ast_type.cpp
> index 14ea936f24..49697d3411 100644
> --- a/src/compiler/glsl/ast_type.cpp
> +++ b/src/compiler/glsl/ast_type.cpp
> @@ -637,6 +637,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;
> @@ -708,6 +712,26 @@ ast_type_qualifier::merge_into_in_qualifier(YYLTYPE *loc,
>        r = false;
>     }
>  
> +   if (state->in_qualifier->flags.q.pixel_interlock_ordered) {
> +      state->fs_pixel_interlock_ordered = true;
> +      state->in_qualifier->flags.q.pixel_interlock_ordered = false;
> +   }
> +
> +   if (state->in_qualifier->flags.q.pixel_interlock_unordered) {
> +      state->fs_pixel_interlock_unordered = true;
> +      state->in_qualifier->flags.q.pixel_interlock_unordered = false;
> +   }
> +
> +   if (state->in_qualifier->flags.q.sample_interlock_ordered) {
> +      state->fs_sample_interlock_ordered = true;
> +      state->in_qualifier->flags.q.sample_interlock_ordered = false;
> +   }
> +
> +   if (state->in_qualifier->flags.q.sample_interlock_unordered) {
> +      state->fs_sample_interlock_unordered = true;
> +      state->in_qualifier->flags.q.sample_interlock_unordered = 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.
> @@ -776,7 +800,7 @@ ast_type_qualifier::validate_flags(YYLTYPE *loc,
>                      "%s '%s':"
>                      "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
>                      "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
> -                    "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
> +                    "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
>                      message, name,
>                      bad.flags.q.invariant ? " invariant" : "",
>                      bad.flags.q.precise ? " precise" : "",
> @@ -840,6 +864,10 @@ ast_type_qualifier::validate_flags(YYLTYPE *loc,
>                      bad.flags.q.bound_sampler ? " bound_sampler" : "",
>                      bad.flags.q.bound_image ? " bound_image" : "",
>                      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": "",
>                      bad.flags.q.non_coherent ? " noncoherent" : "");
>     return false;
>  }
> diff --git a/src/compiler/glsl/builtin_functions.cpp b/src/compiler/glsl/builtin_functions.cpp
> index 5f772c9eab..52c05feb35 100644
> --- a/src/compiler/glsl/builtin_functions.cpp
> +++ b/src/compiler/glsl/builtin_functions.cpp
> @@ -513,6 +513,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;
> @@ -982,6 +988,21 @@ private:
>     ir_function_signature *_read_invocation_intrinsic(const glsl_type *type);
>     ir_function_signature *_read_invocation(const glsl_type *type);
>  
> +
> +   ir_function_signature *_begin_invocation_interlock_ARB_intrinsic(

I don't think GLSL intrinsics have ever used ARB suffixes.  Please drop
it from this file and the various GLSL and NIR intrinsic names below.

> +      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,
> @@ -1219,6 +1240,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),
> @@ -3294,6 +3325,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("__intrinsic_vote_any", vote),
>                  NULL);
> @@ -6228,6 +6271,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;

This seems to be doing exactly the same as the
_begin_invocation_interlock_ARB_intrinsic above.  Maybe define a single
_invocation_interlock_intrinsic method and re-use it?

> +}
> +
> +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;
> +}
> +

Same here.

> +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 e5ea41d4df..49f562551d 100644
> --- a/src/compiler/glsl/glsl_parser.yy
> +++ b/src/compiler/glsl/glsl_parser.yy
> @@ -1432,6 +1432,52 @@ layout_qualifier_id:
>           }
>        }
>  
> +      int pixel_interlock_ordered = match_layout_qualifier($1,
> +         "pixel_interlock_ordered", state) == 0 ? 1 : 0;
> +      int pixel_interlock_unordered = match_layout_qualifier($1,
> +         "pixel_interlock_unordered", state) == 0 ? 1 : 0;
> +      int sample_interlock_ordered = match_layout_qualifier($1,
> +         "sample_interlock_ordered", state) == 0 ? 1 : 0;
> +      int sample_interlock_unordered = match_layout_qualifier($1,
> +         "sample_interlock_unordered", state) == 0 ? 1 : 0;
> +

Maybe constify these declarations and make them of bool type.  The
ternary operators are redundant -- A bool is really just a one-bit
integer, the arithmetic below will still work due to the implicit
promotion to signed integer.

> +      if (pixel_interlock_ordered + pixel_interlock_unordered +
> +          sample_interlock_ordered + sample_interlock_unordered > 0 &&
> +          state->stage != MESA_SHADER_FRAGMENT) {
> +         _mesa_glsl_error(& @1, state, "interlock layout qualifiers: "
> +                          "pixel_interlock_ordered, pixel_interlock_unordered, "
> +                          "sample_interlock_ordered and sample_interlock_unordered, "
> +                          "only valid in fragment shader input layout declaration.");
> +      } else if (pixel_interlock_ordered + pixel_interlock_unordered +
> +                 sample_interlock_ordered + sample_interlock_unordered > 0 &&
> +                 !state->ARB_fragment_shader_interlock_enable) {
> +         _mesa_glsl_error(& @1, state,
> +                          "interlock layout qualifier present, but the "
> +                          "GL_ARB_fragment_shader_interlock extension is not "
> +                          "enabled.");
> +      } else if (pixel_interlock_ordered + pixel_interlock_unordered +
> +                 sample_interlock_ordered + sample_interlock_unordered > 1) {
> +         _mesa_glsl_error(& @1, state,
> +                          "only one interlock mode can be used at any time.");

I don't think this is doing what you want.  The *_interlock_* flags you
declared above are the result of a comparing the *same*
layout-qualifier-id string with each valid qualifier string, so it's
impossible for more than one of them to be non-zero at any point.  You
probably need to do the consistency check at a later point (e.g. during
conversion of the AST to GLSL IR) to make sure you are taking into
account all layout qualifiers provided in the program.

> +      } else if (pixel_interlock_ordered + pixel_interlock_unordered > 0 &&
> +                 state->ctx->Multisample.Enabled) {
> +         _mesa_glsl_error(& @1, state,
> +                          "pixel_interlock_ordered and "
> +                          "pixel_interlock_unordered can only be used when "
> +                          "multisampling is disabled.");

AFAIUI using a pixel interlock with multisampling enabled is completely
valid and useful (otherwise there would be no need for separate pixel
and sample interlock qualifiers if the overlap region was uniquely
determined by the multisampling mode).  You probably need to drop this
error.

> +      } else if (sample_interlock_ordered + sample_interlock_unordered > 0 &&
> +                 !state->ctx->Multisample.Enabled) {
> +            _mesa_glsl_error(& @1, state,
> +                             "sample_interlock_ordered and "
> +                             "sample_interlock_unordered can only be used when "
> +                             "multisampling is enabled.");

I don't think this is right, according to the spec:

| If multisampling is disabled, or if the framebuffer does not include
| sample buffers, fragment coverage is computed per-pixel. In this case,
| the "sample_interlock_ordered" or "sample_interlock_unordered" layout
| qualifiers are treated as "pixel_interlock_ordered" or
| "pixel_interlock_unordered", respectively.

Which means it's not illegal to use a shader with one of the sample
interlock qualifiers while multisampling is disabled, it's just treated
as if the framebuffer had one sample per pixel.

> +      } else {
> +         $$.flags.q.pixel_interlock_ordered = pixel_interlock_ordered;
> +         $$.flags.q.pixel_interlock_unordered = pixel_interlock_unordered;
> +         $$.flags.q.sample_interlock_ordered = sample_interlock_ordered;
> +         $$.flags.q.sample_interlock_unordered = sample_interlock_unordered;
> +      }
> +
>        /* 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 275c4d7571..0819a900fc 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));
> @@ -629,6 +633,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 66bd1a3db6..03b7fa9310 100644
> --- a/src/compiler/glsl/glsl_parser_extras.h
> +++ b/src/compiler/glsl/glsl_parser_extras.h
> @@ -634,6 +634,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;
> @@ -828,6 +830,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 80eb15f1ab..c5666bd443 100644
> --- a/src/compiler/glsl/glsl_to_nir.cpp
> +++ b/src/compiler/glsl/glsl_to_nir.cpp
> @@ -750,6 +750,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;
> @@ -968,6 +974,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 6d3ef89eb8..e36666650d 100644
> --- a/src/compiler/glsl/ir.h
> +++ b/src/compiler/glsl/ir.h
> @@ -1121,6 +1121,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_vote_all,
>     ir_intrinsic_vote_any,
> diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
> index 1444b68cb0..8d41d2ba04 100644
> --- a/src/compiler/glsl/linker.cpp
> +++ b/src/compiler/glsl/linker.cpp
> @@ -1977,6 +1977,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 7b737559d5..b227051fd8 100644
> --- a/src/compiler/nir/nir_intrinsics.h
> +++ b/src/compiler/nir/nir_intrinsics.h
> @@ -129,6 +129,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 b1e200070f..0570c08939 100644
> --- a/src/compiler/shader_info.h
> +++ b/src/compiler/shader_info.h
> @@ -174,6 +174,11 @@ typedef struct shader_info {
>  
>           bool pixel_center_integer;
>  
> +         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 492f7c3d20..79842a5f5d 100644
> --- a/src/mesa/main/extensions_table.h
> +++ b/src/mesa/main/extensions_table.h
> @@ -68,6 +68,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 2df2288899..8bc76ab9b7 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -2738,6 +2738,10 @@ struct gl_shader
>     bool uses_gl_fragcoord;
>  
>     bool PostDepthCoverage;
> +   bool PixelInterlockOrdered;
> +   bool PixelInterlockUnordered;
> +   bool SampleInterlockOrdered;
> +   bool SampleInterlockUnordered;
>     bool InnerCoverage;
>  
>     /**
> @@ -4199,6 +4203,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.11.0
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 227 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20180405/3da13b46/attachment-0001.sig>


More information about the mesa-dev mailing list