如何在 Vulkan 中使用 DepthBuffer 作为 InputAttachment?
How to use a DepthBuffer as InputAttachment in 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;
}
和这个描述
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;
}
如果您正在执行子通道(而不是多个渲染通道)并且想将深度缓冲区用作 inputAttachment 并且想暂时将附件用作输入亚及格,
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 设置为存储。
我在将 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;
}
和这个描述
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;
}
如果您正在执行子通道(而不是多个渲染通道)并且想将深度缓冲区用作 inputAttachment 并且想暂时将附件用作输入亚及格,
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 设置为存储。