On 01/03/17 18:36, Axel Davy wrote:
My understanding of the code is that the disk cache just depends on the
sscreen->b.disk_shader_cache being initialized, and it looks like this
is always
initialized.
Thus the disk cache is always enabled.

Could you add a RADEON_DEBUG env var to disable it, please ?

Replying here for completeness but as discussed on irc the entire cache can be turned off with MESA_GLSL_CACHE_DISABLE=1. I don't think there is much justification for a RADEON_DEBUG flag to disable only the radeonsi cache.


Thanks,

Axel Davy

On 01/03/2017 06:25, Timothy Arceri wrote:
V2:
- when loading from disk cache also binary insert into memory cache.
- check that the binary loaded from disk is the correct size. If not
   delete the cache item and skip loading from cache.

V3:
- remove unrequired variable

Tested-by: Michel Dänzer <[email protected]>
---
  src/gallium/drivers/radeonsi/si_state_shaders.c | 67
++++++++++++++++++++++---
  1 file changed, 60 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c
b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 750cdd6..a82e38e 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -29,20 +29,23 @@
  #include "sid.h"
  #include "radeon/r600_cs.h"
    #include "tgsi/tgsi_parse.h"
  #include "tgsi/tgsi_ureg.h"
  #include "util/hash_table.h"
  #include "util/crc32.h"
  #include "util/u_memory.h"
  #include "util/u_prim.h"
  +#include "util/disk_cache.h"
+#include "util/mesa-sha1.h"
+
  /* SHADER_CACHE */
    /**
   * Return the TGSI binary in a buffer. The first 4 bytes contain its
size as
   * integer.
   */
  static void *si_get_tgsi_binary(struct si_shader_selector *sel)
  {
      unsigned tgsi_size = tgsi_num_tokens(sel->tokens) *
                   sizeof(struct tgsi_token);
@@ -175,54 +178,104 @@ static bool si_load_shader_binary(struct
si_shader *shader, void *binary)
  }
    /**
   * Insert a shader into the cache. It's assumed the shader is not in
the cache.
   * Use si_shader_cache_load_shader before calling this.
   *
   * Returns false on failure, in which case the tgsi_binary should be
freed.
   */
  static bool si_shader_cache_insert_shader(struct si_screen *sscreen,
                        void *tgsi_binary,
-                      struct si_shader *shader)
+                      struct si_shader *shader,
+                      bool insert_into_disk_cache)
  {
      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)
          return false; /* already added */
        hw_binary = si_get_shader_binary(shader);
      if (!hw_binary)
          return false;
        if (_mesa_hash_table_insert(sscreen->shader_cache, tgsi_binary,
                      hw_binary) == NULL) {
          FREE(hw_binary);
          return false;
      }
  +    if (sscreen->b.disk_shader_cache && insert_into_disk_cache) {
+        _mesa_sha1_compute(tgsi_binary, *((uint32_t *)tgsi_binary),
key);
+        disk_cache_put(sscreen->b.disk_shader_cache, key, hw_binary,
+                   *((uint32_t *) hw_binary));
+    }
+
      return true;
  }
    static bool si_shader_cache_load_shader(struct si_screen *sscreen,
                      void *tgsi_binary,
                          struct si_shader *shader)
  {
      struct hash_entry *entry =
          _mesa_hash_table_search(sscreen->shader_cache, tgsi_binary);
-    if (!entry)
-        return false;
+    if (!entry) {
+        if (sscreen->b.disk_shader_cache) {
+            unsigned char sha1[CACHE_KEY_SIZE];
+            size_t tg_size = *((uint32_t *) tgsi_binary);
+
+            _mesa_sha1_compute(tgsi_binary, tg_size, sha1);
+
+            size_t binary_size;
+            uint8_t *buffer =
+                disk_cache_get(sscreen->b.disk_shader_cache,
+                           sha1, &binary_size);
+            if (!buffer)
+                return false;
  -    if (!si_load_shader_binary(shader, entry->data))
-        return false;
+            if (binary_size < sizeof(uint32_t) ||
+                *((uint32_t*)buffer) != binary_size) {
+                 /* Something has gone wrong discard the item
+                  * from the cache and rebuild/link from
+                  * source.
+                  */
+                assert(!"Invalid radeonsi shader disk cache "
+                       "item!");
+
+                disk_cache_remove(sscreen->b.disk_shader_cache,
+                          sha1);
+                free(buffer);
+
+                return false;
+            }
+
+            if (!si_load_shader_binary(shader, buffer)) {
+                free(buffer);
+                return false;
+            }
+            free(buffer);
  +            if (!si_shader_cache_insert_shader(sscreen, tgsi_binary,
+                               shader, false))
+                FREE(tgsi_binary);
+        } else {
+            return false;
+        }
+    } else {
+        if (si_load_shader_binary(shader, entry->data))
+            FREE(tgsi_binary);
+        else
+            return false;
+    }
      p_atomic_inc(&sscreen->b.num_shader_cache_hits);
      return true;
  }
    static uint32_t si_shader_cache_key_hash(const void *key)
  {
      /* The first dword is the key size. */
      return util_hash_crc32(key, *(uint32_t*)key);
  }
  @@ -244,20 +297,21 @@ static void
si_destroy_shader_cache_entry(struct hash_entry *entry)
      FREE(entry->data);
  }
    bool si_init_shader_cache(struct si_screen *sscreen)
  {
      pipe_mutex_init(sscreen->shader_cache_mutex);
      sscreen->shader_cache =
          _mesa_hash_table_create(NULL,
                      si_shader_cache_key_hash,
                      si_shader_cache_key_equals);
+
      return sscreen->shader_cache != NULL;
  }
    void si_destroy_shader_cache(struct si_screen *sscreen)
  {
      if (sscreen->shader_cache)
          _mesa_hash_table_destroy(sscreen->shader_cache,
                       si_destroy_shader_cache_entry);
      pipe_mutex_destroy(sscreen->shader_cache_mutex);
  }
@@ -1400,37 +1454,36 @@ void si_init_shader_selector_async(void *job,
int thread_index)
          shader->selector = sel;
          si_parse_next_shader_property(&sel->info, &shader->key);
            tgsi_binary = si_get_tgsi_binary(sel);
            /* Try to load the shader from the shader cache. */
          pipe_mutex_lock(sscreen->shader_cache_mutex);
            if (tgsi_binary &&
              si_shader_cache_load_shader(sscreen, tgsi_binary,
shader)) {
-            FREE(tgsi_binary);
              pipe_mutex_unlock(sscreen->shader_cache_mutex);
          } else {
              pipe_mutex_unlock(sscreen->shader_cache_mutex);
                /* Compile the shader if it hasn't been loaded from
the cache. */
              if (si_compile_tgsi_shader(sscreen, tm, shader, false,
                             debug) != 0) {
                  FREE(shader);
                  FREE(tgsi_binary);
                  fprintf(stderr, "radeonsi: can't compile a main
shader part\n");
                  return;
              }
                if (tgsi_binary) {
                  pipe_mutex_lock(sscreen->shader_cache_mutex);
-                if (!si_shader_cache_insert_shader(sscreen,
tgsi_binary, shader))
+                if (!si_shader_cache_insert_shader(sscreen,
tgsi_binary, shader, true))
                      FREE(tgsi_binary);
                  pipe_mutex_unlock(sscreen->shader_cache_mutex);
              }
          }
            *si_get_main_shader_part(sel, &shader->key) = shader;
            /* Unset "outputs_written" flags for outputs converted to
           * DEFAULT_VAL, so that later inter-shader optimizations don't
           * try to eliminate outputs that don't exist in the final


_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to