2013-03-01 28 views
2

如果我打电话给glDrawElements,其中抽取目标是后台缓冲区,然后我打电话给glReadPixels,是否保证我会读取提取的内容?glDrawElements是否在后台缓冲区同步?

换句话说,是glDrawElements阻止呼叫?

注:我观察这里的奇怪的问题可以通过glDrawElements没有被阻塞引起...

回答

8

换句话说,是glDrawElements阻塞调用?

这不是OpenGL的工作方式。

OpenGL memory model构建于“仿佛”规则上。除了某些例外,everything in OpenGL will function as if all of the commands you issued have already completed。实际上,一切都会像每个命令都被阻塞直到完成一样。

但是,这并不意味着OpenGL实现实际上以这种方式工作。它只需要尽一切努力使出现即可。

因此,glDrawElements一般不是阻塞呼叫;然而,glReadPixels(当读到客户端内存时)阻塞呼叫。因为当返回glReadPixels时,像素直接传输到客户端内存的结果必须可用,所以实现必须检查是否有任何正在读取的帧缓冲区的渲染命令。如果有,那么它必须阻止,直到这些渲染命令完成。然后它可以执行读取并将数据存储在客户端内存中。

如果您是reading to a buffer object,则不需要glReadPixels来阻止。由于您正在读入缓冲区对象,所以客户端无法访问的内存将被该函数修改。所以驱动程序可以异步发布回读。但是,如果您发出一些取决于此缓冲区内容的命令(如将其映射为读取或使用glGetBufferSubData),则OpenGL实现必须停止,直到读取操作完成。

简而言之,OpenGL试图尽可能延迟阻塞。除非绝对必要,否则你的工作,以确保性能,是帮助 OpenGL这样做,而不是forcing an implicit synchronizationSync objects可以帮助这一点。