On 01/09/2018 05:05 PM, Eric Engestrom wrote:
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 :)
Yes, will clean this up.
+ + 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.
The 'not failure' state (linking_failed) means either success or skipped. Normally it should be 'success' here but _mesa_blob_cache_get may set it to 'skipped', we don't want to call link_shaders when status is 'skipped'.
Should this be if (prog->data->LinkStatus == linking_success) link_shaders(ctx, prog);
Yeah, this is what we want, looks simpler and has same behavior as the condition above. Will change this if the general approach is fine with others. It is a bit dirty here that blob_cache and disk_cache mark skipped in different places but I couldn't figure out nice way to combine this.
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