OpenGL,测量GPU上渲染时间

8
我有一些严重的性能问题在这里
因此,我想在gpu方面进行一些测量。
通过阅读这个线程,我在我的绘图函数周围编写了这段代码,包括gl错误检查和swapBuffers()(自动交换确实已被禁用)。
        gl4.glBeginQuery(GL4.GL_TIME_ELAPSED, queryId[0]);
        {    
            draw(gl4);

            checkGlError(gl4);

            glad.swapBuffers();
        }
        gl4.glEndQuery(GL4.GL_TIME_ELAPSED);
        gl4.glGetQueryObjectiv(queryId[0], GL4.GL_QUERY_RESULT, frameGpuTime, 0);

由于OpenGL渲染命令被认为是异步的(驱动程序可以在发送它们之前缓冲多达X个命令,然后一起发送),因此我的问题实际上是关于:

  • 上述代码是否正确

  • 我是否正确地假设在新帧的开始时,所有先前的GL命令(来自先前的帧)都已经被发送,执行并在gpu上终止

  • 我是否正确地假设使用glGetQueryObjectivGL_QUERY_RESULT获取查询结果时,到目前为止所有的GL命令都已经终止?也就是说,OpenGL会等待结果可用(来自线程)?

1个回答

5
是的,当您查询计时器时,它将阻塞直到数据可用,即直到GPU完成开始和结束查询之间发生的所有操作。为了避免与GPU同步,您可以使用GL_QUERY_RESULT_AVAILABLE检查结果是否已经可用,然后再读取它们。这可能需要更复杂的代码来跟踪打开的查询并定期检查它们,但它会对性能影响最小。每次等待值都是导致性能下降的明确方法。
编辑:针对您的第二个问题,交换缓冲区并不一定意味着它将阻塞直到操作成功。您可能会看到那种行为,但同样有可能只是隐式的glFlush,并且命令缓冲区尚未为空。这也是更受欢迎的行为,因为理想情况下,您希望立即开始下一帧并保持CPU命令缓冲区填满。但是,请查看实现文档以获取更多信息,因为这是实现定义的。
编辑2:检查错误可能最终成为隐式同步,因此在命令流中等待错误检查时,您可能会看到命令缓冲区清空。

1
我知道这会影响性能,但目前我只关心纯渲染函数需要多少时间。 - elect
好的。我只是把它放在那里作为参考,让你知道你将会遇到什么。 - JustSid

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