[Mesa-dev] [PATCH] radeonsi Add disk shader cache
kdj0c
kdj0c at djinvi.net
Tue Jan 24 16:08:22 UTC 2017
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.
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;
}
--
2.11.0
More information about the mesa-dev
mailing list