关于OpenGL内存管理的困惑

时间:2013-05-31 10:08:04

标签: opengl

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

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

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

3 个答案:

答案 0 :(得分:7)

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

OpenGL内存管理模糊不清,无论是出于技术原因(参见上面的t.niese评论)还是出于意识形态原因(“你不需要知道,你不想知道”)。虽然存在供应商扩展(例如ATI_meminfo),但您可以查询某些非授权数字(非授权,因为它们可以更改下一毫秒,并且它们不会考虑碎片等影响)

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

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

通常,但不一定,您消耗的系统内存也与GPU内存一样多(不知道,驱动程序会秘密地执行此操作)。由于驱动程序根据需要交换资源,因此需要维护副本。有时,需要保留2或3个副本(例如,在流式传输或ARB_copy_buffer操作时)。有时,映射缓冲区对象是特殊分配块中的另一个副本,有时您可以直接写入驱动程序的内存。 另一方面,PCIe 2.0(以及PCIe 3.0甚至更多)足以从主内存流式传输顶点,因此您甚至不需要GPU内存(小缓冲区除外)。有些驱动程序会直接从系统内存中传输动态几何体。

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

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

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

答案 1 :(得分:3)

我的评论的其他一些信息不适合那里。

为什么这不是OpenGL的一部分有不同的原因。

系统/驱动程序猜测哪些资源是必需的并不是一件容易的事。如果经常或很少需要资源,那么驱动程序肯定可以创建一个内部启发式(就像CPU为 if语句执行并在该猜测上执行预执行代码某些代码部分)。但GPU将不知道(不知道应用程序代码)接下来需要什么资源。它甚至不知道几何图形在场景中的位置(因为你在模型中执行此操作并查看自己传递给着色器的martix)

如果你是有一个游戏,你可以通过一个场景,你通常不会渲染视图外的部分。因此GPU可以认为不再需要这些资源,但如果你转过身,那么所有这些纹理和几何都需要再次需要从系统内存移动到 gpu内存,这可能导致非常糟糕的性能。但是游戏引擎本身由于使用了八叉树(或类似的技术)和可以走的可能路径,因此可以深入了解场景以及哪些资源可以从GPU中移除,哪一个可以移动到播放时的GPU以及显示加载屏幕所需的位置。

如果你看一下OpenGL的演变以及哪些功能被弃用,你会看到它们会去除除了图形卡,驱动程序和系统可以做到的最佳功能之外的所有功能。其他所有事情都取决于用户自己实现以获得最佳性能。 (例如,您自己创建投影矩阵以将其传递给着色器,因此OpenGl甚至不知道对象在场景中的位置)。

答案 2 :(得分:3)

这是我的TL; DR答案,我建议阅读守护进程和t.niese的答案:

  

OpenGL驱动程序/服务器可以保存比视频卡更多的数据吗?

  

说,我有足够的视频RAM来容纳10个纹理。我是否可以要求OpenGL分配15个纹理而不会出现GL_OUT_OF_MEMORY错误?

是。根据驱动程序/ GPU的组合,甚至可以分配超出GPU内存的单个纹理,并实际使用它进行渲染。在我目前的职业中,我利用这个事实从大体积数据集中提取任意方向和几何切片,使用着色器在原位体素数据上应用滤波器。效果很好,但不适用于交互式帧速率。