-
Notifications
You must be signed in to change notification settings - Fork 249
Description
vsg::RecordAndSubmitTask
doesn't have separate semaphores per frame/swapchain image like vsg::Window
does for image acquisition, so every frame's queued submissions signal the same semaphore, and every frame's presentation waits for the same semaphore.
https://docs.vulkan.org/guide/latest/swapchain_semaphore_reuse.html has a writeup on this being a bad thing, and with a new enough version of the Vulkan SDK (i.e. 1.4.313 or later), this will trigger a validation error in any VSG-based application:
Validation Error: [ VUID-vkQueueSubmit-pSignalSemaphores-00067 ] | MessageID = 0x539277af
vkQueueSubmit(): pSubmits[0].pSignalSemaphores[0] (VkSemaphore 0x30000000003) is being signaled by VkQueue 0x1b6621abd80, but it may still be in use by VkSwapchainKHR 0x220000000022.
Here are the most recently acquired image indices: 0, [1], 2.
(brackets mark the last use of VkSemaphore 0x30000000003 in a presentation operation)
Swapchain image 1 was presented but was not re-acquired, so VkSemaphore 0x30000000003 may still be in use and cannot be safely reused with image index 2.
Vulkan insight: One solution is to assign each image its own semaphore. Here are some common methods to ensure that a semaphore passed to vkQueuePresentKHR is not in use and can be safely reused:
a) Use a separate semaphore per swapchain image. Index these semaphores using the index of the acquired image.
b) Consider the VK_KHR_swapchain_maintenance1 extension. It allows using a VkFence with the presentation operation.
The Vulkan spec states: Each binary semaphore element of the pSignalSemaphores member of any element of pSubmits must be unsignaled when the semaphore signal operation it defines is executed on the device (https://vulkan.lunarg.com/doc/view/1.4.321.1/windows/antora/spec/latest/chapters/cmdbuffers.html#VUID-vkQueueSubmit-pSignalSemaphores-00067)
Objects: 2
[0] VkSemaphore 0x30000000003
[1] VkQueue 0x1b6621abd80
As far as I've been able to tell, this is the cause for the much lower performance with AMD graphics on Windows. As we submit several frames and reuse the same semaphore several times before first waiting on a fence, it's ambiguous which frame's present should wait for which frame's rendering, and we can end up with the first frame's present waiting for the third frame's rendering. For whatever reason, this has ended up being symptomatic with this one driver and hardware combination, but not with others anyone's tested.
I'll take a look at potential fixes for this over the next few days. As the validation error suggests, just using one rendering semaphore per swapchain image should be pretty straightforward, although we could simplify all the synchronisation in the VSG by switching from fences and binary semaphores to timeline semaphores (using LunarG's timeline semaphore emulation layer implemented on top of fences and binary semaphores when running on systems that don't support Vulkan 1.2).