Vulkan 中统一缓冲区的最佳实践

Best practice for uniform buffer in Vulkan

让我先说一下我的统一缓冲方式,我在设备本地内存中有一个缓冲区,在主机相干内存中有一个(用于暂存),每个都分为帧缓冲区数部分,在每一帧中,在开始渲染通道之前,我更新位于一个的主机,然后将其复制到位于的设备,我等到命令缓冲区结束。

(假设我的 GPU 是独立的,CPU 和 GPU 之间没有共享内存)

现在我的问题:

到这里为止,我看到的每个示例代码都使用主机一致的统一缓冲区,如果您参考此类示例代码,我将不胜感激。

我很惊讶你的设备没有 HOST_VISIBLE 可以放置统一缓冲区的堆。使用 CPU 写入 GPU 从中读取的同一缓冲区通常是最佳路径,我认为所有现代 GPU 都支持该路径。

但是,如果您确实需要主机-> 设备副本,那么您要确保尽早开始副本,以便在图形管道准备好使用它们时完成副本,并使用传输-只排队做复制。这会将副本与其他早期工作重叠,因此图形管道永远不会闲置等待。为此:

  1. 将帧的制服写入主机缓冲区。
  2. 将主机->设备复制命令的命令缓冲区提交到传输队列,并在VkSubmitInfo::pSignalSemaphores中放入VkSemaphore
  3. 完成帧渲染命令缓冲区的所有剩余工作,并使用 VkSubmitInfo::pWaitSemaphores 列表中较早的信号量将它们提交到图形队列。不幸的是,由于顶点着色器中可能需要某些制服,因此 *pWaitDstStageMask 将需要 VK_PIPELINE_STAGE_VERTEX_SHADER_BIT.

如果您的 GPU 受限,希望在图形管道仍在处理 N 帧时传输 N+1 帧。您可能需要 GPUView 或 Radeon Graphics Profiler 等工具来查看是否发生这种情况正确。