[Mesa-dev] [PATCH] radeonsi Add disk shader cache

kdj0c kdj0c at djinvi.net
Tue Jan 24 17:10:46 UTC 2017


On 24/01/2017 17:40, Nicolai Hähnle wrote:
> 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).
>

ok This is what I was wondering, it's not the right place to put it. (but it was easy because there was already a RAM cache).

Thanks

-- 

Jocelyn


> 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;
>>  }
>>
>>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev



More information about the mesa-dev mailing list