diff options
author | Axel Davy <[email protected]> | 2020-05-12 22:24:32 +0200 |
---|---|---|
committer | Marge Bot <[email protected]> | 2020-05-13 19:43:05 +0000 |
commit | 4db880d8057bac3209c196edc94c6b1e521a782a (patch) | |
tree | 200ddf62fd0d8c5c83b6d6b7ee14cd0cda7e0389 /src/gallium/auxiliary | |
parent | 522bd414f343c7a132fee17d0d6b755b9ec6766c (diff) |
ttn: Implement disk cache
ttn is slow, let's disk cache it.
Signed-off-by: Axel Davy <[email protected]>
Reviewed-by: Marek Olšák <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4993>
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/nir/tgsi_to_nir.c | 84 |
1 files changed, 82 insertions, 2 deletions
diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.c b/src/gallium/auxiliary/nir/tgsi_to_nir.c index 69c1d5bfc58..07f3f6fe47a 100644 --- a/src/gallium/auxiliary/nir/tgsi_to_nir.c +++ b/src/gallium/auxiliary/nir/tgsi_to_nir.c @@ -22,12 +22,16 @@ * IN THE SOFTWARE. */ +#include "util/blob.h" +#include "util/disk_cache.h" +#include "util/u_memory.h" #include "util/ralloc.h" #include "pipe/p_screen.h" #include "compiler/nir/nir.h" #include "compiler/nir/nir_control_flow.h" #include "compiler/nir/nir_builder.h" +#include "compiler/nir/nir_serialize.h" #include "compiler/shader_enums.h" #include "tgsi_to_nir.h" @@ -2580,21 +2584,97 @@ ttn_finalize_nir(struct ttn_compile *c, struct pipe_screen *screen) nir_validate_shader(nir, "TTN: after all optimizations"); } +static void save_nir_to_disk_cache(struct disk_cache *cache, + uint8_t key[CACHE_KEY_SIZE], + const nir_shader *s) +{ + struct blob blob = {0}; + + blob_init(&blob); + /* Because we cannot fully trust disk_cache_put + * (EGL_ANDROID_blob_cache) we add the shader size, + * which we'll check after disk_cache_get(). + */ + if (blob_reserve_uint32(&blob) != 0) { + blob_finish(&blob); + return; + } + + nir_serialize(&blob, s, true); + *(uint32_t *)blob.data = blob.size; + + disk_cache_put(cache, key, blob.data, blob.size, NULL); + blob_finish(&blob); +} + +static nir_shader * +load_nir_from_disk_cache(struct disk_cache *cache, + struct pipe_screen *screen, + uint8_t key[CACHE_KEY_SIZE], + unsigned processor) +{ + const nir_shader_compiler_options *options = + screen->get_compiler_options(screen, PIPE_SHADER_IR_NIR, processor); + struct blob_reader blob_reader; + size_t size; + nir_shader *s; + + uint32_t *buffer = (uint32_t *)disk_cache_get(cache, key, &size); + if (!buffer) + return NULL; + + /* Match found. No need to check crc32 or other things. + * disk_cache_get is supposed to do that for us. + * However we do still check if the first element is indeed the size, + * as we cannot fully trust disk_cache_get (EGL_ANDROID_blob_cache) */ + if (buffer[0] != size) { + return NULL; + } + + size -= 4; + blob_reader_init(&blob_reader, buffer + 1, size); + s = nir_deserialize(NULL, options, &blob_reader); + free(buffer); /* buffer was malloc-ed */ + return s; +} + struct nir_shader * tgsi_to_nir(const void *tgsi_tokens, struct pipe_screen *screen, bool allow_disk_cache) { + struct disk_cache *cache = NULL; struct ttn_compile *c; - struct nir_shader *s; + struct nir_shader *s = NULL; + uint8_t key[CACHE_KEY_SIZE]; + unsigned processor; + + if (allow_disk_cache) + cache = screen->get_disk_shader_cache(screen); + + /* Look first in the cache */ + if (cache) { + disk_cache_compute_key(cache, + tgsi_tokens, + tgsi_num_tokens(tgsi_tokens) * sizeof(struct tgsi_token), + key); + processor = tgsi_get_processor_type(tgsi_tokens); + s = load_nir_from_disk_cache(cache, screen, key, processor); + } - (void)allow_disk_cache; + if (s) + return s; + + /* Not in the cache */ c = ttn_compile_init(tgsi_tokens, NULL, screen); s = c->build.shader; ttn_finalize_nir(c, screen); ralloc_free(c); + if (cache) + save_nir_to_disk_cache(cache, key, s); + return s; } |