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.
---
 src/compiler/glsl/glsl_parser_extras.cpp | 11 ++++++++++-
 src/mesa/main/mtypes.h                   |  2 ++
 src/mesa/main/shaderapi.c                | 15 ++++++++++++---
 src/mesa/main/shaderobj.c                |  1 +
 4 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/src/compiler/glsl/glsl_parser_extras.cpp 
b/src/compiler/glsl/glsl_parser_extras.cpp
index 8201f00..8783cfb 100644
--- a/src/compiler/glsl/glsl_parser_extras.cpp
+++ b/src/compiler/glsl/glsl_parser_extras.cpp
@@ -1926,7 +1926,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,
@@ -1945,6 +1946,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;
       }
    }
@@ -2066,6 +2070,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);
 }
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index a845a39..86c4e6a 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -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 */
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 3de0a7e..76d3610 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -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
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index b41137f..222efc1 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -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);
 }
-- 
2.9.3

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to