Mesa (main): zink: rebind all buffers on replacement

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Aug 24 14:36:55 UTC 2021


Module: Mesa
Branch: main
Commit: 8d9891088f1cc5d041b7019c7b23d13bd8bba40f
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8d9891088f1cc5d041b7019c7b23d13bd8bba40f

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Thu Jun  3 15:20:34 2021 -0400

zink: rebind all buffers on replacement

in theory it's possible to trigger cases where rebinds aren't based on the
current context, so ensure that (very unlikely) case is handled

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12425>

---

 src/gallium/drivers/zink/zink_context.c | 41 +++++++++++++++++++++++++++++++--
 src/gallium/drivers/zink/zink_context.h |  5 ++++
 src/gallium/drivers/zink/zink_draw.cpp  |  4 ++++
 src/gallium/drivers/zink/zink_screen.h  |  2 ++
 4 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 754757f18b3..27bb8b09e04 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -3359,6 +3359,41 @@ zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res)
       rebind_image(ctx, res);
 }
 
+void
+zink_rebind_all_buffers(struct zink_context *ctx)
+{
+   struct zink_batch *batch = &ctx->batch;
+   u_foreach_bit(slot, ctx->gfx_pipeline_state.vertex_buffers_enabled_mask)
+      set_vertex_buffer_clamped(ctx, slot);
+   ctx->vertex_buffers_dirty = ctx->gfx_pipeline_state.vertex_buffers_enabled_mask > 0;
+   ctx->dirty_so_targets = ctx->num_so_targets > 0;
+   if (ctx->num_so_targets)
+      zink_resource_buffer_barrier(ctx, NULL, zink_resource(ctx->dummy_xfb_buffer),
+                                   VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT);
+   for (unsigned shader = PIPE_SHADER_VERTEX; shader < PIPE_SHADER_TYPES; shader++) {
+      for (unsigned slot = 0; slot < ctx->di.num_ubos[shader]; slot++) {
+         struct zink_resource *res = rebind_ubo(ctx, shader, slot);
+         if (res)
+            zink_batch_resource_usage_set(batch, res, false);
+      }
+      for (unsigned slot = 0; slot < ctx->di.num_sampler_views[shader]; slot++) {
+         struct zink_resource *res = rebind_tbo(ctx, shader, slot);
+         if (res)
+            zink_batch_resource_usage_set(batch, res, false);
+      }
+      for (unsigned slot = 0; slot < ctx->di.num_ssbos[shader]; slot++) {
+         struct zink_resource *res = rebind_ssbo(ctx, shader, slot);
+         if (res)
+            zink_batch_resource_usage_set(batch, res, (ctx->writable_ssbos[shader] & BITFIELD64_BIT(slot)) != 0);
+      }
+      for (unsigned slot = 0; slot < ctx->di.num_images[shader]; slot++) {
+         struct zink_resource *res = rebind_ibo(ctx, shader, slot);
+         if (res)
+            zink_batch_resource_usage_set(batch, res, (ctx->image_views[shader][slot].base.access & PIPE_IMAGE_ACCESS_WRITE) != 0);
+      }
+   }
+}
+
 static void
 zink_context_replace_buffer_storage(struct pipe_context *pctx, struct pipe_resource *dst,
                                     struct pipe_resource *src, unsigned num_rebinds,
@@ -3366,16 +3401,18 @@ zink_context_replace_buffer_storage(struct pipe_context *pctx, struct pipe_resou
 {
    struct zink_resource *d = zink_resource(dst);
    struct zink_resource *s = zink_resource(src);
+   struct zink_context *ctx = zink_context(pctx);
 
    assert(d->internal_format == s->internal_format);
    util_idalloc_mt_free(&zink_screen(pctx->screen)->buffer_ids, delete_buffer_id);
    if (zink_resource_has_unflushed_usage(d))
-      zink_batch_reference_resource(&zink_context(pctx)->batch, d);
+      zink_batch_reference_resource(&ctx->batch, d);
    zink_resource_object_reference(zink_screen(pctx->screen), &d->obj, s->obj);
    d->access = s->access;
    d->access_stage = s->access_stage;
    d->unordered_barrier = s->unordered_barrier;
-   zink_resource_rebind(zink_context(pctx), d);
+   zink_resource_rebind(ctx, d);
+   ctx->buffer_rebind_counter = p_atomic_inc_return(&zink_screen(ctx->base.screen)->buffer_rebind_counter);
 }
 
 static bool
diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h
index f4ebce713e6..1dc83cdcaad 100644
--- a/src/gallium/drivers/zink/zink_context.h
+++ b/src/gallium/drivers/zink/zink_context.h
@@ -269,6 +269,8 @@ struct zink_context {
    struct pipe_surface *dummy_surface;
    struct zink_buffer_view *dummy_bufferview;
 
+   unsigned buffer_rebind_counter;
+
    struct {
       /* descriptor info */
       VkDescriptorBufferInfo ubos[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
@@ -406,6 +408,9 @@ zink_pipeline_flags_from_pipe_stage(enum pipe_shader_type pstage)
    }
 }
 
+void
+zink_rebind_all_buffers(struct zink_context *ctx);
+
 void
 zink_init_draw_functions(struct zink_context *ctx, struct zink_screen *screen);
 void
diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp
index 62ae9e0b226..b4bd2b7b7cb 100644
--- a/src/gallium/drivers/zink/zink_draw.cpp
+++ b/src/gallium/drivers/zink/zink_draw.cpp
@@ -429,6 +429,10 @@ zink_draw_vbo(struct pipe_context *pctx,
 
    update_barriers(ctx, false);
 
+   if (unlikely(ctx->buffer_rebind_counter < screen->buffer_rebind_counter)) {
+      ctx->buffer_rebind_counter = screen->buffer_rebind_counter;
+      zink_rebind_all_buffers(ctx);
+   }
    if (ctx->gfx_pipeline_state.vertices_per_patch != ctx->gfx_pipeline_state.patch_vertices)
       ctx->gfx_pipeline_state.dirty = true;
    bool drawid_broken = ctx->drawid_broken;
diff --git a/src/gallium/drivers/zink/zink_screen.h b/src/gallium/drivers/zink/zink_screen.h
index 082ac2d23a6..feeb80cbe07 100644
--- a/src/gallium/drivers/zink/zink_screen.h
+++ b/src/gallium/drivers/zink/zink_screen.h
@@ -81,6 +81,8 @@ struct zink_screen {
    VkSemaphore prev_sem;
    struct util_queue flush_queue;
 
+   unsigned buffer_rebind_counter;
+
    bool device_lost;
    struct sw_winsys *winsys;
 



More information about the mesa-commit mailing list