From ba55ff15df974197bebd871e28bb96d817ae41c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 12 Mar 2007 13:01:00 +0100 Subject: [PATCH] Fix attempt to flip pages back to normal when the last 3D window disappears. When this succeeds, 2D rendering does not have to be synchronized to back buffers until the next 3D window appears. --- configure.ac | 8 ++++++++ src/i830_dri.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index fbb9c647..52cc07bd 100644 --- a/configure.ac +++ b/configure.ac @@ -180,6 +180,14 @@ if test "$DRI" = yes; then if test "$have_damage_h" = yes; then AC_DEFINE(DAMAGE,1,[Use Damage extension]) fi + + save_CFLAGS="$CFLAGS" + CFLAGS="$DRI_CFLAGS" + AC_CHECK_TYPE(drm_i915_flip_t, + [AC_DEFINE(HAVE_I915_FLIP, 1, + [Have drm_i915_flip_t and related definitions])], + [], [#include ]) + CFLAGS="$save_CFLAGS" fi AM_CONDITIONAL(VIDEO_DEBUG, test x$VIDEO_DEBUG = xyes) diff --git a/src/i830_dri.c b/src/i830_dri.c index f55fa715..52c30ebd 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -81,6 +81,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i830.h" #include "i830_dri.h" +#include "i915_drm.h" + #include "dristruct.h" static char I830KernelDriverName[] = "i915"; @@ -563,12 +565,13 @@ I830DRIScreenInit(ScreenPtr pScreen) #endif } + pDRIInfo->TransitionTo2d = I830DRITransitionTo2d; + #if DRIINFO_MAJOR_VERSION > 5 || \ (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1) if (!pDRIInfo->ClipNotify) #endif { - pDRIInfo->TransitionTo2d = I830DRITransitionTo2d; pDRIInfo->TransitionTo3d = I830DRITransitionTo3d; pDRIInfo->TransitionSingleToMulti3D = I830DRITransitionSingleToMulti3d; pDRIInfo->TransitionMultiToSingle3D = I830DRITransitionMultiToSingle3d; @@ -1470,6 +1473,22 @@ I830DRITransitionTo3d(ScreenPtr pScreen) I830DRISetPfMask(pScreen, pI830->allowPageFlip ? 0x3 : 0); } +/* This block and the corresponding configure test can be removed when + * libdrm >= 2.3.1 is required. + */ +#ifndef HAVE_I915_FLIP + +#define DRM_VBLANK_FLIP 0x8000000 + +typedef struct drm_i915_flip { + int pipes; +} drm_i915_flip_t; + +#undef DRM_IOCTL_I915_FLIP +#define DRM_IOCTL_I915_FLIP DRM_IOW(DRM_COMMAND_BASE + DRM_I915_FLIP, \ + drm_i915_flip_t) + +#endif static void I830DRITransitionTo2d(ScreenPtr pScreen) @@ -1479,10 +1498,27 @@ I830DRITransitionTo2d(ScreenPtr pScreen) drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); /* Try flipping back to the front page if necessary */ - if (sPriv->pf_current_page == 1) - drmCommandNone(pI830->drmSubFD, DRM_I830_FLIP); + if (sPriv->pf_current_page != 0) { + drm_i915_flip_t flip = { .pipes = 0 }; - if (sPriv->pf_current_page == 1) + if (sPriv->pf_current_page & (0x3 << 2)) { + sPriv->pf_current_page = sPriv->pf_current_page & 0x3; + sPriv->pf_current_page |= (sPriv->third_handle ? 2 : 1) << 2; + + flip.pipes |= 0x2; + } + + if (sPriv->pf_current_page & 0x3) { + sPriv->pf_current_page = sPriv->pf_current_page & (0x3 << 2); + sPriv->pf_current_page |= sPriv->third_handle ? 2 : 1; + + flip.pipes |= 0x1; + } + + drmCommandWrite(pI830->drmSubFD, DRM_I915_FLIP, &flip, sizeof(flip)); + } + + if (sPriv->pf_current_page != 0) xf86DrvMsg(pScreen->myNum, X_WARNING, "[dri] %s: kernel failed to unflip buffers.\n", __func__);