From 1feb6ea63f04c539e0e6862fabfea450a4937139 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Fri, 3 Apr 2026 22:09:41 -0700 Subject: [PATCH] fix(rendering): sync async upload batches before rendering MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wait on in-flight upload batch fences at the start of each frame and insert a memory barrier (transfer→fragment shader) so the graphics queue sees completed layout transitions from the transfer queue. Fixes VK_IMAGE_LAYOUT_UNDEFINED validation errors for freshly loaded textures. --- src/rendering/vk_context.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/rendering/vk_context.cpp b/src/rendering/vk_context.cpp index d3da4698..c2a37415 100644 --- a/src/rendering/vk_context.cpp +++ b/src/rendering/vk_context.cpp @@ -1840,6 +1840,22 @@ VkCommandBuffer VkContext::beginFrame(uint32_t& imageIndex) { vkBeginCommandBuffer(frame.commandBuffer, &beginInfo); + // If async upload batches are still in flight (submitted to the transfer queue), + // wait for their fences and insert a memory barrier so the graphics queue sees + // the completed layout transitions and transfer writes. + if (!inFlightBatches_.empty()) { + waitAllUploads(); + + VkMemoryBarrier memBarrier{}; + memBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; + memBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + vkCmdPipelineBarrier(frame.commandBuffer, + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + 0, 1, &memBarrier, 0, nullptr, 0, nullptr); + } + return frame.commandBuffer; }