Mesa (master): zink: guarantee surface lifetimes for shader images

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jan 25 22:59:13 UTC 2021


Module: Mesa
Branch: master
Commit: 0376064783eee6dd798e156836573c457909189d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=0376064783eee6dd798e156836573c457909189d

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Fri Aug  7 10:00:13 2020 -0400

zink: guarantee surface lifetimes for shader images

these may be unset from the ctx before the draw command has completed,
so we need (more) references to prevent that

Fixes: 3f9a6d333b3 ("zink: export shader image caps using features")

Reviewed-by: Erik Faye-Lund <erik.faye-lund at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8627>

---

 src/gallium/drivers/zink/zink_batch.c   | 19 +++++++++++++++++++
 src/gallium/drivers/zink/zink_batch.h   |  6 ++++++
 src/gallium/drivers/zink/zink_context.c |  3 ++-
 src/gallium/drivers/zink/zink_draw.c    |  8 +++++++-
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_batch.c b/src/gallium/drivers/zink/zink_batch.c
index 18621aa238a..fa0ed8258bc 100644
--- a/src/gallium/drivers/zink/zink_batch.c
+++ b/src/gallium/drivers/zink/zink_batch.c
@@ -8,6 +8,7 @@
 #include "zink_render_pass.h"
 #include "zink_resource.h"
 #include "zink_screen.h"
+#include "zink_surface.h"
 
 #include "util/hash_table.h"
 #include "util/u_debug.h"
@@ -39,6 +40,12 @@ zink_batch_release(struct zink_screen *screen, struct zink_batch *batch)
    }
    _mesa_set_clear(batch->sampler_views, NULL);
 
+   set_foreach(batch->surfaces, entry) {
+      struct pipe_surface *surf = (struct pipe_surface *)entry->key;
+      pipe_surface_reference(&surf, NULL);
+   }
+   _mesa_set_clear(batch->surfaces, NULL);
+
    util_dynarray_foreach(&batch->zombie_samplers, VkSampler, samp) {
       vkDestroySampler(screen->dev, *samp, NULL);
    }
@@ -164,3 +171,15 @@ zink_batch_reference_program(struct zink_batch *batch,
       pipe_reference(NULL, &prog->reference);
    }
 }
+
+void
+zink_batch_reference_surface(struct zink_batch *batch,
+                             struct zink_surface *surface)
+{
+   struct pipe_surface *surf = &surface->base;
+   struct set_entry *entry = _mesa_set_search(batch->surfaces, surf);
+   if (!entry) {
+      entry = _mesa_set_add(batch->surfaces, surf);
+      pipe_reference(NULL, &surf->reference);
+   }
+}
diff --git a/src/gallium/drivers/zink/zink_batch.h b/src/gallium/drivers/zink/zink_batch.h
index ce49031dcb1..c543a063c21 100644
--- a/src/gallium/drivers/zink/zink_batch.h
+++ b/src/gallium/drivers/zink/zink_batch.h
@@ -37,6 +37,7 @@ struct zink_render_pass;
 struct zink_resource;
 struct zink_screen;
 struct zink_sampler_view;
+struct zink_surface;
 
 #define ZINK_BATCH_DESC_SIZE 1000
 
@@ -52,6 +53,7 @@ struct zink_batch {
 
    struct set *resources;
    struct set *sampler_views;
+   struct set *surfaces;
 
    struct util_dynarray zombie_samplers;
 
@@ -83,4 +85,8 @@ zink_batch_reference_sampler_view(struct zink_batch *batch,
 void
 zink_batch_reference_program(struct zink_batch *batch,
                              struct zink_gfx_program *prog);
+
+void
+zink_batch_reference_surface(struct zink_batch *batch,
+                             struct zink_surface *surface);
 #endif
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index e87774f3fb3..9065660f10a 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -1559,9 +1559,10 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
       ctx->batches[i].resources = _mesa_pointer_set_create(NULL);
       ctx->batches[i].sampler_views = _mesa_pointer_set_create(NULL);
       ctx->batches[i].programs = _mesa_pointer_set_create(NULL);
+      ctx->batches[i].surfaces = _mesa_pointer_set_create(NULL);
 
       if (!ctx->batches[i].resources || !ctx->batches[i].sampler_views ||
-          !ctx->batches[i].programs)
+          !ctx->batches[i].programs || !ctx->batches[i].surfaces)
          goto fail;
 
       util_dynarray_init(&ctx->batches[i].zombie_samplers, NULL);
diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c
index 73cd7bdb3a1..bb5b8d5a968 100644
--- a/src/gallium/drivers/zink/zink_draw.c
+++ b/src/gallium/drivers/zink/zink_draw.c
@@ -322,10 +322,11 @@ zink_draw_vbo(struct pipe_context *pctx,
    VkWriteDescriptorSet wds[PIPE_SHADER_TYPES * (PIPE_MAX_CONSTANT_BUFFERS + PIPE_MAX_SAMPLERS + PIPE_MAX_SHADER_BUFFERS + PIPE_MAX_SHADER_IMAGES)];
    struct zink_resource *read_desc_resources[PIPE_SHADER_TYPES * (PIPE_MAX_CONSTANT_BUFFERS + PIPE_MAX_SAMPLERS + PIPE_MAX_SHADER_BUFFERS + PIPE_MAX_SHADER_IMAGES)] = {};
    struct zink_resource *write_desc_resources[PIPE_SHADER_TYPES * (PIPE_MAX_CONSTANT_BUFFERS + PIPE_MAX_SAMPLERS + PIPE_MAX_SHADER_BUFFERS + PIPE_MAX_SHADER_IMAGES)] = {};
+   struct zink_surface *surface_refs[PIPE_SHADER_TYPES * PIPE_MAX_SHADER_IMAGES] = {};
    VkDescriptorBufferInfo buffer_infos[PIPE_SHADER_TYPES * (PIPE_MAX_CONSTANT_BUFFERS + PIPE_MAX_SHADER_BUFFERS + PIPE_MAX_SHADER_IMAGES)];
    VkDescriptorImageInfo image_infos[PIPE_SHADER_TYPES * (PIPE_MAX_SAMPLERS + PIPE_MAX_SHADER_IMAGES)];
    VkBufferView buffer_view[] = {VK_NULL_HANDLE};
-   int num_wds = 0, num_buffer_info = 0, num_image_info = 0;
+   int num_wds = 0, num_buffer_info = 0, num_image_info = 0, num_surface_refs = 0;
 
    struct {
       struct zink_resource *res;
@@ -413,6 +414,7 @@ zink_draw_vbo(struct pipe_context *pctx,
                case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
                   struct zink_image_view *image_view = &ctx->image_views[i][index + k];
                   assert(image_view);
+                  surface_refs[num_surface_refs++] = image_view->surface;
                   res = zink_resource(image_view->base.resource);
                   if (!res)
                      break;
@@ -579,6 +581,10 @@ zink_draw_vbo(struct pipe_context *pctx,
             zink_batch_reference_resource_rw(batch, write_desc_resources[i], true);
       }
       vkUpdateDescriptorSets(screen->dev, num_wds, wds, 0, NULL);
+      for (int i = 0; i < num_surface_refs; i++) {
+         if (surface_refs[i])
+            zink_batch_reference_surface(batch, surface_refs[i]);
+      }
    }
 
    vkCmdBindPipeline(batch->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);



More information about the mesa-commit mailing list