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