如何同步`vkMapMemory`?

How to synchronize `vkMapMemory`?

vkMapMemory 状态:

vkMapMemory does not check whether the device memory is currently in use before returning the host-accessible pointer. The application must guarantee that any previously submitted command that writes to this range has completed before the host reads from or writes to that range, and that any previously submitted command that reads from that range has completed before the host writes to that region

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

基本上我需要担心两件事

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

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

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

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

一个完全通用的解决方案是跟踪 gpu 的每个内存访问,并用 begin/end 对包围每个 CPU 映射内存访问,这将在适当的栅栏上等待并调用 flush/invalidate 根据需要。这是大量的状态跟踪和过多的潜在阻塞调用。

然而,对于持久性 mesh/texture 数据,您只需将内存写入暂存缓冲区,然后复制到设备本地非主机可见缓冲区。你不应该经常需要它,所以一个单一的栅栏来跟踪它的副本是否在飞行中就足够了。或者对于只需要在单个帧(每个对象转换)中存活的数据,您可以使用环形缓冲区。回读GPU遮挡测试或计算结果,可以使用环形缓冲区。

我希望你能看到正在出现的模式。只使用几个映射的环形缓冲区,并非常注意它们何时被 gpu 使用,然后你只需要为每个环形缓冲区保留一个 vkFence+offset+size 的小数组,以确保不会发生数据危险。