【问题标题】:Best practice for uniform buffer in VulkanVulkan 中统一缓冲区的最佳实践
【发布时间】:2018-11-07 08:23:22
【问题描述】:

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

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

现在我的问题:

  • 这是管理统一缓冲区并在每帧中进行暂存和复制的最佳方式吗?
  • 确实,我知道我使用的同步机制,不行,最好的方法是什么?
  • 如果您的答案是进行屏障同步,那么执行此操作的确切方法是什么? (因为我没有见过这样的样本。)

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

【问题讨论】:

标签: synchronization vulkan


【解决方案1】:

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

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

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

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

【讨论】:

  • 统一的主机可见性我的意思是github.com/SaschaWillems/Vulkan/blob/… 所以你说这是创建/使用统一缓冲区的最佳方式?
  • “可能影响性能”注释可能是指使用 HOST_COHERENT 标志。如果你不使用 HOST_COHERENT 内存类型,你需要在写入缓冲区之后使用 vkFlushMappedMemoryRanges,在 GPU 开始使用它之前(通常是在 vkQueueSubmit 之前,尽管你可以在提交后使用栅栏来完成一个理由)。您的使用模式足够常规,使用 vkFlushMappedMemoryRanges 可能不会太不方便。
猜你喜欢
  • 2021-05-03
  • 2018-03-23
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-04
  • 1970-01-01
相关资源
最近更新 更多