Multithreading Vulkan:并发主机写入和设备读取到同一VkMemory的不同部分

Multithreading Vulkan:并发主机写入和设备读取到同一VkMemory的不同部分,multithreading,memory,vulkan,memory-mapping,Multithreading,Memory,Vulkan,Memory Mapping,为了将静态数据传输到GPU,我考虑使用一个staging VkMemory对象(ballpark 64MB),并将其用作循环队列。但是,我有多个线程生成内容(例如:渲染图示符、加载文件、过程),我希望它们能够完全自己上传数据(即写加提交Vulkan传输命令) 我打算至少在加载期间永久映射整个staging VkMemory(如果这是哑的,请这样说)(但如果我想流式传输数据,可能会更长) 为了实现上述目标,一旦线程的数据完全写入/刷新到staging,我希望它能够立即提交GPU传输命令 但是,这意

为了将静态数据传输到GPU,我考虑使用一个staging VkMemory对象(ballpark 64MB),并将其用作循环队列。但是,我有多个线程生成内容(例如:渲染图示符、加载文件、过程),我希望它们能够完全自己上传数据(即写加提交Vulkan传输命令)

我打算至少在加载期间永久映射整个staging VkMemory(如果这是哑的,请这样说)(但如果我想流式传输数据,可能会更长)

为了实现上述目标,一旦线程的数据完全写入/刷新到staging,我希望它能够立即提交GPU传输命令

但是,这意味着GPU将读取VkMemory的一部分,而其他线程可能正在写入/刷新它

AFAIK I还需要使用图像内存屏障从VK_图像布局预初始化转换为VK_图像布局传输SRC_优化

我在规范中找不到任何明确表示这是合法的或非法的内容,只是应该注意确保同步。然而,我没有找到足够的细节来确定这一点

注意:暂存队列需要确保在覆盖任何内容之前已完成传输-我打算为此保留一个免费的VkFences队列


问题:

  • 这样行吗
  • 是否需要将每个单独的对象与页面边界对齐?或者别的什么
  • 我是否正确地假设图像内存屏障(如上)不需要设备写入暂存内存
  • 是的,规范中提到读取和写入的区域必须同步

  • 如果内存不一致,则必须将读取或写入的块对齐到
    非一致大小

  • 资料来源:

    vkMapMemory不检查设备内存当前是否在内存中 在返回主机可访问指针之前使用。应用程序必须 确保以前提交的任何写入此文件的命令 在主机读取或写入该范围之前,该范围已完成 范围,以及以前提交的任何从该范围读取的命令 范围在主机写入该区域之前已完成(请参见此处 有关履行此类担保的详细信息)。如果设备内存是 在没有设置
    VK\u MEMORY\u PROPERTY\u HOST\u COHERENT\u位的情况下分配,这些
    必须保证扩展范围:应用程序必须
    将范围的起点向下舍入到最接近的整数倍
    VkPhysicalDeviceLimits::非相干大小,并在
    范围最接近以下各项的倍数:
    VkPhysicalDeviceLimits::非相干大小

  • 布局转换可能会写入内存,但屏障会自行同步先前和后续的内存访问
  • “为了实现上述目标,一旦线程的数据完全写入/刷新到登台,我希望它能够立即提交GPU传输命令。”我强烈建议不要这样做。将GPU命令提交到队列(即使只是副本)是一项繁重的操作。最好是对命令进行批处理,并在帧结束时一次性提交所有命令。一个好的多编写器并发队列就足以实现这一目的。