深度附件需要 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 之前的事物之间的显式依赖关系。但我不是很明白 - 几个问题:

我制作了下面的图片,我知道颜色附件在同一管道阶段被加载和存储,深度附件现在也是如此。但是我仍然不明白为什么这消除了依赖性的需要。管线阶段仍然可以在两个渲染通道之间重叠,对吗?

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?

验证可能实施不完善。或者可能在您的代码中对颜色附件进行了不同的处理(显示了彩色图像,而没有显示深度)。这要么隐藏了那里的依赖性,要么让验证器捕获它变得不那么微不足道。