OpenGL, measuring rendering time on a gpu
I have some big performance issues here
So, I would like to do some measurements on the gpu side.
After reading this thread , I wrote this code around my drawing functions including gl error checking and 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 the OpenGL render commands have to be asynchronous (the driver can buffer up to X commands before sending them all together in one batch), my question is about if:
-
the code is correct
-
I agree that at the start of a new frame, all previous GL commands (from the previous frame) were sent, executed and completed on the gpu
-
I suppose that when I get the query result with
glGetQueryObjectiv
andGL_QUERY_RESULT
, have all the GL commands been terminated so far? Will OpenGL wait for the result to be available (from the stream)?
source to share
Yes, when you request a timer, it will block until data is available, that is, until the GPU completes whatever happened between the start and end of the request. To avoid syncing with the GPU, you can use GL_QUERY_RESULT_AVAILABLE
to check if the results are available and only then read them. This may require less simple code to keep track of open requests and check them periodically, but will have the least impact on performance. Waiting for a value every time is a surefire way to kill your productivity.
Edit: To address the second question, replacing the buffer does not necessarily mean it will block until the operation succeeds. You can see this behavior, but it is also likely that it is just implicit glFlush
and the command buffer is not empty yet. Which is also the more desirable behavior because ideally you want to start your next frame right away and keep the shell buffer full. However, check the implementation documentation for more information as this is implementation-defined.
Edit 2: error checking can turn out to be an implicit synchronization, so you will probably see the command pool reset when you wait for error checking in the command stream.
source to share