opengl - OpenGL 中内存管理的困惑

标签 opengl

我问这个问题是因为我不想花时间编写一些重复 OpenGL 驱动程序功能的代码。

OpenGL 驱动程序/服务器能否容纳比显卡更多的数据?假设我有足够的视频 RAM 来容纳 10 个纹理。我可以要求 OpenGL 分配 15 个纹理而不出现 GL_OUT_OF_MEMORY 错误吗?

如果我可以依靠驱动程序在需要时巧妙地将纹理/缓冲区/对象从“普通”RAM 发送到视频 RAM,那么我真的不需要自己生成/删除这些对象。我受到“普通”RAM 的限制,与视频 RAM 相比,它通常很充足。

最佳答案

“内存充足,所以我不需要删除”的方法是不好的,而“内存充足,所以我永远不会出现内存不足错误”的方法是有缺陷的。

OpenGL 内存管理很晦涩,既有技术原因(参见上面 t.niese 的评论),也有意识形态原因(“你不需要知道,你不想知道”)。尽管存在供应商扩展(例如 ATI_meminfo),可以让您查询一些非权威数字(非权威,因为它们可以改变下一毫秒,并且它们不考虑碎片等影响) .

一般来说,在大多数情况下,您可以使用比 GPU 内存更多的内存的假设是正确的。

但是,您通常无法使用所有可用内存。更有可能的是,由于驱动程序可以分配、锁定和传入/传出哪些内存区域(以及多大的区域)的限制,存在远低于“所有可用 RAM”的限制。即使您通常可以使用比 GPU 适合的内存更多的内存(即使您专门使用它),但这并不意味着粗心的分配不能也不会最终会失败。

通常,但不一定,您消耗的系统内存也与 GPU 内存一样多(驱动程序在不知情的情况下 secret 地这样做)。由于驱动程序根据需要交换资源,因此它需要维护一个副本。有时,有必要保留 2 或 3 个副本(例如,当流式传输或用于 ARB_copy_buffer 操作时)。有时,映射缓冲区对象是专门分配的 block 中的另一个副本,有时您可以直接写入驱动程序的内存。 另一方面,PCIe 2.0(以及 PCIe 3.0 更是如此)足够快,可以从主内存传输顶点,因此您甚至不需要严格需要 GPU 内存(除了一个小缓冲区)。有些驱动程序会立即从系统内存中传输动态几何图形。

某些 GPU 甚至没有单独的系统和 GPU 内存(Intel Sandy Bridge 或 AMD Fusion)。

此外,您应该注意删除对象并不一定会删除它们(至少不会立即删除)。通常,除了极少数异常(exception),删除 OpenGL 对象只是暂时删除,它会阻止您进一步引用该对象。只要需要,驱动程序就会使对象保持有效。

另一方面,您确实应该删除不再需要的内容,而且应该尽早删除。例如,您应该在将着色器附加到程序对象后立即将其删除。这可以确保您不会泄漏资源,并且保证可以正常工作。流式传输时删除并重新指定正在使用的顶点或像素缓冲区(通过调用 glBufferData(... NULL); 是众所周知的习惯用法。这只会影响您对对象的 View ,并且它允许驱动程序根据需要继续并行使用旧对象。

关于opengl - OpenGL 中内存管理的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16854825/

相关文章:

opengl - 是否可以通过模型 View 或投影矩阵弯曲或扭曲 OpenGL 空间?

opengl - 不能同时使用立方体贴图和 2D 纹理

opengl - 在 opengl 纹理中加载带有 alpha channel 的 opencv::mat 图像

opengl - 分割如何提高性能?

java - 多个纹理绑定(bind)到单个 VBO 并使用着色器渲染 (LWJGL)

c++ - 为什么 blender .obj 文件中 vt 和 v 元素的数量不同?

c++ - OpenGL 对多个纹理感到困惑

c++ - 加载的对象模型闪烁并使应用程序崩溃

c++ - 从 3d 对象开始

java - 我想在 LWJGL 中围绕它的中心旋转一个 Sprite