We often neglect to get too involved in the discussion of what options people should always enable when they play games. Rather, we tend to focus on what we test with. Honestly, our recommended settings for playing the games we test would be very similar to the settings we use to benchmark with one very important exception: we would enable triple buffering (which implies vsync) whenever possible. While it's not an available option in all games, it really needs to be, and we are here to make the case for why gamers should use triple buffering and why developers need to support it.
Most often gamers, when it comes to anything regarding vsync, swear by forcing vsync off in the driver or disabling it in the game. In fact, this is what we do when benchmarking because it allows us to see more clearly what is going on under the hood. Those who do enable vsync typically do so to avoid the visual "tearing" that can occur in some cases despite the negative side effects.
We would like to try something a little different with this article. We'll include two polls, one here and one at the end of the article. This first poll is designed to report what our readers already do with respect to vsync and double versus triple buffering.
{poll 134:300}
After reading the rest of this article, our readers are invited to answer a related poll which is designed to determine if arming gamers with the information this article provides will have any impact on what settings are used from here on out.
First up will be a conceptual review of what double buffering and vsync are, then we'll talk about what triple buffering brings to the table. For those who really want the nitty gritty (or who need more convincing) we will provide follow that up with a deeper dive into each approach complete with some nifty diagrams.
184 Comments
View All Comments
Schmide - Friday, June 26, 2009 - link
Nice analysis."In my explanation I'm going to refer to any buffer swapping as copying from one buffer to another; how it is implemented by the hardware is irrelevant."
I think you have to elaborate on what's a copy and what's a swap as they are very different operations. Copying locks both surfaces preventing the use of both and takes processing power, while swapping locks nothing and takes no processing power.
In your explanation, you would have very different results if it was a copy or a swap.
PrinceGaz - Friday, June 26, 2009 - link
I understand if the card is actually copying blocks of memory between fixed buffers that it would have a performance impact. Whether it is copying or swapping is irrelevant as to what I was trying to explain, which is why I said how it is implemented by the hardware isn't relevant. It's best just to assume that in reality it is swapping buffers, which is equivalent to an instantaneous copy/move.The only thing is I've now realised there is a third way triple-buffering could work, which is roughly halfway between the two methods I proposed; if both B and C have been filled at the vertical-refresh meaning the card has been stalled, B is discarded, C is moved to A to be displayed, and the card now starts rendering to B, then to C. Again that makes no difference when the framerate is below the refresh-rate but it allows the card to render at up to double the refresh-rate to reduce the lag to a minimum of one instead of two refreshes when conditions allow.
Schmide - Friday, June 26, 2009 - link
Ok I get it.3 buffers A, B and C all fully renderable. The rendering goes as so:
A is rendered and queued to become the primary on the refresh after it's completion.
B begins rendering right after A is completed then queued to become primary the refresh after A or the next refresh after B completes.
C begins rendering after B finishes rendering and queues as B was queued to A.
repeat.
The advantage being, when vsinc is on, instead of starting the rendering of the next surface after the swap, you start a rendering immediately on 3rd surface rather than wait for the current primary to become available after the swap.
Makes sense.
DerekWilson - Saturday, June 27, 2009 - link
This is a good explanation of render ahead ... it's different than using triple buffering for page flipping.PrinceGaz - Friday, June 26, 2009 - link
ooops, made a slight error in my lag calculations when framerate can exceed refresh-rate.Two frames ago (my method) is correct- 0.033 seconds always because that is how long two refreshes take at 60hz.
Your method (constant back-buffer updating) will be between one and two frames ago, not zero to one frames like I said, so at 100fps the lag would actually be between 0.010 and 0.020 seconds, not 0 and 0.010 seconds like I said earlier.
Sorry about that.
DerekWilson - Friday, June 26, 2009 - link
Actually, this is precisely why I wanted to write this article.The technique you describe here:
"The way I understand triple-buffering works is that once B and C both have frames rendered to them waiting to be displayed, the graphics-card then pauses until the vertical-refresh, at which point B is copied to A to be displayed, C is moved to B, and the card is free to start work on rendering a new frame to fill the now empty C. No frames are thrown away, and the card is not constantly churning out frames which won't be displayed."
While it uses 3 buffers, is actually called render ahead. I'm talking about a page flipping method (which can actually be combined with render-ahead, but that's beyond the scope of this piece).
The benefit of the DirectX render ahead approach (which can be up to 8 frames iirc), is that it incurs a higher potential latency in order to achieve much smoother action.
If my framerate fluctuates a lot between high and low rates, it's possible that the game will feel "jerky." But using render ahead, I can essentailly cache up to X (the default is 3) quickly rendered frames so that the next long frametime I hit doesn't cause the monitor to keep showing the exact same image for multiple frames while it waits -- instead, if i have my 3 frames rendered ahead, if the frametime of my next frame is anything up to 50ms, my rendered ahead frames can be spat out, one after the other, sequentially until my 4th frame is ready. if frame rate goes back up after this, then i've successfully smoothed things out.
the price is, of course, that high framerate means we will see lag because no frames are dropped.
but this is not triple buffering.
DirectX does not support actual triple buffering out of the box -- it has to be programmed by the developer. OpenGL does actually support triple buffering inherently as I described.
I promise that the description I gave in the article is what triple buffering is supposed to be. calling render ahead triple buffering because the default uses 3 buffers has definitely caused a lot of confusion (especially when the wikipedia page cites this as a reason that render ahead is "an implementation" of triple buffering ... which is disingenuous in my mind).
we don't, afterall, call anything that uses 2 buffers double buffering -- like if I use 2 MRTs while I'm rendering something, am I double buffering then? in the same sense that 3 frame render ahead is triple buffering then sure ... but not if we are talking about page flipping.
... so ...
also, the lag between 0 and 1 frames that i was talking about is lag between the END of rendering the frame and when it is displayed. If frametime is taken into account, the input that generated that frame will have happened, at a maximum of (frametime + 16.67ms) ... so it could be longer ago than just one frame but not /because/ of triple buffering.
GreyMulkin - Friday, June 26, 2009 - link
VSYNC for life!This article has convinced me that I only want to use double buffering + vsync. I despise tearing - your example of "only seeing it on fast turns" is disingenuous. When vsync is off, even games with simple graphics tear, everywhere. I find it distracting and undesirable. But I also don't want the input lag associated with being 1 more frame away from the action.
"While enabling vsync does fix tearing, it also sets the internal framerate of the game to, at most, the refresh rate of the monitor (typically 60Hz for most LCD panels)."
I see no problem with this. I'd much rather have the game running near a constant framerate than to have it bounce back and forth between high and low performance. Consistency is what I want.
"This can hurt performance even if the game doesn't run at 60 frames per second as there will still be artificial delays added to effect synchronization. Performance can be cut nearly in half cases where every frame takes just a little longer than 16.67 ms (1/60th of a second). In such a case, frame rate would drop to 30 FPS despite the fact that the game should run at just under 60 FPS."
Well, if your frames are taking longer than 16.67ms to render, then you're not actually rendering 60 fps. Duh! Longer rendering times mean lower framerates. If you don't like the framerate you're seeing, turn down some settings (resolution, quality, AA, AF, etc). Triple buffering won't fix the problem of render times which are too long for the desired framerate.
GreyMulkin - Friday, June 26, 2009 - link
To elaborate on the "while enabling vsync..." thing. Vsync off usually makes the game try to run as fast (high fps) as possible which is generally recognized as a good thing. But because scenes differ in complexity, the frames rendered per second will vary wildy and that will affect input processing which is usually tied directly to fps. So what I don't want is the *feel* of the game, the smoothness of mouse movements, etc, to be affected.MadMan007 - Friday, June 26, 2009 - link
Depends upon the game. For online competitive FPS I disable vsync, for single player games or less twitchy ones I enable it. There's no poll option for this.TonyB - Friday, June 26, 2009 - link
I still use my 21" CRT, i run at 100hz refresh rate with vsync on w/ triple buffering.at 100hz, your input lag is only 10ms (1/100) compared to 16.6ms (1/60) not to mention i'm capped at 100 fps instead of 60fps.
this is why i'm still using CRT instead of LCD.