5

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

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

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

4

3 回答 3

7

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

出于技术原因(参见上面 t.niese 的评论)和意识形态原因(“你不需要知道,你不想知道”),OpenGL 内存管理是模糊的。尽管存在供应商扩展(例如 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);是一个众所周知的习惯用法。这只会影响您对对象的看法,并且它允许驱动程序继续并行使用旧对象只要因为它需要。

于 2013-05-31T11:41:11.647 回答
3

我的评论中有一些不适合的附加信息。

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

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

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

如果您查看 OpenGL 的演变以及哪些功能已被弃用,您会发现它们倾向于删除除显卡、驱动程序和系统可以最好地完成的真正需要的功能之外的所有功能。其他一切都取决于用户自己实现以获得最佳性能。(例如,您自己创建投影矩阵以将其传递给着色器,因此 OpenGL 甚至不知道对象在场景中的放置位置)。

于 2013-05-31T11:10:48.723 回答
3

这是我的 TL;DR 答案,我建议您也阅读 Daemon 和 t.niese 的答案:

OpenGL 驱动程序/服务器能比显卡保存更多的数据吗?

是的

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

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

于 2013-05-31T12:59:52.990 回答