一些 VkSubpassDependency 问题,关于 Sascha Willems 的离屏渲染示例
Some VkSubpassDependency questions, regarding Sascha Willems's offscreen rendering sample
在 Sascha Willems 的离屏渲染示例中,主 renderPass 有 2 个 VkSubpassDependency,离屏 renderPass 有 2 个。
首先,我经常看到成对的VkSubpassDependency,不明白为什么。
主要renderPass的VkSubpassDependency:
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
dependencies[0].dstSubpass = 0;
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies[1].srcSubpass = 0;
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
离屏 renderPass 的 VkSubpassDependency:
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
dependencies[0].dstSubpass = 0;
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies[1].srcSubpass = 0;
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
在主renderPass中,第二个VkSubpassDependency (dependencies[1]) 是否只在这里用于呈现给交换链?是强制性的吗?
对于offScreen renderPass,一般来说我不明白依赖点[0]:
因为我们只需要写入帧缓冲区,并在完成时告诉主 renderPass,在我看来这就是依赖项 [1] 所做的。
dependencies是什么意思[0].srcSubpass = VK_SUBPASS_EXTERNAL;因为在offscreen renderPass之前没有涉及其他pass。是否只是为了让屏幕外渲染通道等待主渲染通道完成呈现到交换链?
我的最后一个问题更具体:如果我使用这 4 个 VkSubpassDependency,与 Sasha 在这个示例中使用的方式类似,那么为了执行屏幕外 renderPass,我遇到了验证错误 "Dependency graph must be specified such that an earlier pass cannot depend on a later pass."我在互联网上找不到有关此错误的任何信息。我刚刚发现触发此错误的原因是:dependency.srcSubpass > dependency.dstSubpass。有什么想法吗?
这是 Sascha Willems 的离屏渲染示例 link:
https://github.com/SaschaWillems/Vulkan/blob/master/examples/offscreen/offscreen.cpp
这个问题与 相似,是相同的代码库。
正如我在 SaschaWillems/Vulkan#665 中所说,示例有点过时了。从那时起,规范得到了广泛的澄清。所以偶尔会有一些不必要的混乱争论。
main renderPass, dependencies[1]
是的,这种依赖性在其后跟一个信号量信号时是典型的。例如。向交换链展示。
现在,dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
的 dst 外部依赖项不执行任何操作。响应。它与隐式依赖相同。尽管如此,无论如何,在这种情况下明确是审美选择。
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
没有访问权限,所以 dstAccessMask
应该只是 0
.
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
对最后一次访问是哪个访问有点困惑。最后一次访问颜色附件是 storeOp
,它只是 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
对于 STORE
或 DONT_CARE
。
offScreen renderPass, dependencies[0]
依赖的dst
方面应该是显而易见的。这只是颜色缓冲区访问。它应该匹配 loadOp
,在颜色缓冲区 CLEAR
的情况下是 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
和 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
.
现在,src
在 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
中是 VK_ACCESS_SHADER_READ_BIT
。这是在片段着色器中作为纹理访问的图像。似乎只有一个屏幕外帧缓冲区。因此,在不过多研究样本的情况下,我会假设这种依赖性确保 "main renderPass" 完成读取屏幕外缓冲区,然后再由屏幕外 renderPass 再次写入。
What is the meaning of dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; because there is no other pass involved before the offscreen renderPass.
当然有。它是这样的:offscreen, main, offscreen, main, offscreen, main, offscreen, main, ...。因此,除非它是第一帧,否则在给定的渲染通道之前总是有 东西 。
I just found that this error is triggered because: dependency.srcSubpass > dependency.dstSubpass. Any idea?
没错。看来你想通了?
srcSubpass
和 dstSubpass
必须是 VK_SUBPASS_EXTERNAL
,或者 srcSubpass
必须小于 dstSubpass
,以免意外产生循环和死锁在依赖 DAG 中。
在 Sascha Willems 的离屏渲染示例中,主 renderPass 有 2 个 VkSubpassDependency,离屏 renderPass 有 2 个。 首先,我经常看到成对的VkSubpassDependency,不明白为什么。
主要renderPass的VkSubpassDependency:
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
dependencies[0].dstSubpass = 0;
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies[1].srcSubpass = 0;
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
离屏 renderPass 的 VkSubpassDependency:
dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
dependencies[0].dstSubpass = 0;
dependencies[0].srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[0].srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
dependencies[1].srcSubpass = 0;
dependencies[1].dstSubpass = VK_SUBPASS_EXTERNAL;
dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
在主renderPass中,第二个VkSubpassDependency (dependencies[1]) 是否只在这里用于呈现给交换链?是强制性的吗?
对于offScreen renderPass,一般来说我不明白依赖点[0]:
因为我们只需要写入帧缓冲区,并在完成时告诉主 renderPass,在我看来这就是依赖项 [1] 所做的。
dependencies是什么意思[0].srcSubpass = VK_SUBPASS_EXTERNAL;因为在offscreen renderPass之前没有涉及其他pass。是否只是为了让屏幕外渲染通道等待主渲染通道完成呈现到交换链?
我的最后一个问题更具体:如果我使用这 4 个 VkSubpassDependency,与 Sasha 在这个示例中使用的方式类似,那么为了执行屏幕外 renderPass,我遇到了验证错误 "Dependency graph must be specified such that an earlier pass cannot depend on a later pass."我在互联网上找不到有关此错误的任何信息。我刚刚发现触发此错误的原因是:dependency.srcSubpass > dependency.dstSubpass。有什么想法吗?
这是 Sascha Willems 的离屏渲染示例 link: https://github.com/SaschaWillems/Vulkan/blob/master/examples/offscreen/offscreen.cpp
这个问题与
正如我在 SaschaWillems/Vulkan#665 中所说,示例有点过时了。从那时起,规范得到了广泛的澄清。所以偶尔会有一些不必要的混乱争论。
main renderPass, dependencies[1]
是的,这种依赖性在其后跟一个信号量信号时是典型的。例如。向交换链展示。
现在,dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
的 dst 外部依赖项不执行任何操作。响应。它与隐式依赖相同。尽管如此,无论如何,在这种情况下明确是审美选择。
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
没有访问权限,所以 dstAccessMask
应该只是 0
.
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
对最后一次访问是哪个访问有点困惑。最后一次访问颜色附件是 storeOp
,它只是 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
对于 STORE
或 DONT_CARE
。
offScreen renderPass, dependencies[0]
依赖的dst
方面应该是显而易见的。这只是颜色缓冲区访问。它应该匹配 loadOp
,在颜色缓冲区 CLEAR
的情况下是 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
和 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
.
现在,src
在 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
中是 VK_ACCESS_SHADER_READ_BIT
。这是在片段着色器中作为纹理访问的图像。似乎只有一个屏幕外帧缓冲区。因此,在不过多研究样本的情况下,我会假设这种依赖性确保 "main renderPass" 完成读取屏幕外缓冲区,然后再由屏幕外 renderPass 再次写入。
What is the meaning of dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL; because there is no other pass involved before the offscreen renderPass.
当然有。它是这样的:offscreen, main, offscreen, main, offscreen, main, offscreen, main, ...。因此,除非它是第一帧,否则在给定的渲染通道之前总是有 东西 。
I just found that this error is triggered because: dependency.srcSubpass > dependency.dstSubpass. Any idea?
没错。看来你想通了?
srcSubpass
和 dstSubpass
必须是 VK_SUBPASS_EXTERNAL
,或者 srcSubpass
必须小于 dstSubpass
,以免意外产生循环和死锁在依赖 DAG 中。