Vulkan多读写场景下RenderPass A/B/C的最大并行同步方案
RenderPass A、B、C的最大并行实现方案
问题背景
我们按顺序提交三个RenderPass:
- A:将图像I作为颜色附件写入;
- B:在片元着色器中采样读取I;
- C:在顶点着色器中采样读取I;
- B与C之间无任何依赖关系。
请问是否存在可行方案实现三者的最大并行?
已尝试的两种方案及问题
方案一:单屏障同步A与B、C
在A和B之间插入屏障b1,参数如下:
b1.srcStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT b1.dstStage = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT b1.srcAccess = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT b1.dstAccess = VK_ACCESS_SHADER_READ_BIT b1.srcLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL b1.dstLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
提交顺序:A → b1 → B → C
问题:虽然能保证A的写入对B、C的顶点阶段可见,但b1会强制B的顶点阶段等待A完全结束,浪费了并行空间。
方案二:拆分屏障但引入冗余依赖
将b1的dstStage改为VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT(记为b1'),仅同步A与B的片元阶段;为了让C的顶点阶段读到正确数据,在B和C之间插入屏障b2:
b2.srcStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT b2.dstStage = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT // B未修改I,仅用执行屏障同步
提交顺序:A → b1' → B → b2 → C
问题:允许B的顶点阶段与A并行,但b2毫无必要地让C的顶点阶段等待B的片元阶段,阻碍了B、C之间的并行。
最优并行方案:独立同步A到B、C,并行提交B和C
存在最优方案,核心是只建立A到B、A到C的内存依赖,完全避免B和C之间的任何执行依赖,具体步骤:
- 提交RenderPass A;
- 插入一个覆盖所有需要读取I的阶段的内存屏障,将图像I的布局从
COLOR_ATTACHMENT_OPTIMAL转换为SHADER_READ_ONLY_OPTIMAL,确保A的写入对后续读操作可见:barrier.srcStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT barrier.dstStage = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT barrier.srcAccess = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT barrier.dstAccess = VK_ACCESS_SHADER_READ_BIT barrier.srcLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL barrier.dstLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL - 并行提交RenderPass B和C(无需在两者间插入任何屏障)。
效果:这个屏障同时保证了B的片元阶段和C的顶点阶段能读到A写入的正确数据;由于B、C无依赖,并行提交后,它们的顶点阶段、片元阶段都能尽可能并行执行,包括B的顶点阶段与A的后期操作并行、C的顶点阶段与B的片元阶段并行,达到最大并行度。
内容的提问来源于stack exchange,提问作者HandsonicV4 Lee
相关产品推荐
相关产品推荐

