driconf, glsl: Add a vs_position_always_invariant option
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 22 Nov 2019 00:11:15 +0000 (16:11 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 27 Nov 2019 18:48:04 +0000 (18:48 +0000)
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: 7025dbe794b ("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>
src/compiler/glsl/builtin_variables.cpp
src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
src/gallium/include/state_tracker/st_api.h
src/gallium/state_trackers/dri/dri_screen.c
src/mesa/drivers/dri/i965/intel_screen.c
src/mesa/main/mtypes.h
src/mesa/state_tracker/st_context.c
src/util/xmlpool/t_options.h

index c10ea9e61a5003d0131ed8421f5fb100a70e92ba..ef8aca76e0cc60d99d3c570c6ffb706cb939a7c1 100644 (file)
@@ -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;
       }
    }
 }
index 69967d916f2678314fd34ff843b7889411f5a4da..bac60215d15132c4883a1e20b50bc84e3a8c4a7f 100644 (file)
@@ -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
index 297954d70bffae39e067a16b655cb2824704e384..9fd36447c7b33b28098438edb6c1ae50b0e595eb 100644 (file)
@@ -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;
index 0da789643fc91b8b617b9ed029dd937f0e88fc0f..8600ce029f028625da042346ae0509971309583d 100644 (file)
@@ -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 =
index c690a8ede7c9e76d4ff579d389a8f3078f06588f..04217b3e6cf3bb4ca651c2f429c02d076584f104 100644 (file)
@@ -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;
 
index 9facc022ceca1faf6a95f9f8f9b62296cac6ed58..e17ae1fa519d2b4cfb4503d1a1f758348f37540d 100644 (file)
@@ -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;
 };
 
index d6025d69f61cb4d22f2bf93604af07c828b02b50..ed50c332c22e76988149cb17d0774811e985f285 100644 (file)
@@ -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;
index 7a665bfd65553f7c5b63ea187320512148006556..fe186c1fa796a87a0ca9e823a33511bd7cb1d097 100644 (file)
@@ -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")) \