Members - Reputation: 565
Posted 05 April 2012 - 09:57 AM
I'm writing rendercode for a cad-like application. It will be used to process lots of unstructured triangles. Rendering those takes some time (vertex data might not fit into video ram, multipass techniques are really slow on some hardware,...), but it should not 'block' the application. That's why all 'real' rendering is done on a second thread, and the main thread should only 'blit' (Present, fullscreen quad,...) the results to a window.
So whenever an application generates an event that should trigger a redraw, the renderthread will first draw a 'quick' approximation (using LOD, simpler techniques, or maybe even drawing bounding boxes or nothing at all...) for the application to show. Afterwards it will start rendering a slow high-quality image. To avoid flickering (because of always showing the 'quick' image) the main application thread will always wait some time (eg. 30Hz) before presenting the 'quick' image. If within that time the high-quality image is ready, the 'quick' image will be discarded.
The renderthread on the other hand should have the possibility to interrupt rendering the high-quality image. So that when lots of render requests arrive (eg. the user is interactively rotating the view) it can continuously generate the 'quick' frames for immediate feedback.
An alternative idea to avoid the render-to-texture-combined-with-fullscreen-quad approach is to create swapchains with one backbuffer. The quick image could be rendered directly to the backbuffer. The slow image is still rendered to texture, but the final stage would be to blit the slow image to the backbuffer. That way, the main thread only has to call Present() whenever it wants, and very little locking has to happen. Well, actually lots of locking has to happen, but it will be relatively simple, and the waiting will be limited. I would use a rendercommand queue approach where every rendercommand does some state setting and typically one draw call. Each one of those would then be locked separately, giving the main thread the opportunity to call Present() in between rendercommands.
Thanks for reading!