使用Pixel Buffer Objects异步读取gpu中的数据

时间:2015-11-30 21:11:05

标签: opengl buffer-objects

如果您想要与应用程序同步读取数据,那么从gpu获取数据似乎是一项非常缓慢的任务。一种可能性是在Pixel Buffer Objects的帮助下读取异步。不幸的是,我无法看到这是如何完成的。

首先我创建一个Pixel Buffer Object:

glGenBuffers(1, &pbo);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
glBufferData(GL_PIXEL_PACK_BUFFER, pbo_size, 0, GL_DYNAMIC_READ);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

然后我想读取帧缓冲对象中的像素:

glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
glReadPixels(0, 0, w, h, GL_RGBA, GL_FLOAT, 0);
GLfloat *ptr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, pbo_size, GL_MAP_READ_BIT);
memcpy(pixels, ptr, pbo_size);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

但这是如何异步的? glReadPixels或glMapBufferRange是否阻止了应用程序,直到gpu准备就绪?

2 个答案:

答案 0 :(得分:3)

glReadPixels调用应该将副本启动到cpu可见缓冲区。 (无论何时将其提交给GPU。您可以使用glFlush强制提交。您以异步方式启动读取。

glMapBufferRange会强制glReadPixels调用完成,如果它不是(因为你现在正在访问CPU上的指针,那里就没办法了)。

所以......不要背对背做2,而是要做得更晚。

答案 1 :(得分:0)

要添加到Bahbar的答案中:

  • glReadPixels之后,如果您打算回读数据,我相信您应该致电glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);

  • glReadPixelsglMemoryBarrier之后,您可以创建与glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)的Fence同步,然后在与{{1]同步之前检查GPU是否已完成所有指令的执行}},或等待GPU完成执行所有指令,然后再与glGetSynciv(fence_sync, GL_SYNC_STATUS, sizeof(GLint), NULL, &result)进行同步。