Wrapping It Up

So there you have it. Triple buffering gives you all the benefits of double buffering with no vsync enabled in addition to all the benefits of enabling vsync. We get smooth full frames with no tearing. These frames are swapped to the front buffer only on refresh, but they have just as little input lag as double buffering with no vsync at the start of output to the monitor. Even though "performance" doesn't always get reported right with triple buffering, the graphics hardware is working just as hard as it does with double buffering and no vsync and the end user gets all the benefit with out the potential downside. Triple buffering does take up a handful of extra memory on the graphics hardware, but on modern hardware this is not a significant issue.

Just to recap, from our previous example, here are what the three frames we looked at rendering stack up side by side.

 


Triple Buffering


 

 


Double Buffering


 

 


Double Buffering with vsync


 

We've presented the qualitative argument and the quantitative argument in support of triple buffering. So, now the question is: does this data change things? Are people going to start looking for that triple buffering option more now than without this information? Let's find out.

{poll 135:300}

Regardless of the results, we do hope that this article has been helpful both in explaining an often overlooked option. While it might not be something we test with because of the issues with measuring performance, triple buffering is the setting we prefer to play with. We hope we've helped show our readers why they should give triple buffering a shot as well. 

We also hope more developers will start making triple buffering the default option in their games, as it will deliver the best experience to gamers interested in both quality and performance. There are only a handful of games that include triple buffering as a built in option, and NVIDIA and AMD drivers currently only allow forcing triple buffering in OpenGL games. This really needs to change, as there is no reason we shouldn't see pervasive triple buffering today.


UPDATE: There has been a lot of discussion in the comments of the differences between the page flipping method we are discussing in this article and implementations of a render ahead queue. In render ahead, frames cannot be dropped. This means that when the queue is full, what is displayed can have a lot more lag. Microsoft doesn't implement triple buffering in DirectX, they implement render ahead (from 0 to 8 frames with 3 being the default).

The major difference in the technique we've described here is the ability to drop frames when they are outdated. Render ahead forces older frames to be displayed. Queues can help smoothness and stuttering as a few really quick frames followed by a slow frame end up being evened out and spread over more frames. But the price you pay is in lag (the more frames in the queue, the longer it takes to empty the queue and the older the frames are that are displayed).

In order to maintain smoothness and reduce lag, it is possible to hold on to a limited number of frames in case they are needed but to drop them if they are not (if they get too old). This requires a little more intelligent management of already rendered frames and goes a bit beyond the scope of this article.

Some game developers implement a short render ahead queue and call it triple buffering (because it uses three total buffers). They certainly cannot be faulted for this, as there has been a lot of confusion on the subject and under certain circumstances this setup will perform the same as triple buffering as we have described it (but definitely not when framerate is higher than refresh rate).

Both techniques allow the graphics card to continue doing work while waiting for a vertical refresh when one frame is already completed. When using double buffering (and no render queue), while vertical sync is enabled, after one frame is completed nothing else can be rendered out which can cause stalling and degrade actual performance.

When vsync is not enabled, nothing more than double buffering is needed for performance, but a render queue can still be used to smooth framerate if it requires a few old frames to be kept around. This can keep instantaneous framerate from dipping in some cases, but will (even with double buffering and vsync disabled) add lag and input latency. Even without vsync, render ahead is required for multiGPU systems to work efficiently.

So, this article is as much for gamers as it is for developers. If you are implementing render ahead (aka a flip queue), please don't call it "triple buffering," as that should be reserved for the technique we've described here in order to cut down on the confusion. There are games out there that list triple buffering as an option when the technique used is actually a short render queue. We do realize that this can cause confusion, and we very much hope that this article and discussion help to alleviate this problem.

Digging Deeper: Galloping Horses Example
Comments Locked

184 Comments

View All Comments

  • vegemeister - Tuesday, August 6, 2013 - link

    >in fact, at higher framerates there is always a higher chance of tearing than at lower frame rates (at 300 FPS tears will happen every frame, whereas at 40 FPS, tears cannot possibly happen every frame -- the lower the frame rate, the less likely or often tearing occurs).

    With vsync off, effectively every rendered frame tears. The only time you render a frame and don't get tearing is if you get lucky and accidentally swap during vblank.
  • Schmide - Friday, June 26, 2009 - link

    Actually if you read PrinceGaz and my discussion.

    When vsinc is on, the rendering of the next frame actually starts immediately after the previous frame and would provide no delay as long as the rendering time was less than the current refresh rate.

    The only real cost is memory.
  • DerekWilson - Friday, June 26, 2009 - link

    When rendering time is more than refresh time, double buffering with vsync can incur up to almost two full frames of lag (~33ms) in addition to the frame time.

    with triple buffering, this will be reduced to at most one frame of lag (~16.7ms) but this is the worst case scenario for triple buffering. average case will absolutely be less than this. average case for double buffering without vsync will be equal to this for the first frame that started being drawn to the screen (before any tear that may or may not happen). average case for double buffering with vsync will always be higher than triple buffering.
  • SonicIce - Friday, June 26, 2009 - link

    if you think vsync with triple buffering has the same performance as double buffering then i feel sorry for you
  • PrinceGaz - Friday, June 26, 2009 - link

    Your explanation of double-buffering and enabling vertical-sync are certainly correct, but your explanation of how triple-buffering works is not how I understand it works (I've read a few articles on such things over the years, yeah... sad).

    I believe triple-buffering is as follows:

    You have three buffers: A (front-buffer), B (back-buffer), C (third-buffer or second back-buffer). 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.

    Your explanation is correct up until the point that all three buffers have a frame written to them, so A is currently being displayed, B has the next frame to be displayed, and C has just been filled with another frame. At that point, you say C is moved to B, and a new frame starts being rendered into C; in other words the card is constantly rendering frames to the two back-buffers as fast as possible and updating B at every opportunity. So that a recently completed frame is available in B to be moved to A at the vertical-refresh.

    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.

    The whole point behind triple-buffering was to prevent framerate slowdowns caused by stalling when using double-buffering with vsync at framerates BELOW the refresh rate, NOT to minimise lag caused by vsync with double-buffering at framerates ABOVE the refresh rate (slight lag when the card was churning out frames faster than the refresh-rate was not seen as a problem with vsync, but big framerate drops like from 55fps to 30fps when it couldn't keep up were a major problem worth fixing).

    It should be noted that there is no difference between the two methods (constantly updating the back-buffers like you say, or stalling once both are filled like I've read elsewhere) at framerates below the refresh-rate as the two back-buffers are never both filled; a frame will always be moved from B to A to be displayed, before the one being drawn to C is completed (which means it can be immediately be moved to B and work continued on another one to fill C).

    The difference is when the framerate is considerably higher than the refresh-rate. In your scenario, when the refresh occurs, the last frame the card has just rendered is displayed. At 100fps, that would be a frame completed no more than 0.01 seconds ago (because thats how quickly the card is churning out frames and pushing them into buffer B), meaning there is negligible lag (between 0 and 0.010 seconds).

    In my scenario, the new frame is one which began rendering two refreshes previous (it was rendered into C very quickly two refreshes back, moved to B at the last refresh, and at this refresh is finally moved to A and displayed). The lag is therefore always exactly two frames provided the card is capable of rendering a frame faster than the refresh-rate. At 60hz refresh the lag will therefore be a constant 0.033 seconds regardless of the framerate the card is capable of (provided it can maintain at least 60fps).

    Whilst the longer lag (0.033 vs 0-0.010) would be a disadvantage in some cases (your best option there is to use double-buffering with no vsync), it is a consistent lag which in most games will feel better. It also means your graphics-card isn't constantly producing frames many of which will never be seen.

    The only problem is I don't know who is right. What I've said happens is what I've read on several other sites over quite a few years. Your article today Derek is the first time I've heard of a triple-buffering which involves the card continually updating the back-buffers.
  • Touche - Friday, June 26, 2009 - link

    I agree. Every site and topic I've read about triple buffering said that it works like you've explained. That's why most people hate it. It does resolve framerate drop issues of DB+vsync, but introduces too much lag. I would really like Anandtech to check this and get back to us.
  • DerekWilson - Saturday, June 27, 2009 - link

    The problem and discrepancy come from the fact that MS implements render ahead in DX, and because the default is 3 frames people took this to be "triple buffering", but you could do 2 frame render ahead and no one is going to call it "double buffering" ...

    It's really a render queue rather than a page flipping method.

    This article describes what, when people are talking about page flipping, "triple buffering" should refer to. This is also the way OpenGL works when triple buffering is enabled.
  • Touche - Sunday, June 28, 2009 - link

    Have you seen this?

    http://msdn.microsoft.com/en-us/library/ms796537.a...">http://msdn.microsoft.com/en-us/library/ms796537.a...
    http://msdn.microsoft.com/en-us/library/ms893104.a...">http://msdn.microsoft.com/en-us/library/ms893104.a...
  • DerekWilson - Wednesday, July 1, 2009 - link

    What they are showing is 1 frame render ahead with vsync. In MS DX terms, this is a flip chain with 2 back buffers and a present interval of one.

    This is them calling it triple if uses three total buffers. This is still a flip queue and should be referred to as such to avoid confusion.
  • DerekWilson - Saturday, June 27, 2009 - link

    Actually, I need to clarify and say that this is my understanding of the way triple buffering with OpenGL works under windows at this time.

Log in

Don't have an account? Sign up now