有没有一种方法可以判断OpenGL操作是否完成?

9

OpenGL函数的定义是它们同步操作的,但是渲染函数(以及其他函数)通常会被GPU异步执行。OpenGL会有效地隐藏这一点:如果您执行需要操作结果的操作(例如从已渲染的帧缓冲区中读取),则OpenGL将停止CPU操作,直到GPU达到该点。

这是可行的,但对于性能来说并不理想,因为CPU基本上会阻塞直到GPU完成。有没有一种方法可以确定特定操作是否已完成,以便您知道依赖操作将被执行而不会有太多CPU阻塞呢?

1个回答

9

是的,有。假设您可以访问OpenGL 3.2+或ARB_sync扩展。

如果您想知道特定命令何时完成,可以在发出该命令后立即将"栅栏" 同步对象 插入到命令流中。这是使用 glFenceSync 函数 完成的。

您必须存储此函数返回的指针。有了该指针,您可以通过检查栅栏是否被 glGetSync 函数 发信号来查询栅栏是否已完成。就像这样:

GLint isSignaled = 0;
glGetSync(syncObj, GL_SYNC_STATUS, 1, NULL, &isSignaled);

if(isSignaled == GL_SIGNALED)
{
  //Prior commands have completed.
}
else
{
  //Not done yet.
}

如果你没有其他事情可做,你不需要等待同步对象完成;你可以直接进行任何想要的OpenGL处理。这将为你引入CPU块。
一旦你完成了同步对象,你必须删除它。使用glDeleteSync函数来完成此操作。

好问题。但是同时提问和回答是否可以呢? ;) 另外,这样的同步检查会不会给管道增加更多不必要的开销呢? - Michael IV
1
@MichaelIV: “但是同时提问和回答是否可以?” 可以。这就是为什么当你提出一个问题时,底部会有一个框,允许你在提问之前就在那里回答它。至于添加“不必要的开销”,栅栏应该是相当轻量级的。内部驱动程序进程一直在使用栅栏,以便他们可以知道何时你已经完成了缓冲对象等等。 - Nicol Bolas

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