0

如果您想与您的应用程序同步读取数据,从 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 “准备好”?

4

2 回答 2

3

glReadPixels调用应该开始复制到一个 cpu 可见的缓冲区。(无论何时提交给 GPU。您可以使用 强制提交glFlush)。您正在异步启动读取。

glMapBufferRange如果不是,将强制glReadPixels调用完成(因为您现在正在访问 CPU 上的指针,所以没有办法解决这个问题)。

所以...不要背靠背做 2 次,而是要晚得多。

于 2015-11-30T21:17:51.323 回答
1

要补充巴巴的答案:

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

  • 之后glReadPixelsglMemoryBarrier您可以创建一个 Fence Sync with glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0),然后检查 GPU 在 sync with 之前是否已完成所有指令的执行glGetSynciv(fence_sync, GL_SYNC_STATUS, sizeof(GLint), NULL, &result),或者等待 GPU 在 sync with 之前完成所有指令的执行glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, nanosecond_timeout)

于 2019-12-16T13:11:39.067 回答