我的游戏引擎尝试分配大型纹理数组,以便能够将其绘制的大部分(如果不是全部)批处理。这个数组可能变得足够大而无法分配,此时我(连续地)将纹理数组分成两半。
在接收glGetError:Out of memory
并从那里缩小之前推动边界是不是很糟糕?
我的应用程序是一个混蛋,因为它分配了大量的VRAM,这可能需要交换到GTT内存?在处理其他操作系统操作时,图形驱动程序操作一些大的纹理数组而不是许多单独的纹理是不是很理想?
答案 0 :(得分:1)
很难评估驱动程序处理大型纹理数组的能力。不同司机的行为可能会有很大不同。
虽然使用纹理数组可以通过减少绘制调用的数量来提高性能,但这不应该是主要目标。减少绘制调用在移动平台上有点重要,即便如此,其中几十个也不是问题。我不确定您的担忧以及您尝试优化的内容,但我建议您在进行任何优化之前使用GPU供应商提供的分析工具。
在接收glGetError之前推动边界是不好的设计:内存不足并从那里缩小?
这是将数据动态加载到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总大小相当的纹理。