[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),
- ¶ms->wm_prog_kernel, ¶ms->wm_prog_data))
+ if (blorp_find_shader(&brw->blorp, BLORP_SHADER_TYPE_BLIT, prog_key,
+ ¶ms->wm_prog_kernel, ¶ms->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),
- ¶ms->wm_prog_kernel, ¶ms->wm_prog_data);
+ blorp_upload_shader(&brw->blorp, BLORP_SHADER_TYPE_BLIT, prog_key,
+ program, program_size, &prog_data,
+ ¶ms->wm_prog_kernel, ¶ms->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),
- ¶ms->wm_prog_kernel, ¶ms->wm_prog_data))
+ if (blorp_find_shader(&brw->blorp, shader_type, NULL,
+ ¶ms->wm_prog_kernel, ¶ms->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),
- ¶ms->wm_prog_kernel, ¶ms->wm_prog_data);
+ blorp_upload_shader(&brw->blorp, shader_type, NULL,
+ program, program_size, &prog_data,
+ ¶ms->wm_prog_kernel, ¶ms->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