深度附件需要 VkSubpassDependency,但颜色附件不需要
VkSubpassDependency required for depth attachment, but not for color attachment
我有一个非常简单的设置 - 实际上是 vkguide.dev 的早期阶段之一。所以一个渲染通道和一个子通道。那些有一种颜色和一种深度附件。
颜色AttachmentDescription
有.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
和.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
。在它的 SubPassDescription
中,它有 .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
.
深度AttachmentDescription
有.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
和.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
。在它的 SubPassDescription
中,它有 .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
.
我正在尝试了解子通道依赖关系,因此我不想依赖规范提供的隐式依赖关系,而是提供我自己的最小依赖关系。
当我提供“清零”子通道依赖项时,我在同步验证打开时收到以下错误:
Validation Error: [ SYNC-HAZARD-WRITE_AFTER_WRITE ] Object 0: handle = 0x83d4ee000000000b, type = VK_OBJECT_TYPE_RENDER_PASS; | MessageID = 0xfdf9f5e1 | vkCmdBeginRenderPass: Hazard WRITE_AFTER_WRITE vs. layout transition in subpass 0 for attachment 1 aspect depth during load with loadOp VK_ATTACHMENT_LOAD_OP_CLEAR.
所以他在抱怨深度附件(附件 1)。我可以使用以下一组显式子通道依赖项来解决此问题:
constexpr VkSubpassDependency in_dependency{
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
};
constexpr VkSubpassDependency out_dependency = {
.srcSubpass = 0,
.dstSubpass = VK_SUBPASS_EXTERNAL,
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
.srcAccessMask = 0,
.dstAccessMask = 0,
.dependencyFlags = 0
};
第二个当然只是为了不使用第二个隐含的,什么都不做。第一个是 renderpass 和 first/only subpass 之前的事物之间的显式依赖关系。但我不是很明白 - 几个问题:
srcAccessMask = 0
是否真正定义了真正的依赖关系?毕竟它是空的,还是 VK_SUBPASS_EXTERNAL
? 有什么不同?
- 为什么我只需要依赖于深度而不是颜色附件?
我制作了下面的图片,我知道颜色附件在同一管道阶段被加载和存储,深度附件现在也是如此。但是我仍然不明白为什么这消除了依赖性的需要。管线阶段仍然可以在两个渲染通道之间重叠,对吗?
does a srcAccessMask = 0
really define a real dependency? it's empty after all, or are things different with a VK_SUBPASS_EXTERNAL
?
是的。它被称为 执行依赖性 (相对于 内存依赖性 )。它在 依赖链 .
中变得相关
考虑这段代码:
vkCmdPipelineBarrier(
srcStage = WHATEVER_STAGE, srcAccess = MEMORY_WRITE,
dstStage = COOL_STAGE, dstAccess = 0
);
vkCmdPipelineBarrier(
srcStage = COOL_STAGE, srcAccess = 0,
dstStage = WHATEVER_ELSE_STAGE, dstAccess = MEMORY_READ
);
相当于单一依赖:
vkCmdPipelineBarrier(
srcStage = WHATEVER_STAGE, srcAccess = MEMORY_WRITE,
dstStage = WHATEVER_ELSE_STAGE, dstAccess = MEMORY_READ
);
Why do I only need a dependency on the depth- and not on the color attachment?
验证可能实施不完善。或者可能在您的代码中对颜色附件进行了不同的处理(显示了彩色图像,而没有显示深度)。这要么隐藏了那里的依赖性,要么让验证器捕获它变得不那么微不足道。
我有一个非常简单的设置 - 实际上是 vkguide.dev 的早期阶段之一。所以一个渲染通道和一个子通道。那些有一种颜色和一种深度附件。
颜色AttachmentDescription
有.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
和.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
。在它的 SubPassDescription
中,它有 .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
.
深度AttachmentDescription
有.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED
和.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
。在它的 SubPassDescription
中,它有 .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
.
我正在尝试了解子通道依赖关系,因此我不想依赖规范提供的隐式依赖关系,而是提供我自己的最小依赖关系。
当我提供“清零”子通道依赖项时,我在同步验证打开时收到以下错误:
Validation Error: [ SYNC-HAZARD-WRITE_AFTER_WRITE ] Object 0: handle = 0x83d4ee000000000b, type = VK_OBJECT_TYPE_RENDER_PASS; | MessageID = 0xfdf9f5e1 | vkCmdBeginRenderPass: Hazard WRITE_AFTER_WRITE vs. layout transition in subpass 0 for attachment 1 aspect depth during load with loadOp VK_ATTACHMENT_LOAD_OP_CLEAR.
所以他在抱怨深度附件(附件 1)。我可以使用以下一组显式子通道依赖项来解决此问题:
constexpr VkSubpassDependency in_dependency{
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccessMask = 0,
.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
};
constexpr VkSubpassDependency out_dependency = {
.srcSubpass = 0,
.dstSubpass = VK_SUBPASS_EXTERNAL,
.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
.srcAccessMask = 0,
.dstAccessMask = 0,
.dependencyFlags = 0
};
第二个当然只是为了不使用第二个隐含的,什么都不做。第一个是 renderpass 和 first/only subpass 之前的事物之间的显式依赖关系。但我不是很明白 - 几个问题:
srcAccessMask = 0
是否真正定义了真正的依赖关系?毕竟它是空的,还是VK_SUBPASS_EXTERNAL
? 有什么不同?
- 为什么我只需要依赖于深度而不是颜色附件?
我制作了下面的图片,我知道颜色附件在同一管道阶段被加载和存储,深度附件现在也是如此。但是我仍然不明白为什么这消除了依赖性的需要。管线阶段仍然可以在两个渲染通道之间重叠,对吗?
does a
srcAccessMask = 0
really define a real dependency? it's empty after all, or are things different with aVK_SUBPASS_EXTERNAL
?
是的。它被称为 执行依赖性 (相对于 内存依赖性 )。它在 依赖链 .
中变得相关考虑这段代码:
vkCmdPipelineBarrier(
srcStage = WHATEVER_STAGE, srcAccess = MEMORY_WRITE,
dstStage = COOL_STAGE, dstAccess = 0
);
vkCmdPipelineBarrier(
srcStage = COOL_STAGE, srcAccess = 0,
dstStage = WHATEVER_ELSE_STAGE, dstAccess = MEMORY_READ
);
相当于单一依赖:
vkCmdPipelineBarrier(
srcStage = WHATEVER_STAGE, srcAccess = MEMORY_WRITE,
dstStage = WHATEVER_ELSE_STAGE, dstAccess = MEMORY_READ
);
Why do I only need a dependency on the depth- and not on the color attachment?
验证可能实施不完善。或者可能在您的代码中对颜色附件进行了不同的处理(显示了彩色图像,而没有显示深度)。这要么隐藏了那里的依赖性,要么让验证器捕获它变得不那么微不足道。