Sampling depth_stencil texture

Hi! In attempts to implement SSAO I am trying to sample depth stencil texture for its depth value, and I always get 0.

My fragment shader has:

layout (binding = 4) uniform sampler2D samplerDepth;

I create image, sampler and imageView with my trivial helper with aspect mask VK_IMAGE_ASPECT_DEPTH_BIT for image view:

create_attachment(VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, depth, init_cmd.cmdBuf, sz,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL | VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,
0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);

Layout binding:

layout_bindings[4].binding = 4;
layout_bindings[4].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
layout_bindings[4].descriptorCount = 1;
layout_bindings[4].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
layout_bindings[4].pImmutableSamplers = NULL;

Descriptor set:

VkDescriptorImageInfo depth_tex_descs = {};
depth_tex_descs.sampler = g_buffer->depth.sampler;
depth_tex_descs.imageView = g_buffer->depth.view;
depth_tex_descs.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;

writes[4].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[4].dstSet = quad.descSet;
writes[4].descriptorCount = 1;
writes[4].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
writes[4].pImageInfo = &depth_tex_descs;
writes[4].dstBinding = 4;

But sampled value from shader is always 0. What am I doing wrong?

Is is the storeOp for the depth attachment of the depth pass set to STORE?

It was dont_care, I’ve changed it to STORE, but it did not help. Here is attachment info:

attachments[0].format = VK_FORMAT_D32_SFLOAT_S8_UINT;
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
attachments[0].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
attachments[0].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

Also tryied both VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL and VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL layouts - results are the same.

If you’re on hardware that requires them: Are you doing proper layout transitions for the depth image?

If you need something to compare, I have several examples that read from depth. E.g. this this basic shadow mapping example.

You are not allowed to access an attachment of a renderpass as a sampled texture in the same renderpass.

This means that you either need to change the sampler2D to a input attachment or do the SSAO in a second renderpass.

You are not allowed to access an attachment of a renderpass as a sampled texture in the same renderpass.

Just FYI: there are input attachments that would be useful in general. But input attachments are limited to only reading from the exact fragment that corresponds to the fragment shader’s invocation. For lighting passes of a deferred shader, that’s fine. For SSAO, that’s not an option.

So yes, you’ll need a separate renderpass.

That restriction doesn’t sound right at all. Could you point to the spec section that would describe that VU rule?
I see that VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL is described specifically to allow shader access:

specifies a layout for both the depth and stencil aspects of a depth/stencil format image allowing read only access as a depth/stencil attachment or in shaders.

If you’re looking for valid usage about using attachments as textures, that’s simple:

Image subresources used as attachments in the current render pass must not be accessed in any way other than as an attachment by this command.

“this command” being rendering commands.

Using an image subresource as a sampled image is not using it as an attachment. Using an image subresource as a storage image is not using it as an attachment. These are forbidden.

Using an image subresource as an input attachment is using it as an attachment (even if it’s part of a descriptor too). That’s what “in shaders” means in the text you quoted.

Interesting, thank you for the info! Also, long time no see :slight_smile: I recall you from the OpenGL forum, and I’m glad to see you still bringing the light of knowledge everywhere :+1:

I filed an issue to get clarification on this - Using a read-only attachment in a shader binding · Issue #1345 · KhronosGroup/Vulkan-Docs · GitHub

What confuses me is: if it’s not allowed to use the image in both the attachment and the shaders, why are there all the read-only layouts?

I thought that was cleared up:

Using an image subresource as an input attachment is using it as an attachment (even if it’s part of a descriptor too). That’s what “in shaders” means in the text you quoted.

“In shaders” doesn’t mean “as a sampled image”.

If you want to read from the depth image arbitrarily, you have to break up the render pass. The same goes for color images or any other form of attachment.

I’m not sure what you mean. The read-only layers are for when you only want to read from the depth image. There’s no reason to assume that means “read it as a sampled image”. Input attachments and depth testing both read the depth image.