opengl 驱动程序如何在有限的 VRAM 中处理大型纹理阵列

How well do opengl drivers handle large texture arrays in limited VRAM

我的游戏引擎尝试分配大型纹理数组,以便能够将大部分(如果不是全部)绘制在一起。该数组可能变得足够大而无法分配,此时我会(不断)将纹理数组分成两半。

在收到 glGetError:Out of memory 之前突破界限并从那里缩减是否是糟糕的设计?

我的应用程序是否因为分配了大量的 VRAM 而出现问题,这可能需要交换到 GTT 内存中?比如,在处理其他 OS 操作时,图形驱动程序是否不太理想地处理一些大型纹理数组而不是许多单独的纹理?

很难评估 driver 处理大型纹理数组的能力。不同 driver 的行为可能会有很大差异。

虽然使用纹理数组可以通过减少绘制调用次数来提高性能,但这不应该是主要目标。减少绘图调用在移动平台上有些重要,即使在那里,几十个也不是问题。我不确定您的顾虑以及您究竟尝试优化什么,但我建议在进行任何优化之前使用 GPU 供应商的分析工具。

Is it bad design to push the boundaries until receiving a glGetError:Out of memory and scale back from there?

这是将数据动态加载到 GPU 时通常执行的操作。收到错误后,应卸载旧数据以加载新数据。

Is my application a jerk because it's allocating huge chunks of VRAM, which may require swapping into GTT memory?

无法检查数据是否已交换到 GTT(如果 driver 完全支持 GTT)。 driver 自行处理,无法从 OpenGL API 访问它。如果您使用的是 NVidia 的 GPU,则可能需要使用像 Nsight 这样的分析工具。

但是,如果您打算拥有一个巨大的纹理阵列,它必须作为一个整体放入 VRAM,不能部分放入 VRAM 和 GTT。我根本不建议依赖 GTT。

它必须适合 VRAM,因为当您绑定它时,driver 无法预先知道哪些层将被使用,哪些不会,因为选择发生在着色器中。

尽管纹理数组和 3dtexture 在概念上有所不同,但在硬件级别它们的工作方式非常相似,不同之处在于第一个使用二维过滤,第二个使用三维过滤。

我玩了一段时间大型 3d 纹理。我用 GeForce 1070(它有 6GB)做了实验,它处理纹理 ~1GB 非常好。我设法加载的最大纹理大约为 3GB (2048x2048x7**),但它经常会引发错误。尽管它应该有大量适合纹理的空闲 VRAM,但由于各种原因它可能无法分配这么大的块。所以我不建议分配与 VRAM 总大小相当的纹理,除非绝对必要。