我在我的引擎中添加了一个新的GL渲染器,它使用核心配置文件。虽然它在Windows 和/或nvidia卡上运行良好,但它在OS X上慢了10倍(3 fps而不是30)。奇怪的是,我的兼容性配置文件渲染器运行正常。
我用仪器和GL分析器收集了一些痕迹:
https://www.dropbox.com/sh/311fg9wu0zrarzm/31CGvUcf2q
它表明应用程序将时间花在glDrawRangeElements上。 我尝试了以下事项:
我没有尝试的是将我的顶点对齐到16字节边界和/或将索引转换为4字节,但严重的是,如果这将是问题那么为什么地狱做标准允许吗?
我正在创建这样的上下文:
NSOpenGLPixelFormatAttribute attributes[] =
{
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAStencilSize, 8,
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFANoRecovery,
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
0
};
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nil];
[self.view setOpenGLContext:context];
[context makeCurrentContext];
尝试以下规格:
你有什么想法我可能会做错吗?同样,它与兼容性配置文件一起工作正常(但不使用VAO)。
更新:向Apple报告。
更新:Apple并没有对此问题表示遗憾......无论如何,我创建了一个实际上很好的小型测试程序。现在我将调用堆栈与Instruments进行了比较,发现在使用引擎时, glDrawRangeElements 会进行两次调用:
在测试程序中它只调用第二个。现在第一个调用就像立即模式渲染一样(gleFlushPrimitivesTCLFunc,gleRunVertexSubmitterImmediate),所以显然会减速。
答案 0 :(得分:2)
最后,我能够重现减速。这很疯狂......显然是由于在“my_Position”属性上调用 glBindAttribLocation 引起的。现在我做了一些测试:
显然我重新连接程序(检查代码)。这不是实现中的问题,我也用“普通”值测试它。
测试程序:
https://www.dropbox.com/s/dgg48g1fwgyc5h0/SLOWDOWN_REPRO.zip
如何重新制作:
答案 1 :(得分:2)
在以下情况下,我设法让自己遇到同样的问题
OS X Mavericks:
使用数组缓冲区进行实例化渲染,为每个实例提供自己的modelToWorld
和inverseNormal
矩阵;属性位置是通过布局指定的,而不是使用glGetAttribLocation
在shader
中遗留了其中一个数组缓冲区,其中声明了位置但该属性实际上并未用于glsl
代码中的任何内容
在这种情况下,对glDrawElementsInstanced
的调用占用了大量的CPU时间(在正常情况下,即使在绘制数千个实例时,此调用也使用几乎为零的CPU)。
如果glDrawElementsInstanced
中使用的gleDrawArraysOrElements_ExecCore
几乎所有CPU时间花费在shader
,您就可以知道这个问题。确保在glsl
代码中实际引用了所有数组缓冲区,从而将CPU时间恢复到(接近)零。
我怀疑这是将{{1}}中的main()中的变量从编译器中删除以删除对该变量的所有引用的情况之一,留下您对属性的悬空引用或均匀的。