单命令缓冲区中的同步

时间:2017-09-10 07:14:48

标签: synchronization vulkan

在我的Vulkan应用程序中,我正在使用单个命令缓冲区,我正在预先记录其中的所有内容,现在我有一个错误,其中一个我对此感到怀疑的地方,就是我复制一个区域的地方从暂存缓冲区到GPU(设备本地)缓冲区的数据,然后我在该缓冲区上执行操作。

问题是,即使我使用单个命令缓冲区,我是否应该进行同步?

我的问题不仅仅是复制缓冲区,这是一个普遍的问题,是否有任何情况,即使在单个命令缓冲区应用程序中,您应该进行同步?

2 个答案:

答案 0 :(得分:1)

在Vulkan中,你必须几乎同步一切。

这不是因为您只使用一个命令缓冲区,命令无法异步运行。

例如,假设您正在复制缓冲区,并希望将此缓冲区作为顶点缓冲区读取。

您必须从TRANSFER_STAGEVERTEX_INPUT_STAGE并使用srcAccess TRANSFER_WRITE和dstAccess VERTEX_ATTRIBUTE_READ发出内存屏障。

这样,屏障确保传输完成并且内存可用且可见。

它可能是红色的: 当第二个命令到达VERTEX_INPUT_STAGE时,请等待先前的命令完成TRANSFER_STAGE(这是执行障碍)。并刷新TRANSFER_WRITE的{​​{1}}缓存,并使TRANSFER_STAGE的{​​{1}}缓存无效(这是内存屏障)。我在这里为特定阶段使用了flush / invalidate这个词,因为某些阶段VERTEX_ATTRIBUTE_READVERTEX_INPUT_STAGE不访问内存,因此尝试对它们执行内存屏障是没用的。

但是,我读到你正在使用一个临时缓冲区,当你写入你的临时缓冲区时,来自HOST的memoryBarrier是由提交命令缓冲区产生的。但是,如果您不使用COHERENT内存,则必须使用TOP

一个好主意可能是在使用数据之前使用屏障:

BOTTOM

您可以获得更多信息here

答案 1 :(得分:0)

  

即使我使用单个命令缓冲区,我是否应该进行同步?

我很想说一句话答案:"是"。

即使使用单个缓冲区(或通常是队列),也需要进行同步,因为命令缓冲区中的命令允许在执行时重叠。您需要同步对资源VkImage s,VkBuffer及其内存的访问权限。您通常使用管道障碍来执行此操作,这会在队列中某些命令的子操作之间添加执行依赖内存依赖

您可能在应用中使用了交换链。没有"演示管道"要与管道障碍同步,因此必须使用信号量进行同步。

最后,您仍然需要与主机(CPU)同步。您不能销毁仍在使用的句柄(并且您最终需要销毁/清除)。您必须使用 fences 或类似围栏的vkDeviceWaitIdle()同步来确保它们未被使用。

让我们不要忘记(一如既往)您需要同步CPU线程。要在Vulkan中具体说明,您仍需要在传递给命令的参数周围同步/互斥。

只有少数例外,您不必进行某种显式同步。例如,只要在调用vkQueueSubmit之前发生一致(或刷新),就不需要同步主机(CPU)写入。