On 02/03/2017 00:27, Timothy Arceri wrote:


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.

I get a different view from our irc discussion.

In my understanding, MESA_GLSL_CACHE_DISABLE only affects the glsl->tgsi cache.
The radeon tgsi->asm cache is always enabled and cannot be disabled.
But it is fine with me, because the cache is discarded if the buildtime of llvm or mesa changes.

Axel

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 <michel.daen...@amd.com>
---
  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
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to