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:
//Image layout transitions
vector<VkImageMemoryBarrier2KHR> barriers;
VkImageMemoryBarrier2KHR barrier = {};
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
barrier.srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR;
barrier.srcAccessMask = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR;
barrier.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR;
barrier.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT_KHR;
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
barrier.subresourceRange.levelCount = 1;
for (auto pair : visset->cameravislists)
{
auto light = pair.first->As<RenderLight>();
if (light == NULL) continue;
barrier.oldLayout = light->shadowbuffer[0]->depthtexture->GetLayout();
barrier.subresourceRange.layerCount = 1;
if (light->description.type == LIGHT_POINT and MULTIPASS_CUBEMAP == true) barrier.subresourceRange.layerCount = 6;
barrier.image = light->shadowbuffer[0]->depthtexture->vkimage;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
switch (light->shadowbuffer[0]->depthtexture->format)
{
case VK_FORMAT_D24_UNORM_S8_UINT:
case VK_FORMAT_D32_SFLOAT_S8_UINT:
case VK_FORMAT_D16_UNORM_S8_UINT:
barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
}
barriers.push_back(barrier);
light->shadowbuffer[0]->depthtexture->imagelayout[0][0] = barrier.newLayout;
if (light->shadowcache[0])
{
barrier.image = light->shadowcache[0]->depthtexture->vkimage;
barriers.push_back(barrier);
light->shadowcache[0]->depthtexture->imagelayout[0][0] = barrier.newLayout;
}
}
VkDependencyInfoKHR dependencyInfo = {};
dependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR;
dependencyInfo.imageMemoryBarrierCount = barriers.size();
dependencyInfo.pImageMemoryBarriers = barriers.data();
device->vkCmdPipelineBarrier2KHR(commandbuffers[currentFrame]->commandbuffer, &dependencyInfo);
I am using Vulkan 1.3. Validation layer VK_LAYER_KHRONOS_validation is enabled and it does not catch any errors.
I have no idea what is wrong with this?