driconf, glsl: Add a vs_position_always_invariant option
Many applications use multi-pass rendering and require their vertex
shader position to be computed the same way each time. Optimizations
may consider, say, fusing a multiply-add based on global usage of an
expression in a shader. But a second shader with the same expression
may have different code, causing that optimization to make the other
choice the second time around.
The correct solution is for applications to mark their VS outputs
'invariant', indicating they need multiple shaders to compute that
output in the same manner. However, most applications fail to do so.
So, we add a new driconf option - vs_position_always_invariant - which
forces the gl_Position output in vertex shaders to be marked invariant.
Fixes: 7025dbe794
("nir: Skip emitting no-op movs from the builder.")
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
@@ -1435,6 +1435,9 @@ builtin_variable_generator::add_varying(int slot, const glsl_type *type,
|
||||
void
|
||||
builtin_variable_generator::generate_varyings()
|
||||
{
|
||||
struct gl_shader_compiler_options *options =
|
||||
&state->ctx->Const.ShaderCompilerOptions[state->stage];
|
||||
|
||||
/* gl_Position and gl_PointSize are not visible from fragment shaders. */
|
||||
if (state->stage != MESA_SHADER_FRAGMENT) {
|
||||
add_varying(VARYING_SLOT_POS, vec4_t, GLSL_PRECISION_HIGH, "gl_Position");
|
||||
@@ -1526,6 +1529,9 @@ builtin_variable_generator::generate_varyings()
|
||||
var->data.sample = fields[i].sample;
|
||||
var->data.patch = fields[i].patch;
|
||||
var->init_interface_type(per_vertex_out_type);
|
||||
|
||||
var->data.invariant = fields[i].location == VARYING_SLOT_POS &&
|
||||
options->PositionAlwaysInvariant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@ DRI_CONF_SECTION_END
|
||||
DRI_CONF_SECTION_MISCELLANEOUS
|
||||
DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER("false")
|
||||
DRI_CONF_GLSL_ZERO_INIT("false")
|
||||
DRI_CONF_VS_POSITION_ALWAYS_INVARIANT("false")
|
||||
DRI_CONF_ALLOW_RGB10_CONFIGS("true")
|
||||
DRI_CONF_ALLOW_FP16_CONFIGS("false")
|
||||
DRI_CONF_SECTION_END
|
||||
|
@@ -228,6 +228,7 @@ struct st_config_options
|
||||
bool allow_glsl_builtin_variable_redeclaration;
|
||||
bool allow_higher_compat_version;
|
||||
bool glsl_zero_init;
|
||||
bool vs_position_always_invariant;
|
||||
bool force_glsl_abs_sqrt;
|
||||
bool allow_glsl_cross_stage_interpolation_mismatch;
|
||||
bool allow_glsl_layout_qualifier_on_function_parameters;
|
||||
|
@@ -84,6 +84,8 @@ dri_fill_st_options(struct dri_screen *screen)
|
||||
options->allow_higher_compat_version =
|
||||
driQueryOptionb(optionCache, "allow_higher_compat_version");
|
||||
options->glsl_zero_init = driQueryOptionb(optionCache, "glsl_zero_init");
|
||||
options->vs_position_always_invariant =
|
||||
driQueryOptionb(optionCache, "vs_position_always_invariant");
|
||||
options->force_glsl_abs_sqrt =
|
||||
driQueryOptionb(optionCache, "force_glsl_abs_sqrt");
|
||||
options->allow_glsl_cross_stage_interpolation_mismatch =
|
||||
|
@@ -98,6 +98,7 @@ DRI_CONF_BEGIN
|
||||
|
||||
DRI_CONF_SECTION_MISCELLANEOUS
|
||||
DRI_CONF_GLSL_ZERO_INIT("false")
|
||||
DRI_CONF_VS_POSITION_ALWAYS_INVARIANT("false")
|
||||
DRI_CONF_ALLOW_RGB10_CONFIGS("false")
|
||||
DRI_CONF_ALLOW_RGB565_CONFIGS("true")
|
||||
DRI_CONF_ALLOW_FP16_CONFIGS("false")
|
||||
@@ -2798,6 +2799,8 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen)
|
||||
screen->compiler->constant_buffer_0_is_relative = devinfo->gen < 8 ||
|
||||
!(screen->kernel_features & KERNEL_ALLOWS_CONTEXT_ISOLATION);
|
||||
|
||||
screen->compiler->glsl_compiler_options[MESA_SHADER_VERTEX].PositionAlwaysInvariant = driQueryOptionb(&screen->optionCache, "vs_position_always_invariant");
|
||||
|
||||
screen->compiler->supports_pull_constants = true;
|
||||
screen->compiler->compact_params = true;
|
||||
|
||||
|
@@ -3194,6 +3194,9 @@ struct gl_shader_compiler_options
|
||||
/** Clamp UBO and SSBO block indices so they don't go out-of-bounds. */
|
||||
GLboolean ClampBlockIndicesToArrayBounds;
|
||||
|
||||
/** (driconf) Force gl_Position to be considered invariant */
|
||||
GLboolean PositionAlwaysInvariant;
|
||||
|
||||
const struct nir_shader_compiler_options *NirOptions;
|
||||
};
|
||||
|
||||
|
@@ -754,6 +754,8 @@ st_create_context_priv(struct gl_context *ctx, struct pipe_context *pipe,
|
||||
ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].EmitNoSat =
|
||||
!screen->get_param(screen, PIPE_CAP_VERTEX_SHADER_SATURATE);
|
||||
|
||||
ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].PositionAlwaysInvariant = options->vs_position_always_invariant;
|
||||
|
||||
if (ctx->Const.GLSLVersion < 400) {
|
||||
for (i = 0; i < MESA_SHADER_STAGES; i++)
|
||||
ctx->Const.ShaderCompilerOptions[i].EmitNoIndirectSampler = true;
|
||||
|
@@ -279,6 +279,11 @@ DRI_CONF_OPT_BEGIN_B(glsl_zero_init, def) \
|
||||
DRI_CONF_DESC(en,gettext("Force uninitialized variables to default to zero")) \
|
||||
DRI_CONF_OPT_END
|
||||
|
||||
#define DRI_CONF_VS_POSITION_ALWAYS_INVARIANT(def) \
|
||||
DRI_CONF_OPT_BEGIN_B(vs_position_always_invariant, def) \
|
||||
DRI_CONF_DESC(en,gettext("Force the vertex shader's gl_Position output to be considered 'invariant'")) \
|
||||
DRI_CONF_OPT_END
|
||||
|
||||
#define DRI_CONF_ALLOW_RGB10_CONFIGS(def) \
|
||||
DRI_CONF_OPT_BEGIN_B(allow_rgb10_configs, def) \
|
||||
DRI_CONF_DESC(en,gettext("Allow exposure of visuals and fbconfigs with rgb10a2 formats")) \
|
||||
|
Reference in New Issue
Block a user