3

我最近在我的渲染引擎中实现了功能,使其能够根据运行时设置将模型编译为显示列表或 VAO,以便我可以将两者相互比较。

我通常更喜欢使用 VAO,因为我可以让多个 VAO 共享实际的顶点数据缓冲区(而且因为它们没有被弃用),但我发现它们实际上比我的 nVidia (GTX 560) 硬件上的显示列表更差. (无论如何,我想继续支持显示列表以支持较旧的硬件/驱动程序,因此保留处理它们的代码并没有真正的损失。)

差别不大但肯定是可以衡量的。例如,在引擎状态的某个点上,我可以使用 VAO 持续测量我的绘图循环,以相当一致的平均值,大约 10.0 毫秒来完成一个循环,我可以切换到显示列表并观察循环时间减少在同样一致的平均值上约为 9.1 毫秒。这里的一致意味着一个周期的偏差通常小于±0.2 ms,远小于差异。

这些设置之间唯一改变的是普通网格的绘制代码。它从 OpenGL 调用看起来简单的 VAO 代码改变......

glBindVertexArray(id);
glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_SHORT, NULL); // Using an index array in the VAO

...到显示列表代码,如下所示:

glCallList(id);

当然,这两种代码路径也适用于各种模型的其他状态,但是以完全相同的方式发生,所以这些应该是唯一的区别。我已经明确确保不要在绘图调用之间不必要地解除绑定 VAO,因为结果也证明它的表现要差得多。

这种行为是可以预期的吗?我曾预计 VAO 的表现会更好,或者至少在显示列表方面表现相同,因为它们更现代且不会被弃用。另一方面,我一直在网上阅读到 nVidia 的实现对显示列表等进行了特别优化,所以我认为他们的 VAO 实现可能仍然落后。有没有其他人得到与我的匹配(或矛盾)的发现?

否则,我会做错什么吗?是否有任何已知情况使 VAO 在 nVidia 硬件或一般情况下的性能比应有的差?

作为参考,我在 Intel HD Graphics (Ironlake) 上也尝试了相同的差异,结果发现使用 VAO 的性能与直接从内存中直接渲染一样好,而显示列表比两者都差得多。我希望我有 AMD 硬件可以尝试,但我没有。

4

0 回答 0