[Mesa-dev] [PATCH] radeonsi Add disk shader cache
Nicolai Hähnle
nhaehnle at gmail.com
Tue Jan 24 16:40:37 UTC 2017
On 24.01.2017 17:08, kdj0c wrote:
> use the util/disk_cache.c interface to cache some? radeonsi shaders on disk
>
> missing features :
>
> - add #if ENABLE_SHADER_CACHE where needed.
> - when loading from disk cache, also insert it to RAM cache.
>
> must be built with --enable-shader-cache to have the cache working.
> ---
> Hi, This is my first mail to the list.
>
> I'm not sure this is the right way to do this, it's my first attempt to patch mesa.
> I've tested on a radeon HD7950 with glxgears and quake3. I have some binary shaders in ~/.cache/mesa after running them, and they are re-used when re-launching them.
> I wanted to test more recent games, but the LD_LIBRARY_PATH trick didn't work with steam games, and I don't want to install mesa master system-wide.
Unfortunately, I'd say that this is a pretty wrong approach. A
radeonsi-level cache is nice, but the GLSL-level compilation and linking
has overhead as well, which we want to avoid with the cache.
We really want to detect a re-used shader already at the GLSL level, to
be able to go straight to binaries (and TGSI I guess, for optimized
monolithic variants).
Nicolai
> src/gallium/drivers/radeonsi/si_pipe.h | 3 +++
> src/gallium/drivers/radeonsi/si_state_shaders.c | 35 ++++++++++++++++++++-----
> 2 files changed, 32 insertions(+), 6 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
> index 421e2a4cf6..e31c4f973c 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.h
> +++ b/src/gallium/drivers/radeonsi/si_pipe.h
> @@ -27,6 +27,7 @@
> #define SI_PIPE_H
>
> #include "si_shader.h"
> +#include "util/disk_cache.h"
>
> #ifdef PIPE_ARCH_BIG_ENDIAN
> #define SI_BIG_ENDIAN 1
> @@ -114,6 +115,8 @@ struct si_screen {
> /* Shader compiler queue for multithreaded compilation. */
> struct util_queue shader_compiler_queue;
> LLVMTargetMachineRef tm[4]; /* used by the queue only */
> +
> + struct disk_cache *disk_shader_cache;
> };
>
> struct si_blend_color {
> diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
> index 010ce15a8b..ebb0a7ac36 100644
> --- a/src/gallium/drivers/radeonsi/si_state_shaders.c
> +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
> @@ -36,6 +36,9 @@
> #include "util/u_memory.h"
> #include "util/u_prim.h"
>
> +#include "util/disk_cache.h"
> +#include "util/mesa-sha1.h"
> +
> /* SHADER_CACHE */
>
> /**
> @@ -186,6 +189,7 @@ static bool si_shader_cache_insert_shader(struct si_screen *sscreen,
> {
> 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)
> @@ -200,7 +204,10 @@ static bool si_shader_cache_insert_shader(struct si_screen *sscreen,
> FREE(hw_binary);
> return false;
> }
> -
> + if (sscreen->disk_shader_cache) {
> + _mesa_sha1_compute(tgsi_binary, *((uint32_t *)tgsi_binary), key);
> + disk_cache_put(sscreen->disk_shader_cache, key, hw_binary, *((uint32_t *) hw_binary));
> + }
> return true;
> }
>
> @@ -210,12 +217,26 @@ static bool si_shader_cache_load_shader(struct si_screen *sscreen,
> {
> struct hash_entry *entry =
> _mesa_hash_table_search(sscreen->shader_cache, tgsi_binary);
> - if (!entry)
> - return false;
> -
> - if (!si_load_shader_binary(shader, entry->data))
> - return false;
> + if (!entry) {
> + if (sscreen->disk_shader_cache) {
> + uint8_t tg_key[CACHE_KEY_SIZE];
> + size_t tg_size = *((uint32_t *) tgsi_binary);
> + char *cached;
> +
> + _mesa_sha1_compute(tgsi_binary, tg_size, tg_key);
> + cached = disk_cache_get(sscreen->disk_shader_cache, tg_key, &tg_size);
> + if (!cached)
> + return false;
>
> + if (!si_load_shader_binary(shader, cached))
> + return false;
> + } else {
> + return false;
> + }
> + } else {
> + if (!si_load_shader_binary(shader, entry->data))
> + return false;
> + }
> p_atomic_inc(&sscreen->b.num_shader_cache_hits);
> return true;
> }
> @@ -251,6 +272,8 @@ bool si_init_shader_cache(struct si_screen *sscreen)
> _mesa_hash_table_create(NULL,
> si_shader_cache_key_hash,
> si_shader_cache_key_equals);
> +
> + sscreen->disk_shader_cache = disk_cache_create();
> return sscreen->shader_cache != NULL;
> }
>
>
More information about the mesa-dev
mailing list