glsl: don't run the GLSL pre-processor when we are skipping compilation
authorTimothy Arceri <tarceri@itsqueeze.com>
Mon, 10 Apr 2017 01:48:49 +0000 (11:48 +1000)
committerTimothy Arceri <tarceri@itsqueeze.com>
Sat, 15 Apr 2017 01:36:52 +0000 (11:36 +1000)
This moves the hashing of shader source for the cache lookup to before
the preprocessor.  In our experience, shaders are unlikely to hash the
same after preprocessing if they didn't hash the same before, so we can
skip preprocessing for cache hits.

Improves Deus Ex start-up times with a warm cache from ~30 seconds to
~22 seconds.

Also fixes the leaking of state.

V2: fix indentation

v3: add the value of MESA_EXTENSION_OVERRIDE to the hash of the shader.

Tested-by (v2): Grazvydas Ignotas <notasas@gmail.com>
Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/compiler/glsl/glsl_parser_extras.cpp
src/compiler/glsl/shader_cache.cpp

index ca74b559dcabe5e37e972c010eca6932015e9d6e..eb12efff8aa9d7bab245d3153e4638f7697d126e 100644 (file)
@@ -2005,18 +2005,9 @@ void
 _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
                           bool dump_ast, bool dump_hir, bool force_recompile)
 {
-   struct _mesa_glsl_parse_state *state =
-      new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader);
    const char *source = force_recompile && shader->FallbackSource ?
       shader->FallbackSource : shader->Source;
 
-   if (ctx->Const.GenerateTemporaryNames)
-      (void) p_atomic_cmpxchg(&ir_variable::temporaries_allocate_names,
-                              false, true);
-
-   state->error = glcpp_preprocess(state, &source, &state->info_log,
-                             add_builtin_defines, state, ctx);
-
    if (!force_recompile) {
       if (ctx->Cache) {
          char buf[41];
@@ -2050,6 +2041,16 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
       }
    }
 
+   struct _mesa_glsl_parse_state *state =
+      new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader);
+
+   if (ctx->Const.GenerateTemporaryNames)
+      (void) p_atomic_cmpxchg(&ir_variable::temporaries_allocate_names,
+                              false, true);
+
+   state->error = glcpp_preprocess(state, &source, &state->info_log,
+                                   add_builtin_defines, state, ctx);
+
    if (!state->error) {
      _mesa_glsl_lexer_ctor(state, source);
      _mesa_glsl_parse(state);
index e51fecd651851ebea231fbb62d0e4677aa494f82..738e5488ac21284b50a0c209d1164af453083f6b 100644 (file)
@@ -1319,6 +1319,16 @@ shader_cache_read_program_metadata(struct gl_context *ctx,
                           ctx->API, ctx->Const.GLSLVersion,
                           ctx->Const.ForceGLSLVersion);
 
+   /* We run the preprocessor on shaders after hashing them, so we need to
+    * add any extension override vars to the hash. If we don't do this the
+    * preprocessor could result in different output and we could load the
+    * wrong shader.
+    */
+   char *ext_override = getenv("MESA_EXTENSION_OVERRIDE");
+   if (ext_override) {
+      ralloc_asprintf_append(&buf, "ext:%s", ext_override);
+   }
+
    /* DRI config options may also change the output from the compiler so
     * include them as an input to sha1 creation.
     */