Reviewed-by: Marek Olšák <marek.ol...@amd.com> Marek
On Wed, Mar 1, 2017 at 6:25 AM, Timothy Arceri <tarc...@itsqueeze.com> wrote: > V2: > - when loading from disk cache also binary insert into memory cache. > - check that the binary loaded from disk is the correct size. If not > delete the cache item and skip loading from cache. > > V3: > - remove unrequired variable > > Tested-by: Michel Dänzer <michel.daen...@amd.com> > --- > src/gallium/drivers/radeonsi/si_state_shaders.c | 67 > ++++++++++++++++++++++--- > 1 file changed, 60 insertions(+), 7 deletions(-) > > diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c > b/src/gallium/drivers/radeonsi/si_state_shaders.c > index 750cdd6..a82e38e 100644 > --- a/src/gallium/drivers/radeonsi/si_state_shaders.c > +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c > @@ -29,20 +29,23 @@ > #include "sid.h" > #include "radeon/r600_cs.h" > > #include "tgsi/tgsi_parse.h" > #include "tgsi/tgsi_ureg.h" > #include "util/hash_table.h" > #include "util/crc32.h" > #include "util/u_memory.h" > #include "util/u_prim.h" > > +#include "util/disk_cache.h" > +#include "util/mesa-sha1.h" > + > /* SHADER_CACHE */ > > /** > * Return the TGSI binary in a buffer. The first 4 bytes contain its size as > * integer. > */ > static void *si_get_tgsi_binary(struct si_shader_selector *sel) > { > unsigned tgsi_size = tgsi_num_tokens(sel->tokens) * > sizeof(struct tgsi_token); > @@ -175,54 +178,104 @@ static bool si_load_shader_binary(struct si_shader > *shader, void *binary) > } > > /** > * Insert a shader into the cache. It's assumed the shader is not in the > cache. > * Use si_shader_cache_load_shader before calling this. > * > * Returns false on failure, in which case the tgsi_binary should be freed. > */ > static bool si_shader_cache_insert_shader(struct si_screen *sscreen, > void *tgsi_binary, > - struct si_shader *shader) > + struct si_shader *shader, > + bool insert_into_disk_cache) > { > void *hw_binary; > struct hash_entry *entry; > + uint8_t key[CACHE_KEY_SIZE]; > > entry = _mesa_hash_table_search(sscreen->shader_cache, tgsi_binary); > if (entry) > return false; /* already added */ > > hw_binary = si_get_shader_binary(shader); > if (!hw_binary) > return false; > > if (_mesa_hash_table_insert(sscreen->shader_cache, tgsi_binary, > hw_binary) == NULL) { > FREE(hw_binary); > return false; > } > > + if (sscreen->b.disk_shader_cache && insert_into_disk_cache) { > + _mesa_sha1_compute(tgsi_binary, *((uint32_t *)tgsi_binary), > key); > + disk_cache_put(sscreen->b.disk_shader_cache, key, hw_binary, > + *((uint32_t *) hw_binary)); > + } > + > return true; > } > > static bool si_shader_cache_load_shader(struct si_screen *sscreen, > void *tgsi_binary, > struct si_shader *shader) > { > struct hash_entry *entry = > _mesa_hash_table_search(sscreen->shader_cache, tgsi_binary); > - if (!entry) > - return false; > + if (!entry) { > + if (sscreen->b.disk_shader_cache) { > + unsigned char sha1[CACHE_KEY_SIZE]; > + size_t tg_size = *((uint32_t *) tgsi_binary); > + > + _mesa_sha1_compute(tgsi_binary, tg_size, sha1); > + > + size_t binary_size; > + uint8_t *buffer = > + disk_cache_get(sscreen->b.disk_shader_cache, > + sha1, &binary_size); > + if (!buffer) > + return false; > > - if (!si_load_shader_binary(shader, entry->data)) > - return false; > + if (binary_size < sizeof(uint32_t) || > + *((uint32_t*)buffer) != binary_size) { > + /* Something has gone wrong discard the item > + * from the cache and rebuild/link from > + * source. > + */ > + assert(!"Invalid radeonsi shader disk cache " > + "item!"); > + > + > disk_cache_remove(sscreen->b.disk_shader_cache, > + sha1); > + free(buffer); > + > + return false; > + } > + > + if (!si_load_shader_binary(shader, buffer)) { > + free(buffer); > + return false; > + } > + free(buffer); > > + if (!si_shader_cache_insert_shader(sscreen, > tgsi_binary, > + shader, false)) > + FREE(tgsi_binary); > + } else { > + return false; > + } > + } else { > + if (si_load_shader_binary(shader, entry->data)) > + FREE(tgsi_binary); > + else > + return false; > + } > p_atomic_inc(&sscreen->b.num_shader_cache_hits); > return true; > } > > static uint32_t si_shader_cache_key_hash(const void *key) > { > /* The first dword is the key size. */ > return util_hash_crc32(key, *(uint32_t*)key); > } > > @@ -244,20 +297,21 @@ static void si_destroy_shader_cache_entry(struct > hash_entry *entry) > FREE(entry->data); > } > > bool si_init_shader_cache(struct si_screen *sscreen) > { > pipe_mutex_init(sscreen->shader_cache_mutex); > sscreen->shader_cache = > _mesa_hash_table_create(NULL, > si_shader_cache_key_hash, > si_shader_cache_key_equals); > + > return sscreen->shader_cache != NULL; > } > > void si_destroy_shader_cache(struct si_screen *sscreen) > { > if (sscreen->shader_cache) > _mesa_hash_table_destroy(sscreen->shader_cache, > si_destroy_shader_cache_entry); > pipe_mutex_destroy(sscreen->shader_cache_mutex); > } > @@ -1400,37 +1454,36 @@ void si_init_shader_selector_async(void *job, int > thread_index) > shader->selector = sel; > si_parse_next_shader_property(&sel->info, &shader->key); > > tgsi_binary = si_get_tgsi_binary(sel); > > /* Try to load the shader from the shader cache. */ > pipe_mutex_lock(sscreen->shader_cache_mutex); > > if (tgsi_binary && > si_shader_cache_load_shader(sscreen, tgsi_binary, > shader)) { > - FREE(tgsi_binary); > pipe_mutex_unlock(sscreen->shader_cache_mutex); > } else { > pipe_mutex_unlock(sscreen->shader_cache_mutex); > > /* Compile the shader if it hasn't been loaded from > the cache. */ > if (si_compile_tgsi_shader(sscreen, tm, shader, false, > debug) != 0) { > FREE(shader); > FREE(tgsi_binary); > fprintf(stderr, "radeonsi: can't compile a > main shader part\n"); > return; > } > > if (tgsi_binary) { > pipe_mutex_lock(sscreen->shader_cache_mutex); > - if (!si_shader_cache_insert_shader(sscreen, > tgsi_binary, shader)) > + if (!si_shader_cache_insert_shader(sscreen, > tgsi_binary, shader, true)) > FREE(tgsi_binary); > > pipe_mutex_unlock(sscreen->shader_cache_mutex); > } > } > > *si_get_main_shader_part(sel, &shader->key) = shader; > > /* Unset "outputs_written" flags for outputs converted to > * DEFAULT_VAL, so that later inter-shader optimizations don't > * try to eliminate outputs that don't exist in the final > -- > 2.9.3 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev