From ef9e3f63ca369e3549b4f17b39934dc4b3cbbb05 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 12 Feb 2018 15:54:33 -0800 Subject: [PATCH] glsl: Add support for the framebuffer fetch layout(noncoherent) qualifier. This allows the application to request framebuffer fetch coherency with per-fragment output granularity. Coherent framebuffer fetch outputs (which is the default if no qualifier is present for compatibility with older versions of the EXT_shader_framebuffer_fetch extension) will have ir_variable_data::memory_coherent set to true. Reviewed-by: Plamena Manolova --- src/compiler/glsl/ast.h | 5 +++ src/compiler/glsl/ast_to_hir.cpp | 45 +++++++++++++++++++++++++ src/compiler/glsl/ast_type.cpp | 6 ++-- src/compiler/glsl/builtin_variables.cpp | 1 + src/compiler/glsl/glsl_parser.yy | 6 ++++ 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/compiler/glsl/ast.h b/src/compiler/glsl/ast.h index 2a38a4b1f73..e5e4b572fff 100644 --- a/src/compiler/glsl/ast.h +++ b/src/compiler/glsl/ast.h @@ -635,6 +635,11 @@ struct ast_type_qualifier { unsigned bound_sampler:1; unsigned bound_image:1; /** \} */ + + /** \name Layout qualifiers for GL_EXT_shader_framebuffer_fetch_non_coherent */ + /** \{ */ + unsigned non_coherent:1; + /** \} */ } /** \brief Set of flags, accessed by name. */ q; diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index 966450ca78b..5acbaa321a9 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -2008,6 +2008,20 @@ ast_expression::do_hir(exec_list *instructions, _mesa_glsl_warning(&loc, state, "`%s' used uninitialized", this->primary_expression.identifier); } + + /* From the EXT_shader_framebuffer_fetch spec: + * + * "Unless the GL_EXT_shader_framebuffer_fetch extension has been + * enabled in addition, it's an error to use gl_LastFragData if it + * hasn't been explicitly redeclared with layout(noncoherent)." + */ + if (var->data.fb_fetch_output && var->data.memory_coherent && + !state->EXT_shader_framebuffer_fetch_enable) { + _mesa_glsl_error(&loc, state, + "invalid use of framebuffer fetch output not " + "qualified with layout(noncoherent)"); + } + } else { _mesa_glsl_error(& loc, state, "`%s' undeclared", this->primary_expression.identifier); @@ -4002,6 +4016,33 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, var->data.fb_fetch_output = (strcmp(var->name, "gl_LastFragData") == 0); } + if (var->data.fb_fetch_output) { + var->data.memory_coherent = !qual->flags.q.non_coherent; + + /* From the EXT_shader_framebuffer_fetch spec: + * + * "It is an error to declare an inout fragment output not qualified + * with layout(noncoherent) if the GL_EXT_shader_framebuffer_fetch + * extension hasn't been enabled." + */ + if (var->data.memory_coherent && + !state->EXT_shader_framebuffer_fetch_enable) + _mesa_glsl_error(loc, state, + "invalid declaration of framebuffer fetch output not " + "qualified with layout(noncoherent)"); + + } else { + /* From the EXT_shader_framebuffer_fetch spec: + * + * "Fragment outputs declared inout may specify the following layout + * qualifier: [...] noncoherent" + */ + if (qual->flags.q.non_coherent) + _mesa_glsl_error(loc, state, + "invalid layout(noncoherent) qualifier not part of " + "framebuffer fetch output declaration"); + } + if (!is_parameter && is_varying_var(var, state->stage)) { /* User-defined ins/outs are not permitted in compute shaders. */ if (state->stage == MESA_SHADER_COMPUTE) { @@ -4268,8 +4309,12 @@ get_variable_being_redeclared(ir_variable **var_ptr, YYLTYPE loc, * "By default, gl_LastFragData is declared with the mediump precision * qualifier. This can be changed by redeclaring the corresponding * variables with the desired precision qualifier." + * + * "Fragment shaders may specify the following layout qualifier only for + * redeclaring the built-in gl_LastFragData array [...]: noncoherent" */ earlier->data.precision = var->data.precision; + earlier->data.memory_coherent = var->data.memory_coherent; } else if (earlier->data.how_declared == ir_var_declared_implicitly && state->allow_builtin_variable_redeclaration) { diff --git a/src/compiler/glsl/ast_type.cpp b/src/compiler/glsl/ast_type.cpp index e9d60de5baf..14ea936f244 100644 --- a/src/compiler/glsl/ast_type.cpp +++ b/src/compiler/glsl/ast_type.cpp @@ -270,6 +270,7 @@ ast_type_qualifier::merge_qualifier(YYLTYPE *loc, input_layout_mask.flags.q.precise = 1; input_layout_mask.flags.q.sample = 1; input_layout_mask.flags.q.smooth = 1; + input_layout_mask.flags.q.non_coherent = 1; if (state->has_bindless()) { /* Allow to use image qualifiers with shader inputs/outputs. */ @@ -775,7 +776,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\n", + "%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" : "", @@ -838,7 +839,8 @@ ast_type_qualifier::validate_flags(YYLTYPE *loc, bad.flags.q.bindless_image ? " bindless_image" : "", 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.post_depth_coverage ? " post_depth_coverage" : "", + bad.flags.q.non_coherent ? " noncoherent" : ""); return false; } diff --git a/src/compiler/glsl/builtin_variables.cpp b/src/compiler/glsl/builtin_variables.cpp index f0210b60bc7..a1cdec597fa 100644 --- a/src/compiler/glsl/builtin_variables.cpp +++ b/src/compiler/glsl/builtin_variables.cpp @@ -1194,6 +1194,7 @@ builtin_variable_generator::generate_fs_special_vars() var->data.precision = GLSL_PRECISION_MEDIUM; var->data.read_only = 1; var->data.fb_fetch_output = 1; + var->data.memory_coherent = 1; } if (state->es_shader && state->language_version == 100 && state->EXT_blend_func_extended_enable) { diff --git a/src/compiler/glsl/glsl_parser.yy b/src/compiler/glsl/glsl_parser.yy index 4faf9602a08..f1986ed0a8a 100644 --- a/src/compiler/glsl/glsl_parser.yy +++ b/src/compiler/glsl/glsl_parser.yy @@ -1587,6 +1587,12 @@ layout_qualifier_id: } } + if (!$$.flags.i && + state->EXT_shader_framebuffer_fetch_non_coherent_enable) { + if (match_layout_qualifier($1, "noncoherent", state) == 0) + $$.flags.q.non_coherent = 1; + } + if (!$$.flags.i) { _mesa_glsl_error(& @1, state, "unrecognized layout identifier " "`%s'", $1); -- 2.30.2