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 <plamena.manolova@intel.com>
This commit is contained in:
@@ -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;
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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) {
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user