Thank you for reviewing Timothy! On Mon, Apr 17, 2017 at 7:10 PM, Timothy Arceri <[email protected]> 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 <[email protected]> >> --- >> 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 >> [email protected] >> https://lists.freedesktop.org/mailman/listinfo/mesa-dev >> >>
_______________________________________________ mesa-dev mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-dev
