From f0d91c9af3b054a94f45fbdc27265aac213c0db4 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 13 May 2020 10:45:37 +1000 Subject: [PATCH] llvmpipe/fs: add caching support Serialize and check if the object is in the cache, it there is a cached object skip compilation code once we've constructed the function interface. Reviewed-by: Roland Scheidegger Part-of: --- src/gallium/drivers/llvmpipe/lp_state_fs.c | 51 ++++++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 4bd201de581..6e48b34622f 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -105,6 +105,9 @@ #include "lp_rast.h" #include "nir/nir_to_tgsi_info.h" +#include "lp_screen.h" +#include "compiler/nir/nir_serialize.h" +#include "util/mesa-sha1.h" /** Fragment shader number (for debugging) */ static unsigned fs_no = 0; @@ -2850,6 +2853,9 @@ generate_fragment(struct llvmpipe_context *lp, if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) lp_add_function_attr(function, i + 1, LP_FUNC_ATTR_NOALIAS); + if (variant->gallivm->cache->data_size) + return; + context_ptr = LLVMGetParam(function, 0); x = LLVMGetParam(function, 1); y = LLVMGetParam(function, 2); @@ -3247,6 +3253,27 @@ lp_debug_fs_variant(struct lp_fragment_shader_variant *variant) debug_printf("\n"); } +static void +lp_fs_get_ir_cache_key(struct lp_fragment_shader_variant *variant, + unsigned char ir_sha1_cache_key[20]) +{ + struct blob blob = { 0 }; + unsigned ir_size; + void *ir_binary; + + blob_init(&blob); + nir_serialize(&blob, variant->shader->base.ir.nir, true); + ir_binary = blob.data; + ir_size = blob.size; + + struct mesa_sha1 ctx; + _mesa_sha1_init(&ctx); + _mesa_sha1_update(&ctx, &variant->key, variant->shader->variant_key_size); + _mesa_sha1_update(&ctx, ir_binary, ir_size); + _mesa_sha1_final(&ctx, ir_sha1_cache_key); + + blob_finish(&blob); +} /** * Generate a new fragment shader variant from the shader code and @@ -3257,11 +3284,14 @@ generate_variant(struct llvmpipe_context *lp, struct lp_fragment_shader *shader, const struct lp_fragment_shader_variant_key *key) { + struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen); struct lp_fragment_shader_variant *variant; const struct util_format_description *cbuf0_format_desc = NULL; boolean fullcolormask; char module_name[64]; - + unsigned char ir_sha1_cache_key[20]; + struct lp_cached_code cached = { 0 }; + bool needs_caching = false; variant = MALLOC(sizeof *variant + shader->variant_key_size - sizeof variant->key); if (!variant) return NULL; @@ -3270,18 +3300,27 @@ generate_variant(struct llvmpipe_context *lp, snprintf(module_name, sizeof(module_name), "fs%u_variant%u", shader->no, shader->variants_created); - variant->gallivm = gallivm_create(module_name, lp->context, NULL); + variant->shader = shader; + memcpy(&variant->key, key, shader->variant_key_size); + + if (shader->base.ir.nir) { + lp_fs_get_ir_cache_key(variant, ir_sha1_cache_key); + + lp_disk_cache_find_shader(screen, &cached, ir_sha1_cache_key); + if (!cached.data_size) + needs_caching = true; + } + variant->gallivm = gallivm_create(module_name, lp->context, &cached); if (!variant->gallivm) { FREE(variant); return NULL; } - variant->shader = shader; variant->list_item_global.base = variant; variant->list_item_local.base = variant; variant->no = shader->variants_created++; - memcpy(&variant->key, key, shader->variant_key_size); + /* * Determine whether we are touching all channels in the color buffer. @@ -3343,6 +3382,10 @@ generate_variant(struct llvmpipe_context *lp, variant->jit_function[RAST_WHOLE] = variant->jit_function[RAST_EDGE_TEST]; } + if (needs_caching) { + lp_disk_cache_insert_shader(screen, &cached, ir_sha1_cache_key); + } + gallivm_free_ir(variant->gallivm); return variant; -- 2.30.2