如何同步`vkMapMemory`?

Mai*_*ein 4 multithreading vulkan

vkMapMemory指出:

vkMapMemory 在返回主机可访问指针之前不会检查设备内存当前是否正在使用。应用程序必须保证任何先前提交的写入此范围的命令在主机读取或写入该范围之前已完成,并且任何先前提交的从该范围读取的命令在主机写入该区域之前已完成

它链接到这个网站,遗憾的是该网站似乎还不存在。我想知道如何同步这个?

基本上我需要担心两件事

  • 只有1个线程同时访问同一个范围
  • Gpu 当前未尝试读取范围

我认为同步的唯一真正方法是使用线程安全列表。每次您想要向该缓冲区写入/读取时,您都必须将当前尝试读取或写入的内存范围添加到该线程安全列表中。

这意味着当您想要访问该缓冲区时,您需要锁定该列表并搜索您尝试访问的范围。

这是您同步的方式vkMapMemory还是有其他方法可以做到这一点?

rat*_*eak 5

GPU 唯一尝试访问映射内存的时间是当访问该内存的命令缓冲区已提交时。该内存将一直使用,直到相关联的vkFence信号发出为止。

一个完全通用的解决方案是跟踪 GPU 的每个内存访问,并用开始/结束对包围每个 CPU 映射的内存访问,该开始/结束对将等待适当的栅栏并根据需要调用刷新/无效。这是大量的状态跟踪和大量潜在的阻塞调用。

但是,对于持久性网格/纹理数据,您只需将内存写入暂存缓冲区,然后复制到设备本地非主机可见缓冲区。您不应该经常需要这样做,因此一个围栏来跟踪其中的副本是否正在运行就足够了。或者,对于仅需要保留单个帧(每个对象转换)的数据,您可以使用环形缓冲区。读回 GPU 遮挡测试或计算结果,可以使用环形缓冲区。

我希望你能看到这种模式的出现。仅使用一些映射的环形缓冲区,并非常清楚 GPU 何时使用它们,然后您只需要为每个环形缓冲区保留一小部分 vkFence+offset+size 即可确保不会发生数据危险。