Mesa (main): iris: Ref count the uncompiled shaders
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jul 28 18:00:25 UTC 2021
Module: Mesa
Branch: main
Commit: d0fac4e4f88debc80b06018f73dd23d5e4e55bcb
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=d0fac4e4f88debc80b06018f73dd23d5e4e55bcb
Author: Ian Romanick <ian.d.romanick at intel.com>
Date: Tue May 25 12:41:14 2021 -0700
iris: Ref count the uncompiled shaders
I tried /just/ ref counting the uncompiled shaders, but that is not
sufficient. At the very least, it's a problem for blorp shaders that
only have variants (and no uncompiled shader).
This is in prepartion for using the live shader cache.
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11229>
---
src/gallium/drivers/iris/iris_context.h | 22 +++++++++++++++++++
src/gallium/drivers/iris/iris_program.c | 39 +++++++++++++++++++++++----------
2 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h
index 0674044fb6d..f8691421676 100644
--- a/src/gallium/drivers/iris/iris_context.h
+++ b/src/gallium/drivers/iris/iris_context.h
@@ -371,6 +371,8 @@ enum iris_predicate_state {
* See iris_compiled_shader, which represents a compiled shader variant.
*/
struct iris_uncompiled_shader {
+ struct pipe_reference ref;
+
/**
* NIR for the shader.
*
@@ -955,6 +957,26 @@ struct iris_compiled_shader *iris_upload_shader(struct iris_screen *screen,
const struct iris_binding_table *bt);
void iris_delete_shader_variant(struct iris_compiled_shader *shader);
+void iris_destroy_shader_state(struct pipe_context *ctx, void *state);
+
+static inline void
+iris_uncompiled_shader_reference(struct pipe_context *ctx,
+ struct iris_uncompiled_shader **dst,
+ struct iris_uncompiled_shader *src)
+{
+ if (*dst == src)
+ return;
+
+ struct iris_uncompiled_shader *old_dst = *dst;
+
+ if (pipe_reference(old_dst != NULL ? &old_dst->ref : NULL,
+ src != NULL ? &src->ref : NULL)) {
+ iris_destroy_shader_state(ctx, *dst);
+ }
+
+ *dst = src;
+}
+
static inline void
iris_shader_variant_reference(struct iris_compiled_shader **dst,
struct iris_compiled_shader *src)
diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c
index 91f4ad3f288..852c26a2aea 100644
--- a/src/gallium/drivers/iris/iris_program.c
+++ b/src/gallium/drivers/iris/iris_program.c
@@ -2282,6 +2282,7 @@ iris_create_uncompiled_shader(struct iris_screen *screen,
if (!ish)
return NULL;
+ pipe_reference_init(&ish->ref, 1);
list_inithead(&ish->variants);
simple_mtx_init(&ish->lock, mtx_plain);
@@ -2537,22 +2538,16 @@ iris_create_shader_state(struct pipe_context *ctx,
}
/**
- * The pipe->delete_[stage]_state() driver hooks.
+ * Called when the refcount on the iris_uncompiled_shader reaches 0.
*
* Frees the iris_uncompiled_shader.
+ *
+ * \sa iris_delete_shader_state
*/
-static void
-iris_delete_shader_state(struct pipe_context *ctx, void *state)
+void
+iris_destroy_shader_state(struct pipe_context *ctx, void *state)
{
struct iris_uncompiled_shader *ish = state;
- struct iris_context *ice = (void *) ctx;
-
- const gl_shader_stage stage = ish->nir->info.stage;
-
- if (ice->shaders.uncompiled[stage] == ish) {
- ice->shaders.uncompiled[stage] = NULL;
- ice->state.stage_dirty |= IRIS_STAGE_DIRTY_UNCOMPILED_VS << stage;
- }
/* No need to take ish->lock; we hold the last reference to ish */
list_for_each_entry_safe(struct iris_compiled_shader, shader,
@@ -2568,6 +2563,28 @@ iris_delete_shader_state(struct pipe_context *ctx, void *state)
free(ish);
}
+/**
+ * The pipe->delete_[stage]_state() driver hooks.
+ *
+ * \sa iris_destroy_shader_state
+ */
+static void
+iris_delete_shader_state(struct pipe_context *ctx, void *state)
+{
+ struct iris_uncompiled_shader *ish = state;
+ struct iris_context *ice = (void *) ctx;
+
+ const gl_shader_stage stage = ish->nir->info.stage;
+
+ if (ice->shaders.uncompiled[stage] == ish) {
+ ice->shaders.uncompiled[stage] = NULL;
+ ice->state.stage_dirty |= IRIS_STAGE_DIRTY_UNCOMPILED_VS << stage;
+ }
+
+ if (pipe_reference(&ish->ref, NULL))
+ iris_destroy_shader_state(ctx, state);
+}
+
/**
* The pipe->bind_[stage]_state() driver hook.
*
More information about the mesa-commit
mailing list