glTexSubImage2D在英特尔显卡上速度极慢

Ste*_*nov 10 opengl performance

我的显卡是Mobile Intel 4系列.我正在更新每帧更改数据的纹理,这是我的主循环:

for(;;) {
    Timer timer;

    glBindTexture(GL_TEXTURE2D, tex);
    glBegin(GL_QUADS); ... /* draw textured quad */ ... glEnd();
    glTexSubImage2D(GL_TEXTURE2D, 0, 0, 0, 512, 512,
        GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
    swapBuffers();

    cout << timer.Elapsed();
}
Run Code Online (Sandbox Code Playgroud)

每次迭代需要120ms.但是,在glTexSubImage2D之前插入glFlush会使迭代时间延长到2ms.

问题不在于像素格式.我已经尝试了像素格式BGRA,RGBA和ABGR_EXT以及像素类型UNSIGNED_BYTE,BYTE,UNSIGNED_INT_8_8_8_8和UNSIGNED_INT_8_8_8_8_EXT.纹理的内部像素格式是RGBA.

通话顺序很重要.例如,在四边形绘图之前移动纹理上载可以修复缓慢的问题.

我也在GeForce GT 420M卡上尝试过这种功能,它在那里工作得很快.我的真实应用确实在glFlush调用修复的非Intel卡上存在性能问题,但我还没有将它们提取到测试用例中.

关于如何调试这个的任何想法?

dat*_*olf 5

一个问题是glTexImage2D执行纹理对象的完全重新初始化.如果只有数据发生变化,但格式保持不变,请使用glTexSubImage2D加速(仅提醒).

另一个问题是,尽管它的名称是立即模式,即glBegin(...)... glEnd(),但是绘图调用不是同步的,即调用在GPU完成绘制之前很久就会返回.添加glFinish()将同步.但是也会调用任何修改排队操作仍然需要的数据的东西.因此,在您的情况下,glTexImage2D(和glTexSubImage2D)必须等待绘图完成.

通常,最好在绘图函数的开头执行所有易失性资源上载,或者在通过缓冲区对象的单独线程中的SwapBuffers块期间执行.出于这个原因引入了缓冲区对象,以允许异步但紧凑的操作.


Ben*_*igt 3

我假设您实际上正在为一个或多个四边形使用该纹理?

上传纹理是最昂贵的操作之一。由于纹理数据每帧都会发生变化,因此上传是不可避免的,但您应该尝试在着色器未使用纹理时执行此操作。请记住,它glBegin(GL_QUADS); ... glEnd();实际上并不绘制四边形,而是请求 GPU 渲染四边形。在渲染完成之前,纹理将被锁定。根据实现的不同,这可能会导致纹理上传等待 (ala glFlush),但也可能导致上传失败,在这种情况下,您浪费了兆字节的 PCIe 带宽,并且驱动程序必须重试。

听起来您已经有了一个解决方案:在帧的开头上传所有新纹理。那么你的问题是什么?

注意:无论如何,英特尔集成显卡都非常慢。