Michael wrote:
>
> On Tue, May 21, 2002 at 12:14:45AM +0100, Keith Whitwell wrote:
> > I have a .XF86config-radeon that sets ModulesPath to that directory, and maybe
> > I need to set an env var or two... I guess the magic is adding up.
>
> Yeah, I should have rtfm'd, ModulesPath into .../exports/lib/modules
> fixes it, thanks.
>
> glxgears
> 5229 frames in 5.0 seconds = 1045.800 FPS
> 5210 frames in 5.0 seconds = 1042.000 FPS
>
> 200fps+ at least there
I've done some more work & will probably commit shortly. This is good stuff,
I think.
Changes since last time:
- Deprecate the Open/Close Fullscreen foo.
- Automatically turn pageflipping on when there is exactly one 3d client
-- There may be situations where this isn't a good idea, perhaps many
many
cliprects?
- 2D driver copes with situations where the pages are left wrong-way-round
after last client exits
- Separate out the 'flip' and 'swap' functions to separate ioctls. (D'oh)
- A little testing
It's looking pretty good now. Multiple 3d clients coordinate amoungst
themselves, pageflipping comes on whenever possible. There are only a couple
of small glitches to fix before I commit.
Keith
Index: lib/GL/mesa/src/drv/radeon/radeon_context.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v
retrieving revision 1.7.2.19
diff -u -r1.7.2.19 radeon_context.c
--- lib/GL/mesa/src/drv/radeon/radeon_context.c 2 May 2002 13:28:07 -0000
1.7.2.19
+++ lib/GL/mesa/src/drv/radeon/radeon_context.c 21 May 2002 11:40:31 -0000
@@ -694,58 +694,19 @@
return GL_TRUE;
}
-/* 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
-radeonOpenFullScreen( __DRIcontextPrivate *driContextPriv )
+radeonOpenCloseFullScreen( __DRIcontextPrivate *driContextPriv )
{
- fprintf(stderr, "%s\n", __FUNCTION__);
-#if 0
- radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate;
- GLint ret;
-
- /* FIXME: Do we need to check this?
- */
- if ( !rmesa->glCtx->Visual.doubleBufferMode )
- return GL_TRUE;
-
- LOCK_HARDWARE( rmesa );
- radeonWaitForIdleLocked( rmesa );
-
- /* Ignore errors. If this fails, we simply don't do page flipping.
- */
- ret = drmRadeonFullScreen( rmesa->driFd, GL_TRUE );
-
- UNLOCK_HARDWARE( rmesa );
-
- rmesa->doPageFlip = ( ret == 0 );
-#endif
return GL_TRUE;
}
-/* Shut down the fullscreen mode.
- */
-static GLboolean
-radeonCloseFullScreen( __DRIcontextPrivate *driContextPriv )
-{
- fprintf(stderr, "%s\n", __FUNCTION__);
-#if 0
- radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate;
-
- LOCK_HARDWARE( rmesa );
- radeonWaitForIdleLocked( rmesa );
-
- /* Don't care if this fails, we're not page flipping anymore.
- */
- drmRadeonFullScreen( rmesa->driFd, GL_FALSE );
-
- UNLOCK_HARDWARE( rmesa );
-
- rmesa->doPageFlip = GL_FALSE;
- rmesa->currentPage = 0;
-#endif
- return GL_TRUE;
-}
/* This function is called by libGL.so as soon as libGL.so is loaded.
@@ -768,8 +729,8 @@
radeonSwapBuffers,
radeonMakeCurrent,
radeonUnbindContext,
- radeonOpenFullScreen,
- radeonCloseFullScreen
+ radeonOpenCloseFullScreen,
+ radeonOpenCloseFullScreen
};
Index: lib/GL/mesa/src/drv/radeon/radeon_ioctl.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v
retrieving revision 1.11.2.20
diff -u -r1.11.2.20 radeon_ioctl.c
--- lib/GL/mesa/src/drv/radeon/radeon_ioctl.c 10 May 2002 13:28:51 -0000
1.11.2.20
+++ lib/GL/mesa/src/drv/radeon/radeon_ioctl.c 21 May 2002 11:40:40 -0000
@@ -693,8 +693,8 @@
rmesa = (radeonContextPtr) dPriv->driContextPriv->driverPrivate;
if ( RADEON_DEBUG & DEBUG_IOCTL ) {
- fprintf( stderr, "\n%s( %p ): page=%d\n\n",
- __FUNCTION__, rmesa->glCtx, rmesa->currentPage );
+ fprintf(stderr, "%s %d/%d\n", __FUNCTION__, rmesa->currentPage,
+ rmesa->sarea->pfCurrentPage );
}
RADEON_FIREVERTICES( rmesa );
@@ -710,15 +710,12 @@
rmesa->hardwareWentIdle = 0;
}
- /* The kernel will have been initialized to perform page flipping
- * on a swapbuffers ioctl.
- */
- ret = drmRadeonSwapBuffers( rmesa->dri.fd );
+ ret = drmRadeonFlipBuffers( rmesa->dri.fd );
UNLOCK_HARDWARE( rmesa );
if ( ret ) {
- fprintf( stderr, "drmRadeonSwapBuffers: return = %d\n", ret );
+ fprintf( stderr, "drmRadeonFlipBuffers: return = %d\n", ret );
exit( 1 );
}
@@ -732,6 +729,7 @@
rmesa->currentPage = 0;
}
+ assert( rmesa->currentPage == rmesa->sarea->pfCurrentPage );
RADEON_STATECHANGE( rmesa, ctx );
rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset;
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch;
Index: lib/GL/mesa/src/drv/radeon/radeon_lock.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c,v
retrieving revision 1.7.2.2
diff -u -r1.7.2.2 radeon_lock.c
--- lib/GL/mesa/src/drv/radeon/radeon_lock.c 20 Feb 2002 17:27:33 -0000 1.7.2.2
+++ lib/GL/mesa/src/drv/radeon/radeon_lock.c 21 May 2002 11:40:40 -0000
@@ -44,6 +44,21 @@
int prevLockLine = 0;
#endif
+/* Turn on/off page flipping according to the flags in the sarea:
+ */
+static void
+radeonUpdatePageFlipping( radeonContextPtr rmesa )
+{
+
+ rmesa->doPageFlip = rmesa->sarea->pfAllowPageFlip;
+ rmesa->currentPage = rmesa->sarea->pfCurrentPage;
+
+ fprintf(stderr, "%s allow %d current %d\n", __FUNCTION__,
+ rmesa->doPageFlip,
+ rmesa->currentPage );
+}
+
+
/* Update the hardware state. This is called if another context has
* grabbed the hardware lock, which includes the X server. This
@@ -73,6 +88,7 @@
DRI_VALIDATE_DRAWABLE_INFO( rmesa->dri.display, sPriv, dPriv );
if ( rmesa->lastStamp != dPriv->lastStamp ) {
+ radeonUpdatePageFlipping( rmesa );
radeonSetCliprects( rmesa, rmesa->glCtx->Color.DriverDrawBuffer );
radeonUpdateViewportOffset( rmesa->glCtx );
rmesa->lastStamp = dPriv->lastStamp;
Index: lib/GL/mesa/src/drv/radeon/radeon_span.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c,v
retrieving revision 1.11.2.4
diff -u -r1.11.2.4 radeon_span.c
--- lib/GL/mesa/src/drv/radeon/radeon_span.c 25 Mar 2002 10:27:15 -0000
1.11.2.4
+++ lib/GL/mesa/src/drv/radeon/radeon_span.c 21 May 2002 11:40:40 -0000
@@ -292,12 +292,22 @@
switch ( mode ) {
case GL_FRONT_LEFT:
- rmesa->state.pixel.readOffset = rmesa->radeonScreen->frontOffset;
- rmesa->state.pixel.readPitch = rmesa->radeonScreen->frontPitch;
+ if ( rmesa->doPageFlip && rmesa->currentPage == 0 ) {
+ rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset;
+ rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch;
+ } else {
+ rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset;
+ rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch;
+ }
break;
case GL_BACK_LEFT:
- rmesa->state.pixel.readOffset = rmesa->radeonScreen->backOffset;
- rmesa->state.pixel.readPitch = rmesa->radeonScreen->backPitch;
+ if ( rmesa->doPageFlip && rmesa->currentPage == 1 ) {
+ rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset;
+ rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch;
+ } else {
+ rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset;
+ rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch;
+ }
break;
default:
assert(0);
Index: lib/GL/mesa/src/drv/radeon/radeon_state.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v
retrieving revision 1.10.2.23
diff -u -r1.10.2.23 radeon_state.c
--- lib/GL/mesa/src/drv/radeon/radeon_state.c 10 May 2002 14:38:59 -0000
1.10.2.23
+++ lib/GL/mesa/src/drv/radeon/radeon_state.c 21 May 2002 11:40:40 -0000
@@ -1508,7 +1508,9 @@
rmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects;
break;
case GL_BACK_LEFT:
- if ( dPriv->numBackClipRects == 0 ) {
+ /* Can't ignore 2d windows if we are page flipping.
+ */
+ if ( dPriv->numBackClipRects == 0 || rmesa->doPageFlip ) {
rmesa->numClipRects = dPriv->numClipRects;
rmesa->pClipRects = (XF86DRIClipRectPtr)dPriv->pClipRects;
}
@@ -1540,14 +1542,24 @@
switch ( mode ) {
case GL_FRONT_LEFT:
FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE );
- rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset;
- rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch;
+ if ( rmesa->doPageFlip && rmesa->currentPage == 0 ) {
+ rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset;
+ rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch;
+ } else {
+ rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset;
+ rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch;
+ }
radeonSetCliprects( rmesa, GL_FRONT_LEFT );
break;
case GL_BACK_LEFT:
FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE );
- rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset;
- rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch;
+ if ( rmesa->doPageFlip && rmesa->currentPage == 1 ) {
+ rmesa->state.color.drawOffset = rmesa->radeonScreen->frontOffset;
+ rmesa->state.color.drawPitch = rmesa->radeonScreen->frontPitch;
+ } else {
+ rmesa->state.color.drawOffset = rmesa->radeonScreen->backOffset;
+ rmesa->state.color.drawPitch = rmesa->radeonScreen->backPitch;
+ }
radeonSetCliprects( rmesa, GL_BACK_LEFT );
break;
default:
Index: programs/Xserver/GL/dri/dri.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/programs/Xserver/GL/dri/dri.c,v
retrieving revision 1.37
diff -u -r1.37 dri.c
--- programs/Xserver/GL/dri/dri.c 27 Jan 2002 20:05:25 -0000 1.37
+++ programs/Xserver/GL/dri/dri.c 21 May 2002 11:40:50 -0000
@@ -844,14 +844,26 @@
static void
DRITransitionToSharedBuffers(ScreenPtr pScreen)
{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
DRIClipNotifyAllDrawables( pScreen );
+
+ if (pDRIInfo->TransitionSingleToMulti3D)
+ pDRIInfo->TransitionSingleToMulti3D( pScreen );
}
static void
DRITransitionToPrivateBuffers(ScreenPtr pScreen)
{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
DRIClipNotifyAllDrawables( pScreen );
+
+ if (pDRIInfo->TransitionMultiToSingle3D)
+ pDRIInfo->TransitionMultiToSingle3D( pScreen );
}
Index: programs/Xserver/GL/dri/dri.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/programs/Xserver/GL/dri/dri.h,v
retrieving revision 1.18
diff -u -r1.18 dri.h
--- programs/Xserver/GL/dri/dri.h 9 Apr 2001 21:56:18 -0000 1.18
+++ programs/Xserver/GL/dri/dri.h 21 May 2002 11:40:50 -0000
@@ -121,6 +121,9 @@
CARD32 indx);
void (*TransitionTo3d)(ScreenPtr pScreen);
void (*TransitionTo2d)(ScreenPtr pScreen);
+ void (*TransitionSingleToMulti3D)(ScreenPtr pScreen);
+ void (*TransitionMultiToSingle3D)(ScreenPtr pScreen);
+
void (*SetDrawableIndex)(WindowPtr pWin, CARD32 indx);
Bool (*OpenFullScreen)(ScreenPtr pScreen);
Bool (*CloseFullScreen)(ScreenPtr pScreen);
Index: programs/Xserver/hw/xfree86/drivers/ati/Imakefile
===================================================================
RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile,v
retrieving revision 1.7
diff -u -r1.7 Imakefile
--- programs/Xserver/hw/xfree86/drivers/ati/Imakefile 27 Jan 2002 20:05:30 -0000
1.7
+++ programs/Xserver/hw/xfree86/drivers/ati/Imakefile 21 May 2002 11:40:50 -0000
@@ -185,6 +185,7 @@
-I$(XF86SRC)/vgahw -I$(XF86SRC)/fbdevhw \
-I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb \
-I$(SERVERSRC)/fb -I$(SERVERSRC)/mi \
+ -I$(SERVERSRC)/miext/shadow \
-I$(SERVERSRC)/render -I$(SERVERSRC)/Xext -I$(SERVERSRC)/include \
$(DRIINCLUDES) -I$(FONTINCSRC) -I$(EXTINCSRC) -I$(XINCLUDESRC)
#endif
Index: programs/Xserver/hw/xfree86/drivers/ati/radeon.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h,v
retrieving revision 1.19.2.1
diff -u -r1.19.2.1 radeon.h
--- programs/Xserver/hw/xfree86/drivers/ati/radeon.h 25 Mar 2002 10:35:48 -0000
1.19.2.1
+++ programs/Xserver/hw/xfree86/drivers/ati/radeon.h 21 May 2002 11:40:51 -0000
@@ -368,6 +368,9 @@
unsigned char *PCI; /* Map */
Bool depthMoves; /* Enable depth moves -- slow! */
+
+ Bool allowPageFlip; /* Enable 3d page flipping */
+ int drmMinor;
drmSize agpSize;
drmHandle agpMemHandle; /* Handle from drmAgpAlloc */
Index: programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c,v
retrieving revision 1.21.2.3
diff -u -r1.21.2.3 radeon_dri.c
--- programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c 25 Mar 2002 10:35:48
-0000 1.21.2.3
+++ programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c 21 May 2002 11:40:51
+-0000
@@ -46,6 +46,8 @@
#include "xf86.h"
#include "windowstr.h"
+
+#include "shadow.h"
/* GLX/DRI/DRM definitions */
#define _XF86DRI_SERVER_
#include "GL/glxtokens.h"
@@ -68,6 +70,16 @@
# define DRM_PAGE_SIZE 4096
#endif
+
+static Bool RADEONDRICloseFullScreen(ScreenPtr pScreen);
+static Bool RADEONDRIOpenFullScreen(ScreenPtr pScreen);
+static void RADEONDRITransitionTo2d(ScreenPtr pScreen);
+static void RADEONDRITransitionTo3d(ScreenPtr pScreen);
+static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen);
+static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen);
+
+static void RADEONDRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf);
+
/* 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
@@ -663,6 +675,9 @@
info->accel->NeedToSync = TRUE;
}
+
+
+
/* Initialize the AGP state. Request memory for use in AGP space, and
initialize the Radeon registers to point to that memory. */
static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen)
@@ -1301,6 +1316,12 @@
pDRIInfo->InitBuffers = RADEONDRIInitBuffers;
pDRIInfo->MoveBuffers = RADEONDRIMoveBuffers;
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
+ pDRIInfo->OpenFullScreen = RADEONDRIOpenFullScreen;
+ pDRIInfo->CloseFullScreen = RADEONDRICloseFullScreen;
+ pDRIInfo->TransitionTo2d = RADEONDRITransitionTo2d;
+ pDRIInfo->TransitionTo3d = RADEONDRITransitionTo3d;
+ pDRIInfo->TransitionSingleToMulti3D = RADEONDRITransitionSingleToMulti3d;
+ pDRIInfo->TransitionMultiToSingle3D = RADEONDRITransitionMultiToSingle3d;
pDRIInfo->createDummyCtx = TRUE;
pDRIInfo->createDummyCtxPriv = FALSE;
@@ -1331,6 +1352,15 @@
RADEONDRICloseScreen(pScreen);
return FALSE;
}
+ if (version->version_minor < 3) {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "[dri] Some DRI features disabled because of version mismatch.\n"
+ "[dri] radeon.o kernel module version is %d.%d.%d but 1.1.3 is
+preferred.\n",
+ version->version_major,
+ version->version_minor,
+ version->version_patchlevel);
+ info->drmMinor = version->version_minor;
+ }
drmFreeVersion(version);
}
@@ -1460,6 +1490,16 @@
pRADEONDRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
+
+ /* Have shadow run only while there is 3d active.
+ */
+ if (info->allowPageFlip /* && info->drmMinor >= 3 */) {
+ shadowSetup (pScreen);
+ shadowAdd( pScreen, 0, RADEONDRIShadowUpdate, 0, 0, 0 );
+ }
+ else
+ info->allowPageFlip = 0;
+
return TRUE;
}
@@ -1533,3 +1573,158 @@
info->pVisualConfigsPriv = NULL;
}
}
+
+
+
+/* Fullscreen hooks. The DRI fullscreen mode can probably be removed
+ * as it adds little or nothing above the mechanism below. (and isn't
+ * widely used)
+ */
+static Bool
+RADEONDRIOpenFullScreen(ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+static Bool
+RADEONDRICloseFullScreen(ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+
+
+/* Use callbacks from dri.c to support pageflipping mode for a single
+ * 3d context without need for any specific full-screen extension.
+ *
+ * Also see tdfx driver for example of using these callbacks to
+ * allocate and free 3d-specific memory on demand.
+ */
+
+
+/* Use the miext/shadow 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 shadow 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...
+ */
+
+
+/* This should be done *before* XAA syncs or fires its buffer.
+ * Otherwise will have to fire it again???
+ */
+static void
+RADEONDRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RegionPtr damage = &pBuf->damage;
+ int i, num = REGION_NUM_RECTS(damage);
+ BoxPtr pbox = REGION_RECTS(damage);
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+
+ /* Don't want to do this when no 3d is active and pages are
+ * right-way-round :
+ */
+ if (!info->allowPageFlip)
+ return;
+
+ (*info->accel->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, GXcopy,
+ (CARD32)(-1), -1);
+
+ for (i = 0 ; i < num ; i++, pbox++) {
+ (*info->accel->SubsequentScreenToScreenCopy)(pScrn,
+ pbox->x1,
+ pbox->y1,
+ pbox->x1 + info->backX,
+ pbox->y1 + info->backY,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+
+ }
+}
+
+
+static void
+RADEONDRITransitionSingleToMulti3d(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.
+ */
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+ pSAREAPriv->pfAllowPageFlip = 0;
+}
+
+static void
+RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen)
+{
+ /* Let the remaining 3d app start page flipping again.
+ */
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+
+ if (info->allowPageFlip)
+ pSAREAPriv->pfAllowPageFlip = 1;
+}
+
+
+static void
+RADEONDRITransitionTo3d(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+
+ if (info->allowPageFlip && !pSAREAPriv->pfAllowPageFlip) {
+ /* 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
+RADEONDRITransitionTo2d(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+
+ /* Go back to the front buffer if things were left in a flipped state.
+ */
+ if (pSAREAPriv->pfCurrentPage != 0) {
+ drmRadeonFlipBuffers( info->drmFD );
+ }
+
+ /* Shut down shadowing if we've made it back to the front page:
+ */
+ if (pSAREAPriv->pfCurrentPage == 0) {
+ pSAREAPriv->pfAllowPageFlip = 0;
+ }
+ else
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "[dri] RADEONDRITransitionTo2d failed to unflip buffers.\n");
+
+}
+
+
Index: programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v
retrieving revision 1.19
diff -u -r1.19 radeon_driver.c
--- programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c 27 Jan 2002 20:05:31
-0000 1.19
+++ programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c 21 May 2002 11:40:52
+-0000
@@ -52,7 +52,7 @@
* This server does not yet support these XFree86 4.0 features:
* !!!! FIXME !!!!
* DDC1 & DDC2
- * shadowfb
+ * shadowfb (Note: dri uses shadow for another purpose in radeon_dri_shadow.c)
* overlay planes
*
* Modified by Marc Aurele La France ([EMAIL PROTECTED]) for ATI driver merge.
@@ -130,6 +130,7 @@
OPTION_RING_SIZE,
OPTION_BUFFER_SIZE,
OPTION_DEPTH_MOVE,
+ OPTION_NO_PAGE_FLIP,
#endif
OPTION_CRT_SCREEN,
OPTION_PANEL_SIZE,
@@ -150,6 +151,7 @@
{ OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE },
{ OPTION_BUFFER_SIZE, "BufferSize", OPTV_INTEGER, {0}, FALSE },
{ OPTION_DEPTH_MOVE, "EnableDepthMoves", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_NO_PAGE_FLIP, "DisablePageFlip", OPTV_BOOLEAN, {0}, FALSE },
#endif
{ OPTION_CRT_SCREEN, "CrtScreen", OPTV_BOOLEAN, {0}, FALSE},
{ OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE },
@@ -293,6 +295,11 @@
"GlxSetVisualConfigs",
NULL
};
+
+static const char *driShadowSymbols[] = {
+ "shadowInit",
+ NULL
+};
#endif
static const char *vbeSymbols[] = {
@@ -1980,6 +1987,22 @@
"Depth moves disabled by default\n");
}
+ if ((info->allowPageFlip = !xf86ReturnOptValBool(info->Options,
+ OPTION_NO_PAGE_FLIP,
+ FALSE))) {
+ if (!xf86LoadSubModule(pScrn, "shadow")) {
+ info->allowPageFlip = 0;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling page flipping\n");
+ }
+ else {
+ xf86LoaderReqSymLists(driShadowSymbols, NULL);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page flipping enabled\n");
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Disabling page flipping\n");
+ }
+
+
return TRUE;
}
#endif
@@ -2637,7 +2660,7 @@
* pixmap cache. Should be enough for a fullscreen background
* image plus some leftovers.
*/
- info->textureSize = info->FbMapSize - 6 * bufferSize;
+ info->textureSize = info->FbMapSize - 4 * bufferSize;
/* If that gives us less than half the available memory, let's
* be greedy and grab some more. Sorry, I care more about 3D
@@ -2700,6 +2723,9 @@
scanlines = info->backOffset / width_bytes - 1;
if (scanlines > 8191) scanlines = 8191;
+
+ info->backY = scanlines;
+ info->backX = (info->backOffset - (scanlines * width_bytes - 1)) / cpp;
MemBox.x1 = 0;
MemBox.y1 = 0;
Index: programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h,v
retrieving revision 1.5.2.1
diff -u -r1.5.2.1 radeon_sarea.h
--- programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h 12 Mar 2002 12:11:59
-0000 1.5.2.1
+++ programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h 21 May 2002 11:40:55
+-0000
@@ -236,6 +236,8 @@
int texAge[RADEON_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 */
} RADEONSAREAPriv, *RADEONSAREAPrivPtr;
#endif
Index: programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h
===================================================================
RCS file:
/cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/Attic/xf86drmRadeon.h,v
retrieving revision 1.10.2.3
diff -u -r1.10.2.3 xf86drmRadeon.h
--- programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h 25 Mar 2002 10:30:41
-0000 1.10.2.3
+++ programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h 21 May 2002 11:40:56
+-0000
@@ -227,6 +227,8 @@
extern int drmRadeonFullScreen( int fd, int enable );
extern int drmRadeonSwapBuffers( int fd );
+extern int drmRadeonFlipBuffers( int fd );
+
extern int drmRadeonClear( int fd, unsigned int flags,
unsigned int clear_color, unsigned int clear_depth,
unsigned int color_mask, unsigned int stencil,
Index: programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c
===================================================================
RCS file:
/cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Attic/xf86drmRadeon.c,v
retrieving revision 1.11.2.2
diff -u -r1.11.2.2 xf86drmRadeon.c
--- programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c 25 Mar 2002
10:30:41 -0000 1.11.2.2
+++ programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c 21 May 2002
+11:40:56 -0000
@@ -237,6 +237,15 @@
}
}
+int drmRadeonFlipBuffers( int fd )
+{
+ if ( ioctl( fd, DRM_IOCTL_RADEON_FLIP, NULL ) ) {
+ return -errno;
+ } else {
+ return 0;
+ }
+}
+
int drmRadeonClear( int fd, unsigned int flags,
unsigned int clear_color, unsigned int clear_depth,
unsigned int color_mask, unsigned int stencil,
Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h
===================================================================
RCS file:
/cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v
retrieving revision 1.35.2.2
diff -u -r1.35.2.2 drm.h
--- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h 25 Mar 2002
10:29:12 -0000 1.35.2.2
+++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h 21 May 2002
+11:40:56 -0000
@@ -492,6 +492,7 @@
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t)
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
+#define DRM_IOCTL_RADEON_FLIP DRM_IO( 0x52)
/* Gamma specific ioctls */
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c
===================================================================
RCS file:
/cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c,v
retrieving revision 1.20.2.5
diff -u -r1.20.2.5 radeon_cp.c
--- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c 3 May 2002
20:51:04 -0000 1.20.2.5
+++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c 21 May 2002
+11:40:59 -0000
@@ -1144,60 +1144,12 @@
* Fullscreen mode
*/
-static int radeon_do_init_pageflip( drm_device_t *dev )
-{
- drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
-
- dev_priv->crtc_offset = RADEON_READ( RADEON_CRTC_OFFSET );
- dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
-
- RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset );
- RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL,
- dev_priv->crtc_offset_cntl |
- RADEON_CRTC_OFFSET_FLIP_CNTL );
-
- dev_priv->page_flipping = 1;
- dev_priv->current_page = 0;
-
- return 0;
-}
-
-int radeon_do_cleanup_pageflip( drm_device_t *dev )
-{
- drm_radeon_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG( "%s\n", __FUNCTION__ );
-
- RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->crtc_offset );
- RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
-
- dev_priv->page_flipping = 0;
- dev_priv->current_page = 0;
-
- return 0;
-}
-
+/* KW: Deprecated to say the least:
+ */
int radeon_fullscreen( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_radeon_fullscreen_t fs;
-
- LOCK_TEST_WITH_RETURN( dev );
-
- if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg,
- sizeof(fs) ) )
- return -EFAULT;
-
- switch ( fs.func ) {
- case RADEON_INIT_FULLSCREEN:
- return radeon_do_init_pageflip( dev );
- case RADEON_CLEANUP_FULLSCREEN:
- return radeon_do_cleanup_pageflip( dev );
- }
-
- return -EINVAL;
+ return 0;
}
Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h
===================================================================
RCS file:
/cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h,v
retrieving revision 1.9.2.4
diff -u -r1.9.2.4 radeon_drm.h
--- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h 25 Mar
2002 10:29:12 -0000 1.9.2.4
+++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h 21 May
+2002 11:41:01 -0000
@@ -291,6 +291,8 @@
drm_radeon_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1];
int tex_age[RADEON_NR_TEX_HEAPS];
int ctx_owner;
+ int pfState; /* number of 3d windows (0,1,2ormore) */
+ int pfCurrentPage; /* which buffer is being displayed? */
} drm_radeon_sarea_t;
Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c
===================================================================
RCS file:
/cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c,v
retrieving revision 1.13.2.4
diff -u -r1.13.2.4 radeon_drv.c
--- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c 8 Apr
2002 16:12:20 -0000 1.13.2.4
+++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c 21 May
+2002 11:41:01 -0000
@@ -51,6 +51,8 @@
* - Increase MAX_TEXTURE_LEVELS (brian)
* 1.3 - Add cmdbuf ioctl (keith)
* - Add support for new radeon packets (keith)
+ * - Add getparam ioctl (keith)
+ * - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
*/
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, \
@@ -70,7 +72,8 @@
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 },
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)] = { radeon_cp_flip, 1, 0 },
#include "drm_agpsupport.h"
Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h
===================================================================
RCS file:
/cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h,v
retrieving revision 1.13.2.4
diff -u -r1.13.2.4 radeon_drv.h
--- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h 25 Mar
2002 10:29:12 -0000 1.13.2.4
+++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h 21 May
+2002 11:41:01 -0000
@@ -171,6 +171,8 @@
unsigned int cmd, unsigned long arg );
extern int radeon_cp_getparam( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
+extern int radeon_cp_flip( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg );
Index: programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c
===================================================================
RCS file:
/cvsroot/dri/xc/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c,v
retrieving revision 1.12.2.8
diff -u -r1.12.2.8 radeon_state.c
--- programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c 25 Mar
2002 10:29:12 -0000 1.12.2.8
+++ programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c 21 May
+2002 11:41:01 -0000
@@ -51,7 +51,8 @@
OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) );
OUT_RING( (box->y1 << 16) | box->x1 );
OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) );
- OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );
+/* OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );*/
+ OUT_RING( (box->y2 << 16) | box->x2 );
ADVANCE_RING();
}
@@ -543,9 +544,17 @@
RADEON_DP_SRC_SOURCE_MEMORY |
RADEON_GMC_CLR_CMP_CNTL_DIS |
RADEON_GMC_WR_MSK_DIS );
-
- OUT_RING( dev_priv->back_pitch_offset );
- OUT_RING( dev_priv->front_pitch_offset );
+
+ /* Make this work even if front & back are flipped:
+ */
+ if (dev_priv->current_page == 0) {
+ OUT_RING( dev_priv->back_pitch_offset );
+ OUT_RING( dev_priv->front_pitch_offset );
+ }
+ else {
+ OUT_RING( dev_priv->front_pitch_offset );
+ OUT_RING( dev_priv->back_pitch_offset );
+ }
OUT_RING( (x << 16) | y );
OUT_RING( (x << 16) | y );
@@ -580,11 +589,12 @@
radeon_cp_performance_boxes( dev_priv );
#endif
- BEGIN_RING( 6 );
+ BEGIN_RING( 4 );
RADEON_WAIT_UNTIL_3D_IDLE();
+/*
RADEON_WAIT_UNTIL_PAGE_FLIPPED();
-
+*/
OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 0 ) );
if ( dev_priv->current_page == 0 ) {
@@ -602,6 +612,7 @@
* performing the swapbuffer ioctl.
*/
dev_priv->sarea_priv->last_frame++;
+ dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
BEGIN_RING( 2 );
@@ -1045,25 +1056,71 @@
sarea_priv->nbox * sizeof(depth_boxes[0]) ) )
return -EFAULT;
- /* Needed for depth clears via triangles???
- */
- if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
- radeon_emit_state( dev_priv,
- &sarea_priv->context_state,
- sarea_priv->tex_state,
- sarea_priv->dirty );
-
- sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
- RADEON_UPLOAD_TEX1IMAGES |
- RADEON_UPLOAD_TEX2IMAGES |
- RADEON_REQUIRE_QUIESCENCE);
- }
-
radeon_cp_dispatch_clear( dev, &clear, depth_boxes );
return 0;
}
+
+
+/* Not sure why this isn't set all the time:
+ */
+static int radeon_do_init_pageflip( drm_device_t *dev )
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ dev_priv->crtc_offset = RADEON_READ( RADEON_CRTC_OFFSET );
+ dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
+
+ RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset );
+ RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL,
+ dev_priv->crtc_offset_cntl |
+ RADEON_CRTC_OFFSET_FLIP_CNTL );
+
+ dev_priv->page_flipping = 1;
+ dev_priv->current_page = 0;
+
+ return 0;
+}
+
+int radeon_do_cleanup_pageflip( drm_device_t *dev )
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->crtc_offset );
+ RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
+
+ dev_priv->page_flipping = 0;
+ dev_priv->current_page = 0;
+
+ return 0;
+}
+
+/* Swapping and flipping are different operations, need different ioctls.
+ * They can & should be intermixed to support multiple 3d windows.
+ */
+int radeon_cp_flip( struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg )
+{
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG( "%s\n", __FUNCTION__ );
+
+ LOCK_TEST_WITH_RETURN( dev );
+
+ RING_SPACE_TEST_WITH_RETURN( dev_priv );
+
+ if (!dev_priv->page_flipping)
+ radeon_do_init_pageflip( dev );
+
+ radeon_cp_dispatch_flip( dev );
+
+ return 0;
+}
+
int radeon_cp_swap( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -1080,12 +1137,8 @@
if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
- if ( !dev_priv->page_flipping ) {
- radeon_cp_dispatch_swap( dev );
- dev_priv->sarea_priv->ctx_owner = 0;
- } else {
- radeon_cp_dispatch_flip( dev );
- }
+ radeon_cp_dispatch_swap( dev );
+ dev_priv->sarea_priv->ctx_owner = 0;
return 0;
}