OpenGL,在gpu上测量渲染时间

OpenGL,在gpu上测量渲染时间,opengl,gpu,timing,opengl-4,elapsedtime,Opengl,Gpu,Timing,Opengl 4,Elapsedtime,我有一些大的性能问题 所以我想在gpu端进行一些测量 通过阅读本文,我围绕绘图函数编写了以下代码,包括gl错误检查和swapBuffers()(自动交换确实已禁用) 由于OpenGL渲染命令应该是(驱动程序可以在一批发送之前缓冲多达X个命令),因此我的问题主要涉及以下方面: 上面的代码是正确的 我正确地假设在新帧开始时,所有先前的GL命令(来自前一帧)都已在gpu上发送、执行和终止 我正确地假设,当我使用glGetQueryObjectiv和GL\u query\u result获得查询结果时

我有一些大的性能问题

所以我想在gpu端进行一些测量

通过阅读本文,我围绕绘图函数编写了以下代码,包括gl错误检查和swapBuffers()(自动交换确实已禁用)

由于OpenGL渲染命令应该是(驱动程序可以在一批发送之前缓冲多达X个命令),因此我的问题主要涉及以下方面:

  • 上面的代码是正确的

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

  • 我正确地假设,当我使用
    glGetQueryObjectiv
    GL\u query\u result
    获得查询结果时,到目前为止所有的GL命令都已终止?也就是说OpenGL将等待结果变为可用(从线程中)


是,当您查询计时器时,它将阻塞,直到数据可用为止,即直到GPU完成从开始到结束查询之间发生的所有事情。为了避免与GPU同步,您可以使用
GL\u QUERY\u RESULT\u AVAILABLE
检查结果是否已经可用,然后再读取。这可能需要不那么简单的代码来跟踪打开的查询并定期检查它们,但对性能的影响最小。每次等待值肯定会扼杀您的性能

编辑:为了解决第二个问题,交换缓冲区并不一定意味着它将阻塞,直到操作成功。您可能会看到这种行为,但它很可能只是一个隐式的
glFlush
,并且命令缓冲区还不是空的。这也是更需要的行为,因为理想情况下,您希望立即从下一帧开始,并保持CPU命令缓冲区已满。查看实现文档以了解更多信息,因为这是实现定义的


编辑2:顺便说一句,检查错误可能会导致隐式同步,因此当您在命令流中等待错误检查时,可能会看到命令缓冲区清空。

我知道这是一种性能杀手,但目前我只关心纯渲染功能需要多少时间。我只是把它放在那里作为参考,这样你就知道你会学到什么
        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);