Mesa (main): zink: add vertex buffer barriers during bind

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed May 26 01:29:42 UTC 2021


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Tue Jan 19 12:05:48 2021 -0500

zink: add vertex buffer barriers during bind

now we have tracking for vbo binds and can automatically reapply the correct
barrier just before draw if the resource is modified after bind

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

---

 src/gallium/drivers/zink/zink_context.c  | 47 ++++++++++++++++++++++++++++----
 src/gallium/drivers/zink/zink_draw.c     | 21 ++++----------
 src/gallium/drivers/zink/zink_resource.h |  1 +
 3 files changed, 47 insertions(+), 22 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index f92e71fa84d..67106acd6b4 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -812,6 +812,18 @@ zink_set_polygon_stipple(struct pipe_context *pctx,
 {
 }
 
+static void
+update_existing_vbo(struct zink_context *ctx, unsigned slot)
+{
+   if (!ctx->vertex_buffers[slot].buffer.resource)
+      return;
+   struct zink_resource *res = zink_resource(ctx->vertex_buffers[slot].buffer.resource);
+   res->vbo_bind_count--;
+   res->bind_count[0]--;
+   if (!res->bind_count[0])
+      _mesa_set_remove_key(ctx->need_barriers[0], res);
+}
+
 static void
 zink_set_vertex_buffers(struct pipe_context *pctx,
                         unsigned start_slot,
@@ -822,9 +834,29 @@ zink_set_vertex_buffers(struct pipe_context *pctx,
 {
    struct zink_context *ctx = zink_context(pctx);
 
-   if (!zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state &&
-       (num_buffers || (!buffers && ctx->gfx_pipeline_state.vertex_buffers_enabled_mask)))
-      ctx->gfx_pipeline_state.vertex_state_dirty = true;
+   if (buffers) {
+      if (!zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state)
+         ctx->gfx_pipeline_state.vertex_state_dirty = true;
+      for (int i = 0; i < num_buffers; ++i) {
+         const struct pipe_vertex_buffer *vb = buffers + i;
+         update_existing_vbo(ctx, start_slot + i);
+         if (vb->buffer.resource) {
+            struct zink_resource *res = zink_resource(vb->buffer.resource);
+            res->vbo_bind_count++;
+            res->bind_count[0]++;
+            zink_resource_buffer_barrier(ctx, NULL, res, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
+                                         VK_PIPELINE_STAGE_VERTEX_INPUT_BIT);
+         }
+      }
+   } else if (ctx->gfx_pipeline_state.vertex_buffers_enabled_mask) {
+      if (!zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state)
+         ctx->gfx_pipeline_state.vertex_state_dirty = true;
+      unsigned vertex_buffers_enabled_mask = ctx->gfx_pipeline_state.vertex_buffers_enabled_mask;
+      while (vertex_buffers_enabled_mask) {
+         unsigned slot = u_bit_scan(&vertex_buffers_enabled_mask);
+         update_existing_vbo(ctx, slot);
+      }
+   }
    util_set_vertex_buffers_mask(ctx->vertex_buffers, &ctx->gfx_pipeline_state.vertex_buffers_enabled_mask,
                                 buffers, start_slot, num_buffers,
                                 unbind_num_trailing_slots, take_ownership);
@@ -1887,9 +1919,12 @@ is_shader_pipline_stage(VkPipelineStageFlags pipeline)
 static void
 resource_check_defer_barrier(struct zink_context *ctx, struct zink_resource *res, VkPipelineStageFlags pipeline)
 {
-   if (res->bind_count[0] && !is_shader_pipline_stage(pipeline))
-      /* gfx rebind */
-      _mesa_set_add(ctx->need_barriers[0], res);
+   if (res->bind_count[0]) {
+      if ((res->obj->is_buffer && res->vbo_bind_count && !(pipeline & VK_PIPELINE_STAGE_VERTEX_INPUT_BIT)) ||
+          ((!res->obj->is_buffer || res->vbo_bind_count != res->bind_count[0]) && !is_shader_pipline_stage(pipeline)))
+         /* gfx rebind */
+         _mesa_set_add(ctx->need_barriers[0], res);
+   }
    if (res->bind_count[1] && !(pipeline & VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT))
       /* compute rebind */
       _mesa_set_add(ctx->need_barriers[1], res);
diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c
index 8c5863f9350..efcb90373c2 100644
--- a/src/gallium/drivers/zink/zink_draw.c
+++ b/src/gallium/drivers/zink/zink_draw.c
@@ -101,21 +101,6 @@ zink_emit_stream_output_targets(struct pipe_context *pctx)
    ctx->dirty_so_targets = false;
 }
 
-static void
-barrier_vertex_buffers(struct zink_context *ctx)
-{
-   const struct zink_vertex_elements_state *elems = ctx->element_state;
-   for (unsigned i = 0; i < elems->hw_state.num_bindings; i++) {
-      struct pipe_vertex_buffer *vb = ctx->vertex_buffers + ctx->element_state->binding_map[i];
-      assert(vb);
-      if (vb->buffer.resource) {
-         struct zink_resource *res = zink_resource(vb->buffer.resource);
-         zink_resource_buffer_barrier(ctx, NULL, res, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
-                                      VK_PIPELINE_STAGE_VERTEX_INPUT_BIT);
-      }
-   }
-}
-
 static void
 check_buffer_barrier(struct zink_context *ctx, struct pipe_resource *pres, VkAccessFlags flags, VkPipelineStageFlags pipeline)
 {
@@ -376,6 +361,11 @@ update_barriers(struct zink_context *ctx, bool is_compute)
                   access |= VK_ACCESS_UNIFORM_READ_BIT;
                   bind_count -= res->ubo_bind_count[is_compute];
                }
+               if (!is_compute && res->vbo_bind_count) {
+                  access |= VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
+                  pipeline |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
+                  bind_count -= res->vbo_bind_count;
+               }
             }
             if (bind_count)
                access |= VK_ACCESS_SHADER_READ_BIT;
@@ -512,7 +502,6 @@ zink_draw_vbo(struct pipe_context *pctx,
    if (so_target)
       zink_emit_xfb_vertex_input_barrier(ctx, zink_resource(so_target->base.buffer));
 
-   barrier_vertex_buffers(ctx);
    barrier_draw_buffers(ctx, dinfo, dindirect, index_buffer);
 
    for (int i = 0; i < ZINK_SHADER_COUNT; i++) {
diff --git a/src/gallium/drivers/zink/zink_resource.h b/src/gallium/drivers/zink/zink_resource.h
index 92ac55c3773..821f616c807 100644
--- a/src/gallium/drivers/zink/zink_resource.h
+++ b/src/gallium/drivers/zink/zink_resource.h
@@ -96,6 +96,7 @@ struct zink_resource {
    union {
       struct {
          struct util_range valid_buffer_range;
+         uint16_t vbo_bind_count;
          uint16_t ubo_bind_count[2];
       };
       struct {



More information about the mesa-commit mailing list