zink: use c++ template to deduplicate all the buffer barrier code
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Tue, 21 Mar 2023 14:38:51 +0000 (10:38 -0400)
committerMarge Bot <emma+marge@anholt.net>
Tue, 28 Mar 2023 22:28:59 +0000 (22:28 +0000)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22057>

src/gallium/drivers/zink/zink_context.h
src/gallium/drivers/zink/zink_screen.c
src/gallium/drivers/zink/zink_synchronization.cpp

index e109bec..df48e2d 100644 (file)
@@ -130,6 +130,8 @@ zink_resource_image_transfer_dst_barrier(struct zink_context *ctx, struct zink_r
 bool
 zink_resource_buffer_transfer_dst_barrier(struct zink_context *ctx, struct zink_resource *res, unsigned offset, unsigned size);
 void
+zink_synchronization_init(struct zink_screen *screen);
+void
 zink_update_descriptor_refs(struct zink_context *ctx, bool compute);
 void
 zink_init_vk_sample_locations(struct zink_context *ctx, VkSampleLocationsInfoEXT *loc);
index 3d535ae..44ce9cc 100644 (file)
@@ -3031,12 +3031,11 @@ zink_internal_create_screen(const struct pipe_screen_config *config)
    screen->base.vertex_state_destroy = zink_cache_vertex_state_destroy;
    glsl_type_singleton_init_or_ref();
 
+   zink_synchronization_init(screen);
    if (screen->info.have_vulkan13 || screen->info.have_KHR_synchronization2) {
       screen->image_barrier = zink_resource_image_barrier2;
-      screen->buffer_barrier = zink_resource_buffer_barrier2;
    } else {
       screen->image_barrier = zink_resource_image_barrier;
-      screen->buffer_barrier = zink_resource_buffer_barrier;
    }
 
    zink_init_screen_pipeline_libs(screen);
index feccbb9..001c782 100644 (file)
@@ -524,6 +524,7 @@ buffer_needs_barrier(struct zink_resource *res, VkAccessFlags flags, VkPipelineS
           ((unordered ? res->obj->unordered_access : res->obj->access) & flags) != flags;
 }
 
+template <bool HAS_SYNC2>
 void
 zink_resource_buffer_barrier(struct zink_context *ctx, struct zink_resource *res, VkAccessFlags flags, VkPipelineStageFlags pipeline)
 {
@@ -570,17 +571,6 @@ zink_resource_buffer_barrier(struct zink_context *ctx, struct zink_resource *res
    bool can_skip_ordered = unordered ? false : (!res->obj->access && !unordered_usage_matches);
 
    if (!can_skip_unordered && !can_skip_ordered) {
-      VkMemoryBarrier bmb;
-      bmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
-      bmb.pNext = NULL;
-      VkPipelineStageFlags stages = res->obj->access_stage ? res->obj->access_stage : pipeline_access_stage(res->obj->access);;
-      if (unordered) {
-         stages = usage_matches ? res->obj->unordered_access_stage : stages;
-         bmb.srcAccessMask = usage_matches ? res->obj->unordered_access : res->obj->access;
-      } else {
-         bmb.srcAccessMask = res->obj->access;
-      }
-
       VkCommandBuffer cmdbuf = is_write ? zink_get_cmdbuf(ctx, NULL, res) : zink_get_cmdbuf(ctx, res, NULL);
       bool marker = false;
       if (unlikely(zink_tracing)) {
@@ -595,125 +585,54 @@ zink_resource_buffer_barrier(struct zink_context *ctx, struct zink_resource *res
          }
          marker = zink_cmd_debug_marker_begin(ctx, cmdbuf, "buffer_barrier(%s)", buf);
       }
-      VKCTX(CmdPipelineBarrier)(
-         cmdbuf,
-         stages,
-         pipeline,
-         0,
-         1, &bmb,
-         0, NULL,
-         0, NULL
-      );
-      zink_cmd_debug_marker_end(ctx, cmdbuf, marker);
-   }
-
-   resource_check_defer_buffer_barrier(ctx, res, pipeline);
-
-   if (is_write)
-      res->obj->last_write = flags;
-   if (unordered) {
-      /* these should get automatically emitted during submission */
-      res->obj->unordered_access = flags;
-      res->obj->unordered_access_stage = pipeline;
-      if (is_write) {
-         ctx->batch.state->unordered_write_access |= flags;
-         ctx->batch.state->unordered_write_stages |= pipeline;
-      }
-   }
-   if (!unordered || !usage_matches || res->obj->ordered_access_is_copied) {
-      res->obj->access = flags;
-      res->obj->access_stage = pipeline;
-      res->obj->ordered_access_is_copied = unordered;
-   }
-   if (pipeline != VK_PIPELINE_STAGE_TRANSFER_BIT && is_write)
-      zink_resource_copies_reset(res);
-}
-
-void
-zink_resource_buffer_barrier2(struct zink_context *ctx, struct zink_resource *res, VkAccessFlags flags, VkPipelineStageFlags pipeline)
-{
-   if (!pipeline)
-      pipeline = pipeline_access_stage(flags);
-
-   bool is_write = zink_resource_access_is_write(flags);
-   bool unordered = unordered_res_exec(ctx, res, is_write);
-   if (!buffer_needs_barrier(res, flags, pipeline, unordered))
-      return;
-   enum zink_resource_access rw = is_write ? ZINK_RESOURCE_ACCESS_RW : ZINK_RESOURCE_ACCESS_WRITE;
-   bool completed = zink_resource_usage_check_completion_fast(zink_screen(ctx->base.screen), res, rw);
-   bool usage_matches = !completed && zink_resource_usage_matches(res, ctx->batch.state);
-   bool unordered_usage_matches = res->obj->unordered_access && usage_matches;
-   if (completed) {
-      /* reset access on complete */
-      res->obj->access = VK_ACCESS_NONE;
-      res->obj->access_stage = VK_PIPELINE_STAGE_NONE;
-      res->obj->last_write = VK_ACCESS_NONE;
-   } else if (unordered && unordered_usage_matches && res->obj->ordered_access_is_copied) {
-      /* always reset propagated access to avoid weirdness */
-      res->obj->access = VK_ACCESS_NONE;
-      res->obj->access_stage = VK_PIPELINE_STAGE_NONE;
-   } else if (!unordered && !unordered_usage_matches) {
-      /* reset unordered access on first ordered barrier */
-      res->obj->unordered_access = VK_ACCESS_NONE;
-      res->obj->unordered_access_stage = VK_PIPELINE_STAGE_NONE;
-   }
-   if (!usage_matches) {
-      /* reset unordered on first new cmdbuf barrier */
-      res->obj->unordered_access = VK_ACCESS_NONE;
-      res->obj->unordered_access_stage = VK_PIPELINE_STAGE_NONE;
-      res->obj->ordered_access_is_copied = false;
-   }
-   /* unordered barriers can be skipped if either:
-    * - there is no current-batch unordered access
-    * - the unordered access is not write access
-    */
-   bool can_skip_unordered = !unordered ? false : (!unordered_usage_matches || !zink_resource_access_is_write(res->obj->unordered_access));
-   /* ordered barriers can be skipped if both:
-    * - there is no current access
-    * - there is no current-batch unordered access
-    */
-   bool can_skip_ordered = unordered ? false : (!res->obj->access && !unordered_usage_matches);
 
-   if (!can_skip_unordered && !can_skip_ordered) {
-      VkMemoryBarrier2 bmb;
-      bmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2;
-      bmb.pNext = NULL;
       VkPipelineStageFlags stages = res->obj->access_stage ? res->obj->access_stage : pipeline_access_stage(res->obj->access);;
-      if (unordered) {
-         bmb.srcStageMask = usage_matches ? res->obj->unordered_access_stage : stages;
-         bmb.srcAccessMask = usage_matches ? res->obj->unordered_access : res->obj->access;
+      if (HAS_SYNC2) {
+         VkMemoryBarrier2 bmb;
+         bmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2;
+         bmb.pNext = NULL;
+         if (unordered) {
+            bmb.srcStageMask = usage_matches ? res->obj->unordered_access_stage : stages;
+            bmb.srcAccessMask = usage_matches ? res->obj->unordered_access : res->obj->access;
+         } else {
+            bmb.srcStageMask = stages;
+            bmb.srcAccessMask = res->obj->access;
+         }
+         bmb.dstStageMask = pipeline;
+         bmb.dstAccessMask = flags;
+         VkDependencyInfo dep = {
+            VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
+            NULL,
+            0,
+            1,
+            &bmb,
+            0,
+            NULL,
+            0,
+            NULL
+         };
+         VKCTX(CmdPipelineBarrier2)(cmdbuf, &dep);
       } else {
-         bmb.srcStageMask = stages;
-         bmb.srcAccessMask = res->obj->access;
-      }
-      bmb.dstStageMask = pipeline;
-      bmb.dstAccessMask = flags;
-      VkDependencyInfo dep = {
-         VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
-         NULL,
-         0,
-         1,
-         &bmb,
-         0,
-         NULL,
-         0,
-         NULL
-      };
-      VkCommandBuffer cmdbuf = is_write ? zink_get_cmdbuf(ctx, NULL, res) : zink_get_cmdbuf(ctx, res, NULL);
-      bool marker = false;
-      if (unlikely(zink_tracing)) {
-         char buf[4096];
-         bool first = true;
-         unsigned idx = 0;
-         u_foreach_bit64(bit, flags) {
-            if (!first)
-               buf[idx++] = '|';
-            idx += snprintf(&buf[idx], sizeof(buf) - idx, "%s", vk_AccessFlagBits_to_str((VkAccessFlagBits)(1ul<<bit)));
-            first = false;
+         VkMemoryBarrier bmb;
+         bmb.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
+         bmb.pNext = NULL;
+         if (unordered) {
+            stages = usage_matches ? res->obj->unordered_access_stage : stages;
+            bmb.srcAccessMask = usage_matches ? res->obj->unordered_access : res->obj->access;
+         } else {
+            bmb.srcAccessMask = res->obj->access;
          }
-         marker = zink_cmd_debug_marker_begin(ctx, cmdbuf, "buffer_barrier(%s)", buf);
+         VKCTX(CmdPipelineBarrier)(
+            cmdbuf,
+            stages,
+            pipeline,
+            0,
+            1, &bmb,
+            0, NULL,
+            0, NULL
+         );
       }
-      VKCTX(CmdPipelineBarrier2)(cmdbuf, &dep);
+
       zink_cmd_debug_marker_end(ctx, cmdbuf, marker);
    }
 
@@ -738,3 +657,13 @@ zink_resource_buffer_barrier2(struct zink_context *ctx, struct zink_resource *re
    if (pipeline != VK_PIPELINE_STAGE_TRANSFER_BIT && is_write)
       zink_resource_copies_reset(res);
 }
+
+void
+zink_synchronization_init(struct zink_screen *screen)
+{
+   if (screen->info.have_vulkan13 || screen->info.have_KHR_synchronization2) {
+      screen->buffer_barrier = zink_resource_buffer_barrier<true>;
+   } else {
+      screen->buffer_barrier = zink_resource_buffer_barrier<false>;
+   }
+}