Izman
Izman

Reputation: 419

Double Buffering vs Triple Buffering for Vertex Buffers

A lot of graphics programming resources seem to recommend triple buffering data to avoid synchronizations on the GPU. Here are a few examples:

OpenGL Insights - Asynchronous Buffer Transfers

Apple's Best Practices (Triple Buffering)

And another source says that:

GPU and CPU runs asynchronously... but there is also another factor: the driver. It may happen (and on desktop driver implementations it happens quite often) that the driver also runs asynchronously. To solve this, even more complicated synchronization scenario, you might consider triple buffering:

  • one buffer for cpu
  • one for the driver
  • one for gpu

This way there should be no stalls in the pipeline, but you need to sacrifice a bit more memory for your data.

--

Is the third buffer actually for the driver? What synchronization issue on the driver is the third buffer trying to solve? It feels like we could avoid all synchronization with just two buffers.

Upvotes: 3

Views: 2884

Answers (1)

bernie
bernie

Reputation: 10380

The triple or double buffering issue is in the context of persistently mapped buffers. I have yet to work with persistently mapped buffers, but I have read a presentation from Nvidia (How Modern OpenGL Can Radically Reduce Driver Overhead) that talks about the subject and explains how it works. Triple buffering is only necessary to avoid stalls when streaming new data each frame:

  • You are responsible for not stomping on data in flight.
  • Why 3x?
    • 1x: What the GPU is using right now.
    • 2x: What the driver is holding, getting ready for the GPU to use.
    • 3x: What you are writing to.
  • 3x should ~ guarantee enough buffer room*…
  • Use fences to ensure that rendering is complete before you begin to write new data.

Efficient Buffer Management [McDonald 2012] referenced in the above mentioned presentation also provides more in-depth information regarding proper buffer management.

See also the OpenGL wiki which outlines an efficient buffer update algorithm.

As long as you protect buffer memory areas from overwrites with fences, you can even use a single buffered vertex buffer. This will however give much slower performance because you will lose the benefits of asynchronous memory transfers. The write operation will wait for the previous rendering operation to complete which serializes the update and draw stages.

Again, all this double and triple buffering is only relevant for streamed vertex data that changes each frame.

Upvotes: 7

Related Questions