OpenGL 和 DirectX 12 中的 GPU 内存管理

GPU Memory Management in OpenGL and DirectX 12

我目前正在提高我在 OpenGL 和 DirectX 12 方面的知识,以便使用这两种 API 创建图形应用程序。看了好几篇教程还是不太明白GPU端是怎么管理内存的。

在 OpenGL 中(我的应用程序运行 OpenGL 3.3 上下文),帧缓冲区是隐式创建的,所以我假设它们也被 API 隐式释放。在我的示例程序中,我使用 glGenBuffers 创建了顶点和索引缓冲区,并使用 glBufferData 将它们上传到 GPU。如果我想在每一帧更新我的顶点缓冲区,我可以简单地使用 glBufferSubData 来完成。让我们假设,我想使用 glBufferData 在每一帧重新上传我的顶点缓冲区。根据 OpenGL 文档,此函数创建并初始化缓冲区在 GPU 上的数据存储。所以我假设,映射到这个 VBO 的 GPU 内存在下一帧中再次调用 glBufferData 后被重用。

在 DirectX 12 中,帧缓冲区必须由图形程序员创建。这些在程序的生命周期内由交换链管理和重用。在我的 DirectX 12 测试程序中,我还使用上传堆和 ID3D12Device::CreateCommittedResource 函数创建顶点和索引缓冲区。为了测试目的,我也在每一帧都这样做。缓冲区存储在 Microsoft::WRL::ComPtr<ID3D12Resource> 个变量中。在 render 方法结束时,这些缓冲区指针的使用计数应该达到 0,这将释放 CPU 侧后面的内存。不过,我不明白,GPU 端的数据和底层堆会发生什么情况。它们是否被释放,每当缓冲区指针的使用计数达到0时,它们是否需要手动释放,它们是否在到达栅栏时被GPU丢弃或none。

如果您能就此主题和我的假设提供一些说明,我将不胜感激。

图形程序员是否需要以及如何释放 GPU 数据,能否请您也提供解释。

此致。

对于 DirectX 12,它使用与以前版本的 Direct3D 相同的生命周期模型:对象一直保持活动状态,直到引用计数达到 0。然后它才有资格销毁。清理的确切时间取决于 driver/runtime,因为它通常会 'delayed destruction'(它实际上有一个 'internal' 和 'external' 引用计数,并且两者都必须在之前为 0它确实有资格销毁)。

Microsoft Docs

You should watch this YouTube video if you want an overview of the underlying details.