From f4c4bcc73a62376bfd53ea473ab354ee7e9676db Mon Sep 17 00:00:00 2001 From: Alexey Panteleev Date: Wed, 20 Nov 2024 18:04:19 -0800 Subject: [PATCH] Fixed the validation errors from Vulkan SDK 1.3.296.0. "vkAcquireNextImageKHR(): Semaphore must not have any pending operations" Also removed the empty barrier command list, it's no longer necessary since NVRHI supports executeCommandLists with no command lists. --- src/app/vulkan/DeviceManager_VK.cpp | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/app/vulkan/DeviceManager_VK.cpp b/src/app/vulkan/DeviceManager_VK.cpp index 8363723..408e5de 100644 --- a/src/app/vulkan/DeviceManager_VK.cpp +++ b/src/app/vulkan/DeviceManager_VK.cpp @@ -258,8 +258,9 @@ class DeviceManager_VK : public DeviceManager nvrhi::vulkan::DeviceHandle m_NvrhiDevice; nvrhi::DeviceHandle m_ValidationLayer; - nvrhi::CommandListHandle m_BarrierCommandList; + std::vector m_AcquireSemaphores; std::vector m_PresentSemaphores; + uint32_t m_AcquireSemaphoreIndex = 0; uint32_t m_PresentSemaphoreIndex = 0; std::queue m_FramesInFlight; @@ -1208,12 +1209,12 @@ bool DeviceManager_VK::CreateSwapChain() { CHECK(createSwapChain()) - m_BarrierCommandList = m_NvrhiDevice->createCommandList(); - m_PresentSemaphores.reserve(m_DeviceParams.maxFramesInFlight + 1); + m_AcquireSemaphores.reserve(m_DeviceParams.maxFramesInFlight + 1); for (uint32_t i = 0; i < m_DeviceParams.maxFramesInFlight + 1; ++i) { m_PresentSemaphores.push_back(m_VulkanDevice.createSemaphore(vk::SemaphoreCreateInfo())); + m_AcquireSemaphores.push_back(m_VulkanDevice.createSemaphore(vk::SemaphoreCreateInfo())); } return true; @@ -1233,7 +1234,14 @@ void DeviceManager_VK::DestroyDeviceAndSwapChain() } } - m_BarrierCommandList = nullptr; + for (auto& semaphore : m_AcquireSemaphores) + { + if (semaphore) + { + m_VulkanDevice.destroySemaphore(semaphore); + semaphore = vk::Semaphore(); + } + } m_NvrhiDevice = nullptr; m_ValidationLayer = nullptr; @@ -1266,7 +1274,7 @@ void DeviceManager_VK::DestroyDeviceAndSwapChain() bool DeviceManager_VK::BeginFrame() { - const auto& semaphore = m_PresentSemaphores[m_PresentSemaphoreIndex]; + const auto& semaphore = m_AcquireSemaphores[m_AcquireSemaphoreIndex]; vk::Result res; @@ -1295,8 +1303,11 @@ bool DeviceManager_VK::BeginFrame() break; } + m_AcquireSemaphoreIndex = (m_AcquireSemaphoreIndex + 1) % m_AcquireSemaphores.size(); + if (res == vk::Result::eSuccess) { + // Schedule the wait. The actual wait operation will be submitted when the app executes any command list. m_NvrhiDevice->queueWaitForSemaphore(nvrhi::CommandQueue::Graphics, semaphore, 0); return true; } @@ -1310,9 +1321,9 @@ bool DeviceManager_VK::Present() m_NvrhiDevice->queueSignalSemaphore(nvrhi::CommandQueue::Graphics, semaphore, 0); - m_BarrierCommandList->open(); // umm... - m_BarrierCommandList->close(); - m_NvrhiDevice->executeCommandList(m_BarrierCommandList); + // NVRHI buffers the semaphores and signals them when something is submitted to a queue. + // Call 'executeCommandLists' with no command lists to actually signal the semaphore. + m_NvrhiDevice->executeCommandLists(nullptr, 0); vk::PresentInfoKHR info = vk::PresentInfoKHR() .setWaitSemaphoreCount(1)