whn*_*whn 2 synchronization vulkan
纵观Vulkan的规格由以前的版本被混淆后,我看到了下面的更新说明vkCmdPipelineBarrier:
如果
vkCmdPipelineBarrier记录在渲染通道实例之外,则第一个同步范围包括所有在提交顺序中较早出现的命令。如果vkCmdPipelineBarrier记录在渲染通道实例中,则第一个同步范围仅包括在同一子通道内按提交顺序较早出现的命令。在任何一种情况下,第一个同步范围都限于对由 指定的源阶段掩码确定的流水线阶段的操作srcStageMask。如果
vkCmdPipelineBarrier记录在渲染通道实例之外,则第二个同步范围包括按提交顺序稍后发生的所有命令。如果vkCmdPipelineBarrier记录在渲染通道实例中,则第二个同步范围仅包括在同一子通道内按提交顺序稍后出现的命令。在任何一种情况下,第二个同步范围都限于对由 指定的目标阶段掩码确定的流水线阶段的操作dstStageMask。
如果我理解正确,这些陈述是否是在说:
第一个同步范围是可能的命令,用于之前可以考虑进行同步的内容(来源)
第二个同步范围是在(目标)之后可以考虑进行同步的可能命令
唯一改变的是,当渲染通道中使用管道屏障时,其他子通道中的命令不会被考虑用于任何同步范围。
我感到困惑的是它的措辞方式让我认为甚至可能是以前的命令,在渲染通道不被考虑用于第一个同步范围之前。(与第二个相同)
这些同步示例是否正确?
如果在渲染通道之外,我会执行以下操作:
1. transfer;
2. computeDispatch;
3. beginRenderPass;
...
endRenderPass;
pipelineBarrier(...);
4. computeDispatch;
5. beginRenderPass;
...
endRenderPass;
Run Code Online (Sandbox Code Playgroud)
命令1、2、3在pipelineBarrier同步之前会考虑,即在第一同步范围内,命令4、5会在之后考虑,即第二同步范围。
如果我有以下命令列表:
1. transfer;
2. computeDispatch;
3. beginRenderPass;
3.1 next subpass;
3.1.1 bindPipeline;
3.1.2 bindDescriptor;
3.1.3 bindVertexBuffer;
pipelineBarrier(...);
3.1.4 bindIndexBuffer;
3.1.5 drawIndexed;
endRenderPass;
4. computeDispatch;
5. beginRenderPass;
...
endRenderPass;
Run Code Online (Sandbox Code Playgroud)
命令 1、2、3.1.1、3.1.2 和 3.1.3 将在第一个同步范围内,而 3.1.4 和 3.1.5、4、5 将在第二个同步范围内。
最后粗体部分的文字是说,如果我执行以下操作:
1. transfer;
2. computeDispatch;
3. beginRenderPass;
3.1 first subpass;
3.1.1 bindPipeline;
3.1.2 bindDescriptors;
3.1.3 bindVertexBuffer;
3.1.4 draw;
3.2 next subpass;
3.2.1 bindPipeline;
3.2.2 bindDescriptor;
3.2.3 bindVertexBuffer;
pipelineBarrier(...);
3.2.4 bindIndexBuffer;
3.2.5 drawIndexed;
3.3 next subpass;
3.3.1 bindPipeline;
3.3.2 bindDescriptors;
3.3.4 draw;
endRenderPass;
4. computeDispatch;
5. beginRenderPass;
...
endRenderPass;
Run Code Online (Sandbox Code Playgroud)
命令 1,2, 3.2.1, 3.2.2, 和 3.2.3 将在第一个同步范围内,命令 3.2.4, 3.2.5, 4, 5 将在第二个同步范围内,对吗?换句话说,渲染通道中使用的管道屏障的同步范围不考虑其他子通道?只有当前的子通行证?
我感到困惑的是它的措辞方式让我认为甚至可能是以前的命令,在渲染通道不被考虑用于第一个同步范围之前。
他们不被考虑。直接。
子通道中的管道屏障将在子通道内的命令之间创建依赖关系。子通道依赖关系创建子通道之间的依赖关系。外部子通道依赖关系在子通道和渲染通道之前/之后的命令之间创建依赖关系。
如果子通道 1 在子通道 0 完成之前无法开始执行(因此它们之间存在依赖性),则子通道 1 中的任何命令都可以假设子通道 0 已完成。这包括障碍。所以这使得依赖项具有可传递性;子通道 1 中屏障之后的内容可以假设子通道 0 已完成,因为子通道 1 中的所有内容都可以做出该假设。类似地,子通道中的命令(如屏障)将依赖于子通道直接或间接依赖的任何外部依赖项。
现在,因为依赖是基于特定的阶段,传递性只适用于依赖链包括实际相互依赖的阶段。