Vulkan:等待栅栏后提交的工作可以读取先前提交的写入吗?

Vulkan: can work submitted after waiting on a fence read previous submit's writes?

在全面阅读 Vulkan 规范的同步语言后,我试图确认特定场景不会引入数据竞争。考虑下面的代码片段,第二个队列中的工作提交读取第一个提交的工作结果,主机在第一个提交之间的围栏上等待:

VkFence first_work_fence = ... (unsignaled);
VkSubmitInfo first_work_submit_info = ... (no semaphore wait / signal);
vkQueueSubmit(chosen_queue, 1, &first_work_submit_info, first_work_fence);     // (1)
...
vkWaitForFences(device, 1, &first_work_fence, VK_TRUE, UINT64_MAX);            // (2)
...
VkSubmitInfo reads_first_work_submit_info = ... (no semaphore wait / signal);
vkQueueSubmit(chosen_queue, 1, &reads_first_work_submit_info, ...);            // (3)

根据我对规范的阅读,以下三个步骤是正确的:

  1. 创建一个fence信号操作,这是一个内存依赖,其第一个同步范围涵盖提交命令中的所有工作,第一个访问范围涵盖设备执行的所有内存访问(spec 7.3); as an operation that performs a memory dependency, it generates an availability operation making the writes in the operation's first access scope available to the device (spec appendix B)
  2. 在栅栏上等待确保栅栏信号操作已经发生,因此根据上述使第一次提交的写入可用但不一定对设备域可见
  3. "vkQueueSubmit 执行...可见性操作,其中包含设备域的源范围和设备上所有代理和引用的目标范围。" (spec appendix B)

总而言之,这似乎意味着在 (3) 中提交的工作可以访问在 (1) 中提交的工作的所有副作用,而无需进一步同步或显式内存可见性操作(例如,屏障)。这是正确的吗?

差不多,是的。

一个好的规范应该确保人们在没有串通的情况下达成相同的解释。如果您付出了这么多努力,但仍然不确定,请在 KhronosGroup/Vulkan-Docs.

报告缺陷

为了避免 VK_KHR_vulkan_memory_model,我可能不得不调用 Host Write Ordering Guarantees,它(尽管名称)似乎包括对主机上先前 Vulkan 命令的执行依赖性,以及对设备。