glXSwapBuffers very slow, potential problems?
Aaron Plattner
aplattner at nvidia.com
Wed Oct 6 08:38:56 PDT 2010
On Wed, Oct 06, 2010 at 07:20:11AM -0700, Roland Plüss wrote:
> On 10/05/2010 06:48 PM, Aaron Plattner wrote:
> > On Tue, Oct 05, 2010 at 08:05:47AM -0700, Roland Plüss wrote:
> >> I'm running here into a heavy performance problem on both ATI and nVidia cards and the culprit is the glXSwapBuffers call. I've got here two performance readings showing the problem.
> >>
> >> The first reading is in a case where performance is somewhat okay.
> >>
> >> II [OpenGL] OpenGL Timer: BeginFrame: Run Optimizers = 3ys
> >> II [OpenGL] OpenGL Timer: BeginFrame: Make Current = 57ys
> >> II [OpenGL] OpenGL Timer: BeginFrame: Activate primary GC = 7ys
> >> II [OpenGL] OpenGL Timer: EndFrame: Entering = 2312ys
> >> II [OpenGL] OpenGL Timer: EndFrame: Activate primary GC = 28ys
> >> II [OpenGL] OpenGL Timer: EndFrame: Flush = 27ys
> >> II [OpenGL] OpenGL Timer: EndFrame: Swap Buffers = 4238ys
> >> II [OpenGL] OpenGL Timer-Total End Frame = 6694ys
> >>
> >> "EndFrame: Entering" is the time for all rendering for the window
> >> (hence the time between leaving BeginFrame and entering EndFrame
> >> calls). The flush there is only to make sure it is a problem with
> >> glXSwapBuffers. 4ms for a swap I would consider a bit high if the
> >> rendering itself is done in <3ms but maybe this is normal, I don't
> >> know. But when I show/hide the window to switch to another window
> >> rendering the same 3D scene (for testing purpose) and switching back
> >> (always only one of the two windows visible, aka mapped to the screen)
> >> performance breaks down horribly.
> >
> > Rendering on the GPU is queued by the rendering commands, and is processed
> > asynchronously. This means that you can't assume that just because all of
> > your rendering commands have returned, that the rendering is actually
> > complete. Also, glXSwapBuffers will queue a swap to occur when the
> > rendering is complete, but most GL implementations have code to prevent the
> > CPU from getting too far ahead. In particular, at least on our driver, if
> > there's a previous swap still pending, glXSwapBuffers won't return until
> > that swap is complete. This means that if your rendering is slow on the
> > GPU for some reason (e.g. because you have a pixel shader that takes ages
> > to complete), you'll see that time show up in the SwapBuffers call for the
> > next frame.
> >
> Ah yeah, though glFlush does an implicit glFinish but looks like it
> doesn't.
No, it's the other way around: Finish does an implicit Flush (section 5.2
in OpenGL 4).
> Adding a glFinish instead turns the swap into 120ys or so, which sounds
> fine. Looks like the problem seems to be elsewhere. Placing glFinish at
> various places for testing it looks like glClear (0.18ms raised up to
> 6ms) and some FBO activation (0.14ms raised up to 6ms) go through the
> roof. No idea why hiding/showing a window causes them to suddenly spike
> from fast to horribly slow (especially since you need clearing for shadow
> map sooner or later).
>
> > SwapBuffers from a separate thread should work fine, but you may have
> > trouble making sure everything is synchronized correctly. Also, it's
> > almost certainly barking up the wrong tree.
>
> Makes sense. Would be nice if there is a call like in DirectX where you
> can check if rendering is done already so you could skip the actual
> rendering for a frame while still having the game logic updates done in
> that frame.
I think you can do that with GL_ARB_sync: http://www.opengl.org/registry/specs/ARB/sync.txt
(or the core sync objects in OpenGL 4, which are described in section 5.3,
coindicentally right after the section for Flush and Finish).
More information about the xorg
mailing list