如何在Vulkan中使用DepthBuffer作为InputAttachment?

时间:2016-11-06 01:54:13

标签: c++ graphics vulkan

我在将DepthBuffer实现为辅助子通道的InputAttachment时遇到了一些麻烦。我想使用我的第一个子通道的深度信息。我怎么能这样做呢?似乎我当前的代码只给了我一个空的缓冲区..

我的深度缓冲区设置如下:

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;

然后我使用以下布局转换:

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 };
}

这对渲染来说完全没问题。 我使用的VkAttachmentReference具有布局VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,我将其用作VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
在我的片段着色器中,我然后使用layout (set = 0, binding = 1) uniform sampler2D inputDepth;来访问它,但是没有任何成功..我得到的信息只是任何颜色通道的零。

此外,我使用此依赖项:

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;
}

和这个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;
}

1 个答案:

答案 0 :(得分:3)

如果您正在进行子通道(而不是多次渲染过程),并希望将深度缓冲区用作 inputAttachment ,并希望将附件用作第二个 sub <的输入/强>通,

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

不是从着色器中采样的正确语法。

从输入附件中进行采样需要特殊的语法:

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

这还需要类型为VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT的描述符,而不是VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER。请注意,输入附件的实际描述符不需要采样器。

如果您尝试在第二个渲染过程中对深度附件进行采样,请确保附件说明的storeOp设置为存储。