Re: [Mesa-dev] [PATCH 1/2] mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.
Plamena Manolova 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 Reviewed-by: Francisco Jerez > --- > src/compiler/glsl/ast.h | 10 ++ > src/compiler/glsl/ast_to_hir.cpp | 10 ++ > src/compiler/glsl/ast_type.cpp | 39 ++- > src/compiler/glsl/builtin_functions.cpp | 54 > > src/compiler/glsl/glsl_parser.yy | 30 ++ > 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.py | 2 ++ > src/compiler/shader_info.h | 5 +++ > src/mesa/main/extensions_table.h | 1 + > src/mesa/main/mtypes.h | 5 +++ > 14 files changed, 197 insertions(+), 1 deletion(-) > > diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h > index 9b88ff51d4..4d5e045b82 100644 > --- a/src/compiler/glsl/ast.h > +++ b/src/compiler/glsl/ast.h > @@ -626,6 +626,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 3bf581571e..dd60a2a87f 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..c2b6e6b3c2 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,35 @@ 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; > + } > + > + if (state->fs_pixel_interlock_ordered + > + state->fs_pixel_interlock_unordered + > + s
[Mesa-dev] [PATCH 1/2] mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.
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 --- src/compiler/glsl/ast.h | 10 ++ src/compiler/glsl/ast_to_hir.cpp | 10 ++ src/compiler/glsl/ast_type.cpp | 39 ++- src/compiler/glsl/builtin_functions.cpp | 54 src/compiler/glsl/glsl_parser.yy | 30 ++ 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.py | 2 ++ src/compiler/shader_info.h | 5 +++ src/mesa/main/extensions_table.h | 1 + src/mesa/main/mtypes.h | 5 +++ 14 files changed, 197 insertions(+), 1 deletion(-) diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h index 9b88ff51d4..4d5e045b82 100644 --- a/src/compiler/glsl/ast.h +++ b/src/compiler/glsl/ast.h @@ -626,6 +626,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 3bf581571e..dd60a2a87f 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..c2b6e6b3c2 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,35 @@ 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; + } + + if (state->fs_pixel_interlock_ordered + + state->fs_pixel_interlock_unordered + + state->fs_sample_interlock_ordered + + state->fs_sample_interlock_unordered > 1) { + _mesa_glsl_error(loc, state, + "only one interlock mode can be used at any time."); + r = false; + } + /* We allow the creation of multiple cs_input_layout nodes.
[Mesa-dev] [PATCH 1/2] mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.
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 --- 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" -
Re: [Mesa-dev] [PATCH 1/2] mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.
Plamena Manolova 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 > --- > 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 transforme
Re: [Mesa-dev] [PATCH 1/2] mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.
On 19/04/17 11:12, Manolova, Plamena wrote: Thank you for reviewing Timothy! On Mon, Apr 17, 2017 at 7:10 PM, Timothy Arceri mailto:tarc...@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 mailto:plamena.manol...@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. I expect it will be tricky, but worth it if we can. Good luck. :) + /** * 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 li
Re: [Mesa-dev] [PATCH 1/2] mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.
Thank you for reviewing Nicolai! On Tue, Apr 18, 2017 at 4:17 AM, Nicolai Hähnle wrote: > On 18.04.2017 03: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 >> --- >> 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(-) >> >> [snip] > > @@ -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; >
Re: [Mesa-dev] [PATCH 1/2] mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.
Thank you for reviewing Timothy! On Mon, Apr 17, 2017 at 7:10 PM, 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 >> --- >> 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_
Re: [Mesa-dev] [PATCH 1/2] mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.
On 18.04.2017 03: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 --- 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(-) [snip] @@ -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; + } + } + } There is a lot of code (almost-)duplication here. At the very least, the "only one interloc
Re: [Mesa-dev] [PATCH 1/2] mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.
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 --- 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_ord
Re: [Mesa-dev] [PATCH 1/2] mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.
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 --- 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? + /** * 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->fl
[Mesa-dev] [PATCH 1/2] mesa: Add GL/GLSL plumbing for ARB_fragment_shader_interlock.
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 --- 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; + /** * 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."); + } } 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 "