Most efficient ordering of thingies during frame.

Started by
12 comments, last by Staffan E 18 years ago
Quote:Original post by CV
Quote:Original post by clb
I've been trying to figure out what would be the best way to order various task during a single game frame.

The driver is buffering some frames before rendering. You certainly know the driver setting 'Max Frames to Render Ahead'. This buffer avoid such synchronisation bubbles.
So if you don't force any synchronisation (e.g. readbacks), don't be worry about it.


Ah of course, triple buffering, that explains why my test model didn't behave according to the diagram. I tried and forced a back buffer lock right before Present(), which of course stalls until all rendering is complete. Then profiling again the results were just like expected. So, lessons learned:

1) 'Update, Render, Present' vs 'Update, Present, Render' doesn't matter much IF you have more than one back buffer in your swap chain (D3DPP.BackBufferCount > 1 ).

2) Present() returns immediately if there's a free back buffer in your swap chain available. If not, it stalls until one is flipped and freed.

3) Obviously, locking the back buffer is BAD. Not only it stalls until all rendering is complete, but it also makes the whole back buffer chain obsolete. The reason is that if you're locking back buffer each frame, you need to go in sync with the GPU and the extra back buffer chains are totally wasted!
Advertisement
Quote:Original post by clb
Ah of course, triple buffering, that explains why my test model didn't behave according to the diagram.

Triple buffering usually means having three framebuffers. A framebuffer takes place "between" the gpu and the ramdac. I mean a buffer inside the driver between the application and the gpu.



The point is that calling EndScene() doesnt effectively stop the GPU. Its telling the Drivers/GPU to finish off all pending render requests (there can be a queue of requests pending in many cases)

While Present() in the tripple-buffering case means there is never (?) a stall at this specific point in time, that doesnt negate the fact that the GPU still isnt finished and simply cannot perform a bonified state change (altering render targets, changing streams, and so forth) until its done - the stall is only deferred until the next render request or state change.

I suggest taking microsofts advice, because it plays well with BOTH 2-buffer and 3-buffer strategies. Find some expensive CPU work and do it between EndScene() and Present() .. seems simple enough. Idealy the GPU finishes up the current frame precisely when the CPU issues Present()


Quote:Original post by Rockoon1
While Present() in the tripple-buffering case means there is never (?) a stall at this specific point in time, that doesnt negate the fact that the GPU still isnt finished and simply cannot perform a bonified state change (altering render targets, changing streams, and so forth) until its done - the stall is only deferred until the next render request or state change.

That's what I was trying to get at earlier but you put it in better words. The point is that a) using multiple backbuffers and b) trying to fill out the time between EndScene() and Present() with CPU work are two separate techniques that can enhance efficiency. They are neither mutually exclusive nor the same thing.

Hack my projects! Oh Yeah! Use an SVN client to check them out.BlockStacker

This topic is closed to new replies.

Advertisement