[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