Vulkan - 如何有效地将数据复制到 CPU *并*等待它

Vulkan - How to efficiently copy data to CPU *and* wait for it

假设我要执行以下命令:

cmd_buff start
dispatch (write to texture1)
copy (texture1 on gpu to buffer1 host-visible)
dispatch (write to texture2)
cmd_buff end

我想尽快知道缓冲区 1 的数据何时可用。

我的想法是有一个等待线程,我将在其上等待复制完成。我要做的是首先将上面的命令列表拆分为:

cmd_buff_1 start
dispatch (write to texture1)
copy (texture1 on gpu to buffer1 host-visible)
cmd_buff_1 end

和:

cmd_buff_2 start
dispatch (write to texture2)
cmd_buff_2 end

现在,我将使用 cmd_buff_1 和一些 fence1 调用 vkQueueSubmit,然后使用 cmd_buff_2 和 NULL fence 调用另一个 vkQueueSubmit。

在等待线程上,我将调用 vkWaitForFences( fence1 )。

这就是我对这种操作的看法。但是,我想知道这是否是最优的,是否真的有任何方法可以将直接同步仍在 cmd_buff_1 内,这样我就不需要将 cmd 缓冲区分成两个?

永远不要为了测试围栏而分解提交操作;提交操作太重量级无法做到这一点。如果 CPU 需要检查 GPU 上的工作是否已达到特定点,除了栅栏之外还有很多选择。

像这样的最简单的机制是使用事件。设置传输操作后的事件,然后在CPU上使用vkGetEventStatus,看看什么时候准备好了。这是一个轮询函数,因此等待的 CPU 线程不会在数据准备就绪时立即唤醒(但是,也不能保证非轮询函数也会发生这种情况)。

如果您可以使用时间线信号量,您可以等待它们在 CPU 上达到特定计数器值 vkWaitSemaphores。这要求您将批次分成两批,但它们可以在同一个提交命令中提交。