Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 8 of 8

Thread: Flip queue (AKA Pre-rendered frames)

  1. #1
    Junior Member Newbie
    Join Date
    Jan 2014
    Posts
    4

    Flip queue (AKA Pre-rendered frames)

    It appears that some drivers implement a "flip queue" such that, even with vsync enabled, the first few calls to swap buffers return immediately (queuing those frames for later use). It is only after this queue is filled that buffer swaps will block to synchronize with vblank.

    This behavior is detrimental to my application. It creates latency. Does anyone know of a way to disable it or a workaround for dealing with it?

    The OpenGL Wiki on Swap Interval suggests a call to glFinish after the swap but I've had no such luck with that trick.

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,126
    Quote Originally Posted by applejohn View Post
    It appears that some drivers implement a "flip queue" such that, even with vsync enabled, the first few calls to swap buffers return immediately (queuing those frames for later use). It is only after this queue is filled that buffer swaps will block to synchronize with vblank.

    This behavior is detrimental to my application. It creates latency. Does anyone know of a way to disable it or a workaround for dealing with it?
    Put a glFinish() after your SwapBuffers() call. This tells OpenGL: "finish all the work I've given you including the buffer swap (which waits on vsync), and don't return to me until you're done."

    This also has the benefit of making full-frame timing statistics reasonable, which is important if you want to detect when you overrun a frame (i.e. took too long to render and missed a vsync).
    Last edited by Dark Photon; 01-22-2014 at 06:13 AM.

  3. #3
    Junior Member Newbie
    Join Date
    Jan 2014
    Posts
    4
    Quote Originally Posted by Dark Photon View Post
    Put a glFinish() after your SwapBuffers() call. This tells OpenGL: "finish all the work I've given you including the buffer swap (which waits on vsync), and don't return to me until you're done."
    Is this true of OpenGL 3.2+? I've tried both glFlush() and glFinish() after SwapBuffers() and it appears to have no effect on the flip queue behavior.
    Last edited by applejohn; 01-22-2014 at 11:06 AM.

  4. #4
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,126
    How are you gauging the effect on the flip queue behavior?

    Also:

    It is only after this queue is filled that buffer swaps will block to synchronize with vblank.
    This is not what I've seen with no glFinish() after swap buffers. What I see is that the API blocks at some random point while queuing some future frame, not necessarily at the end of a frame.

  5. #5
    Junior Member Newbie
    Join Date
    Jan 2014
    Posts
    4
    Quote Originally Posted by Dark Photon View Post
    How are you gauging the effect on the flip queue behavior?
    I'm taking a timestamp directly after calling SwapBuffers() (and glFinish() but it makes no difference). What you see is that the first few swaps occur almost instantly. Subsequent swaps align with the refresh interval as expected.

    The code is nothing more than:

    Code :
    enable vsync
    for a few seconds
      SwapBuffers()
      glFinish()
      record timestamp
    end

    Here's what the durations between timestamps look like. Notice the first few small durations before it jumps up to the correct ~16.7ms:

  6. #6
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,126
    Quote Originally Posted by applejohn View Post
    I'm taking a timestamp directly after calling SwapBuffers() (and glFinish() but it makes no difference). What you see is that the first few swaps occur almost instantly. Subsequent swaps align with the refresh interval as expected.
    That's interesting. A few questions come to mind. Are you waiting until the buffer is mapped first? Are you rendering indirectly through a compositing window manager or directly to a screen window? Windows or Linux? If an NVidia, which yield behavior are you using (sched_yield, usleep(0), or never yield).

    To verify your assumption that it is the flip queue that's needing to fill, after say frame 50 or so when you've reached a steady state, sleep in your application a second, and then start drawing again. Do you see the same "ramp up" behavior with your frame times?

  7. #7
    Junior Member Newbie
    Join Date
    Jan 2014
    Posts
    4
    Quote Originally Posted by Dark Photon View Post
    Are you waiting until the buffer is mapped first?
    Yes.

    Quote Originally Posted by Dark Photon View Post
    Are you rendering indirectly through a compositing window manager or directly to a screen window?
    Directly to a screen window.

    Quote Originally Posted by Dark Photon View Post
    Windows or Linux?
    Windows.

    Quote Originally Posted by Dark Photon View Post
    If an NVidia, which yield behavior are you using (sched_yield, usleep(0), or never yield).
    It's an ATI card. From what I've read Nvidia actually offers a way to disable the flip queue in their drivers. ATI apparently used to but no longer does.

    Quote Originally Posted by Dark Photon View Post
    To verify your assumption that it is the flip queue that's needing to fill, after say frame 50 or so when you've reached a steady state, sleep in your application a second, and then start drawing again. Do you see the same "ramp up" behavior with your frame times?
    Yes, I see the same ramp up behavior after sleeping the application for a second and then drawing again.

  8. #8
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,126
    Quote Originally Posted by applejohn View Post
    Yes, I see the same ramp up behavior after sleeping the application for a second and then drawing again.
    Interesting. And weird. Seems to suggest that ATI is not doing a glFinish() when you request one.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •