首页 > 解决方案 > 应该如何正确使用暂存缓冲区?

问题描述

应该如何正确使用 Vulkan API 的暂存缓冲区?因为将顶点数据保存到暂存缓冲区,而不是复制到 GPU 中的顶点缓冲区,似乎比直接将顶点提交到顶点缓冲区要花费更长的时间。这是一个 Minecraft 克隆程序,所以会有很多顶点数据(也有索引数据)和动态块加载,那么还有其他类型的缓冲区或缓冲方法可以从中受益吗?

即使这样,使用单独的设备线程甚至跨设备线程似乎也比直接将顶点直接提交到顶点缓冲区要慢。而且我目前还不清楚使用传统的直接顶点缓冲区与暂存缓冲区的优缺点。

我目前正在关注的教程在绘图和演示之前使用一次暂存缓冲区。似乎缺少讨论上述问题的论坛或文章。

标签: memory-managementbuffervulkan

解决方案


用于实现高性能的确切机制在很大程度上取决于硬件的细节数据更新的预期频率。

暂存缓冲区仅与具有多个设备内存池的 GPU 相关。集成 GPU 通常只有一个内存池,因此暂存顶点数据没有意义(由于平铺,纹理仍需要暂存)。

因此,在具有多个内存池的设备中,您需要找出的第一件事就是您的选择是什么。在多内存 GPU(又名:拥有自己内存的 GPU)中,一个或多个池将被标记为DEVICE_LOCAL. 这是为了表示对 GPU 操作具有最快访问时间的内存。

但是设备本地内存(通常)不能直接从 CPU 访问;因此需要分期。

但是,不是设备本地的内存可能能够用于 GPU 任务。也就是说,GPU 可能能够直接从 CPU 可访问的内存中读取某些类型的操作。您可以询问是否可以将特定内存类型用作顶点数据的源内存。

如果 CPU 可访问的非设备本地内存可用于顶点数据,那么您现在有一个真正的选择:从哪个池中读取?您是否通过 PCI-e 总线读取顶点数据?还是您将顶点数据传输到更快的内存,然后从中读取?

在每帧动态生成顶点数据的情况下,我可能说您应该默认不暂存(但您仍然应该在适用的硬件上对其进行分析)。

如果你在做某种数据流,当相机在场景中移动时你正在加载世界数据,那么我会说最好的做法是将其传输到设备本地内存。您使用数据的频率比执行传输操作的频率高得多,并且您应该能够在几个传输调用中转储整个数据块。

但是您的用例是关于间歇性数据生成。即使玩家不断放置块,您也可能会重复使用相同的数据来渲染多个帧。即使放置了一个块,您也只是更改了那一部分数据。每个传输操作都有一定程度的开销,所以做一堆小传输会使事情变得迟缓。

因此,很难说哪个更好。您应该在各种硬件上对其进行分析,以查看性能如何。

另外,请注意,AMD 硬件往往有一个 256MB 的特殊池,它既是 CPU 可访问的,也是设备本地的。据推测,CPU 有一些快速通道将其数据写入此设备内存。此内存池专为流式使用而设计,因此非常适合您的需求(假设 256MB 是足够的空间;所有 AMD 硬件对该池使用相同大小,而不管卡有多少 RAM)。


推荐阅读