【发布时间】:2019-10-26 01:05:00
【问题描述】:
看vulkan spec被之前的修改搞糊涂了,看到下面更新澄清vkCmdPipelineBarrier:
如果
vkCmdPipelineBarrier记录在渲染通道实例之外, 第一个同步范围包括所有发生的命令 提交顺序较早。 如果vkCmdPipelineBarrier被记录 在渲染通道实例中,第一个同步范围 仅包括在提交顺序中较早出现的命令 相同的子通道。 在任何一种情况下,第一个同步范围都是 仅限于源确定的流水线阶段上的操作srcStageMask指定的舞台掩码。如果
vkCmdPipelineBarrier记录在渲染通道实例之外,则第二个同步范围包括所有命令 在提交顺序的后面发生。 如果vkCmdPipelineBarrier被记录 在渲染通道实例内,第二个同步范围 仅包括在提交顺序中稍后出现的命令 相同的子通道。 在任何一种情况下,第二个同步范围都是 仅限于对流水线阶段的操作由 由dstStageMask指定的目标阶段掩码。
如果我理解正确,这些陈述是不是在说:
第一个同步范围是可能的命令,用于在之前可以考虑同步的内容(来源)
第二个同步范围是在(目标)之后可以考虑进行同步的可能命令
并且唯一改变的是当在渲染通道中使用管道屏障时,其他子通道中的命令不会被考虑用于任何同步范围。
让我感到困惑的是,它的措辞让我觉得甚至可能之前的命令,在第一个同步范围没有考虑渲染通道之前。 (与 after 相同)
这些同步示例是否正确?
如果在渲染通道之外,我会执行以下操作:
1. transfer;
2. computeDispatch;
3. beginRenderPass;
...
endRenderPass;
pipelineBarrier(...);
4. computeDispatch;
5. beginRenderPass;
...
endRenderPass;
命令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;
命令 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;
命令 1,2、3.2.1、3.2.2 和 3.2.3 将在第一个同步范围内,命令 3.2.4、3.2.5、4 和 5 将在第二个同步范围内正确?换句话说,渲染通道中使用的管道屏障的同步范围是否不考虑其他子通道?只有当前的子通道?
【问题讨论】: