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. --- 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 583db47..729dd09 100644 --- a/src/compiler/glsl/shader_cache.cpp +++ b/src/compiler/glsl/shader_cache.cpp @@ -1276,6 +1276,35 @@ shader_cache_read_program_metadata(struct gl_context *ctx, if (!cache || prog->data->cache_fallback) return false; + /* Free previous fallback information */ + if (prog->data->FallbackShaders == NULL) { + prog->data->NumFallbackShaders = 0; + for (unsigned i = 0; i < prog->data->NumFallbackShaders; i++) { + ralloc_free(prog->data->FallbackShaders); + prog->data->FallbackShaders = NULL; + } + } + + /* 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, ""); + } + for (unsigned i = 0; i < prog->NumShaders; i++) { if (prog->Shaders[i]->Stage == MESA_SHADER_COMPUTE) { compile_shaders(ctx, prog); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index c7ca182..f65cd76 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2685,6 +2685,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 */ /** List of all active resources after linking. */ struct gl_program_resource *ProgramResourceList; diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index b41137f..6ddccd2 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -404,10 +404,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 67c9267..e286408 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -3130,8 +3130,14 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) } } - 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); + } } } /* extern "C" */ -- 2.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev