Vulkan:并发主机写入和设备读取以分离相同VkMemory的部分

时间:2017-01-18 22:47:34

标签: multithreading memory vulkan memory-mapping

要将我的静态数据传输到GPU,我正在考虑使用单个暂存VkMemory对象(球场64MB),并将其用作旋转队列。但是,我有多个线程产生内容(例如:渲染字形,加载文件,程序),如果他们可以完全自己上传他们的数据,我会喜欢它(即写提交Vulkan传输命令)

我打算至少在加载过程中保持整个暂存VkMemory永久映射(如果这是愚蠢的请说)(但如果我想流式传输数据,可能会更长)。

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

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

AFAIK我还需要使用图像内存屏障来从VK_IMAGE_LAYOUT_PREINITIALIZED过渡到VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL。

我无法在规范中找到任何明确说明这是合法或非法的内容,只需要注意确保同步。但是,我没有找到足够的细节来确定这种或那种方式。

注意:登台队列需要确保在覆盖任何内容之前完成转移 - 我打算为此保留一个免费的VkFences队列。

问题:

  1. 这样可以吗?
  2. 我是否需要将每个单独的对象与页面边界对齐?或者别的什么。
  3. 我是否正确假设图像内存屏障(上图)不需要设备到暂存内存。

1 个答案:

答案 0 :(得分:1)

  1. 是的,关于要读取和写入的区域的规范必须同步。

  2. 如果内存不连贯,那么您必须将正在读取或写入的块对齐到NonCoherentAtomSize

  3. 来源:Vulkan spec under the note after the declaration of vkMapMemory

      

    vkMapMemory不检查设备内存当前是否存在   在返回主机可访问指针之前使用。应用程序必须   保证任何先前提交的命令写入此   范围在主机读取或写入之前已完成   范围,以及从中读取的任何先前提交的命令   范围已在主机写入该区域之前完成(请参阅此处   有关履行此类保证的详细信息)。如果设备内存是   这些是在没有VK_MEMORY_PROPERTY_HOST_COHERENT_BIT集的情况下分配的   必须保证扩展范围:应用程序必须   将范围的开头向下舍入到最接近的倍数   VkPhysicalDeviceLimits :: nonCoherentAtomSize,并绕过结束   范围最大的倍数   VkPhysicalDeviceLimits :: nonCoherentAtomSize。

    1. 布局转换可能会写入内存但是屏障会针对之前和之后的内存访问进行自己的同步。