From 60af511fc60c8b5033b695837c4c7ab43195c516 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Tue, 21 Mar 2023 10:38:51 -0400 Subject: [PATCH] zink: use c++ template to deduplicate all the buffer barrier code Part-of: --- src/gallium/drivers/zink/zink_context.h | 2 + src/gallium/drivers/zink/zink_screen.c | 3 +- src/gallium/drivers/zink/zink_synchronization.cpp | 179 +++++++--------------- 3 files changed, 57 insertions(+), 127 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index e109bec..df48e2d 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -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); diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 3d535ae..44ce9cc 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -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); diff --git a/src/gallium/drivers/zink/zink_synchronization.cpp b/src/gallium/drivers/zink/zink_synchronization.cpp index feccbb9..001c782 100644 --- a/src/gallium/drivers/zink/zink_synchronization.cpp +++ b/src/gallium/drivers/zink/zink_synchronization.cpp @@ -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 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<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; + } else { + screen->buffer_barrier = zink_resource_buffer_barrier; + } +} -- 2.7.4