From a4a5bf5d63054bda6d536edc1f08ead761c9a357 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 1 Mar 2025 14:14:38 +0100 Subject: [PATCH] [dxvk] Add helpers for transfer queue release barriers --- src/dxvk/dxvk_context.cpp | 86 +++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_context.h | 12 ++++++ 2 files changed, 98 insertions(+) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index ad0fbadc8..d14edddc9 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -8087,6 +8087,56 @@ namespace dxvk { } + void DxvkContext::accessImageTransfer( + DxvkImage& image, + const VkImageSubresourceRange& subresources, + VkImageLayout srcLayout, + VkPipelineStageFlags2 srcStages, + VkAccessFlags2 srcAccess) { + auto& transferBatch = getBarrierBatch(DxvkCmdBuffer::SdmaBuffer); + auto& graphicsBatch = getBarrierBatch(DxvkCmdBuffer::InitBarriers); + + if (srcLayout == VK_IMAGE_LAYOUT_UNDEFINED || srcLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) + image.trackInitialization(subresources); + + if (m_device->hasDedicatedTransferQueue()) { + VkImageMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 }; + barrier.srcStageMask = srcStages; + barrier.srcAccessMask = srcAccess; + barrier.dstStageMask = srcStages; + barrier.dstAccessMask = VK_ACCESS_2_NONE; + barrier.oldLayout = srcLayout; + barrier.newLayout = image.info().layout; + barrier.srcQueueFamilyIndex = m_device->queues().transfer.queueFamily; + barrier.dstQueueFamilyIndex = m_device->queues().graphics.queueFamily; + barrier.image = image.handle(); + barrier.subresourceRange = subresources; + + transferBatch.addImageBarrier(barrier); + + barrier.srcAccessMask = VK_ACCESS_2_NONE; + barrier.dstStageMask = image.info().stages; + barrier.dstAccessMask = image.info().access; + + graphicsBatch.addImageBarrier(barrier); + } else { + VkImageMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 }; + barrier.srcStageMask = srcStages; + barrier.srcAccessMask = srcAccess; + barrier.dstStageMask = image.info().stages; + barrier.dstAccessMask = image.info().access; + barrier.oldLayout = srcLayout; + barrier.newLayout = image.info().layout; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = image.handle(); + barrier.subresourceRange = subresources; + + transferBatch.addImageBarrier(barrier); + } + } + + void DxvkContext::accessBuffer( DxvkCmdBuffer cmdBuffer, DxvkBuffer& buffer, @@ -8206,6 +8256,42 @@ namespace dxvk { } + void DxvkContext::accessBufferTransfer( + DxvkBuffer& buffer, + VkPipelineStageFlags2 srcStages, + VkAccessFlags2 srcAccess) { + auto& transferBatch = getBarrierBatch(DxvkCmdBuffer::SdmaBuffer); + auto& graphicsBatch = getBarrierBatch(DxvkCmdBuffer::InitBarriers); + + if (m_device->hasDedicatedTransferQueue()) { + // No queue ownership transfer necessary since buffers all + // use SHARING_MODE_CONCURRENT, but we need a split barrier. + VkMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 }; + barrier.srcStageMask = srcStages; + barrier.srcAccessMask = srcAccess; + barrier.dstStageMask = srcStages; + barrier.dstAccessMask = VK_ACCESS_2_NONE; + + transferBatch.addMemoryBarrier(barrier); + + barrier.srcStageMask = srcStages; + barrier.srcAccessMask = VK_ACCESS_2_NONE; + barrier.dstStageMask = buffer.info().stages; + barrier.dstAccessMask = buffer.info().access; + + graphicsBatch.addMemoryBarrier(barrier); + } else { + VkMemoryBarrier2 barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 }; + barrier.srcStageMask = srcStages; + barrier.srcAccessMask = srcAccess; + barrier.dstStageMask = buffer.info().stages; + barrier.dstAccessMask = buffer.info().access; + + transferBatch.addMemoryBarrier(barrier); + } + } + + void DxvkContext::accessDrawBuffer( VkDeviceSize offset, uint32_t count, diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 97805a96b..81cb14bf7 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1973,6 +1973,13 @@ namespace dxvk { VkAccessFlags2 dstAccess, DxvkAccessOp accessOp); + void accessImageTransfer( + DxvkImage& image, + const VkImageSubresourceRange& subresources, + VkImageLayout srcLayout, + VkPipelineStageFlags2 srcStages, + VkAccessFlags2 srcAccess); + void accessBuffer( DxvkCmdBuffer cmdBuffer, DxvkBuffer& buffer, @@ -2025,6 +2032,11 @@ namespace dxvk { VkAccessFlags2 dstAccess, DxvkAccessOp accessOp); + void accessBufferTransfer( + DxvkBuffer& buffer, + VkPipelineStageFlags2 srcStages, + VkAccessFlags2 srcAccess); + void accessDrawBuffer( VkDeviceSize offset, uint32_t count,