Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do glQueryCounter and GL_TIMESTAMP really measure?

Tags:

opengl

My main question is, can someone confirm that glQueryCounter captures the GL_TIMESTAMP after all previous commands were executed on the GPU? So that the difference of two timestamps will roughly be equivalent to capturing GL_ELAPSED_TIME?


What I'm looking for is a way to measure timings between more than two timestamps, while ensuring that the timestamps are captured when all previously scheduled commands were executed. I know that GL_TIME_ELAPSED works for two points in time, but I'd need something that can be nested and used with multiple timestamps within a single frame, which is why I'd like to use GL_TIMESTAMP. Timestamps may be frameStart, drawCertainThingsStart, drawCertainThingsEnd, frameEnd. The spec on GL_TIMESTAMP confuses me, though, and I'm not sure if it does what I'm looking for.

Disjoint timer query spec: https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_disjoint_timer_query.txt


Some information seems contradictory. For example: glQueryCounter: "record the GL time into a query object after all previous commands have reached the GL server but have not yet necessarily executed"

The disjoint timer query spec on the other hand says "The time is recorded after all previous commands on the GL client and server state and the framebuffer have been fully realized.", which sounds like it records the timestamp after previously scheduled commands were executed. It also specifically mentions that the synchronous alternative, GetInteger64v, returns the timestamp without necessarly having executed the commands, which emphasizes that glQueryCounter is supposed to return a timestamp after previous commands were executed, contrary to what the khronos page says.


The spec also comes with an example: Section "(2) This example uses QueryCounter" supposedly shows how glQueryCounter and GL_TIMESTAMP are used to measure elapsed time on the GPU. However, it seems like this example is incomplete. Two variables, _timeStart_ and _timeEnd_, are never used. Instead, the example reads the value of GL_TIMESTAMP directly into the _timeElapsed_ variable, which seems wrong. From my understanding, we'd need to read GL_TIMESTAMP into _timeStart_ and _timeEnd_, and then compute _timeElapsed_ = _timeEnd_ - _timeStart_ .

like image 744
Markus Avatar asked Aug 30 '18 09:08

Markus


1 Answers

The OpenGL function documentation pages have an unfortunately large number of errors on them. This is one of them. It's even self-contradictory, since the text of the description contradicts the intro text.

The OpenGL specification is very clear on the behavior of glQueryCounter:

The time is recorded after all previous commands on the GL client and server state and the framebuffer have been fully realized.


The spec also comes with an example

Wrong specification. The ARB_timer_query specification is for desktop OpenGL; the EXT_disjoint_timer_query is for OpenGL ES. Don't confuse the two.

The EXT_disjoint_timer_query specification's examples seem to have been incorrectly copied from ARB_timer_query.

like image 110
Nicol Bolas Avatar answered Sep 21 '22 16:09

Nicol Bolas