Vblanks, CRTCs and GLX, oh my!

Jesse Barnes jbarnes at virtuousgeek.org
Tue Sep 18 14:54:11 PDT 2007

Both the generic DRM vblank-rework and Intel specific pipe/plane 
swapping have uncovered some vblank related problems which we discussed 
at XDS last week.  Unfortunately, no matter what we do (including 
the "do nothing" option), some applications will break some of the time 
in the new world order.

Basically we have a few vblank related bits of code:
  1) DRM_IOCTL_WAIT_VBLANK - core DRM vblank wait ioctl
  2) driver interrupt code - increments appropriate vblank counter
  3) DRM_I915_VBLANK_SWAP - Intel specific scheduled swap ioctl
  4) SAREA private data - used for tracking which gfx plane to swap
  5) glX*VideoSyncSGI - GL interfaces for sync'ing to vblank events

As it stands, DRM_IOCTL_WAIT_VBLANK is downright broken in the new world 
of dyanmically controlled outputs and CRTCs (at least for i915 and 
radeon):  a client trying to sync against the second CRTC that doesn't 
pass _DRM_VBLANK_SECONDARY will only work if one CRTC is enabled, due 
to the way current interrupt handlers increment the respective vblank 
counters (i.e. they increment the correct counter if both CRTCs are 
generating events, but only the primary counter if only one CRTC vblank 
interrupt is enabled).

The Intel specific DRM_I915_VBLANK_SWAP is a really nice interface, and 
is the only reliable way to get tear free vblank swap on a loaded 
system.  However, what it really cares about is display planes (in the 
Intel sense), so it uses the _DRM_VBLANK_SECONDARY flag to indicate 
whether it wants to flip plane A or B.  Whether or not to pass the 
_DRM_VBLANK_SECONDARY flag is determined by DRI code based on the SAREA 
private data that describes how much of a given client's window is 
visible on either pipe.  This should work fine as of last week's mods 
and only the DDX and DRM code have to be aware of potential pipe->plane 
swapping due to hardware limitations.

The vblank-rework branch of the DRM tree tries to address (1) and (2) by 
splitting the logic for handling CRTCs and their associated vblank 
interrupts into discrete paths, but this defeats the original purpose 
of the driver interrupt code that tries to fall back to a single 
counter, which is due to limitations in (5), namely that the 
glX*VideoSyncSGI APIs can only handle a single pipe.

So, what to do?  One way of making the glX*VideoSyncSGI interfaces 
behave more or less as expected would be to make them more like 
DRM_I915_VBLANK_SWAP internally, i.e. using SAREA values to determine 
which pipe needs to be sync'd against by passing in the display plane 
the client is most tied to (this would imply making the Intel specific 
SAREA plane info more generic), letting the DRM take care of the rest.

Another option (which could be done in addition to the above) would be 
to add some new CRTC-aware interfaces along with ways at getting at 
current CRTC/display plane for a client (does GL already have this?).

And no matter the outcome, we should encourage people to use interfaces 
like DRM_I915_VBLANK_SWAP rather than glXWaitVideoSyncSGI, otherwise 
they'll be highly susceptible to unpredictable scheduling hiccups.

Any other thoughts?


More information about the xorg mailing list