Occlusion queries with FBOs

Does anyone have any experience using occlusion queries on primitives being drawn into an FBO? I can’t find any mention of this in the extension specs for FBOs or occlusion queries. I’m rendering into a texture using an FBO with a renderbuffer attached. The texture drawing comes back fine, but the occlusion queries all come back as zeros. I have a flush after drawing into the texture, but the pixel count comes back as zero for every primitive. Anyone know of documentation that explains how you might go about doing this? Thanks!

Never tried it but do you use any depth renderbuffer ?

The specs don’t say anything about this combination. I believe it’s intended to “just work”, where fragments rendered into an FBO do get counted by occlusion query. What GPU and driver version?

Originally posted by jide:
Never tried it but do you use any depth renderbuffer ?
Yep, that’s what I’m doing. The renderbuffer I’m attaching to the FBO is attached to the depth attachment. It’s depth_component24.

Originally posted by JeffJ:
The specs don’t say anything about this combination. I believe it’s intended to “just work”, where fragments rendered into an FBO do get counted by occlusion query. What GPU and driver version?
It’s a 7800 GTX with a driver from 8/11/06 for Windows x64. I had some trouble getting a shader to link the other day so I updated to fix that. I also got the impression that it’s supposed to “just work,” which bothers me because I don’t know where the problem actually is.

So maybe it has something to do with the stencil buffer. I just remember some talked about it for OQ but for another purpose: (http://www.opengl.org/discussion_boards/ubb/ultimatebb.php?ubb=get_topic;f=3;t=014730)

Sorry for the only guesses… but I would also like to know if that could even be doable.

FWIW im using occlusion + FBO no probs on a gffx.
u r querying to see if the result is available first i take it

I’ve recently run into a bug on NV drivers where changing OpenGL context and immediately changing back again would break an active occlusion query (cause it to return 0). This could be something similar.

You shouldn’t have to check if the result is available - querying the result is supposed to block until the result is available.

Originally posted by zed:
FWIW im using occlusion + FBO no probs on a gffx.
u r querying to see if the result is available first i take it

No, I’m not checking to see if the result was available. I put in a flush after all my queries and assumed it would be enough. If I query to see if the result is available, won’t it block until the results are finished?

im not to sure about this but glFinish() means it wont proceed furture until everythings finished (ie high precedence than flush()) but then again i dont think thats the problem, also sticking flush/finish in your code generally aint a good idea if u care about performance.
in the spec example they do use the query_if result is avaiable method (personally i dont cause it always seems to be available with the stuff ive done)

theres an example app using it on the vnidia developer website i suggest u download that + see if it works

You really need to wait until the OQ has finished before doing any queries, and it could take a moment depending on the complexity of your scene. Or as zed said do something long enough so that you can always assume this is okay even if I think this is a bit dangerous (queries of occlusion generally go faster than the generation of them so that you could end with unavailable queries whereas the first ones where available).

As it was mentioned, you need to wait until the result is available. You can do a loop similar as:

do {
// you can do something to avoid waste this time

glGetQueryObjectiv(query_id,GL_QUERY_RESULT_AVAILABLE,&samples);
}while(samples != GL_TRUE);

glGetQueryObjectiv(query_id,GL_QUERY_RESULT,&samples);

You do not need to wait manually. If the result is not available, then GetQueryObjectiv(GL_QUERY_RESULT) will block until it is available.

You also do not need to manually place a Flush or Finish anywhere for queries to work.

As always, the OpenGL spec is the authoritative place to learn about these things:

There may be an indeterminate delay before the above query returns. If pname is QUERY RESULT AVAILABLE, it immediately returns FALSE if such a delay would be required, TRUE otherwise.
and

Querying the state for any given query object forces that occlusion query to complete within a finite amount of time.
The OpenGL implementation you are using is broken.

No, definately no. This is not a blocking function.

jide: It is. The spec is absolutely clear about it. It has always been a blocking function. You can query, if the result is available, but that’s not necessary for it to work, only to be able to speed things up.

And it should just work, but the implementation indeed seems to be broken. It’s not like that would be something surprising… :frowning:

Jan.

So I am surpised. I often have to wait until the result are available and do a loop around it. So I really don’t understand.

So how should I interpret such a code (kept from the specs example) ?

do {
   DoSomeStuff();
   glGetQueryObjectivARB(queries[i],                                  GL_QUERY_RESULT_AVAILABLE_ARB, &available);
} while (!available);

Or maybe we have different means for the term ‘blocking’ (just as system blocking function) ?

Originally posted by jide:
[b]
So how should I interpret such a code (kept from the specs example) ?

do {
   DoSomeStuff();
   glGetQueryObjectivARB(queries[i],                                  GL_QUERY_RESULT_AVAILABLE_ARB, &available);
} while (!available);

[/b]
That code serve as demonstation that the application can do something usefull while waiting for the query results. The last example in the specification simply queries the results without querying for the availability.

I’m just realizing I misunderstand the phrase from Frogblast:

If the result is not available, then GetQueryObjectiv(GL_QUERY_RESULT) will block until it is available

I really should read the phrases ten times…

Sorry for the rubbishes.

Originally posted by Justin Bozalina:
I also got the impression that it’s supposed to “just work,” which bothers me because I don’t know where the problem actually is.
Bozalina, is this still a problem for you? Can you make available your application that shows the problem?

I have a couple applications that use FBO + occlusion query (on geforce) without issue. I’d like to compare against your application’s use of the OGL API.