glsl: use correct shader source in case of cache fallback
authorTimothy Arceri <tarceri@itsqueeze.com>
Sun, 12 Feb 2017 22:34:54 +0000 (09:34 +1100)
committerTimothy Arceri <tarceri@itsqueeze.com>
Fri, 17 Feb 2017 00:18:42 +0000 (11:18 +1100)
The scenario is:

glShaderSource
glCompileShader <-- deferred due to cache hit of shader

glShaderSource <-- with new source code

glAttachShader
glLinkProgram <-- no cache hit for program

At this point we need to compile the original source when we
fallback.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/compiler/glsl/glsl_parser_extras.cpp
src/mesa/main/mtypes.h
src/mesa/main/shaderapi.c
src/mesa/main/shaderobj.c

index 833b5fefa18882455796f74c279da1df911f3fae..375a99a49dacf7002a9842e7e621dc97d016297f 100644 (file)
@@ -1927,7 +1927,8 @@ _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);
-   const char *source = shader->Source;
+   const char *source = force_recompile && shader->FallbackSource ?
+      shader->FallbackSource : shader->Source;
 
    if (ctx->Const.GenerateTemporaryNames)
       (void) p_atomic_cmpxchg(&ir_variable::temporaries_allocate_names,
@@ -1946,6 +1947,9 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
                     _mesa_sha1_format(buf, shader->sha1));
          }
          shader->CompileStatus = true;
+
+         free((void *)shader->FallbackSource);
+         shader->FallbackSource = NULL;
          return;
       }
    }
@@ -2067,6 +2071,11 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
 
    _mesa_glsl_initialize_derived_variables(ctx, shader);
 
+   if (!force_recompile) {
+      free((void *)shader->FallbackSource);
+      shader->FallbackSource = NULL;
+   }
+
    delete state->symbols;
    ralloc_free(state);
 }
index efe0cbcad756c479d80b64946c16bfffcce96ed6..e24ee3c0c00f43747442f07a26b6a7ea785d9f24 100644 (file)
@@ -2397,6 +2397,8 @@ struct gl_shader
 #endif
    const GLchar *Source;  /**< Source code string */
 
+   const GLchar *FallbackSource;  /**< Fallback string used by on-disk cache*/
+
    GLchar *InfoLog;
 
    unsigned Version;       /**< GLSL version used for linking */
index 86ce0bc5fdfe635aad76ca77601c34b6624f016b..0c38cea25553c393480f2fd5ab0614ffb25e8175 100644 (file)
@@ -1003,9 +1003,18 @@ shader_source(struct gl_shader *sh, const GLchar *source)
 {
    assert(sh);
 
-   /* free old shader source string and install new one */
-   free((void *)sh->Source);
-   sh->Source = source;
+   if (sh->CompileStatus == GL_TRUE && !sh->FallbackSource) {
+      /* If shader was previously compiled back-up the source in case of cache
+       * fallback.
+       */
+      sh->FallbackSource = sh->Source;
+      sh->Source = source;
+   } else {
+      /* free old shader source string and install new one */
+      free((void *)sh->Source);
+      sh->Source = source;
+   }
+
 #ifdef DEBUG
    sh->SourceChecksum = util_hash_crc32(sh->Source, strlen(sh->Source));
 #endif
index b41137fbce3b3820bb51fb3a77bd28ca21ec6d07..222efc12c4e6260bea330ad918d53032619c76d9 100644 (file)
@@ -122,6 +122,7 @@ void
 _mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh)
 {
    free((void *)sh->Source);
+   free((void *)sh->FallbackSource);
    free(sh->Label);
    ralloc_free(sh);
 }