我的测试基于这个流行的PBO示例(请参阅http://www.songho.ca/opengl/gl_pbo.html中的pboUnpack.zip)。根据示例,在PBO模式1上进行测试。
运行原始样本,我发现在我的NVIDIA 560GTX PCIe x16(驱动程序v334.89 Win7 PRO x64 Core i5 Ivy Bridge 3.6GHz)上,glMapBufferARB()
阻塞了15ms,即使前面有glBufferDataARB()
是为了防止它阻塞(即丢弃PBO)。
然后我将图像大小从原来的1024 * 1024更改为400 * 400,当然可以减少阻塞时间。令我惊讶的是,它仍然保持在15毫秒! CPU利用率仍然很高。
进一步尝试,我将图像大小增加到4000 * 4000,但我又感到惊讶 - glBufferDataARB从15ms减少到0.1ms,CPU利用率同时大幅降低。
我很想解释这里发生了什么,我希望熟悉这个问题的人可以解释一下。
感兴趣的代码:
// bind PBO to update pixel values
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboIds[nextIndex]);
// map the buffer object into client's memory
// Note that glMapBufferARB() causes sync issue.
// If GPU is working with this buffer, glMapBufferARB() will wait(stall)
// for GPU to finish its job. To avoid waiting (stall), you can call
// first glBufferDataARB() with NULL pointer before glMapBufferARB().
// If you do that, the previous data in PBO will be discarded and
// glMapBufferARB() returns a new allocated pointer immediately
// even if GPU is still working with the previous data.
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, DATA_SIZE, 0, GL_STREAM_DRAW_ARB);
GLubyte* ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);
if(ptr)
{
// update data directly on the mapped buffer
updatePixels(ptr, DATA_SIZE);
glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); // release pointer to mapping buffer
}