Vblanks, CRTCs and GLX, oh my!
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