首页 > 解决方案 > Vulkan 中统一缓冲区的最佳实践

问题描述

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

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

现在我的问题:

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

标签: synchronizationvulkan

解决方案


我很惊讶你有一个没有 HOST_VISIBLE 堆的设备,可以在其中定位统一缓冲区。使用 CPU 写入 GPU 读取的同一个缓冲区通常是最好的路径,我认为所有现代 GPU 都支持这一点。

但是,如果您确实需要主机->设备副本,那么您要确保足够早地启动副本,以便在图形管道准备好使用它们时完成它们,并使用仅传输队列来完成副本。这将使副本与其他早期工作重叠,因此图形管道永远不会闲置等待它。要做到这一点:

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

如果您受 GPU 限制,希望帧 N+1 的传输发生在图形管道仍在帧 N 上工作时。您可能需要 GPUView 或 Radeon Graphics Profiler 之类的工具来查看这是否正常发生。


推荐阅读