我的视频卡是Mobile Intel 4 Series。我正在通过每帧更改数据来更新纹理,这是我的主循环:

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();
}

每次迭代需要120毫秒。但是,在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卡上确实存在性能问题,但是我还没有将这些问题提炼到测试用例中。

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

最佳答案

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

另一个问题是,尽管命名为即时模式,即glBegin(…)…glEnd(),绘制调用仍不同步,即,调用在GPU完成绘制之前很久就返回了。添加glFinish()将同步。但是也将调用任何修改队列操作仍需要的数据的内容。因此,在您的情况下,glTexImage2D(和glTexSubImage2D)必须等待绘图完成。

通常,最好是在绘图函数的开头,或在单独的线程中的SwapBuffers块中,通过缓冲区对象上传所有 volatile 资源。出于这个原因引入了缓冲区对象,以允许异步但严格的操作。

关于performance - 英特尔显卡上的glTexSubImage2D非常慢,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7808146/

10-09 13:41