Bug 4451

Summary: pageflip doesn't always work correctly
Product: Mesa Reporter: Roland Scheidegger <sroland>
Component: Drivers/DRI/r200Assignee: Default DRI bug account <dri-devel>
Status: NEW --- QA Contact:
Severity: normal    
Priority: high    
Version: git   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:

Description Roland Scheidegger 2005-09-14 06:50:46 UTC
Pageflip has some issues since some time (note I'm not sure it's a Mesa bug,
could be xorg or DRM too).
If a 3d app is running and the user switches to another terminal, when switching
back the 3d app will flicker (some additional debug info indicates it is still
using page flip and switching the buffers, so nothing unordinary). This always
happens, and switching back again to the VT won't cure it.
There's a second issue, which may not be related, when a 3d app is started and
then another one, there's a 50% chance pfCurrentPage will be 1. In that case, if
a third 3d app is started and one of the 3 closed, pfCurrentPage will go back to
0 for some reason and the two remaining apps will flicker (this can be corrected
by for instance moving the windows of the 3d apps around).
(with Mesa from xorg cvs (without the latest renderbuffer changes) there are
even more issues it seems (e.g. starting glxgears and quake3 will result in
heavy flicker) but these two issues above remain.)
Comment 1 Michel Dänzer 2005-09-14 08:26:37 UTC
(In reply to comment #0)
> There's a second issue, which may not be related, when a 3d app is started and
> then another one, there's a 50% chance pfCurrentPage will be 1. In that case, if
> a third 3d app is started and one of the 3 closed, pfCurrentPage will go back to
> 0 for some reason and the two remaining apps will flicker (this can be corrected
> by for instance moving the windows of the 3d apps around).

Can you verify that the correct RADEONDRITransition*() functions are called
under the right circumstances? Also, it looks to me like we should try flipping
to page 0 in RADEONDisablePageFlip() before actually disabling page flipping,
but I'm not sure that's related to the issues you're seeing.
Comment 2 Roland Scheidegger 2005-09-14 10:38:18 UTC
(In reply to comment #1)
> Can you verify that the correct RADEONDRITransition*() functions are called
> under the right circumstances?
Yes, all calls to TransitionTo2D/3D and SingleToMulti/MultiToSingle3d happen as
expected when multiple 3d apps are started. When switching to/from another
terminal, none of them are called (I think that's expected too?).

> Also, it looks to me like we should try flipping
> to page 0 in RADEONDisablePageFlip() before actually disabling page flipping,
> but I'm not sure that's related to the issues you're seeing.
I've wondered about that, but the code as-is seems to be specifically designed
so it can handle the case when pfCurrentPage stays at 1 and buffer swapping
happens. I think changing this might be problematic, as I suppose if you'd start
a second 3d app the first one might still dispatch a flip even when the xserver
just had set the page to 0 and disabled page flipping.
Comment 3 Michel Dänzer 2005-09-14 13:01:58 UTC
(In reply to comment #0)
> If a 3d app is running and the user switches to another terminal, when switching
> back the 3d app will flicker [...]

I just realized this is probably because page 1 isn't synchronized with page 0
in EnterVT?

(In reply to comment #2)
> 
> [...] but the code as-is seems to be specifically designed so it can handle
> the case when pfCurrentPage stays at 1 and buffer swapping happens. 

Sure, it can handle it, but it's far from ideal nonetheless.

> I think changing this might be problematic, as I suppose if you'd start
> a second 3d app the first one might still dispatch a flip even when the xserver
> just had set the page to 0 and disabled page flipping.

Doesn't the server hold the HW lock when it disables page flipping?
Comment 4 Roland Scheidegger 2005-09-14 14:02:32 UTC
> (In reply to comment #0)
> > If a 3d app is running and the user switches to another terminal, when switching
> > back the 3d app will flicker [...]
> 
> I just realized this is probably because page 1 isn't synchronized with page 0
> in EnterVT?
What needs to be synchronized?

> > [...] but the code as-is seems to be specifically designed so it can handle
> > the case when pfCurrentPage stays at 1 and buffer swapping happens. 
> 
> Sure, it can handle it, but it's far from ideal nonetheless.
Well I just guessed there's a reason things are handled that way :-)

> > I think changing this might be problematic, as I suppose if you'd start
> > a second 3d app the first one might still dispatch a flip even when the xserver
> > just had set the page to 0 and disabled page flipping.
> 
> Doesn't the server hold the HW lock when it disables page flipping?
It should. However, the clients don't when they decide if they should dispatch a
flip or a swap. Thus, they could easily dispatch a flip even after the xserver
has disabled page flipping, and drm doesn't care at all if page flipping is
enabled or not when it dispatches a flip (and btw I think it's not really a good
idea that the sarea page flip variable has a different name in drm/dri (pfState)
and xorg (pfAllowPageFlip) - moreover the comment in drm what this variable is
good for isn't quite how it's used).
Comment 5 Keith Whitwell 2005-09-15 01:13:24 UTC
(In reply to comment #4)

> > > [...] but the code as-is seems to be specifically designed so it can handle
> > > the case when pfCurrentPage stays at 1 and buffer swapping happens. 
> > 
> > Sure, it can handle it, but it's far from ideal nonetheless.
> Well I just guessed there's a reason things are handled that way :-)

If you think about what would happen if the X server decided to do a pageflip
(rather than the application doing one), it should be clear - you'd end up on
page 0, sure, but there would be a half-rendered scene in what the application
thought was the backbuffer.  

You could jump through all sorts of hoops trying to get things to work out -
perhaps tell the app to abandon that frame, generate expose events to make sure
that it really is rendering a new frame.  Or backcopy the old frontbuffer over
the top of what was the backbuffer, etc.  In short it would be a mess.

The only real choice is to leave pageflipping to the application and have the X
server and everybody else deal with the possibility that you might end up on
page 1 after a session of flipping.
Comment 6 Michel Dänzer 2005-09-15 21:31:23 UTC
(In reply to comment #4)
> > (In reply to comment #0)
> > > If a 3d app is running and the user switches to another terminal, when
switching
> > > back the 3d app will flicker [...]
> > 
> > I just realized this is probably because page 1 isn't synchronized with page 0
> > in EnterVT?
> What needs to be synchronized?

The page contents. :) See RADEONEnablePageFlip(). BTW, that blit should probably
really set the destination offset instead of using coordinates...
Comment 7 Roland Scheidegger 2005-09-16 11:10:56 UTC
Actually, turns out this is a simple problem (the vt switch one). The FLIP_CNTL
bit will not get set. This has to do with that while X sets up the
CRTC_OFFSET_CNTL register we're relying on drm to set the flip cntl bit, which
it will only do when a new client dispatches a flip.
Not sure how exactly a good solution would look like, since we don't save any
regs when LeaveVT is called (only when using fbdev, which indeed saves that reg
just for page flipping). Probably just saving those offset cntl regs when
leaving vt might do the trick (though I think a solution which would also get
rid of the FLIP_CNTL bit when page flipping is not enabled would be better).
Comment 8 Adam Jackson 2009-08-24 12:23:25 UTC
Mass version move, cvs -> git
Comment 9 Alex Deucher 2013-01-11 14:35:11 UTC
Pageflip should be working fine with KMS.  Closing.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.