ToxiCore ToxiCore - 9 months ago 76
C++ Question

How to use a DepthBuffer as InputAttachment in Vulkan?

I have some trouble implementing my DepthBuffer as InputAttachment of a secondary subpass. I want to use the depth information of my first subpass. How can I archieve this? It seems that my current code gives me just an empty buffer..

My depth buffer is setup as follows:

create_info.imageType = VK_IMAGE_TYPE_2D;
create_info.format = VK_FORMAT_D32_SFLOAT;
create_info.mipLevels = 1;
create_info.arrayLayers = 1;
create_info.samples = VK_SAMPLE_COUNT_1_BIT;
create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;


I then use the following layout transition:

VkImageMemoryBarrier layout_transition_barrier{};
{
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
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 = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = image;
barrier.subresourceRange = { VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1 };
}


This works totally fine for rendering..
The VkAttachmentReference I use has the layout
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
and I use it as an
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
.

In my fragment shader I then use
layout (set = 0, binding = 1) uniform sampler2D inputDepth;
to access it, however without any success.. the information I get is only zeros for any color channel.




Further I use this dependency:

VkSubpassDependency dependency{};
{
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
dependency.dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
}


and this descritpion

static VkAttachmentDescription depth_input_attachment{};
{
depth_input_attachment.format = VK_FORMAT_D32_SFLOAT;
depth_input_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
depth_input_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
depth_input_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depth_input_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
depth_input_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depth_input_attachment.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
depth_input_attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
}

Answer Source

If you're doing subpasses (and not multiple render passes) and want to use your depth buffer as an inputAttachment and want to use an attachment as an input for a second subpass,

layout (set = 0, binding = 1) uniform sampler2D inputDepth

is not the correct syntax to sample from that in your shader.

Sampling from an input attachment requires a special syntax:

layout (input_attachment_index = n, binding = m) uniform subpassInput inputDepth;

This also requires a descriptor of type VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT instead of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER. Note that the actual descriptor for input attachments does not require a sampler.

If you're instead trying to sample your depth attachment in a second render pass, make sure that the storeOp of the attachment description is set to store.