使用OpenGL客户端等待,应该选择哪个:glGetSynciv还是glClientWaitSync?

12

根据OpenGL规范中的同步对象(Sync objects),我不清楚在不等待检查同步对象信号时是该使用glGetSynciv还是glClientWaitSync。这两个指令在行为和性能方面有何区别:

GLint syncStatus;
glGetSynciv(*sync, GL_SYNC_STATUS, sizeof(GLint), NULL, &syncStatus);
bool finished = syncStatus == GL_SIGNALED;

对比

bool finished = glClientWaitSync(*sync, 0 /*flags*/, 0 /*timeout*/) == ALREADY_SIGNALED;

对于这些问题的一些细节:

  • glGetSynciv 是否会向 GL 服务器执行往返操作?
  • 任何一种方法是否在驱动程序支持/错误方面更优选?
  • 任一方法是否可能死锁或无法立即返回?

一些背景信息:

  • 这是一个视频播放器,从物理源流式传输图像到 GPU 进行渲染。
  • 一个线程正在流式传输/连续上传纹理,另一个线程在完成上传后渲染它们。每个渲染帧都会检查下一个纹理是否已经上传完成。如果是,则开始渲染这个新纹理,否则继续使用旧纹理。
  • 决策仅由客户端进行,我不想等待,而是快速继续渲染正确的纹理。

两种方法都有人使用它们来实现不等待的目的,但似乎没有讨论使用其中一种还是另一种的优点。


有趣的是,虽然我怀疑这两种用法之间不会有太大的区别。 - Dietrich Epp
第一次测试似乎表明,glGetSynciv需要0.01毫秒,glClientWaitSync需要0.001毫秒(在NVIDIA上,可能会有所不同)。 - Christopher Oezbek
1
没错,但是时间数据缺少一些基本信息,比如你是如何测量的以及方差是多少。你不想仅仅测量函数前后的时间戳,因为它没有考虑到函数对整个帧性能的影响(特别是在涉及多线程性能的情况下),而且你也不想报告一个没有样本方差的时间,因为它可能只是偶然现象。 - Dietrich Epp
1
此外,要真正挑剔的是,请记住,如果没有glWaitSync(而不是 Client!),以及重新绑定对象,您可能看不到共享上下文中的更改。 参见规范§5.3.1 ... - peppe
1
很遗憾,我不知道。到目前为止,对这个主题的研究很少,但它是整个“逼近零驱动程序开销”倡议中非常关键的概念。它实际上是二级平铺资源,相当于D3D中的等效概念。我敢打赌,对D3D概念的探讨会更多一些,但它仍然很新颖。 - Andon M. Coleman
显示剩余7条评论
1个回答

4
引用《Red Book》的内容:
``` void glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *lenght, GLint *values); ```
函数用于检索同步对象的属性。参数`sync`指定了要读取`pname`所指定的属性的同步对象句柄。`bufSize`是给定在`values`中的缓冲区的字节数。`length`是一个整数变量的地址,该变量将接收写入`values`中的字节数。
而对于`glClientWaitSync`:
``` GLenum glClientWaitSync(GLsync sync, GLbitfields flags, GLuint64 timeout); ```
函数使客户端等待同步对象变为 signaled 状态。`glClientWaitSync()`会等待至多`timeout`纳秒,以使对象在超时前成为 signaled 状态。`flags`参数可用于控制命令的刷新行为。指定`GL_SYNC_FLUSH_COMMANDS_BIT`相当于在执行等待之前调用`glFlush()`。
因此,基本上`glGetSynciv()`用于知道围栏对象是否已变更为 signaled 状态,而`glClientWaitSync()`用于等待直到围栏对象变为 signaled 状态。
如果您只想知道围栏对象是否已变为 signaled 状态,则建议使用`glGetSynciv()`。显然,`glClientWaitSync()`的执行时间应比`glGetSynciv()`长,但这只是猜测。希望这可以帮助您。

2
重要的是glClientSyncWait在超时为0时与glGetSynciv()的比较。我的测试似乎表明,在NVIDIA上,glClientWaitSync更快。这让我好奇glGetSynciv()是否有更多的缺点。 - Christopher Oezbek
是的,我觉得有趣的是那个本应该“等待”的函数实际上比那个只应该检索OpenGL状态的函数运行得更快。 - Matth
1
@MatthUnderpants 如果指定了0的超时时间,它将不会等待。这就是问题的重点。 - Reto Koradi
我理解你的意思,但这是一个文档不良且实现依赖性很强的事情。 - Matth
值得一提的是 - 分析表明,在最近的Nvidia驱动程序中,glClientWaitSync在这种情况下比glGetSynciv更快。 - val is still with Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接