Vulkan 管道顶部/底部和 ALL_COMMANDS

Ant*_*ier 5 vulkan

作为很多“初学者”,我认为使用 TOP_OF_PIPELINE 作为 dst 和 BOTTOM_OF_PIPELINE 作为 src 意味着两者的 ALL_COMMANDS 。

Nicol Bolas在这里写道,“由于管道的顶部/底部对内存屏障没有意义,也许使用它们应该完全无效。因此仅对执行屏障有用。”

据我了解,由于 TOP 和 BOTTOM 不执行任何对内存的访问,因此将屏障放在顶部或底部不能使内存可见^^。

据我了解 Nicol Bolas 的含义以及我刚才所说的内存访问/可见性,当您使用底部或顶部时,必须将 accessMask 设置为 0。

如果我想呈现图像,我可以这样做:

srcStage = COLOR_ATTACHMENT_OUTPUT_BIT
srcAccess = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
oldLayout = ATTACHMENT_OPTIMAL
dstStage = BOTTOM
dstAccess = 0; // Since memory read access will be "issued" by semaphore
newLayout = PRESENT_KHR;
Run Code Online (Sandbox Code Playgroud)

我们在这里使用底部是因为我们不希望内存屏障使当前队列等待,如规范中所述:

当下一个访问将在不同的队列中或由表示引擎完成时,VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT 对于完成内存屏障和布局转换很有用;在这些情况下,同一队列中的后续命令不需要等待,但屏障或转换必须在与批处理信号关联的信号量之前完成。

所以现在,我可以说(我希望...)我了解何时使用每个阶段,但 TOP_OF_PIPE nop...

所以,我的问题是:执行屏障到底是什么(因此没有内存屏障)?它们为什么有用?(因为说一个操作一个接一个地发生很好,但最好说我们可以在第二个操作中使用第一个操作中产生的数据)。什么时候应该在管道底部或顶部放置屏障?

谢谢 !

Nic*_*las 4

执行屏障到底是什么(因此没有内存屏障)?

这正是规范所说的:它会阻止操作的执行,直到先前发出的操作完成为止。

它们为什么有用?(因为说一个操作一个接一个地发生很好,但最好说我们可以在第二个操作中使用第一个操作中产生的数据)。

您假设消耗数据是您可能等待的唯一事情。

例如,假设您正在传输一些纹理数据。嗯,在该纹理的所有使用完成之前,您无法开始执行到该纹理内存的复制。但你并没有消耗这些过程所产生的东西;而是消耗了这些过程所产生的东西。您只需要等待这些过程完成即可。

这就是纯粹的执行障碍的用途。


由于1.0.35已经明确了管道的含义,因此TOP和BOTTOM的含义更加明确。

具体说明是,无论您为源和目标指定哪个管道阶段,都指定该阶段及其之前/之后的所有阶段。因此,如果您指定片段着色器作为源,那么在它之前执行的所有阶段也是该屏障的一部分。如果您指定顶点着色器作为目标,那么它之后的所有阶段也将在同步后执行。

因此,BOTTOM 作为源意味着在先前命令的所有阶段之后。TOP 作为目标意味着在后续命令的所有阶段之前。BOTTOM 作为目的地没有任何实际意义,TOP 作为源也没有实际意义。


注意:最近的规格更改已澄清顶部/底部...根本不是实际阶段。叹。

相反,这些“阶段”被指定为“所有阶段”或“无阶段”,具体取决于它们是指定源范围还是目标范围。TOP 表示作为目标作用域时的所有阶段,而 BOTTOM 表示作为源作用域时的所有阶段。

基本上,它的含义与之前相同,但在 Vulkan 执行模型中没有任何特定的想法,即有一个阶段是所有阶段的开始。

  • @damix911 这实际上很有道理;规范:“`VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT` 和 `VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT` 在通过其他方式满足所需的执行依赖性时(例如,队列之间的信号量操作)可用于完成布局转换和队列所有权操作。” 相反,这是没有意义的,为了代码清晰起见,应该使用“ALL_COMMANDS”。 (3认同)