opengl 使用像素缓冲区对象从GPU异步阅读数据

xmq68pz9  于 2022-11-23  发布在  其他
关注(0)|答案(2)|浏览(204)

从GPU获取数据似乎是一个非常缓慢的任务,如果你想读取它与其余的应用程序同步。一种可能性是读取 * 异步 * 的帮助下,像素缓冲区对象。不幸的是,我不能看到这是如何做到的。
首先,我创建一个像素缓冲区对象:

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“准备好”吗?

hxzsmxv2

hxzsmxv21#

glReadPixels调用应该开始复制到一个cpu可见的缓冲区。(每当它被提交到GPU时。你可以用glFlush强制提交)。你正在异步地开始读取。
glMapBufferRange将强制glReadPixels调用完成(因为您现在访问的是CPU上的指针,所以没有办法)。
所以......不要连续做两次,而要明显晚一点。

1yjd4xko

1yjd4xko2#

在Bahbar的回答中补充一点:

  • glReadPixels之后,如果您打算阅读回数据,我认为您应该调用glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
  • glReadPixelsglMemoryBarrier之后,您可以使用glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0)创建围栏同步,然后在与glGetSynciv(fence_sync, GL_SYNC_STATUS, sizeof(GLint), NULL, &result)同步之前检查GPU是否已完成执行所有指令,或者在与glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, nanosecond_timeout)同步之前等待GPU完成执行所有指令。

相关问题