【问题标题】:Vulkan TOP/ BOTTOM OF PIPE and ALL_COMMANDSVulkan 顶部/管道底部和 ALL_COMMANDS
【发布时间】:2021-10-11 13:21:55
【问题描述】:

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

HereNicol 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;

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

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

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

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

谢谢!

【问题讨论】:

    标签: vulkan


    【解决方案1】:

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

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

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

    您假设消费数据是您唯一可能等待的东西。

    例如,假设您正在流式传输一些纹理数据。好吧,在该纹理的所有使用完成之前,您不能开始将副本执行到该纹理的内存中。但是您并没有消耗这些进程正在生成的东西;你只需要等到这些过程完成。

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


    自从1.0.35明确了管道的含义后,TOP和BOTTOM的含义就更加清晰了。

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

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


    注意:最近的规范更改已阐明顶部/底部到...根本不是实际阶段。叹息。

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

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

    【讨论】:

    • 好吧,在你回答之前真的是我没看懂!但是你有管道顶部的例子吗???
    • 对于一个仅用于转移队列所有权的简单管道屏障,通过栅栏完成同步,目的地是什么重要吗?图形队列可能被其他命令使用,所以我认为在这里使用 BOTTOM 作为目的地可能是有意义的(因为我没有依赖项,而且我无论如何都在等待栅栏)。例如:vkCmdPipelineBarrier(..., [src] TRANSFER, [dst] BOTTOM, ... , bufferMemBarrier, ...); BOTTOM 作为目的地是有道理的,还是我弄错了?
    • @Selmar:不,目的地总是很重要。目的地告诉系统哪些操作需要等待队列所有权的转移,哪些流水线操作可以访问现在转移的内存。如果你说“BOTTOM”,那么你说“没有”会等待它,没有任何东西可以访问它。
    • “BOTTOM 作为目的地没有实际意义,TOP 作为源也没有”。 @Nicol 谢谢,这正是我希望听到的,但 LunarG 教程似乎确实讲述了一个不同的故事。见:vulkan.lunarg.com/doc/sdk/1.1.82.1/windows/tutorial/html/…你对此有什么见解吗?会不会是他们在 src/dst 和/或 top/bottom 之间搞混了?请注意,他们似乎犯了两次相同的“错误”;在vkQueueSubmit 和他们使用vkCmdPipelineBarrier 的某种替代场景中。
    • @damix911 这真的很有意义;规范:“VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BITVK_PIPELINE_STAGE_TOP_OF_PIPE_BIT 在通过其他方式(例如队列之间的信号量操作)满足所需的执行依赖性时,对于完成布局转换和队列所有权操作很有用。”反之则没有意义,为了代码清晰,应该在那里使用ALL_COMMANDS
    猜你喜欢
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-20
    • 1970-01-01
    相关资源
    最近更新 更多