Timer query result unavailable after swap buffers call

I’m using OpenGL timers to benchmark some of the render stages in my program. Each render stage has its own query object and is rendered independently of the other stages.

My code looks something like this:


GLuint queryObjectFirst;
GLuint queryObjectSecond;
glGenQueries(1, &queryObjectFirst);
glGenQueries(1, &queryObjectSecond);

while(true)
{
    glBeginQuery(GL_TIME_ELAPSED, queryObjectFirst);
    ... Render first thing ...
    glEndQuery(GL_TIME_ELAPSED);

    glBeginQuery(GL_TIME_ELAPSED, queryObjectSecond);
    ... Render second thing ...
    glEndQuery(GL_TIME_ELAPSED);

    glfwSwapBuffers();

    GLuint timeDifferenceFirst;
    glGetQueryObjectuiv(queryObjectFirst, GL_QUERY_RESULT, &timeDifferenceFirst);
    GLuint timeDifferenceSecond;
    glGetQueryObjectuiv(queryObjectSecond, GL_QUERY_RESULT, &timeDifferenceSecond);
}

Strangely, some timer values are not available after the swap buffers call. Calling glGetQueryObjectuiv with the GL_QUERY_RESULT_AVAILABLE parameter often returns false and I must run a while loop until it’s true. I even tried calling glFinish() before retrieving the timer value, but it made little difference. The timer values themselves appear to be mostly accurate, but I wish I didn’t have to slow down my program with the while loop.

I’m fairly confident that I’m otherwise using the timers correctly because I don’t have any warnings when running with a debug context. I’m using an NVIDIA GTX 460 with driver version 320.18.

Why would you expect them to be available? Just because you swapped buffers doesn’t mean that the CPU waited until that’s done. Just like any other rendering call, it will be executed whenever the driver gets around to it.

I assumed glfwSwapBuffers would stall the CPU until the buffers finished swapping, but I can see how that assumption is faulty. However, one thing I still can’t explain is having an unavailable query even when I call glFinish() right before retrieving it.

duh! scratch that

That would seem to be a bug in the driver, although the specification isn’t entirely clear on this. It may be that glFinish() returns as soon as the timer has been stopped but before the value has actually been transferred from the hardware to client memory.
Have you tried using a fence sync object instead?
In any case, there shouldn’t be any need for a while loop; if you’re just going to spin until the result is available, you may as well just skip the GL_QUERY_RESULT_AVAILABLE step and go straight to GL_QUERY_RESULT. GL_QUERY_RESULT_AVAILABLE is meant for the case where there are other things you can be getting on with in the meantime.