Issue with reading depth buffer after depth render pass

Hello everyone!
Sorry for the kind of “open question”, but what are the usual suspects to check when trying to have a first render pass rendering only to a depth buffer and then trying to read from it on the next render pass (typically what you would see in a shadow map implementation)? Currently my depth buffer has only 1.0’s when reading the .r value in the second render pass…

A little bit about my setup:

  • I have 2 frames in flight, and 2 sets of descriptor sets, one for each frame in flight (even though I have 3 swap chain images/swap chain frameBuffers, could that be a problem?)
  • I create the images/imageViews and use them as an attachment in the first render pass, and then try to read from it in the second render pass - each is also loaded as a SAMPLED_IMAGE in their respective descriptor set… I use subpasses to perform layout transitions in the first render pass (there are no vulkan validation messages)
  • loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; and storeOp = VK_ATTACHMENT_STORE_OP_STORE;
  • A lot of the code is based on (Vulkan/shadowmapping.cpp at master · SaschaWillems/Vulkan · GitHub). with the biggest difference perhaps being this 2 sets of resources: I have 2 framebuffers for the depth pass and 2 descriptor sets, so I use/bind always the ones using the same imageView when recording the command buffer (so if the first render pass would write to “imageView[0]” , this would be the one also referenced in the bound descriptor set)

Any hint/tip/guidance about common issues I should be looking for would be much appreciated!
Thanks a lot!

The first thing you should always look at are validation layers. Second is dependencies: do you have proper synchronization between the two render passes? The third are layout transitions.

Thanks a lot for the comment!

I don’t have any validation layer messages, so I assume everything is alright there.
As for the proper synchronization between the two render passes, on the example code I’m following, there is this:

Note: Explicit synchronization is not required between the render pass, as this is done implicit via sub pass dependencies

And I’m doing the sub pass’ dependencies as the code indicates (Vulkan/shadowmapping.cpp at master · SaschaWillems/Vulkan · GitHub), so I guess it should be fine? Anyways, I will try to perform some explicit synchronization and see if it helps!

Thanks again!

I have no knowledge of the context of that quote, so I cannot judge its veracity. But absent context, my question was ultimately about “sub pass dependencies”. Specifically, external sub pass dependencies, which are not “implicit” in the traditional meaning of that term. Do you have them, and if so, are they properly arranged?

For example, I find the use of VK_DEPENDENCY_BY_REGION_BIT for the destination external dependency to be… dubious. It is for “framebuffer-local dependencies”, and this dependency is definitely not “framebuffer-local”.

I have 2 subpass dependencies for the first render pass:

dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
dependencies[0].dstSubpass = 0;
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
dependencies[0].dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

dependencies[1].srcSubpass = 0;
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependencies[1].srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

Indeed it’s using the VK_DEPENDENCY_BY_REGION_BIT. I’ve just tried using the other dependency values available (and also the value “0”), but no success… still the same plain “red image” (or white, if you use R for the RGB values)

I’m considering simply starting from scratch :sweat_smile: I’m sure there is a silly bug somewhere in the code.

Anyways, thanks again for the help! Appreciate it!

Is that unexpected? What value do you expect?

I would look in your second render pass if you accidentally include the depth attachment and clearing it again.

Thanks for the tip!
I double checked that and I do have a different depth attachment for the second render pass, which is the swap chain render pass in my case.

In the second render pass, I was expecting to get the values of the depth of the scene, so I can read them (now as a sampled image) and do some effects.

It does look like the depth attachment/sampled image is being “cleared up” somehow between the 2 render passes, or perhaps the depth renderer of the first render pass is not doing anything… I will look into it!

Thanks again!

Just a quick update, for anyone interested…
I’ve found the issue: I’m using a “global descriptor set” setup (some people call it “bindless”, but there is the one binding…) and the issue was that one of the buffers used in the shader changed index, but I forgot to update it in the shader code and the bogus calculations were resulting in all the 1.0’s :man_facepalming:t3: :man_facepalming:t3:
After updating the buffer index to the correct value in the shader, everything seems to be working as expected

Once more, thanks for all the help everyone!