Tuesday, January 12, 2010

D3D Occlusion Queries are Eeeeeeeeevil

I haven't yet decided if they were born evil or if they're making a conscious effort to be evil, but evil is what they are nonetheless.

The trick with occlusion queries is to prevent them from stalling the pipeline while fetching the results. In order to do this I use a technique where I get the previous frame's results before issuing the current frame's queries (checking of course that there were results to get in the first place).

Now, there are certain things about D3D queries where things go bad here. In D3D, if a query has been issued it's results MUST be fetched before it can be reissued. Zere iz nein otzer OPTION!

So how does D3D respond if you accidentally do this? Does it fail silently? Does it discard the pending results and just reissue? Is there anything even remotely graceful or elegant about it's handling of the situation? What do you think?

No.

It locks your GPU.

Violently.

No further comment, m'lud.

FOLLOW-UP

In attempting to track this down I implemented the "naive" version of occlusion queries and just did an issue/getdata directly in the same frame. It still locks. Then I split the loop in 2, did a batch of issues, followed by a batch of getdatas. Still locks.

The current theory here is that there is some undocumented thing going on when you combine occlusion queries with VBOs, as this approach had worked before.

Or maybe it is documented but you need to join the dots yourself between 47 completely different and unconnected pages of the SDK, then follow a convoluted train of logic before you get to the info you need (just like so many other things, in other words).

Anyway - guess what D3D feature I won't be using? Maybe I'll find a way of doing this in software instead, as I really do want to be able to filter out those entities.

Sigh. It's times like this that I miss OpenGL.

5 comments:

=peg= said...

I did a little googling on occlusion queries and stumbled upon this and this article that *might* be helpful..

gloVA said...

Try searching also CHC++, it supposed to be better than this article from GPU Gems 2. When I will implement it i will tell you the results. But it can be a while since i've just started the reaserch about oclussion culling topic.

mhquake said...

Cheers folks. I'd already figured out much of the techniques from those articles on my own (in particular the previous frame stuff), right now it's specifically the D3D implementation that's breaking.

The real killer is that it didn't break before I had implemented VBOs.

mhquake said...

As a follow-up, the big question after seeing what D3D queries are csapable of doing is: "can I trust them?"

I could put in the work to resolve this, and I don't doubt that I would succeed, but can I be absolutely certain that a DirectQ that included occlusion queries would not do the same to your machines in some situations once it got out in the wild?

Unless Microsoft have a document explaining precisely what is going on here, precisely the circumstances under which it happens, and precisely how to avoid it, and all under one roof, the answer has to be "no".

=peg= said...

There *might* be some more useful info here..