From 6d00e95b2e448f1bbb95abb54a85159a659764e9 Mon Sep 17 00:00:00 2001 From: Mary Guillemard Date: Mon, 15 Sep 2025 16:43:08 +0000 Subject: [PATCH] panvk: Take VK_DEPENDENCY_ASYMMETRIC_EVENT_BIT_KHR into account VK_DEPENDENCY_ASYMMETRIC_EVENT_BIT_KHR makes vkCmdSetEvent2 behaves like vkCmdSetEvent, let's handle that appropriately. This fixes failures on VKCTS main with "dEQP-VK.synchronization2.op.single_queue.event.*_maintenance9". Signed-off-by: Mary Guillemard Fixes: b8ccbc414a2b ("panvk: enable KHR_maintenance9") Reviewed-by: Christoph Pillmayer Part-of: --- src/panfrost/vulkan/csf/panvk_cmd_buffer.h | 3 ++- src/panfrost/vulkan/csf/panvk_vX_cmd_buffer.c | 22 ++++++++++++++++--- src/panfrost/vulkan/csf/panvk_vX_cmd_event.c | 14 ++++++------ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/panfrost/vulkan/csf/panvk_cmd_buffer.h b/src/panfrost/vulkan/csf/panvk_cmd_buffer.h index 8871b8bb8ab..0732e8f2d72 100644 --- a/src/panfrost/vulkan/csf/panvk_cmd_buffer.h +++ b/src/panfrost/vulkan/csf/panvk_cmd_buffer.h @@ -483,7 +483,8 @@ void panvk_per_arch(add_cs_deps)( struct panvk_cmd_buffer *cmdbuf, enum panvk_barrier_stage barrier_stage, const VkDependencyInfo *in, - struct panvk_cs_deps *out); + struct panvk_cs_deps *out, + bool is_set_event); VkResult panvk_per_arch(cmd_prepare_exec_cmd_for_draws)( struct panvk_cmd_buffer *primary, struct panvk_cmd_buffer *secondary); diff --git a/src/panfrost/vulkan/csf/panvk_vX_cmd_buffer.c b/src/panfrost/vulkan/csf/panvk_vX_cmd_buffer.c index af0fa644297..072bf414e49 100644 --- a/src/panfrost/vulkan/csf/panvk_vX_cmd_buffer.c +++ b/src/panfrost/vulkan/csf/panvk_vX_cmd_buffer.c @@ -553,12 +553,28 @@ void panvk_per_arch(add_cs_deps)(struct panvk_cmd_buffer *cmdbuf, enum panvk_barrier_stage barrier_stage, const VkDependencyInfo *in, - struct panvk_cs_deps *out) + struct panvk_cs_deps *out, + bool is_set_event) { + bool is_asymmetric_event = + is_set_event && + in->dependencyFlags & VK_DEPENDENCY_ASYMMETRIC_EVENT_BIT_KHR; + + /* As per Vulkan spec, this should look like a vkCmdSetEvent */ + assert(!is_asymmetric_event || + (in->memoryBarrierCount == 1 && in->bufferMemoryBarrierCount == 0 && + in->imageMemoryBarrierCount == 0)); + for (uint32_t i = 0; i < in->memoryBarrierCount; i++) { const VkMemoryBarrier2 *barrier = &in->pMemoryBarriers[i]; struct panvk_sync_scope src = {barrier->srcStageMask, barrier->srcAccessMask}; struct panvk_sync_scope dst = {barrier->dstStageMask, barrier->dstAccessMask}; + + /* In case of asymmetric event, we need to use the src stages mask just + * like vkCmdSetEvent */ + if (is_asymmetric_event) + dst.stages = src.stages; + normalize_dependency(&src, &dst, (struct panvk_sync_scope){0}, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, @@ -728,7 +744,7 @@ panvk_per_arch(CmdPipelineBarrier2)(VkCommandBuffer commandBuffer, struct panvk_cs_deps deps = {0}; - panvk_per_arch(add_cs_deps)(cmdbuf, PANVK_BARRIER_STAGE_FIRST, pDependencyInfo, &deps); + panvk_per_arch(add_cs_deps)(cmdbuf, PANVK_BARRIER_STAGE_FIRST, pDependencyInfo, &deps, false); if (deps.needs_draw_flush) panvk_per_arch(cmd_flush_draws)(cmdbuf); @@ -746,7 +762,7 @@ panvk_per_arch(CmdPipelineBarrier2)(VkCommandBuffer commandBuffer, panvk_per_arch(add_cs_deps)( cmdbuf, PANVK_BARRIER_STAGE_AFTER_LAYOUT_TRANSITION, - pDependencyInfo, &trans_deps); + pDependencyInfo, &trans_deps, false); assert(!trans_deps.needs_draw_flush); diff --git a/src/panfrost/vulkan/csf/panvk_vX_cmd_event.c b/src/panfrost/vulkan/csf/panvk_vX_cmd_event.c index 0e2f0c36e99..12d80b781b6 100644 --- a/src/panfrost/vulkan/csf/panvk_vX_cmd_event.c +++ b/src/panfrost/vulkan/csf/panvk_vX_cmd_event.c @@ -29,7 +29,7 @@ panvk_per_arch(CmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent _event, }; struct panvk_cs_deps deps = {0}; - panvk_per_arch(add_cs_deps)(cmdbuf, PANVK_BARRIER_STAGE_FIRST, &info, &deps); + panvk_per_arch(add_cs_deps)(cmdbuf, PANVK_BARRIER_STAGE_FIRST, &info, &deps, false); for (uint32_t i = 0; i < PANVK_SUBQUEUE_COUNT; i++) { struct cs_builder *b = panvk_get_cs_builder(cmdbuf, i); @@ -67,7 +67,7 @@ panvk_per_arch(CmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent _event, VK_FROM_HANDLE(panvk_event, event, _event); struct panvk_cs_deps deps = {0}; - panvk_per_arch(add_cs_deps)(cmdbuf, PANVK_BARRIER_STAGE_FIRST, pDependencyInfo, &deps); + panvk_per_arch(add_cs_deps)(cmdbuf, PANVK_BARRIER_STAGE_FIRST, pDependencyInfo, &deps, true); if (deps.needs_draw_flush) panvk_per_arch(cmd_flush_draws)(cmdbuf); @@ -107,13 +107,13 @@ panvk_per_arch(CmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent _event, } static void -cmd_wait_event(struct panvk_cmd_buffer *cmdbuf, - struct panvk_event *event, const VkDependencyInfo *info, - struct panvk_cs_deps *trans_deps, bool *needs_trans_barrier) +cmd_wait_event(struct panvk_cmd_buffer *cmdbuf, struct panvk_event *event, + const VkDependencyInfo *info, struct panvk_cs_deps *trans_deps, + bool *needs_trans_barrier) { struct panvk_cs_deps deps = {0}; - panvk_per_arch(add_cs_deps)(cmdbuf, PANVK_BARRIER_STAGE_FIRST, info, &deps); + panvk_per_arch(add_cs_deps)(cmdbuf, PANVK_BARRIER_STAGE_FIRST, info, &deps, false); for (uint32_t i = 0; i < PANVK_SUBQUEUE_COUNT; i++) { struct cs_builder *b = panvk_get_cs_builder(cmdbuf, i); @@ -142,7 +142,7 @@ cmd_wait_event(struct panvk_cmd_buffer *cmdbuf, panvk_per_arch(add_cs_deps)( cmdbuf, PANVK_BARRIER_STAGE_AFTER_LAYOUT_TRANSITION, - info, trans_deps); + info, trans_deps, false); *needs_trans_barrier = true; } }