What are Double Buffering, vsync and Triple Buffering?
When a computer needs to display something on a monitor, it draws a picture of what the screen is supposed to look like and sends this picture (which we will call a buffer) out to the monitor. In the old days there was only one buffer and it was continually being both drawn to and sent to the monitor. There are some advantages to this approach, but there are also very large drawbacks. Most notably, when objects on the display were updated, they would often flicker.
The computer draws in as the contents are sent out.
All illustrations courtesy Laura Wilson.
In order to combat the issues with reading from while drawing to the same buffer, double buffering, at a minimum, is employed. The idea behind double buffering is that the computer only draws to one buffer (called the "back" buffer) and sends the other buffer (called the "front" buffer) to the screen. After the computer finishes drawing the back buffer, the program doing the drawing does something called a buffer "swap." This swap doesn't move anything: swap only changes the names of the two buffers: the front buffer becomes the back buffer and the back buffer becomes the front buffer.
Computer draws to the back, monitor is sent the front.
After a buffer swap, the software can start drawing to the new back buffer and the computer sends the new front buffer to the monitor until the next buffer swap happens. And all is well. Well, almost all anyway.
In this form of double buffering, a swap can happen anytime. That means that while the computer is sending data to the monitor, the swap can occur. When this happens, the rest of the screen is drawn according to what the new front buffer contains. If the new front buffer is different enough from the old front buffer, a visual artifact known as "tearing" can be seen. This type of problem can be seen often in high framerate FPS games when whipping around a corner as fast as possible. Because of the quick motion, every frame is very different, when a swap happens during drawing the discrepancy is large and can be distracting.
The most common approach to combat tearing is to wait to swap buffers until the monitor is ready for another image. The monitor is ready after it has fully drawn what was sent to it and the next vertical refresh cycle is about to start. Synchronizing buffer swaps with the Vertical refresh is called vsync.
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). 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. The elimination of tearing and consistency of framerate, however, do contribute to an added smoothness that double buffering without vsync just can't deliver.
Input lag also becomes more of an issue with vsync enabled. This is because the artificial delay introduced increases the difference between when something actually happened (when the frame was drawn) and when it gets displayed on screen. Input lag always exists (it is impossible to instantaneously draw what is currently happening to the screen), but the trick is to minimize it.
Our options with double buffering are a choice between possible visual problems like tearing without vsync and an artificial delay that can negatively effect both performance and can increase input lag with vsync enabled. But not to worry, there is an option that combines the best of both worlds with no sacrifice in quality or actual performance. That option is triple buffering.
Computer has two back buffers to bounce between while the monitor is sent the front buffer.
The name gives a lot away: triple buffering uses three buffers instead of two. This additional buffer gives the computer enough space to keep a buffer locked while it is being sent to the monitor (to avoid tearing) while also not preventing the software from drawing as fast as it possibly can (even with one locked buffer there are still two that the software can bounce back and forth between). The software draws back and forth between the two back buffers and (at best) once every refresh the front buffer is swapped for the back buffer containing the most recently completed fully rendered frame. This does take up some extra space in memory on the graphics card (about 15 to 25MB), but with modern graphics card dropping at least 512MB on board this extra space is no longer a real issue.
In other words, with triple buffering we get the same high actual performance and similar decreased input lag of a vsync disabled setup while achieving the visual quality and smoothness of leaving vsync enabled.
Now, it is important to note, that when you look at the "frame rate" of a triple buffered game, you will not see the actual "performance." This is because frame counters like FRAPS only count the number of times the front buffer (the one currently being sent to the monitor) is swapped out. In double buffering, this happens with every frame even if the next frames done after the monitor is finished receiving and drawing the current frame (meaning that it might not be displayed at all if another frame is completed before the next refresh). With triple buffering, front buffer swaps only happen at most once per vsync.
The software is still drawing the entire time behind the scenes on the two back buffers when triple buffering. This means that when the front buffer swap happens, unlike with double buffering and vsync, we don't have artificial delay. And unlike with double buffering without vsync, once we start sending a fully rendered frame to the monitor, we don't switch to another frame in the middle.
This last point does bring to bear the one issue with triple buffering. A frame that completes just a tiny bit after the refresh, when double buffering without vsync, will tear near the top and the rest of the frame would carry a bit less lag for most of that refresh than triple buffering which would have to finish drawing the frame it had already started. Even in this case, though, at least part of the frame will be the exact same between the double buffered and triple buffered output and the delay won't be significant, nor will it have any carryover impact on future frames like enabling vsync on double buffering does. And even if you count this as an advantage of double buffering without vsync, the advantage only appears below a potential tear.
Let's help bring the idea home with an example comparison of rendering using each of these three methods.
184 Comments
View All Comments
DerekWilson - Friday, June 26, 2009 - link
In game options for DX games are what we need to rely on right now, as there is no control panel option in a driver for this.It is possible to force triple buffering in some DX games through other means, but what is needed is game and driver developer pressure to get this feature into every game.
ukbrainstew - Sunday, June 28, 2009 - link
You'd be surprised the amount of games D3DOverrider works with, I find compatibility is easily over 90%.That developers don't include the option is really rather frustrating, though I just thank the PC community for coming up with a very good workaround as they invariably tend to do.
Another setting that I'd like to become standard is the ability to choose a framerate cap. Plenty of engines allow it (though its often locked away) and it can work wonders for increasing the smoothness and playability of games on older hardware.
Even sub $100 parts could maintain a damn near constant 30fps in most games at 720p resolution but they very well may struggle trying to hit 60fps often resulting in wild variances. Would it not be to the benefit of Nvidia and AMD's marketing if they could produce a driver level setting that caps games at half your refresh rate? A setting that would suddenly making their budget parts capable of maintaining a steady framerate in so many more games thus making them much more attractive products.
Anyway, thanks a lot for the article, triple buffering has been something of particular interest to me as I really can't bear a game with any appreciable amount of tearing and I'd really rather not suffer increased input lag and as much as a 50% reduction in my framerate when a simple setting can do away with it all in one fell swoop.
Could I suggest a mention of D3DOVerrider in the article? Surely giving readers advice on how to benefit from triple buffering in more games would be a worthy addition and something many may be craving now that they're armed with knowledge of its inherent benefits.
erple2 - Sunday, June 28, 2009 - link
I think the reduction in frame rate is to an even multiple of the maximum frame rate - You'll get 1 (refresh rate of monitor), 1/2, 1/3, 1/4, 1/5, 1/6 etc. and nothing in between with vsync on.I've noticed that in games that allow me to show the frame rate, I get exactly 60 FPS (I have an LCD monitor), 30 FPS, 20 FPS, 15 FPS, 12 FPS, or 10FPS (and so on) and nothing in between. But that's the way the vsync operates with double buffering.
With triple buffering, I can get more or less any FPS rate lower than 60.
fiveday - Friday, June 26, 2009 - link
Yes. D3DOverrider is a utility that (as the name implies) overrides certain D3D calls and forces a few of its own settings. Specifically, it can force Triple Buffering and VSync (on or off) in any Direct 3D application. It comes with RivaTuner, but is a seperate app - you won't find it in RT's settings, but in it's installed folder as a standalone program.So yeah - download the latest RivaTuner (which you don't even have to run, tho it's useful!) and use D3DOverrider to force triple buffering in Direct 3D.
This saved my experience with Dead Space... and I've been singing it's praises ever since.
toyota - Friday, June 26, 2009 - link
I have to go ahead and laugh at the people that turn triple buffering on from the standard control panel and claim they see a difference. that setting has NO effect on DX games and is for OpenGL only. of course you have to use a third party app like rivatuner nhancer to actually force triple buffering on. its nice that some games like L4D have it built right into the game options though so that it is very convenient to enable from within the game without any third party crap to fool with.leexgx - Saturday, June 27, 2009 - link
Why is there not an Pole option for triple buffer with Vsync on and off or is the pole option ment for Vsync on with triple if so its Not what most of us would of pickedi allways run the games if i can with triple but No Vsync as the lag is to much
Vsync on has always made input lag be it 3 buffers or 2
Hrel - Monday, June 29, 2009 - link
pole is supposed to be poll, the way you mean. Confusing the way it is.The0ne - Friday, June 26, 2009 - link
For now, I just check the games to make sure there's an option for it. If not then I don't bother trying to find a way around it. Derek has it right, developers has to see the benefits and implement it if video card mfger's or MS doesn't implement it.DerekWilson - Friday, June 26, 2009 - link
This is the reason the last line of our article is focused on the developers.They definitely, like Valve, need to start including triple buffering in in-game options.
And it would be nice if NVIDIA and AMD could build something into the driver to make it work for everything. They put a lot of time into making AA work in most games, why not do the same for triple buffering?
GourdFreeMan - Friday, June 26, 2009 - link
I was under the impression that if you set VSync to "Force On" and Tripple Buffering to "On" in the nVIDIA control panel under the "Global Settings" tab you effectively force triple buffering on for all aplications, except those specifically excluded by their individual profiles. Is this not the case? This option has been available for years... admittedly I have never attempted to capture frames to verify that triple buffering is actually occuring.I don't see why this shouldn't work universally for applications -- as far as the application knows the only thing that has changed is the size of the pool of available graphics memory.