I noticed my shadow map renders were sometimes experiencing a single frame lag where the old shadow map was shown in the scene render:
I started out to fix the memory barrier settings to try to eliminate this error, using this tutorial as a guide to the correct settings. This is a little different because it is using the 2KHR version of vkCommandPipelineBarrier(), which I have not used before:
In my code, following the shadow map rendering, I add a memory barrier like below:
What is synchronization validation? Is this a validation layer? I tried adding “VK_LAYER_KHRONOS_synchronization2” to the validation layers but it had no effect.
VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT specifies that Vulkan synchronization validation is enabled. This feature reports resource access conflicts due to missing or incorrect synchronization operations between actions (Draw, Copy, Dispatch, Blit) reading or writing the same regions of memory.
If it is not reporting anything, then you enabled validation wrong™, the layers are not complete enough to catch the problem, or it is not a synchronization problem.
You could try to violate something more blatantly to make sure your validation setup works correctly.
My general validation error reporting is working correctly. I’ve also set up what I think is a correct barrier with the older API, but it does not alleviate the original problem:
No, all it needs is add the VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT and boilerplate to pNext and enable the extension that defines this enum.
I’ve also set up what I think is a correct barrier with the older API, but it does not alleviate the original problem:
Problem with excerpts is the autor rarely shows the actual bug. Looks vaguely sane. Not much more that can be done here without complete minimal example.
Kinda sus it is a barrier and not render pass dependency.
Try more brutal synchronization (e.g. vk*WaitIdle) to eliminate if it even is sync problem. Make sure that the synchronization primitive is actually executed between the two things it is supposed to separate.
Also check if you are looking at the right thing. Looks like it is exactly one frame delayed. Might be a swapchain related problem, or bad management of multi-buffering of other resources.
vkDeviceWaitIdle or vkQueueWaitIdle. I meant *, not sure why I have gone with X…
PS: Ups, also no Cmd.
Also less brutal option (and potentially less reliable for debugging purposes) is the total barrier. Anyway the debugging strategy here is to oversynchronize to check if we are even after the right problem.
Okay, the good news is I am a better Vulkan programmer than I thought, because my Vulkan code is flawless.
The bad news is I am worse at multithreading than I thought.
What was happening is the light position was changing, but a new visibility list had not been received yet from the culling thread. So the light 4x4 matrix was moving but the shadow did not get updated until a signal was sent to the culling thread indicating that the light had shifted, and a new vis list was returned that included the visibility set for the light’s shadow render. The result was new light position with old out-of-date shadow map. My solution was to store an extra 4x4 matrix that only gets updated when the shadow is rendered, and use that in the scene render for the shadowmap lookup, which sounds kind of obvious now.
Basically.
Thank you for your help determining that memory barriers were not the issue.