Jump to content
  • Advertisement
Sign in to follow this  
Lolums

OpenGL OpenGL Check if VBO Upload is Complete

This topic is 937 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've learnt that the upload of VBOs is asynchronous.

 

How can I check that my VBO is uploaded?

 

I'd like to do this in order not to try to draw it before the upload is complete, as this halts the program (and a lag spike is felt).

 

Edit: I've read up on fence syncing but supposing that I have my fence, how do I check for whether it's been used by the GPU without using glWaitSync? I'd like to check and get a boolean response, as opposed to waiting.

Edited by Lolums

Share this post


Link to post
Share on other sites
Advertisement

Because the OpenGL spec doesn't recognize the transfer as asynchronous, per se, there's no way to check. The only option is to force it to wait by issuing a dummy draw call. There are a variety of other things that can also be deferred and lead to hitching in-game, and so it's standard practice to issue dummy draw calls for these things. Getting rid of all this is one of the big improvements in the new APIs (DX12/Vulkan).

Share this post


Link to post
Share on other sites

Because the OpenGL spec doesn't recognize the transfer as asynchronous, per se, there's no way to check. The only option is to force it to wait by issuing a dummy draw call. There are a variety of other things that can also be deferred and lead to hitching in-game, and so it's standard practice to issue dummy draw calls for these things. Getting rid of all this is one of the big improvements in the new APIs (DX12/Vulkan).

 

Ah, I see! In that case, I may just set a time-out and only try to render after half a second or something; this won't be noticeable. Problem with DX12 is that one can't support Linux,  which for me is a crime if one can avoid it. Vulkan looks promising. Thanks for letting me know though.

Share this post


Link to post
Share on other sites

 

Because the OpenGL spec doesn't recognize the transfer as asynchronous, per se, there's no way to check. The only option is to force it to wait by issuing a dummy draw call. There are a variety of other things that can also be deferred and lead to hitching in-game, and so it's standard practice to issue dummy draw calls for these things. Getting rid of all this is one of the big improvements in the new APIs (DX12/Vulkan).

 

Ah, I see! In that case, I may just set a time-out and only try to render after half a second or something; this won't be noticeable. Problem with DX12 is that one can't support Linux,  which for me is a crime if one can avoid it. Vulkan looks promising. Thanks for letting me know though.

 

It's not necessarily on a timer. Sometimes the driver simply can't be bothered to finish the upload until you actually issue a draw call.

Share this post


Link to post
Share on other sites
All GL commands are asynchronous, but act like they're immediate. Drawing commands are async too, so if you update a VBO and then draw, both those commands go into the same queue and are processed by the GPU one after the other.

If you want it to he truely async where the GPU is doing two things at once, you need to create another GL context and share the VBO between both contexts. This gives you a second queue that's independent of your main queue, and then you can use fences to track the progress of this secondary queue.
This is tricky though -- multiple contexts can ruin performance, because GPUs only ever have one hardware queue. However, if you only ever use this second queue for buffer updates, some drivers will detect that usage pattern and create a DMA command queue instead of a graphics command queue, which can simultaneously run alongside the main context.

This is getting into very advanced and vendor-specific territory though, so if you're looking for a solution, some more details on your exact situation and problem would help --- in the common situation of small buffer updates, you just update the buffer, then draw immediately after, and let the driver do it's thing.

Share this post


Link to post
Share on other sites

Going with what Hodgman said. If you are NOT using multiple context from multiple threads then your concerns are unfounded.


All GL commands are asynchronous, but act like they're immediate. Drawing commands are async too, so if you update a VBO and then draw, both those commands go into the same queue and are processed by the GPU one after the other.


Meaning that if you update the VBO then call draw, the result will appear to be sequential/serialized..they WILL happen in the order submitted.

Share this post


Link to post
Share on other sites

Meaning that if you update the VBO then call draw, the result will appear to be sequential/serialized..they WILL happen in the order submitted.

We're not talking about logical ordering or things appearing serialized. There's a ton of operations in GL that are deferred internally, which in turn will cause runtime hitches when the driver decides to actually commit operations. Buffer uploads, texture uploads, and especially shader (re)compiles are the prime suspects here. This is not an imaginary problem for anyone who has actually shipped a game on a GL pipeline.

 

Issuing a dummy draw call - and potentially a fence or glFlush/glFinish/SwapBuffers - is the only way to combat this problem of runtime hitches. 

Edited by Promit

Share this post


Link to post
Share on other sites

Thank you! I've literally learnt so much from your responses. This made me think about where the problem actually lies, since I was not mapping any buffers or performing any sort of expensive GPU downloads. After running my profiler in "Telemetry" mode for the first time, I've discovered (within two minutes) that actually, the garbage collector usage correlates perfectly with lag spikes and I happen to be wasting a lot of memory in a certain place.

Share this post


Link to post
Share on other sites

apitest shows how to issue a fence and wait for it. The first time it checks if the fence has been signaled. The second time it tries again but flushing the queue since the driver may not have processed the copy yet (thus the GPU hasn't even started the copy, or whatever you're waiting for. If we don't flush, we'll be waiting forever. aka deadlock)
 
Of course if you want to just check if the copy has finished, and if not finished then do something else: you just need to do the 'wait' like the first time (i.e. without flushing), but using waiting period of zero (so that you don't wait, and get a boolean-like response like OP wants). We do this in Ogre to check for async transfer's status.

So can you use a fence to test for the actual status of a BufferSubData call uploading to server? And that works consistently across platforms without issuing a draw call against that buffer? After all the driver must do a full copy of the buffer to somewhere in-core at the point of call, but what the rube goldberg machine does after that is anyone's guess.

 

 


Calling glDraw* family of functions won't stall because it's also asynchronous. I can't think of a scenario where the API will stall because an upload isn't complete yet.

It'll stall if it gets caught in a situation where it can't continue dispatching frames without finishing a pending operation. I don't remember seeing this happen with buffer uploads, but I've seen it many, many times with shader recompiles. Whether this is because shader recompiles are a long goddamn process, or they have to happen in the main thread, or it just runs up against the limit of buffered frames, or some combination thereof, I'm not sure. It seems conceivable that a large upload followed by lots of dispatched frames could conceivably trigger the same effect.

Edited by Promit

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!