glMapBufferRange()下载完整的缓冲区?

时间:2014-06-27 03:22:07

标签: opengl optimization buffer

我注意到在调用一些openGL函数时减速了15ms。经过一些测试后,我相信我已经缩小了这个问题。我确实有几个MBytes的缓冲区(主要包含粒子)。我有时需要添加一些粒子。为此,我绑定缓冲区,获取当前数量的粒子以了解写入的偏移量,然后写入粒子。正如预期的那样,减速是在阅读部分。 (对于这个问题,请假设不可能跟踪CPU端的粒子数。)

glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
GLvoid* rangePtr = glMapBufferRange( //This function takes 15ms to return
    GL_ARRAY_BUFFER, 
    m_offsetToCounter, 
    sizeof(GLuint), 
    1);
if(rangePtr != NULL)
    value = *(GLuint*) rangePtr;
m_functions->glBindBuffer(GL_ARRAY_BUFFER, 0);

我假设提供了一个非常有限的尺寸(这里是一个GLuint),只会下载一个GLuint。但是,通过将缓冲区的大小大幅减少到200 KB,该函数的执行时间降至8毫秒。

两个问题:

  1. glMapBufferRange以及glGetBufferSubData确实下载了完整的缓冲区,即使用户只是要求它的一部分?
  2. 数学没有加起来,任何想法为什么?还有8ms下载一个非常小的缓冲区。执行时间等式看起来像y = ax + b,其中b是7-8 ms。当我在怀疑缓冲区大小之前试图找到问题的根源时,我还发现glUniform*函数也需要大约10ms。但只有第一个电话。如果一个接一个地有多个glUniform*个调用,则只有第一个需要花费很多时间。其他的是瞬间的。当读取缓冲区时,也没有下载时间。 glUniform*是否会触发某些内容?
  3. 我正在使用Qt 5 API。我想首先确定我正在使用openGL,然后才认为它可能是导致速度减慢的Qt层,并用glu / glut重新实现整个程序。

1 个答案:

答案 0 :(得分:2)

8分听起来好像很多时间......你如何衡量时间?

  

glMapBufferRange以及glGetBufferSubData会下载完整的缓冲区,即使用户只要求它的一部分吗?

OpenGL规范没有定义实现缓冲区映射的方式。它可能是缓冲区内容的完整下载。它可能是单页I / O内存映射。它可能是使缓冲区对象的内容出现在主机进程地址空间中的任何内容。

  

数学没有加起来,任何想法为什么?

一方面,内存映射的最小大小是系统的页面大小。如果它是由完整的对象副本或I / O内存映射完成的,或者是完全不同的东西,那么你总是处理至少几kiB的内存块。

  

我使用的是Qt 5 API

您是否正在使用Qt5 OpenGL函数类? AFAIK这个类会根据需要加载函数指针,因此第一次调用函数可能会触发一系列需要一些时间才能完成的操作。