0

How does an OpenGL application with double buffering achieve more than 60 fps (dislay refresh limit)?
Does it depend on driver implementation, namely whether it uses double or tripple buffering?

Consider next application main loop:

while (1) {
  draw_scene();
  swap_buffers(); 
}

The second statement in the loop is mandatory if I don't use some fancy synchronization with display vsync and don't want to tearings when displaying images. With such a loop my fps is correlated with driver implementation: with double buffering the pipeline would stall and I archive about 60 fps while with tripple buffrering no stall would occur and my fps depend only on my videocard throughput. So if there is a need to archive high fps opengl application I should have tripple buffering implementation inside application. Am I right?

Derek
  • 1,104
  • 13
  • 35
nshy
  • 1,074
  • 8
  • 13
  • I failed to realize why double/triple buffering would perform a framerate cap. Sure displays have a fixed, configurable refresh rate (usually 60Hz), but that doesn't change how fast each frame is executed in your application. – E_net4 Sep 14 '12 at 10:54
  • @E_net4 Please consider my comments on datenwolf answer I hope they should shed some light on what I actually mean. – nshy Sep 14 '12 at 12:50
  • Well then, what are you using to benchmark the application? Are you sure that disabling vsync still keeps the application running at 60 FPS? – E_net4 Sep 14 '12 at 12:59

1 Answers1

2

How OpenGL application with double buffering archive more than 60 fps (dislay refresh limit)?

By disable synchronisation with the display vertical retrace.

with double buffering the pipeline would stall and I archive about 60 fps while with tripple buffrering no stall would occur and my fps depend only on my videocard throughput.

The only difference between double and triple buffering is the amount of frames "in the queue" for displaying. Effectively it adds another frame of latency. However the total framerate does not increase. Also there's little sense it trying to render more frames per second than the display device can process.

The buffer swap doesn't stall the pipeline! Stalling the pipeline means, that some operation within the pipeline forces the device to flush the whole pipeline and has to replay a significant amount of operations, thereby reducing total throughput. The buffer swap however is a synchronization point, which means that it waits for the pipeline to complete. This is actually desireable, because it gives your GPU and the drivers some time to do other things like cleaning up memory marked for deallocation and similar. The duration SwapBuffers blocks is also beneficial for your programs process, as this gives other threads in your program CPU time, that can be used to process user input, to I/O, networking, etc.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • Buffer swap flushes GL which means all commands issued before flush should be places in hardware queue, thus if you have double buffer, after first buffer swap the rendering into back buffer would be impossible as it should be kept intact for future actual swapping on vsync. So when you render scene again and issue another buffer swap (say the scene is so simple you can archive 200 fps whithout double buffering) - your commands will be placed in queue if its have enough space but they will no be executed until vsync. If you keep issuing buffer swaps in main loop-app will be blocked. – nshy Sep 14 '12 at 12:40
  • On the other hand if you have tripple buffer the hardware always has a free buffer to render into. In other words with double buffer graphics hardware would spend some time waiting for vsync and with tripple buffer it would be continously busy. – nshy Sep 14 '12 at 12:46
  • Also if I disable synchronisation with vsync - tearings should be noticeble which is not the case. – nshy Sep 14 '12 at 12:47
  • @nshy: Why would you want to render a scene with 200Hz when the display can reach only, say 60Hz? There's no sense in it. Also any simulation should be based on the **display** intervalls not the time it takes to render a frame. If you really want to implement triple buffering you can use a Framebuffer Object for this. – datenwolf Sep 14 '12 at 14:06
  • @nshy: What kind of animation do you render to test for tearing? – datenwolf Sep 14 '12 at 14:07
  • Sorry for conversation delay. Well, most fps games I dealt with can optionally show frame rate, Quake3 for example, and with descent computer it was quite larger then 60 fps. I heard for fps games it's an advantage to render faster than 60 fps as game pace is fast and larger framerate minimize the delay between user input and visual reaction. And one more notice. In the same Quake 3 I saw no frame tearings - thus I conclude there is a syncronization. – nshy Sep 17 '12 at 03:53
  • @nshy: If the framerate is higher than what the monitor can manage, there will be tearings. Especially in Quake3 which does neither triple buffering, nor any synchronization with the display (look into Quake 3's source code, if you don't believe me). Also rendering at higher framerates will not reduce latency, as the limiting factor is the display, and the number of frames it takes for the display between receiving the picture, processing it and showing it to the user. That's why some gamers still use CRTs: Those allow much higher FPS than TFTs and the signal goes directly from input to screen – datenwolf Sep 17 '12 at 07:57
  • Well I belive you considering Quake 3. Nethertheless I find logically correct that with higher fps willd reduce latency. Say you render almost instantly a frame and then wait for vsync to show it - thus you have maximum delay of 1/60s between user input and its influence on game. Then if you constantly render frames and show latest one when it comes to vsync - you have no delay between input and reaction at all. Thus I find it useful to render faster than 60 fps. – nshy Sep 17 '12 at 09:18
  • Regarding my original question - with double buffer you will have to wait for vsync, with tripple buffer you can constantly rendering. Wikipedia article http://en.wikipedia.org/wiki/Multiple_buffering states the same in section 'tripple buffering' – nshy Sep 17 '12 at 09:20
  • @nshy: With tripple buffering you can either render frames constantly and discard those, which are replaced if the render is far faster than the display. Or you have exactly one additional frame in the queue, and after rendering that one you're synchronized to the display frame rate. In either case, tripple buffering *always* **increases** the latency. The idea of triple buffering is to smooth out stuttering in the animation, not to improve the framerate. And again: Rendering at a higher framerate than the display can deliver makes no sense. – datenwolf Sep 17 '12 at 09:50
  • 1
    @nshy: Trying to render more frames than a display can deliver makes no sense due laws of nature. You display is taking samples (of frames you deliver to it). If you deliver signal with a higher sampling rate you will create aliasing. See http://en.wikipedia.org/wiki/Aliasing and http://en.wikipedia.org/wiki/Nyquist_frequency – if your goal is smooth high quality animation, aim for your renderer to render exactly one frame each V-sync period and time your animation so that when rendering the animation step its status will be that of the time of display. Use a Kalman filter to match user input. – datenwolf Sep 17 '12 at 09:53
  • @datewolf I don't get it. How will I create aliasing? I'd rather increase sampling frequency if I render with more fps. If we forget sampling approach, in the limit of infinite fps - I just always show the current state of world on vsync, don't I? – nshy Sep 17 '12 at 10:36
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/16769/discussion-between-nshy-and-datenwolf) – nshy Sep 17 '12 at 10:37