Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform asynchronous off-screen queries?

I have several (potentially thousands) of scenes I would like to render in order to perform queries on what is drawn. The problem I am running into is that calls to glGetQueryObjectiv() are expensive, so I'd like to figure out a way to render several scenes in advance while I wait for the results of the queries to become available.

I have read a bit about Framebuffer Objects and Pixel Buffer Objects, but mostly in the context of saving to a file using glReadPixels() and I haven't been able to track down an example of using either of these objects in asynchronous queries. Is there any reason why the setup for performing glGetQueryObjectiv() would be different from glReadPixels() as in this example (e.g., should I use an FBO or a PBO)?

Note: This is NOT for a graphics application. All I'm interested in is the result of the GL_SAMPLES_PASSED query (i.e. how many pixels were drawn?).

The specific application is estimating how much sunlight is striking a surface when other surfaces are casting shadows. If you are interested, you can read about it here.

like image 646
Neal Kruis Avatar asked Nov 01 '22 07:11

Neal Kruis


1 Answers

Neither Framebuffer Objects nor (Pixel) Buffer Objects are the proper class of objects to use in an (asynchronous) query; GL has an entirely separate class of objects called Query Objects. You can feed the results of certain queries into Buffer Objects, but that is about as far as their relationship goes.

Basically the idea with asynchronous queries is that you put the query into the graphics pipeline and let some time pass before you try to read it back. This gives the GPU time to actually finish all of the commands in between the beginning and end of your query first. The alternative is a synchronous query, which means that your calling thread stops doing anything useful and waits for the GPU to finish everything necessary to complete your query.

The simplest way of implementing a query that does not force synchronization would be to start and finish your query as you would typically, but rather than reading the result immediately, in your application's main loop periodically check the status of GL_QUERY_RESULT_AVAILABLE for your query object. When this gives you GL_TRUE, it means you can read the results from the query object without disrupting the render pipeline. If you do try to get the results from a query object before it is in this state, you are going to force a synchronous query.

like image 116
Andon M. Coleman Avatar answered Nov 15 '22 03:11

Andon M. Coleman