[Mesa-dev] [PATCH 02/31] i965/blorp: Add an internal shader cache

Jason Ekstrand jason at jlekstrand.net
Fri Aug 19 16:55:39 UTC 2016


The main shader cache in the i965 driver is just used as the backing
storage and all of the actual caching is done internally to blorp.
---
 src/mesa/drivers/dri/i965/blorp.c       | 123 ++++++++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/blorp.h       |   9 +++
 src/mesa/drivers/dri/i965/blorp_blit.c  |  14 ++--
 src/mesa/drivers/dri/i965/blorp_clear.c |  25 ++-----
 src/mesa/drivers/dri/i965/blorp_priv.h  |  23 +++++-
 src/mesa/drivers/dri/i965/brw_blorp.c   |  22 ++++++
 6 files changed, 188 insertions(+), 28 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/blorp.c b/src/mesa/drivers/dri/i965/blorp.c
index 4005ec7..062de62 100644
--- a/src/mesa/drivers/dri/i965/blorp.c
+++ b/src/mesa/drivers/dri/i965/blorp.c
@@ -30,17 +30,29 @@
 #include "brw_nir.h"
 #include "brw_state.h"
 
+static uint32_t blorp_hash_key(const void *void_key);
+static bool blorp_key_equal(const void *void_a, const void *void_b);
+
 void
 blorp_init(struct blorp_context *blorp, void *driver_ctx,
            struct isl_device *isl_dev)
 {
    blorp->driver_ctx = driver_ctx;
    blorp->isl_dev = isl_dev;
+
+   blorp->ralloc_ctx = ralloc_context(NULL);
+
+   mtx_init(&blorp->cache_mtx, mtx_plain);
+   blorp->shader_cache = _mesa_hash_table_create(blorp->ralloc_ctx,
+                                                 blorp_hash_key,
+                                                 blorp_key_equal);
 }
 
 void
 blorp_finish(struct blorp_context *blorp)
 {
+   mtx_destroy(&blorp->cache_mtx);
+   ralloc_free(blorp->ralloc_ctx);
    blorp->driver_ctx = NULL;
 }
 
@@ -147,6 +159,117 @@ brw_blorp_init_wm_prog_key(struct brw_wm_prog_key *wm_key)
       wm_key->tex.swizzles[i] = SWIZZLE_XYZW;
 }
 
+struct blorp_shader_key {
+   enum blorp_shader_type shader_type;
+   struct brw_blorp_blit_prog_key blit_key;
+};
+
+struct blorp_shader_entry {
+   uint32_t kernel;
+   struct brw_blorp_prog_data prog_data;
+};
+
+static uint32_t
+blorp_hash_key(const void *void_key)
+{
+   const struct blorp_shader_key *key = void_key;
+
+   if (key->shader_type == BLORP_SHADER_TYPE_BLIT)
+      return _mesa_hash_data(&key->blit_key, sizeof(key->blit_key));
+   else
+      return key->shader_type;
+}
+
+static bool
+blorp_key_equal(const void *void_a, const void *void_b)
+{
+   const struct blorp_shader_key *a = void_a, *b = void_b;
+
+   if (a->shader_type != b->shader_type)
+      return false;
+
+   if (a->shader_type == BLORP_SHADER_TYPE_BLIT)
+      return memcmp(&a->blit_key, &b->blit_key, sizeof(b->blit_key)) == 0;
+
+   return true;
+}
+
+static bool
+blorp_find_shader_locked(struct blorp_context *blorp,
+                         enum blorp_shader_type shader_type,
+                         const struct brw_blorp_blit_prog_key *blit_key,
+                         uint32_t *kernel_out,
+                         const struct brw_blorp_prog_data **prog_data_out)
+{
+   struct blorp_shader_key key = {
+      .shader_type = shader_type,
+   };
+
+   if (shader_type == BLORP_SHADER_TYPE_BLIT)
+      key.blit_key = *blit_key;
+
+   struct hash_entry *entry = _mesa_hash_table_search(blorp->shader_cache, &key);
+   if (!entry)
+      return false;
+
+   const struct blorp_shader_entry *blorp_entry = entry->data;
+   *kernel_out = blorp_entry->kernel;
+   *prog_data_out = &blorp_entry->prog_data;
+
+   return true;
+}
+
+bool
+blorp_find_shader(struct blorp_context *blorp,
+                  enum blorp_shader_type shader_type,
+                  const struct brw_blorp_blit_prog_key *blit_key,
+                  uint32_t *kernel_out,
+                  const struct brw_blorp_prog_data **prog_data_out)
+{
+   mtx_lock(&blorp->cache_mtx);
+
+   bool found = blorp_find_shader_locked(blorp, shader_type, blit_key,
+                                         kernel_out, prog_data_out);
+
+   mtx_unlock(&blorp->cache_mtx);
+
+   return found;
+}
+
+void
+blorp_upload_shader(struct blorp_context *blorp,
+                    enum blorp_shader_type shader_type,
+                    const struct brw_blorp_blit_prog_key *blit_key,
+                    const void *data, uint32_t size,
+                    const struct brw_blorp_prog_data *prog_data_in,
+                    uint32_t *kernel_out,
+                    const struct brw_blorp_prog_data **prog_data_out)
+{
+   mtx_lock(&blorp->cache_mtx);
+
+   if (blorp_find_shader_locked(blorp, shader_type, blit_key,
+                                kernel_out, prog_data_out))
+      return;
+
+   struct blorp_shader_key *key =
+      rzalloc(blorp->ralloc_ctx, struct blorp_shader_key);
+   key->shader_type = shader_type;
+   if (shader_type == BLORP_SHADER_TYPE_BLIT)
+      key->blit_key = *blit_key;
+
+   struct blorp_shader_entry *entry =
+      rzalloc(blorp->ralloc_ctx, struct blorp_shader_entry);
+   entry->kernel = blorp->upload_shader(blorp, data, size);
+   entry->prog_data = *prog_data_in;
+
+   _mesa_hash_table_insert(blorp->shader_cache, key, entry);
+
+   mtx_unlock(&blorp->cache_mtx);
+
+   *kernel_out = entry->kernel;
+   *prog_data_out = &entry->prog_data;
+}
+
 static int
 nir_uniform_type_size(const struct glsl_type *type)
 {
diff --git a/src/mesa/drivers/dri/i965/blorp.h b/src/mesa/drivers/dri/i965/blorp.h
index 7dbf022..68cca05a 100644
--- a/src/mesa/drivers/dri/i965/blorp.h
+++ b/src/mesa/drivers/dri/i965/blorp.h
@@ -26,12 +26,14 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+#include "c11/threads.h"
 #include "isl/isl.h"
 #include "intel_resolve_map.h" /* needed for enum gen6_hiz_op */
 #include "intel_bufmgr.h" /* needed for drm_intel_bo */
 
 struct brw_context;
 struct brw_wm_prog_key;
+struct hash_table;
 
 #ifdef __cplusplus
 extern "C" {
@@ -41,6 +43,13 @@ struct blorp_context {
    void *driver_ctx;
 
    const struct isl_device *isl_dev;
+
+   void *ralloc_ctx;
+   mtx_t cache_mtx;
+   struct hash_table *shader_cache;
+
+   uint32_t (*upload_shader)(struct blorp_context *,
+                             const void *data, uint32_t size);
 };
 
 void blorp_init(struct blorp_context *blorp, void *driver_ctx,
diff --git a/src/mesa/drivers/dri/i965/blorp_blit.c b/src/mesa/drivers/dri/i965/blorp_blit.c
index edbd726..5797e55 100644
--- a/src/mesa/drivers/dri/i965/blorp_blit.c
+++ b/src/mesa/drivers/dri/i965/blorp_blit.c
@@ -32,7 +32,6 @@
 
 #include "blorp_priv.h"
 #include "brw_context.h"
-#include "brw_state.h"
 #include "brw_meta_util.h"
 
 #define FILE_DEBUG_FLAG DEBUG_BLORP
@@ -1196,9 +1195,8 @@ brw_blorp_get_blit_kernel(struct brw_context *brw,
                           struct brw_blorp_params *params,
                           const struct brw_blorp_blit_prog_key *prog_key)
 {
-   if (brw_search_cache(&brw->cache, BRW_CACHE_BLORP_PROG,
-                        prog_key, sizeof(*prog_key),
-                        &params->wm_prog_kernel, &params->wm_prog_data))
+   if (blorp_find_shader(&brw->blorp, BLORP_SHADER_TYPE_BLIT, prog_key,
+                         &params->wm_prog_kernel, &params->wm_prog_data))
       return;
 
    const unsigned *program;
@@ -1219,11 +1217,9 @@ brw_blorp_get_blit_kernel(struct brw_context *brw,
    program = brw_blorp_compile_nir_shader(brw, nir, &wm_key, false,
                                           &prog_data, &program_size);
 
-   brw_upload_cache(&brw->cache, BRW_CACHE_BLORP_PROG,
-                    prog_key, sizeof(*prog_key),
-                    program, program_size,
-                    &prog_data, sizeof(prog_data),
-                    &params->wm_prog_kernel, &params->wm_prog_data);
+   blorp_upload_shader(&brw->blorp, BLORP_SHADER_TYPE_BLIT, prog_key,
+                       program, program_size, &prog_data,
+                       &params->wm_prog_kernel, &params->wm_prog_data);
 }
 
 static void
diff --git a/src/mesa/drivers/dri/i965/blorp_clear.c b/src/mesa/drivers/dri/i965/blorp_clear.c
index 2da08f8..fb4d050 100644
--- a/src/mesa/drivers/dri/i965/blorp_clear.c
+++ b/src/mesa/drivers/dri/i965/blorp_clear.c
@@ -35,30 +35,21 @@
 #include "brw_meta_util.h"
 #include "brw_context.h"
 #include "brw_eu.h"
-#include "brw_state.h"
 
 #include "nir_builder.h"
 
 #define FILE_DEBUG_FLAG DEBUG_BLORP
 
-struct brw_blorp_const_color_prog_key
-{
-   bool use_simd16_replicated_data;
-   bool pad[3];
-};
-
 static void
 brw_blorp_params_get_clear_kernel(struct brw_context *brw,
                                   struct brw_blorp_params *params,
                                   bool use_replicated_data)
 {
-   struct brw_blorp_const_color_prog_key blorp_key;
-   memset(&blorp_key, 0, sizeof(blorp_key));
-   blorp_key.use_simd16_replicated_data = use_replicated_data;
+   const enum blorp_shader_type shader_type = use_replicated_data ?
+      BLORP_SHADER_TYPE_REPCLEAR : BLORP_SHADER_TYPE_SLOW_CLEAR;
 
-   if (brw_search_cache(&brw->cache, BRW_CACHE_BLORP_PROG,
-                        &blorp_key, sizeof(blorp_key),
-                        &params->wm_prog_kernel, &params->wm_prog_data))
+   if (blorp_find_shader(&brw->blorp, shader_type, NULL,
+                         &params->wm_prog_kernel, &params->wm_prog_data))
       return;
 
    void *mem_ctx = ralloc_context(NULL);
@@ -88,11 +79,9 @@ brw_blorp_params_get_clear_kernel(struct brw_context *brw,
       brw_blorp_compile_nir_shader(brw, b.shader, &wm_key, use_replicated_data,
                                    &prog_data, &program_size);
 
-   brw_upload_cache(&brw->cache, BRW_CACHE_BLORP_PROG,
-                    &blorp_key, sizeof(blorp_key),
-                    program, program_size,
-                    &prog_data, sizeof(prog_data),
-                    &params->wm_prog_kernel, &params->wm_prog_data);
+   blorp_upload_shader(&brw->blorp, shader_type, NULL,
+                       program, program_size, &prog_data,
+                       &params->wm_prog_kernel, &params->wm_prog_data);
 
    ralloc_free(mem_ctx);
 }
diff --git a/src/mesa/drivers/dri/i965/blorp_priv.h b/src/mesa/drivers/dri/i965/blorp_priv.h
index 582677c..97a176a 100644
--- a/src/mesa/drivers/dri/i965/blorp_priv.h
+++ b/src/mesa/drivers/dri/i965/blorp_priv.h
@@ -179,7 +179,7 @@ struct brw_blorp_params
    unsigned num_draw_buffers;
    unsigned num_layers;
    uint32_t wm_prog_kernel;
-   struct brw_blorp_prog_data *wm_prog_data;
+   const struct brw_blorp_prog_data *wm_prog_data;
 };
 
 void
@@ -296,6 +296,27 @@ struct brw_blorp_blit_prog_key
 
 void brw_blorp_init_wm_prog_key(struct brw_wm_prog_key *wm_key);
 
+enum blorp_shader_type {
+   BLORP_SHADER_TYPE_SLOW_CLEAR,
+   BLORP_SHADER_TYPE_REPCLEAR,
+   BLORP_SHADER_TYPE_BLIT,
+};
+
+bool
+blorp_find_shader(struct blorp_context *blorp,
+                  enum blorp_shader_type shader_type,
+                  const struct brw_blorp_blit_prog_key *blit_key,
+                  uint32_t *kernel_out,
+                  const struct brw_blorp_prog_data **prog_data_out);
+void
+blorp_upload_shader(struct blorp_context *blorp,
+                    enum blorp_shader_type shader_type,
+                    const struct brw_blorp_blit_prog_key *blit_key,
+                    const void *data, uint32_t size,
+                    const struct brw_blorp_prog_data *prog_data_in,
+                    uint32_t *kernel_out,
+                    const struct brw_blorp_prog_data **prog_data_out);
+
 const unsigned *
 brw_blorp_compile_nir_shader(struct brw_context *brw, struct nir_shader *nir,
                              const struct brw_wm_prog_key *wm_key,
diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c
index 727be63..041aa82 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.c
+++ b/src/mesa/drivers/dri/i965/brw_blorp.c
@@ -27,6 +27,7 @@
 #include "main/fbobject.h"
 #include "main/renderbuffer.h"
 #include "main/glformats.h"
+#include "util/u_atomic.h"
 
 #include "brw_blorp.h"
 #include "brw_context.h"
@@ -37,10 +38,31 @@
 
 #define FILE_DEBUG_FLAG DEBUG_BLORP
 
+static uint32_t
+brw_blorp_upload_shader(struct blorp_context *blorp,
+                        const void *data, uint32_t size)
+{
+   struct brw_context *brw = blorp->driver_ctx;
+   static unsigned shader_id = 0;
+
+   /* All we really need for a key is a way to make it unique */
+   const unsigned key = p_atomic_inc_return(&shader_id);
+
+   /* Use a prog data size of 0 since blorp will store prog_data itself */
+   void *prog_data;
+   uint32_t kernel;
+   brw_upload_cache(&brw->cache, BRW_CACHE_BLORP_PROG, &key, sizeof(key),
+                    data, size, NULL, 0, &kernel, &prog_data);
+
+   return kernel;
+}
+
 void
 brw_blorp_init(struct brw_context *brw)
 {
    blorp_init(&brw->blorp, brw, &brw->isl_dev);
+
+   brw->blorp.upload_shader = brw_blorp_upload_shader;
 }
 
 static void
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list