iOS OpenGL ES 2.0 VBO 顶点数限制:一旦超过,CPU 受限

Posted

技术标签:

【中文标题】iOS OpenGL ES 2.0 VBO 顶点数限制:一旦超过,CPU 受限【英文标题】:iOS OpenGL ES 2.0 VBO vertex count limit: Once exceeded, CPU bound 【发布时间】:2013-09-05 02:58:56 【问题描述】:

我正在测试超大 3d 网格的渲染,我目前正在 iPhone 5 上进行测试(我也有 iPad 3)。

我这里有两张带有分析运行的 Instruments 屏幕截图。第一个是渲染一个 1.3M 的顶点网格,第二个是渲染一个 2.1M 的顶点网格。

顶部的蓝色直方图显示 CPU 负载,可以看出对于第一个网格,CPU 负载徘徊在约 10% 左右,因此 GPU 承担了大部分繁重工作。网格非常详细,如果我自己这么说的话,我的点光与镜面着色器让它看起来非常令人印象深刻,因为它能够以每秒 20 帧以上的速度持续渲染。哦,还启用了 4x MSAA!

但是,一旦我升级到超过 200 万个顶点网格,一切都会变得一团糟,因为我们在这里看到大量 CPU 受限情况,并且所有仪器都报告每秒 1 帧的性能。

因此,很明显,在这两个资产之间的某个位置(我承认它们都是在一个 VBO 下加载的非常大的网格),无论是顶点缓冲区大小还是索引缓冲区大小超过限制,2megavertex (462K tris) 网格超出了某些限制。

那么,问题是,这个限制是多少,我该如何查询呢?如果我可以合理地保证我的应用程序在不详尽测试每台设备的情况下运行良好,那将是非常可取的。

我还看到了解决此问题的另一种方法,即坚持已知的良好 VBO 大小限制(我已经读过大约 4MB 是一个很好的限制),并且如果网格基本上只是让 CPU 工作得更努力一点被渲染是可怕的。对于 100MB VBO,将其分成 4MB 块(将网格划分为 25 个绘制调用)听起来并没有那么糟糕。

但是,我还是很好奇。如何检查最大大小以解决 CPU 回退问题?我是否会遇到内存不足的情况,而 Apple 只是在应用基于 CPU 的解决方法(哦,上帝保佑,立即模式下有 200 万个顶点......)?

【问题讨论】:

【参考方案1】:

在纯 OpenGL 中,有两个实现定义的属性:GL_MAX_ELEMENTS_VERTICESGL_MAX_ELEMENTS_INDICES。在某些实现中,当超出性能时可能会一落千丈。

我花了一些时间查看 OpenGL ES 规范中的等效项,但找不到。有可能它隐藏在 OES 之一或 OpenGL ES 上特定于供应商的扩展中。然而,您可以绘制的元素数量和顶点数量存在非常实际的硬件限制。在索引过多的点之后,您可能会超出 T&L 后缓存的容量。 200 万对于单个绘图调用来说是很多的,而不是能够查询 OpenGL ES 实现以获取此信息,我会尝试连续降低二次幂,直到您将其拨回最佳位置。

65,536 曾经是 DX9 硬件的最佳选择。这是 16 位索引的限制,并且始终保证低于最大硬件顶点数。很有可能它也适用于 OpenGL ES 类硬件......

【讨论】:

确实,通过将 VBO 限制为 16 位大小,我的 IBO 始终可以分配短 uint,从而进一步减少宝贵的共享内存消耗。我认为仅凭这个理由就足以说服我在那个“最佳位置”设置一个限制。考虑到顶点的最低限度,我们有 3 个位置和 3 个正常的 4 字节浮点组件,大小为 24*64K = ~1.5MB,这已经有足够的空间来放置大量几何图形了。 "GL_MAX_ELEMENTS_VERTICES 和 GL_MAX_ELEMENTS_INDICES." 请注意,这些仅适用于 glDrawRangeElements,主要用于您使用客户端内存时(这就是在1.2:因此实现可以知道要使用的顶点数据的范围是什么,而不必通读整个索引列表)。 65536“最佳位置”(适用于 NVIDIA GPU)主要是因为它们无法在硬件中使用 32 位整数索引。没有任何支持 GL 3.x 的硬件在这两个方面存在任何重大问题。 @NicolBolas:您会说大多数 OpenGL ES 2.0 硬件都支持 OpenGL 3.0 吗?我知道有许多支持几何着色器的嵌入式 GPU,但它并没有在 GL ES 2 中公开。所以在我看来,将典型的 OpenGL ES 2 GPU 与哪一代桌面 GPU 进行比较有点灰色地带功能方面:) @AndonM.Coleman:“你会说大多数 OpenGL ES 2.0 硬件都支持 OpenGL 3.0 吗?”即使忽略 GS,也​​不会。我看不到 ES 3.0 之前的移动硬件对 UBO 的任何支持。有 RG 支持,但没有 RGTC 扩展。我没有看到整数纹理扩展或任何允许在着色器中使用(真实)整数的扩展。 NVIDIA 的 ES 2.0 硬件最接近桌面 3.x 支持,甚至他们也没有进行扩展来公开这些功能(尽管他们做了很多其他功能)。因为他们的 ES 2.0 硬件做不到。 @AndonM.Coleman:“所以在我看来,将典型的 OpenGL ES 2 GPU 与功能方面的哪一代桌面 GPU 进行比较,这在我看来是一个灰色地带”同意。这就是为什么将这些glDrawRangeElements 限制与他可能遇到的问题进行比较是不合适的。这是我的主要观点。

以上是关于iOS OpenGL ES 2.0 VBO 顶点数限制:一旦超过,CPU 受限的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在顶点着色器内持续更改 iPhone OpenGL ES 2.0 上的 VBO 值?

安卓 OpenGL ES 2.0 VBO

OpenGL ES 2.0 VBO 问题

OpenGL ES 2.0 vbo 白屏

共享内存架构中的 OpenGL (ES 2.0) VBO 性能

OpenGL ES 2.0:似乎无法渲染第二个 VBO?