From: Timothy Arceri <timothy.arc...@collabora.com> A number of things can happen that change the shader source after it is compiled or linked.
For example: - Source changed after it is first compiled - Source changed after linking - Shader detached after linking In order to be able to fallback to a full rebuild on a cache miss we make a copy of the shader source and store it in the new FallbackShaders field when linking. [jordan.l.jus...@intel.com: fix 'Free previous fallback information'] Signed-off-by: Jordan Justen <jordan.l.jus...@intel.com> --- src/compiler/glsl/shader_cache.cpp | 29 +++++++++++++++++++++++++++++ src/mesa/main/mtypes.h | 2 ++ src/mesa/main/shaderobj.c | 4 ++++ src/mesa/program/ir_to_mesa.cpp | 8 +++++++- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/compiler/glsl/shader_cache.cpp b/src/compiler/glsl/shader_cache.cpp index 0d4a93c879..273c173725 100644 --- a/src/compiler/glsl/shader_cache.cpp +++ b/src/compiler/glsl/shader_cache.cpp @@ -1360,6 +1360,35 @@ shader_cache_read_program_metadata(struct gl_context *ctx, if (!cache || prog->data->cache_fallback || prog->data->skip_cache) return false; + /* Free previous fallback information */ + if (prog->data->FallbackShaders != NULL) { + for (unsigned i = 0; i < prog->data->NumFallbackShaders; i++) { + ralloc_free(prog->data->FallbackShaders[i]); + prog->data->FallbackShaders[i] = NULL; + } + prog->data->NumFallbackShaders = 0; + } + + /* Shaders could be recompiled using different source code after linking, + * or the shader could be detached from the program so store some + * information about the shader to be used in case of fallback. + */ + prog->data->NumFallbackShaders = prog->NumShaders; + prog->data->FallbackShaders = (struct gl_shader **) + reralloc(NULL, prog->data->FallbackShaders, struct gl_shader *, + prog->NumShaders); + for (unsigned i = 0; i < prog->NumShaders; i++) { + prog->data->FallbackShaders[i] = rzalloc(prog->data->FallbackShaders, + struct gl_shader); + memcpy(prog->data->FallbackShaders[i]->sha1, prog->Shaders[i]->sha1, + sizeof(prog->Shaders[i]->sha1)); + prog->data->FallbackShaders[i]->Stage = prog->Shaders[i]->Stage; + prog->data->FallbackShaders[i]->Source = + ralloc_strdup(prog->data->FallbackShaders, prog->Shaders[i]->Source); + prog->data->FallbackShaders[i]->InfoLog = + ralloc_strdup(prog->data->FallbackShaders, ""); + } + /* Include bindings when creating sha1. These bindings change the resulting * binary so they are just as important as the shader source. */ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index d7996a15bd..25e90bad53 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2865,6 +2865,8 @@ struct gl_shader_program_data union gl_constant_value *UniformDataSlots; bool cache_fallback; + GLuint NumFallbackShaders; + struct gl_shader **FallbackShaders; /**< Shaders used for cache fallback */ /* TODO: This used by Gallium drivers to skip the cache on tgsi fallback. * All structures (gl_program, uniform storage, etc) will get recreated diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index 999a389c53..f45ad850d9 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -427,10 +427,14 @@ _mesa_free_shader_program_data(struct gl_context *ctx, _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); } shProg->NumShaders = 0; + shProg->data->NumFallbackShaders = 0; free(shProg->Shaders); shProg->Shaders = NULL; + ralloc_free(shProg->data->FallbackShaders); + shProg->data->FallbackShaders = NULL; + /* Transform feedback varying vars */ for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { free(shProg->TransformFeedback.VaryingNames[i]); diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 0e6a95ce99..e0a97478ab 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -3132,8 +3132,14 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) } #ifdef ENABLE_SHADER_CACHE - if (prog->data->LinkStatus) + if (prog->data->LinkStatus && !prog->data->cache_fallback) { + if (prog->data->FallbackShaders) { + prog->data->NumFallbackShaders = 0; + ralloc_free(prog->data->FallbackShaders); + prog->data->FallbackShaders = NULL; + } shader_cache_write_program_metadata(ctx, prog); + } #endif } -- 2.14.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev