From b35d115f7b076c7796ff7c502c985c505a6ab7bf Mon Sep 17 00:00:00 2001 From: David Date: Wed, 21 Jan 2026 10:42:08 +0100 Subject: [PATCH] =?UTF-8?q?Fix=20vkCmdCopyBuffer=20SYNC-HAZARD-WRITE-AFTER?= =?UTF-8?q?-WRITE=20error=20Added=20a=20per=E2=80=91TransferTask=20fence?= =?UTF-8?q?=20to=20serialize=20transfer=20submissions=20so=20back=E2=80=91?= =?UTF-8?q?to=E2=80=91back=20vkCmdCopyBuffer=20writes=20can't=20overlap=20?= =?UTF-8?q?on=20the=20same=20queue.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/vsg/app/TransferTask.h | 3 +++ src/vsg/app/TransferTask.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/vsg/app/TransferTask.h b/include/vsg/app/TransferTask.h index b098bbb0b..d783bf60f 100644 --- a/include/vsg/app/TransferTask.h +++ b/include/vsg/app/TransferTask.h @@ -17,6 +17,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include #include +#include namespace vsg { @@ -97,6 +98,8 @@ namespace vsg VkDeviceSize dataTotalSize = 0; VkDeviceSize imageTotalSize = 0; + ref_ptr transferCompleteFence; + bool waitOnTransferFence = false; ref_ptr transferCompleteSemaphore; ref_ptr transferConsumerCompletedSemaphore; diff --git a/src/vsg/app/TransferTask.cpp b/src/vsg/app/TransferTask.cpp index cf320b2a5..c7b0d8e54 100644 --- a/src/vsg/app/TransferTask.cpp +++ b/src/vsg/app/TransferTask.cpp @@ -415,7 +415,7 @@ TransferTask::TransferResult TransferTask::_transferData(DataToCopy& dataToCopy) log(level, " totalSize = ", totalSize); auto& frame = *(dataToCopy.frames[dataToCopy.frameIndex]); - auto& fence = frame.fence; + auto& fence = dataToCopy.transferCompleteFence; auto& staging = frame.staging; auto& commandBuffer = frame.transferCommandBuffer; auto& newSignalSemaphore = dataToCopy.transferCompleteSemaphore; @@ -432,13 +432,13 @@ TransferTask::TransferResult TransferTask::_transferData(DataToCopy& dataToCopy) log(level, " newSignalSemaphore = ", newSignalSemaphore, ", ", newSignalSemaphore ? newSignalSemaphore->vk() : VK_NULL_HANDLE); log(level, " copyRegions.size() = ", copyRegions.size()); - if (frame.waitOnFence && fence) + if (dataToCopy.waitOnTransferFence && fence) { uint64_t timeout = std::numeric_limits::max(); if (VkResult result = fence->wait(timeout); result != VK_SUCCESS) return TransferResult{result, {}}; fence->resetFenceAndDependencies(); } - frame.waitOnFence = false; + dataToCopy.waitOnTransferFence = false; // advance frameIndex dataToCopy.frameIndex = (dataToCopy.frameIndex + 1) % dataToCopy.frames.size(); @@ -545,7 +545,7 @@ TransferTask::TransferResult TransferTask::_transferData(DataToCopy& dataToCopy) result = transferQueue->submit(submitInfo, fence); - frame.waitOnFence = true; + dataToCopy.waitOnTransferFence = true; dataToCopy.transferConsumerCompletedSemaphore.reset();