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

Nicolai Hähnle nhaehnle at gmail.com
Fri Feb 10 14:12:00 UTC 2017


On 07.02.2017 04:42, Timothy Arceri wrote:
> From: Timothy Arceri <timothy.arceri at 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) {

!= NULL?

> +      prog->data->NumFallbackShaders = 0;
> +      for (unsigned i = 0; i < prog->data->NumFallbackShaders; i++) {
> +         ralloc_free(prog->data->FallbackShaders);

FallbackShaders[i]?

Or maybe use the ralloc hierarchy, but then you don't need the loop.

Cheers,
Nicolai


> +         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" */
>



More information about the mesa-dev mailing list