Walnut
Walnut copied to clipboard
Fix semaphore reuse validation error by waiting on all fences
While creating my own application with Walnut, my terminal was spammed with a Vulkan Validation Error:
[vulkan] Debug report from ObjectType: 5
Message: Validation Error: [ VUID-vkAcquireNextImageKHR-semaphore-01779 ] Object 0: handle = 0xdcc8fd0000000012, type = VK_OBJECT_TYPE_SEMAPHORE; | MessageID = 0x5717e75b | vkAcquireNextImageKHR(): Semaphore must not have any pending operations. The Vulkan spec states: If semaphore is not VK_NULL_HANDLE it must not have any uncompleted signal or wait operations pending (https://vulkan.lunarg.com/doc/view/1.3.283.0/windows/1.3-extensions/vkspec.html#VUID-vkAcquireNextImageKHR-semaphore-01779)
After some debugging line by line, digging into the Application.cpp file in the Application::Run() function I found the lines that triggered my console to be spammed
// Update and Render additional Platform Windows
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
}
When calling vkAcquireNextImageKHR, you pass in a semaphore and it expects that this semaphore is not already in use, meaning it is still pending in some queue operation. This violates the Vulkan spec. A simple fix is to just wait for the semaphore to finish:
// Wait for all fences to avoid semaphore reuse issues in multi-viewport mode
for (uint32_t i = 0; i < g_MainWindowData.ImageCount; i++)
{
ImGui_ImplVulkanH_Frame* frame = &g_MainWindowData.Frames[i];
if (frame->Fence != VK_NULL_HANDLE)
{
vkWaitForFences(g_Device, 1, &frame->Fence, VK_TRUE, UINT64_MAX);
}
}
// Update and Render additional Platform Windows
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindowsDefault();
}
This is also my first ever open source contribution so be brutal