On Tuesday, 2018-01-09 09:48:19 +0200, Tapani Pälli wrote: > Cache set and get are called in similar fashion as what is happening > with disk cache. Functionality requires ARB_get_program_binary and > EGL_ANDROID_blob_cache support. > > Signed-off-by: Tapani Pälli <tapani.pa...@intel.com> > --- > src/mesa/Makefile.sources | 2 + > src/mesa/main/program_blob_cache.c | 141 > +++++++++++++++++++++++++++++++++++++ > src/mesa/main/program_blob_cache.h | 48 +++++++++++++ > src/mesa/meson.build | 2 + > src/mesa/program/ir_to_mesa.cpp | 9 ++- > 5 files changed, 201 insertions(+), 1 deletion(-) > create mode 100644 src/mesa/main/program_blob_cache.c > create mode 100644 src/mesa/main/program_blob_cache.h > > diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources > index 53fa486364..bbcfdb425e 100644 > --- a/src/mesa/Makefile.sources > +++ b/src/mesa/Makefile.sources > @@ -177,6 +177,8 @@ MAIN_FILES = \ > main/polygon.h \ > main/program_binary.c \ > main/program_binary.h \ > + main/program_blob_cache.c \ > + main/program_blob_cache.h \ > main/program_resource.c \ > main/program_resource.h \ > main/querymatrix.c \ > diff --git a/src/mesa/main/program_blob_cache.c > b/src/mesa/main/program_blob_cache.c > new file mode 100644 > index 0000000000..0b3ea1a549 > --- /dev/null > +++ b/src/mesa/main/program_blob_cache.c > @@ -0,0 +1,141 @@ > +/* > + * Mesa 3-D graphics library > + * > + * Copyright (C) 2018 Intel Corporation. All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included > + * in all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS > + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + */ > + > +#include "main/errors.h" > +#include "main/mtypes.h" > +#include "main/shaderobj.h" > +#include "main/program_binary.h" > +#include "util/mesa-sha1.h" > +#include "compiler/glsl/program.h" > + > +#include "program_blob_cache.h" > + > +/* This is what Android EGL defines as the maxValueSize in egl_cache_t > + * class implementation. > + */ > +#define MAX_BLOB_SIZE 64 * 1024 > + > +static void > +generate_sha1_string(struct gl_context *ctx, struct gl_shader_program > *shProg, > + char *key) > +{ > + char *buf = create_shader_program_keystr(ctx, shProg); > + struct mesa_sha1 sha_ctx; > + unsigned char sha1str[20]; > + > + /* Add driver sha1 to the key string. */ > + uint8_t driver_sha1[20]; > + char driver_sha1buf[41]; > + > + ctx->Driver.GetProgramBinaryDriverSHA1(ctx, driver_sha1); > + _mesa_sha1_format(driver_sha1buf, driver_sha1); > + ralloc_asprintf_append(&buf, "%s", driver_sha1buf); > + > + _mesa_sha1_init(&sha_ctx); > + _mesa_sha1_update(&sha_ctx, buf, strlen(buf)); > + _mesa_sha1_final(&sha_ctx, sha1str); > + _mesa_sha1_format(key, sha1str); > + > + ralloc_free(buf); > +} > + > +void > +_mesa_blob_cache_set(struct gl_context *ctx, > + struct gl_shader_program *shProg) > +{ > + assert(shProg->data->LinkStatus == linking_success); > + > + /* ARB_get_program_binary support required. */ > + if (!ctx->blobCacheSet || !ctx->Driver.GetProgramBinaryDriverSHA1) > + return; > + > + /* Skip cache for fixed-function programs and programs that use > + * transform feedback. > + */ > + if (!shProg->Name || shProg->TransformFeedback.NumVarying > 0) > + return; > + > + GLint length; > + _mesa_get_program_binary_length(ctx, shProg, &length); > + > + /* Skip cache if exceeds max blob size. */ > + if (length > MAX_BLOB_SIZE) > + return; > + > + char *blob = (char *) malloc (length);
Nit: in C, malloc returns (void*) so the cast is unnecessary, and the space after malloc looks weird :) > + > + if (!blob) > + return; > + > + GLsizei real_len; > + GLenum format; > + _mesa_get_program_binary(ctx, shProg, length, &real_len, > + &format, blob); > + > + assert(format == GL_PROGRAM_BINARY_FORMAT_MESA); > + > + char key[41]; > + generate_sha1_string(ctx, shProg, key); > + > + ctx->blobCacheSet(key, 41, blob, real_len); > + free(blob); > +} > + > +void > +_mesa_blob_cache_get(struct gl_context *ctx, > + struct gl_shader_program *shProg) > +{ > + /* ARB_get_program_binary support required. */ > + if (!ctx->blobCacheGet || !ctx->Driver.GetProgramBinaryDriverSHA1) > + return; > + > + void *blob = malloc(MAX_BLOB_SIZE); > + > + if (!blob) > + return; > + > + char key[41]; > + generate_sha1_string(ctx, shProg, key); > + > + signed long bytes = > + ctx->blobCacheGet(key, 41, blob, MAX_BLOB_SIZE); > + > + if (!bytes) { > + free(blob); > + return; > + } > + > + _mesa_program_binary(ctx, shProg, GL_PROGRAM_BINARY_FORMAT_MESA, > + blob, bytes); > + > + assert(shProg->data->LinkStatus == linking_success); > + > + shProg->data->Validated = false; > + shProg->data->LinkStatus = linking_skipped; > + > + free(blob); > +} > + > +#undef MAX_BLOB_SIZE > diff --git a/src/mesa/main/program_blob_cache.h > b/src/mesa/main/program_blob_cache.h > new file mode 100644 > index 0000000000..c17146b7d9 > --- /dev/null > +++ b/src/mesa/main/program_blob_cache.h > @@ -0,0 +1,48 @@ > +/* > + * Mesa 3-D graphics library > + * > + * Copyright (C) 2018 Intel Corporation. All Rights Reserved. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included > + * in all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS > + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + */ > + > +#ifndef PROGRAM_BLOB_CACHE_H > +#define PROGRAM_BLOB_CACHE_H > + > +#include "glheader.h" > +#include "mtypes.h" > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +void > +_mesa_blob_cache_set(struct gl_context *ctx, > + struct gl_shader_program *shProg); > + > +void > +_mesa_blob_cache_get(struct gl_context *ctx, > + struct gl_shader_program *shProg); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif > diff --git a/src/mesa/meson.build b/src/mesa/meson.build > index ab6bc27312..55276d50c2 100644 > --- a/src/mesa/meson.build > +++ b/src/mesa/meson.build > @@ -219,6 +219,8 @@ files_libmesa_common = files( > 'main/polygon.h', > 'main/program_binary.c', > 'main/program_binary.h', > + 'main/program_blob_cache.c', > + 'main/program_blob_cache.h', > 'main/program_resource.c', > 'main/program_resource.h', > 'main/querymatrix.c', > diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp > index 29198509a6..782a6891b8 100644 > --- a/src/mesa/program/ir_to_mesa.cpp > +++ b/src/mesa/program/ir_to_mesa.cpp > @@ -33,6 +33,7 @@ > #include "main/compiler.h" > #include "main/macros.h" > #include "main/mtypes.h" > +#include "main/program_blob_cache.h" > #include "main/shaderapi.h" > #include "main/shaderobj.h" > #include "main/uniforms.h" > @@ -3111,7 +3112,10 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct > gl_shader_program *prog) > } > } > > - if (prog->data->LinkStatus) { > + /* EGL_ANDROID_blob_cache. */ > + _mesa_blob_cache_get(ctx, prog); > + > + if (prog->data->LinkStatus && prog->data->LinkStatus != linking_skipped) { I'm not familiar with shader code, but this condition looks really weird, between the implicit 'not failure' zero check on the left, and eliminating the only other posibility than `success` on the right. Should this be if (prog->data->LinkStatus == linking_success) link_shaders(ctx, prog); or if (prog->data->LinkStatus == linking_skipped) link_shaders(ctx, prog); ? I feel like the latter is the right one, but the former is the current behaviour; could this be the issue you're seeing? > link_shaders(ctx, prog); > } > > @@ -3147,6 +3151,9 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct > gl_shader_program *prog) > if (prog->data->LinkStatus) > shader_cache_write_program_metadata(ctx, prog); > #endif > + > + /* EGL_ANDROID_blob_cache. */ > + _mesa_blob_cache_set(ctx, prog); > } > > } /* extern "C" */ > -- > 2.14.3 > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev