[Mesa-dev] [PATCH 12/15] glsl: Add support for the framebuffer fetch layout(noncoherent) qualifier.
Francisco Jerez
currojerez at riseup.net
Wed Feb 14 21:18:34 UTC 2018
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.
---
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 b0db14e20b6..ba025266bd7 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 a686cb6a457..2fafea532f3 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 = true;
}
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.16.1
More information about the mesa-dev
mailing list