Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL, measuring rendering time on gpu

I have some big performance issues here

So I would like to take some measurements on the gpu side.

By reading this thread I wrote this code around my draw functions, including the gl error check and the swapBuffers() (auto swapping is indeed disabled)

        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);

And since OpenGL rendering commands are supposed to be asynchronous ( the driver can buffer up to X commands before sending them all together in one batch), my question regards essentially if:

  • the code above is correct

  • I am right assuming that at the begin of a new frame all the previous GL commands (from the previous frame) have been sent, executed and terminated on the gpu

  • I am right assuming that when I get query result with glGetQueryObjectiv and GL_QUERY_RESULT all the GL commands so far have been terminated? That is OpenGL will wait until the result become available (from the thread)?

like image 513
elect Avatar asked May 07 '15 15:05

elect


1 Answers

Yes, when you query the timer it will block until the data is available, ie until the GPU is finished with everything that happened between beginning and ending the query. To avoid synchronising with the GPU, you can use GL_QUERY_RESULT_AVAILABLE to check if the results are already available and only then read them then. That might require less straightforward code to keep tabs on open queries and periodically checking them, but it will have the least performance impact. Waiting for the value every time is a sure way to kill your performance.

Edit: To address your second question, swapping the buffer doesn't necessarily mean it will block until the operation succeeds. You may see that behaviour, but it's just as likely that it is just an implicit glFlush and the command buffer is not empty yet. Which is also the more wanted behaviour because ideally you want to start with your next frame right away and keep the CPUs command buffer filled. Check the implementations documentation for more info though, as that is implementation defined.

Edit 2: Checking for errors might end up being an implicit synchronization by the way, so you will probably see the command buffer emptying when you wait for error checking in the command stream.

like image 77
JustSid Avatar answered Oct 02 '22 20:10

JustSid