我的游戏引擎尝试分配大型纹理数组,以便能够将大部分(如果不是全部)绘制在一起。这个数组可能变得足够大而无法分配,此时我会(不断地)将纹理数组分成两半。
glGetError:Out of memory
突破界限直到收到 a并从那里缩减是不是糟糕的设计?
我的应用程序是不是因为它分配了巨大的 VRAM 块,而这可能需要交换到 GTT 内存中?例如,在处理其他操作系统操作时,图形驱动程序处理一些大型纹理数组而不是许多单独的纹理是否不太理想?
很难评估驱动程序处理大型纹理数组的能力。不同驱动程序的行为可能会有很大差异。
虽然使用纹理数组可以通过减少绘制调用次数来提高性能,但这不应该是主要目标。减少draw call在移动平台上有些重要,即使在那里,几十个也不是问题。我不确定您的担忧以及您尝试优化的具体内容,但我建议在进行任何优化之前使用 GPU 供应商的分析工具。
突破界限直到收到 glGetError:Out of memory 并从那里缩减是不是糟糕的设计?
这通常是在将数据动态加载到 GPU 时执行的操作。收到错误后,应卸载旧数据以加载新数据。
我的应用程序是不是因为它分配了巨大的 VRAM 块,而这可能需要交换到 GTT 内存中?
无法检查数据是否已交换到 GTT(如果驱动程序完全支持 GTT)。驱动程序自行处理它,并且无法从 OpenGL API 访问它。如果您使用的是 NVidia 的 GPU,您可能需要使用Nsight等分析工具。
但是,如果你打算拥有一个巨大的纹理阵列,它必须作为一个整体适合 VRAM,它不能部分在 VRAM 和 GTT 中。我不建议完全依赖 GTT。
它必须适合 VRAM,因为当您绑定它时,驱动程序无法事先知道哪些层将被使用,哪些不会,因为选择发生在着色器中。
尽管纹理数组和 3dtexture 在概念上有所不同,但在硬件级别它们的工作方式非常相似,不同之处在于第一个使用二维过滤,第二个使用三维过滤。
我玩了一段时间的大型 3d 纹理。我用 GeForce 1070(它有 6GB)做了实验,它处理纹理 ~1GB 非常好。我设法加载的最大纹理约为 3GB (2048x2048x7**),但通常会引发错误。尽管它应该有大量适合纹理的空闲 VRAM,但由于各种原因,它可能无法分配这么大的块。因此,除非绝对必要,否则我不建议分配与 VRAM 总大小相当的纹理。