My setup is like this:
- Render a small scene (ie. a single 3D model) into a framebuffer with 1 color and 1 depth attachment.
- Render the color buffer into a fullscreen quad
Most code examples online use render passes and subpass dependencies, however I'm using dynamic rendering extension and therefore VkRenderingInfo
, VkRenderingAttachmentInfo
, and vkCmdBeginRendering
. The setup is identical to dynamic rendering with swapchain and swapchain depth buffer, which I have got working fine. So I was thinking to extend this system and try deferred. However, it would seem the depth testing is not being performed, because every fragment passes the depth test (something that is clear upon inspection by visualizing the depth buffer, and from Renderdoc).
This is my command buffer recording for each frame:
// 1) begin recording on the command buffer// 2) begin dynamic rendering on the framebuffer// 3) bind main pipeline and set dynamic states// 4) bind and render model, including descriptor sets and push constants// 5) end dynamic rendering on the framebuffer// 6) begin dynamic rendering on the swapchain// 7) bind the quad pipeline// 8) bind framebuffer targets for reading (descriptor sets?)// 9) draw fullscreen quad// 10) end dynamic rendering on the swapchain// 11) end recording on the command buffer
Steps 6-11 are working fine (checked with Renderdoc). Also, since the problem is depth testing not working correctly, I expect the problem is either:
- How the main pipeline is configured; or
- How dynamic rendering is configured for the framebuffer
The pipeline is configured as it should be - the setup was copy/pasted from other projects where depth buffering is enabled and working. Therefore, this is what happens in step 2:
// color attachment pipeline barrier, omitted here.// depth attachment pipeline barrier, shown below:VkImageMemoryBarrier depthBarrier{};barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;barrier.pNext = nullptr;barrier.srcAccessMask = 0;barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;barrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;barrier.srcQueueFamilyIndex = graphicsQueueFamilyIndex;barrier.dstQueueFamilyIndex = graphicsQueueFamilyIndex;barrier.image = framebuffer->depthAttachment.image;barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;barrier.subresourceRange.baseMipLevel = 0;barrier.subresourceRange.levelCount = 1;barrier.subresourceRange.baseArrayLayer = 0;barrier.subresourceRange.layerCount = 1;const VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;const VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;vkCmdPipelineBarrier( cmdBuf, srcStageMask, dstStageMask, 0, 0, nullptr, 0, nullptr, 1, &depthBarrier);VkRenderingAttachmentInfo colorInfo{};colorInfo.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;colorInfo.pNext = nullptr;colorInfo.imageView = framebuffer->colorAttachment.imageView;colorInfo.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL;colorInfo.resolveMode = VK_RESOLVE_MODE_NONE;colorInfo.resolveImageView = VK_NULL_HANDLE;colorInfo.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;colorInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;colorInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;colorInfo.clearValue = { .color = { .float32 = {0.1f, 0.1f, 0.1f, 1.0f} } }VkRenderingAttachmentInfo depthInfo{};depthInfo.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;depthInfo.pNext = nullptr;depthInfo.imageView = framebuffer->depthAttachment.imageView;depthInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;depthInfo.resolveMode = VK_RESOLVE_MODE_NONE;depthInfo.resolveImageView = VK_NULL_HANDLE;depthInfo.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;depthInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;depthInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;depthInfo.clearValue = { .depthStencil = { 1.0f, 0 } };VkRenderingInfo renderingInfo{};renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;renderingInfo.pNext = nullptr;renderingInfo.flags = 0;renderingInfo.renderArea = { 0U, 0U, framebuffer->width, framebuffer->height };renderingInfo.layerCount = 1;renderingInfo.viewMask = 0;renderingInfo.colorAttachmentCount = 1;renderingInfo.pColorAttachments = &colorInfo;renderingInfo.pDepthAttachment = &depthInfo;renderingInfo.pStencilAttachment = nullptr;vkCmdBeginRendering(cmdBuf, &renderingInfo);
Step 3 and 4 have been tested before and should work fine. Step 5 is ending dynamic rendering on the framebuffer, and it only transitions the color attachment to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
so it can be sampled from in the fullscreen quad shader. I don't get any validation messages here, and I can see the final image on-screen - only without proper depth testing.
What could I be doing wrong? I hope I'm presenting the problem properly, otherwise let me know if I'm missing an important step. And thank you in advance!