[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