[Mesa-dev] [PATCH 31/56] glsl/i965: make a copy of the shader source for use with cache fallback

Timothy Arceri timothy.arceri at collabora.com
Tue Nov 29 03:58:30 UTC 2016


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 a41bb4b..c829f6b 100644
--- a/src/compiler/glsl/shader_cache.cpp
+++ b/src/compiler/glsl/shader_cache.cpp
@@ -1256,6 +1256,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_VERTEX &&
           prog->Shaders[i]->Stage != MESA_SHADER_FRAGMENT) {
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 39be592..dd234e7 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2657,6 +2657,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 c39578a..b86bcb1 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -408,10 +408,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 6214940..4c5bde7 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -3088,8 +3088,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.7.4



More information about the mesa-dev mailing list