Index: xc/lib/GL/mesa/src/drv/r128/r128_context.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r128/r128_context.h,v retrieving revision 1.28.16.5 diff -u -r1.28.16.5 r128_context.h --- xc/lib/GL/mesa/src/drv/r128/r128_context.h 12 Apr 2003 04:06:57 -0000 1.28.16.5 +++ xc/lib/GL/mesa/src/drv/r128/r128_context.h 12 Apr 2003 07:36:04 -0000 @@ -177,7 +177,6 @@ /* Page flipping */ GLuint doPageFlip; - GLuint currentPage; /* Busy waiting */ Index: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c,v retrieving revision 1.18.10.7 diff -u -r1.18.10.7 r128_ioctl.c --- xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c 12 Apr 2003 06:59:11 -0000 1.18.10.7 +++ xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c 12 Apr 2003 07:36:04 -0000 @@ -337,7 +337,7 @@ if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "\n%s( %p ): page=%d\n\n", - __FUNCTION__, rmesa->glCtx, rmesa->currentPage ); + __FUNCTION__, rmesa->glCtx, rmesa->sarea->pfCurrentPage ); } FLUSH_BATCH( rmesa ); @@ -357,26 +357,21 @@ driWaitForVBlank( &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target ); LOCK_HARDWARE( rmesa ); - /* The kernel will have been initialized to perform page flipping - * on a swapbuffers ioctl. - */ - ret = drmCommandNone( rmesa->driFd, DRM_R128_SWAP ); + ret = drmCommandNone( rmesa->driFd, DRM_R128_FLIP ); UNLOCK_HARDWARE( rmesa ); if ( ret ) { - fprintf( stderr, "DRM_R128_SWAP: return = %d\n", ret ); + fprintf( stderr, "DRM_R128_FLIP: return = %d\n", ret ); exit( 1 ); } - if ( rmesa->currentPage == 0 ) { + if ( rmesa->sarea->pfCurrentPage == 1 ) { rmesa->drawOffset = rmesa->r128Screen->frontOffset; rmesa->drawPitch = rmesa->r128Screen->frontPitch; - rmesa->currentPage = 1; } else { rmesa->drawOffset = rmesa->r128Screen->backOffset; rmesa->drawPitch = rmesa->r128Screen->backPitch; - rmesa->currentPage = 0; } rmesa->setup.dst_pitch_offset_c = (((rmesa->drawPitch/8) << 21) | Index: xc/lib/GL/mesa/src/drv/r128/r128_lock.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r128/r128_lock.c,v retrieving revision 1.9.36.4 diff -u -r1.9.36.4 r128_lock.c --- xc/lib/GL/mesa/src/drv/r128/r128_lock.c 7 Apr 2003 21:54:21 -0000 1.9.36.4 +++ xc/lib/GL/mesa/src/drv/r128/r128_lock.c 12 Apr 2003 07:36:04 -0000 @@ -41,6 +41,35 @@ int prevLockLine = 0; #endif +/* Turn on/off page flipping according to the flags in the sarea: + */ +static void +r128UpdatePageFlipping( r128ContextPtr rmesa ) +{ + int use_back; + + rmesa->doPageFlip = rmesa->sarea->pfAllowPageFlip; + + use_back = (rmesa->glCtx->Color._DrawDestMask == BACK_LEFT_BIT); + use_back ^= (rmesa->sarea->pfCurrentPage == 1); + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) + fprintf(stderr, "%s allow %d current %d\n", __FUNCTION__, + rmesa->doPageFlip, + rmesa->sarea->pfCurrentPage ); + + if ( use_back ) { + rmesa->drawOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->r128Screen->backPitch; + } else { + rmesa->drawOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->r128Screen->frontPitch; + } + + rmesa->setup.dst_pitch_offset_c = (((rmesa->drawPitch/8) << 21) | + (rmesa->drawOffset >> 5)); + rmesa->new_state |= R128_NEW_WINDOW; +} /* Update the hardware state. This is called if another context has * grabbed the hardware lock, which includes the X server. This @@ -70,6 +99,7 @@ DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv ); if ( rmesa->lastStamp != dPriv->lastStamp ) { + r128UpdatePageFlipping( rmesa ); rmesa->lastStamp = dPriv->lastStamp; rmesa->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP; rmesa->SetupNewInputs = ~0; Index: xc/lib/GL/mesa/src/drv/r128/r128_screen.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r128/r128_screen.c,v retrieving revision 1.16.16.4 diff -u -r1.16.16.4 r128_screen.c --- xc/lib/GL/mesa/src/drv/r128/r128_screen.c 7 Apr 2003 21:54:22 -0000 1.16.16.4 +++ xc/lib/GL/mesa/src/drv/r128/r128_screen.c 12 Apr 2003 07:36:04 -0000 @@ -197,61 +197,16 @@ } -/* Initialize the fullscreen mode. +/* Fullscreen mode isn't used for much -- could be a way to shrink + * front/back buffers & get more texture memory if the client has + * changed the video resolution. + * + * Pageflipping is now done automatically whenever there is a single + * 3d client. */ static GLboolean -r128OpenFullScreen( __DRIcontextPrivate *driContextPriv ) +r128OpenCloseFullScreen( __DRIcontextPrivate *driContextPriv ) { -#if 0 - r128ContextPtr rmesa = (r128ContextPtr)driContextPriv->driverPrivate; - drmR128Fullscreen fullscreen; - GLint ret; - - /* FIXME: Do we need to check this? - */ - if ( !r128Ctx->glCtx->Visual.doubleBufferMode ) - return GL_TRUE; - - LOCK_HARDWARE( rmesa ); - r128WaitForIdleLocked( rmesa ); - - /* Ignore errors. If this fails, we simply don't do page flipping. - */ - fullscreen.func = DRM_R128_INIT_FULLSCREEN; - ret = drmCommandWrite( rmesa->driFd, DRM_R128_FULLSCREEN, - &fullscreen, sizeof(drmR128Fullscreen) ); - - UNLOCK_HARDWARE( rmesa ); - - rmesa->doPageFlip = ( ret == 0 ); -#endif - - return GL_TRUE; -} - -/* Shut down the fullscreen mode. - */ -static GLboolean -r128CloseFullScreen( __DRIcontextPrivate *driContextPriv ) -{ -#if 0 - r128ContextPtr rmesa = (r128ContextPtr)driContextPriv->driverPrivate; - drmR128Fullscreen fullscreen; - LOCK_HARDWARE( rmesa ); - r128WaitForIdleLocked( rmesa ); - - /* Don't care if this fails, we're not page flipping anymore. - */ - fullscreen.func = DRM_R128_CLEANUP_FULLSCREEN; - drmCommandWrite( rmesa->driFd, DRM_R128_FULLSCREEN, - &fullscreen, sizeof(drmR128Fullscreen) ); - - UNLOCK_HARDWARE( rmesa ); - - rmesa->doPageFlip = GL_FALSE; - rmesa->currentPage = 0; -#endif - return GL_TRUE; } @@ -368,8 +323,8 @@ r128SwapBuffers, r128MakeCurrent, r128UnbindContext, - r128OpenFullScreen, - r128CloseFullScreen + r128OpenCloseFullScreen, + r128OpenCloseFullScreen }; Index: xc/lib/GL/mesa/src/drv/r128/r128_span.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r128/r128_span.c,v retrieving revision 1.17.36.3 diff -u -r1.17.36.3 r128_span.c --- xc/lib/GL/mesa/src/drv/r128/r128_span.c 7 Apr 2003 21:54:23 -0000 1.17.36.3 +++ xc/lib/GL/mesa/src/drv/r128/r128_span.c 12 Apr 2003 07:36:04 -0000 @@ -391,12 +391,22 @@ switch ( bufferBit ) { case FRONT_LEFT_BIT: - rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->frontOffset; - rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->frontPitch; + if ( rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->backPitch; + } else { + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->frontPitch; + } break; case BACK_LEFT_BIT: - rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset; - rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->backPitch; + if ( rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->frontPitch; + } else { + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->backPitch; + } break; default: break; Index: xc/lib/GL/mesa/src/drv/r128/r128_state.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/r128/r128_state.c,v retrieving revision 1.23.10.7 diff -u -r1.23.10.7 r128_state.c --- xc/lib/GL/mesa/src/drv/r128/r128_state.c 7 Apr 2003 21:54:24 -0000 1.23.10.7 +++ xc/lib/GL/mesa/src/drv/r128/r128_state.c 12 Apr 2003 07:36:04 -0000 @@ -1069,7 +1069,7 @@ rmesa->Fallback = 0; - if ( rmesa->glCtx->Visual.doubleBufferMode ) { + if ( rmesa->glCtx->Visual.doubleBufferMode && rmesa->sarea->pfCurrentPage == 0 ) { rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset; rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->backPitch; } else { Index: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h,v retrieving revision 1.19.2.2 diff -u -r1.19.2.2 r128.h --- xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h 2 Apr 2003 04:30:26 -0000 1.19.2.2 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h 12 Apr 2003 07:36:05 -0000 @@ -303,6 +303,10 @@ drmSize pciSize; drmHandle pciMemHandle; unsigned char *PCI; /* Map */ + + Bool allowPageFlip; /* Enable 3d page flipping */ + Bool have3DWindows; /* Are there any 3d clients? */ + int drmMinor; drmSize agpSize; drmHandle agpMemHandle; /* Handle from drmAgpAlloc */ Index: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_common.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_common.h,v retrieving revision 1.3.24.1 diff -u -r1.3.24.1 r128_common.h --- xc/programs/Xserver/hw/xfree86/drivers/ati/r128_common.h 11 Nov 2002 23:32:30 -0000 1.3.24.1 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/r128_common.h 12 Apr 2003 07:36:05 -0000 @@ -67,6 +67,7 @@ #define DRM_R128_FULLSCREEN 0x10 #define DRM_R128_CLEAR2 0x11 #define DRM_R128_GETPARAM 0x12 +#define DRM_R128_FLIP 0x13 #define DRM_R128_FRONT_BUFFER 0x1 #define DRM_R128_BACK_BUFFER 0x2 Index: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c,v retrieving revision 1.30.16.3 diff -u -r1.30.16.3 r128_dri.c --- xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c 2 Apr 2003 04:30:27 -0000 1.30.16.3 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c 12 Apr 2003 07:36:07 -0000 @@ -49,6 +49,8 @@ #include "windowstr.h" #include "xf86PciInfo.h" +#include "shadowfb.h" + /* GLX/DRI/DRM definitions */ #define _XF86DRI_SERVER_ #include "GL/glxtokens.h" @@ -64,6 +66,13 @@ # define DRM_PAGE_SIZE 4096 #endif +static void R128DRITransitionTo2d(ScreenPtr pScreen); +static void R128DRITransitionTo3d(ScreenPtr pScreen); +static void R128DRITransitionMultiToSingle3d(ScreenPtr pScreen); +static void R128DRITransitionSingleToMulti3d(ScreenPtr pScreen); + +static void R128DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox); + /* Initialize the visual configs that are supported by the hardware. These are combined with the visual configs that the indirect rendering core supports, and the intersection is exported to the @@ -355,7 +364,11 @@ int nbox, nboxSave; int depth; - /* FIXME: Use accel when CCE 2D code is written */ + /* FIXME: Use accel when CCE 2D code is written + * EA: What is this code kept for? Radeon doesn't have it and + * has a comment: "There's no need for the 2d driver to be clearing + * buffers for the 3d client. It knows how to do that on its own." + */ if (info->directRenderingEnabled) return; @@ -1063,6 +1076,10 @@ pDRIInfo->InitBuffers = R128DRIInitBuffers; pDRIInfo->MoveBuffers = R128DRIMoveBuffers; pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + pDRIInfo->TransitionTo2d = R128DRITransitionTo2d; + pDRIInfo->TransitionTo3d = R128DRITransitionTo3d; + pDRIInfo->TransitionSingleToMulti3D = R128DRITransitionSingleToMulti3d; + pDRIInfo->TransitionMultiToSingle3D = R128DRITransitionMultiToSingle3d; pDRIInfo->createDummyCtx = TRUE; pDRIInfo->createDummyCtxPriv = FALSE; @@ -1130,6 +1147,7 @@ R128DRICloseScreen(pScreen); return FALSE; } + info->drmMinor = version->version_minor; drmFreeVersion(version); } @@ -1253,6 +1271,13 @@ pR128DRI->agpTexOffset = info->agpTexStart; pR128DRI->sarea_priv_offset = sizeof(XF86DRISAREARec); + /* Have shadowfb run only while there is 3d active. */ + if (info->allowPageFlip && info->drmMinor >= 4 ) { + ShadowFBInit( pScreen, R128DRIRefreshArea ); + } else { + info->allowPageFlip = 0; + } + return TRUE; } @@ -1334,4 +1359,130 @@ xfree(info->pVisualConfigsPriv); info->pVisualConfigsPriv = NULL; } +} + +/* Use callbacks from dri.c to support pageflipping mode for a single + * 3d context without need for any specific full-screen extension. + */ + +/* Use the shadowfb module to maintain a list of dirty rectangles. + * These are blitted to the back buffer to keep both buffers clean + * during page-flipping when the 3d application isn't fullscreen. + * + * Unlike most use of the shadowfb code, both buffers are in video memory. + * + * An alternative to this would be to organize for all on-screen drawing + * operations to be duplicated for the two buffers. That might be + * faster, but seems like a lot more work... + */ + + +static void R128DRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + R128InfoPtr info = R128PTR(pScrn); + int i; + R128SAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen); + + /* Don't want to do this when no 3d is active and pages are + * right-way-round + */ + if (!pSAREAPriv->pfAllowPageFlip && pSAREAPriv->pfCurrentPage == 0) + return; + + (*info->accel->SetupForScreenToScreenCopy)(pScrn, + 1, 1, GXcopy, + (CARD32)(-1), -1); + + for (i = 0 ; i < num ; i++, pbox++) { + int xa = max(pbox->x1, 0), xb = min(pbox->x2, pScrn->virtualX-1); + int ya = max(pbox->y1, 0), yb = min(pbox->y2, pScrn->virtualY-1); + + if (xa <= xb && ya <= yb) { + (*info->accel->SubsequentScreenToScreenCopy)(pScrn, xa, ya, + xa + info->backX, + ya + info->backY, + xb - xa + 1, + yb - ya + 1); + } + } +} + +static void R128EnablePageFlip(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + R128SAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); + + if (info->allowPageFlip) { + /* Duplicate the frontbuffer to the backbuffer */ + (*info->accel->SetupForScreenToScreenCopy)(pScrn, + 1, 1, GXcopy, + (CARD32)(-1), -1); + + (*info->accel->SubsequentScreenToScreenCopy)(pScrn, + 0, + 0, + info->backX, + info->backY, + pScrn->virtualX, + pScrn->virtualY); + + pSAREAPriv->pfAllowPageFlip = 1; + } +} + +static void R128DisablePageFlip(ScreenPtr pScreen) +{ + /* Tell the clients not to pageflip. How? + * -- Field in sarea, plus bumping the window counters. + * -- DRM needs to cope with Front-to-Back swapbuffers. + */ + R128SAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); + + pSAREAPriv->pfAllowPageFlip = 0; +} + +static void R128DRITransitionSingleToMulti3d(ScreenPtr pScreen) +{ + R128DisablePageFlip(pScreen); +} + +static void R128DRITransitionMultiToSingle3d(ScreenPtr pScreen) +{ + /* Let the remaining 3d app start page flipping again */ + R128EnablePageFlip(pScreen); +} + +static void R128DRITransitionTo3d(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + + R128EnablePageFlip(pScreen); + + info->have3DWindows = 1; + + if (info->cursor_start) + xf86ForceHWCursor(pScreen, TRUE); +} + +static void R128DRITransitionTo2d(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + R128InfoPtr info = R128PTR(pScrn); + R128SAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen); + + /* Shut down shadowing if we've made it back to the front page */ + if (pSAREAPriv->pfCurrentPage == 0) { + R128DisablePageFlip(pScreen); + } else { + xf86DrvMsg(pScreen->myNum, X_WARNING, + "[dri] R128DRITransitionTo2d: " + "kernel failed to unflip buffers.\n"); + } + + info->have3DWindows = 0; + + if (info->cursor_start) + xf86ForceHWCursor(pScreen, FALSE); } Index: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c,v retrieving revision 1.26.2.3 diff -u -r1.26.2.3 r128_driver.c --- xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c 12 Apr 2003 07:29:50 -0000 1.26.2.3 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c 12 Apr 2003 07:36:07 -0000 @@ -135,6 +135,7 @@ OPTION_AGP_SIZE, OPTION_RING_SIZE, OPTION_BUFFER_SIZE, + OPTION_PAGE_FLIP, #endif #if USE_CRT_ONLY /* FIXME: Disable CRTOnly until it is tested */ @@ -164,6 +165,7 @@ { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, { OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE }, { OPTION_BUFFER_SIZE, "BufferSize", OPTV_INTEGER, {0}, FALSE }, + { OPTION_PAGE_FLIP, "EnablePageFlip", OPTV_BOOLEAN, {0}, FALSE }, #endif { OPTION_DISPLAY, "Display", OPTV_STRING, {0}, FALSE }, { OPTION_PANEL_WIDTH, "PanelWidth", OPTV_INTEGER, {0}, FALSE }, @@ -318,6 +320,11 @@ "GlxSetVisualConfigs", NULL }; + +static const char *driShadowFBSymbols[] = { + "ShadowFBInit", + NULL +}; #endif static const char *vbeSymbols[] = { @@ -351,6 +358,7 @@ #ifdef XF86DRI drmSymbols, driSymbols, + driShadowFBSymbols, #endif fbdevHWSymbols, int10Symbols, @@ -1847,6 +1855,22 @@ &(info->CCEusecTimeout))) { /* This option checked by the R128 DRM kernel module */ } + + if (!xf86LoadSubModule(pScrn, "shadowfb")) { + info->allowPageFlip = 0; + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't load shadowfb module:\n"); + } else { + xf86LoaderReqSymLists(driShadowFBSymbols, NULL); + + info->allowPageFlip = xf86ReturnOptValBool(info->Options, + OPTION_PAGE_FLIP, + FALSE); + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page flipping %sabled\n", + info->allowPageFlip ? "en" : "dis"); + return TRUE; } Index: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h,v retrieving revision 1.10.48.2 diff -u -r1.10.48.2 r128_sarea.h --- xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h 5 Feb 2003 22:58:54 -0000 1.10.48.2 +++ xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h 12 Apr 2003 07:36:08 -0000 @@ -190,6 +190,8 @@ unsigned int texAge[R128_NR_TEX_HEAPS]; int ctxOwner; /* last context to upload state */ + int pfAllowPageFlip; /* set by the 2d driver, read by the client */ + int pfCurrentPage; /* set by kernel, read by others */ } R128SAREAPriv, *R128SAREAPrivPtr; #endif Index: xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128.h,v retrieving revision 1.2.12.2 diff -u -r1.2.12.2 r128.h --- xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128.h 3 Dec 2002 03:36:15 -0000 1.2.12.2 +++ xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128.h 12 Apr 2003 07:36:08 -0000 @@ -47,10 +47,10 @@ #define DRIVER_NAME "r128" #define DRIVER_DESC "ATI Rage 128" -#define DRIVER_DATE "20021029" +#define DRIVER_DATE "20030411" #define DRIVER_MAJOR 2 -#define DRIVER_MINOR 3 +#define DRIVER_MINOR 4 #define DRIVER_PATCHLEVEL 0 @@ -64,6 +64,7 @@ [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 }, \ + [DRM_IOCTL_NR(DRM_IOCTL_R128_FLIP)] = { r128_cce_flip, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, \ [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, \ Index: xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_cce.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_cce.c,v retrieving revision 1.3.2.1 diff -u -r1.3.2.1 r128_cce.c --- xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_cce.c 2 Apr 2003 04:32:28 -0000 1.3.2.1 +++ xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_cce.c 12 Apr 2003 07:36:08 -0000 @@ -766,59 +766,8 @@ return r128_do_engine_reset( dev ); } - -/* ================================================================ - * Fullscreen mode - */ - -static int r128_do_init_pageflip( drm_device_t *dev ) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); - - dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET ); - dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL ); - - R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset ); - R128_WRITE( R128_CRTC_OFFSET_CNTL, - dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL ); - - dev_priv->page_flipping = 1; - dev_priv->current_page = 0; - - return 0; -} - -int r128_do_cleanup_pageflip( drm_device_t *dev ) -{ - drm_r128_private_t *dev_priv = dev->dev_private; - DRM_DEBUG( "\n" ); - - R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset ); - R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); - - dev_priv->page_flipping = 0; - dev_priv->current_page = 0; - - return 0; -} - int r128_fullscreen( DRM_IOCTL_ARGS ) { - DRM_DEVICE; - drm_r128_fullscreen_t fs; - - LOCK_TEST_WITH_RETURN( dev, filp ); - - DRM_COPY_FROM_USER_IOCTL( fs, (drm_r128_fullscreen_t *)data, sizeof(fs) ); - - switch ( fs.func ) { - case R128_INIT_FULLSCREEN: - return r128_do_init_pageflip( dev ); - case R128_CLEANUP_FULLSCREEN: - return r128_do_cleanup_pageflip( dev ); - } - return DRM_ERR(EINVAL); } Index: xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_drm.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_drm.h,v retrieving revision 1.2.12.2 diff -u -r1.2.12.2 r128_drm.h --- xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_drm.h 5 Feb 2003 22:58:54 -0000 1.2.12.2 +++ xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_drm.h 12 Apr 2003 07:36:08 -0000 @@ -164,6 +164,8 @@ drm_tex_region_t tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1]; unsigned int tex_age[R128_NR_TEX_HEAPS]; int ctx_owner; + int pfAllowPageFlip; /* number of 3d windows (0,1,2 or more) */ + int pfCurrentPage; /* which buffer is being displayed? */ } drm_r128_sarea_t; @@ -191,6 +193,7 @@ #define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x50, drm_r128_fullscreen_t) #define DRM_IOCTL_R128_CLEAR2 DRM_IOW( 0x51, drm_r128_clear2_t) #define DRM_IOCTL_R128_GETPARAM DRM_IOW( 0x52, drm_r128_getparam_t) +#define DRM_IOCTL_R128_FLIP DRM_IO( 0x53) typedef struct drm_r128_init { enum { Index: xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_drv.h =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_drv.h,v retrieving revision 1.3.2.2 diff -u -r1.3.2.2 r128_drv.h --- xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_drv.h 2 Apr 2003 04:32:28 -0000 1.3.2.2 +++ xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_drv.h 12 Apr 2003 07:36:08 -0000 @@ -147,6 +147,7 @@ /* r128_state.c */ extern int r128_cce_clear( DRM_IOCTL_ARGS ); extern int r128_cce_swap( DRM_IOCTL_ARGS ); +extern int r128_cce_flip( DRM_IOCTL_ARGS ); extern int r128_cce_vertex( DRM_IOCTL_ARGS ); extern int r128_cce_indices( DRM_IOCTL_ARGS ); extern int r128_cce_blit( DRM_IOCTL_ARGS ); Index: xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_state.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_state.c,v retrieving revision 1.3.2.2 diff -u -r1.3.2.2 r128_state.c --- xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_state.c 2 Apr 2003 04:32:28 -0000 1.3.2.2 +++ xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/r128_state.c 12 Apr 2003 07:36:09 -0000 @@ -500,8 +500,16 @@ R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS ); - OUT_RING( dev_priv->back_pitch_offset_c ); - OUT_RING( dev_priv->front_pitch_offset_c ); + /* Make this work even if front & back are flipped: + */ + if (dev_priv->current_page == 0) { + OUT_RING( dev_priv->back_pitch_offset_c ); + OUT_RING( dev_priv->front_pitch_offset_c ); + } + else { + OUT_RING( dev_priv->front_pitch_offset_c ); + OUT_RING( dev_priv->back_pitch_offset_c ); + } OUT_RING( (x << 16) | y ); OUT_RING( (x << 16) | y ); @@ -528,7 +536,10 @@ { drm_r128_private_t *dev_priv = dev->dev_private; RING_LOCALS; - DRM_DEBUG( "page=%d\n", dev_priv->current_page ); + DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", + __FUNCTION__, + dev_priv->current_page, + dev_priv->sarea_priv->pfCurrentPage); #if R128_PERFORMANCE_BOXES /* Do some trivial performance monitoring... @@ -543,10 +554,8 @@ if ( dev_priv->current_page == 0 ) { OUT_RING( dev_priv->back_offset ); - dev_priv->current_page = 1; } else { OUT_RING( dev_priv->front_offset ); - dev_priv->current_page = 0; } ADVANCE_RING(); @@ -556,6 +565,8 @@ * performing the swapbuffer ioctl. */ dev_priv->sarea_priv->last_frame++; + dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page = + 1 - dev_priv->current_page; BEGIN_RING( 2 ); @@ -1264,6 +1275,62 @@ return 0; } +static int r128_do_init_pageflip( drm_device_t *dev ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET ); + dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL ); + + R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset ); + R128_WRITE( R128_CRTC_OFFSET_CNTL, + dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL ); + + dev_priv->page_flipping = 1; + dev_priv->current_page = 0; + dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page; + + return 0; +} + +int r128_do_cleanup_pageflip( drm_device_t *dev ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "\n" ); + + R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset ); + R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); + + if (dev_priv->current_page != 0) + r128_cce_dispatch_flip( dev ); + + dev_priv->page_flipping = 0; + return 0; +} + +/* Swapping and flipping are different operations, need different ioctls. + * They can & should be intermixed to support multiple 3d windows. + */ + +int r128_cce_flip( DRM_IOCTL_ARGS ) +{ + DRM_DEVICE; + drm_r128_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + LOCK_TEST_WITH_RETURN( dev, filp ); + + RING_SPACE_TEST_WITH_RETURN( dev_priv ); + + if (!dev_priv->page_flipping) + r128_do_init_pageflip( dev ); + + r128_cce_dispatch_flip( dev ); + + return 0; +} + int r128_cce_swap( DRM_IOCTL_ARGS ) { DRM_DEVICE; @@ -1278,13 +1345,9 @@ if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; - if ( !dev_priv->page_flipping ) { - r128_cce_dispatch_swap( dev ); - dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT | - R128_UPLOAD_MASKS); - } else { - r128_cce_dispatch_flip( dev ); - } + r128_cce_dispatch_swap( dev ); + dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT | + R128_UPLOAD_MASKS); return 0; }