From 21bf49050a7b868c50831fb3951086fe9c21e8f6 Mon Sep 17 00:00:00 2001 From: Felix Kuehling Date: Sat, 26 Feb 2005 13:56:27 +0000 Subject: Fixed ShadowStatus handling with DRI: - always enable ShadowStatus when DRI is enabled - if DRI initialization fails, reset ShadowStatus to configured setting - if DRI initialization fails, fall back to ShadowStatus in framebuffer --- src/savage_dri.c | 67 ++++++++++++------------ src/savage_driver.c | 145 +++++++++++++++++++++++++++++++++------------------- src/savage_driver.h | 3 +- 3 files changed, 130 insertions(+), 85 deletions(-) diff --git a/src/savage_dri.c b/src/savage_dri.c index 382b941..c7d5e63 100644 --- a/src/savage_dri.c +++ b/src/savage_dri.c @@ -931,39 +931,40 @@ static Bool SAVAGEDRIMapInit( ScreenPtr pScreen ) }*/ - if ( psav->ShadowStatus ) { - pSAVAGEDRIServer->status.size = 4096; /* 1 page */ - - if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->status.size, - DRM_CONSISTENT, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL, - &pSAVAGEDRIServer->status.handle ) < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[drm] Could not add status page mapping\n" ); - return FALSE; - } - xf86DrvMsg( pScreen->myNum, X_INFO, - "[drm] Status handle = 0x%08lx\n", - pSAVAGEDRIServer->status.handle ); - - if ( drmMap( psav->drmFD, - pSAVAGEDRIServer->status.handle, - pSAVAGEDRIServer->status.size, - &pSAVAGEDRIServer->status.map ) < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[drm] Could not map status page\n" ); - return FALSE; - } - xf86DrvMsg( pScreen->myNum, X_INFO, - "[drm] Status page mapped at 0x%08lx\n", - (unsigned long)pSAVAGEDRIServer->status.map ); + /* Always enable ShadowStatus for direct rendering. */ + if ( !psav->ShadowStatus ) { + psav->ShadowStatus = 1; + xf86DrvMsg( pScreen->myNum, X_INFO, + "[drm] Enabling ShadowStatus for DRI.\n" ); + } - psav->ShadowPhysical = pSAVAGEDRIServer->status.handle; - psav->ShadowVirtual = pSAVAGEDRIServer->status.map; - } else { - pSAVAGEDRIServer->status.size = 0; - pSAVAGEDRIServer->status.handle = 0; - pSAVAGEDRIServer->status.map = NULL; + pSAVAGEDRIServer->status.size = 4096; /* 1 page */ + + if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->status.size, + DRM_CONSISTENT, DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL, + &pSAVAGEDRIServer->status.handle ) < 0 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, + "[drm] Could not add status page mapping\n" ); + return FALSE; + } + xf86DrvMsg( pScreen->myNum, X_INFO, + "[drm] Status handle = 0x%08lx\n", + pSAVAGEDRIServer->status.handle ); + + if ( drmMap( psav->drmFD, + pSAVAGEDRIServer->status.handle, + pSAVAGEDRIServer->status.size, + &pSAVAGEDRIServer->status.map ) < 0 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, + "[drm] Could not map status page\n" ); + return FALSE; } + xf86DrvMsg( pScreen->myNum, X_INFO, + "[drm] Status page mapped at 0x%08lx\n", + (unsigned long)pSAVAGEDRIServer->status.map ); + + psav->ShadowPhysical = pSAVAGEDRIServer->status.handle; + psav->ShadowVirtual = pSAVAGEDRIServer->status.map; return TRUE; } @@ -1597,7 +1598,9 @@ void SAVAGEDRICloseScreen( ScreenPtr pScreen ) DRICloseScreen( pScreen ); - /*Don't use shadow status any more*/ + /* Don't use shadow status any more. If this happens due to failed + * DRI initialization then SavageScreenInit will do the real + * cleanup and restore ShadowStatus to sane settings. */ psav->ShadowVirtual = NULL; psav->ShadowPhysical = 0; diff --git a/src/savage_driver.c b/src/savage_driver.c index 921cb87..74ff6a0 100644 --- a/src/savage_driver.c +++ b/src/savage_driver.c @@ -50,6 +50,9 @@ static void SavageLeaveVT(int scrnIndex, int flags); static void SavageSave(ScrnInfoPtr pScrn); static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr, SavageRegPtr, Bool); +static void SavageInitStatus(ScrnInfoPtr pScrn); +static void SavageInitShadowStatus(ScrnInfoPtr pScrn); + static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv); static int SavageInternalScreenInit(int scrnIndex, ScreenPtr pScreen); @@ -1223,7 +1226,9 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) if( xf86GetOptValBool( psav->Options, OPTION_SHADOW_STATUS, &psav->ShadowStatus)) xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, "Option: ShadowStatus enabled\n" ); - + /* If ShadowStatus is off it will be automatically enabled for DRI. + * If DRI initialization fails fall back to ConfigShadowStatus. */ + psav->ConfigShadowStatus = psav->ShadowStatus; if( xf86GetOptValBool( psav->Options, OPTION_CRT_ONLY, &psav->CrtOnly)) xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, @@ -1756,37 +1761,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) usleep(10000); /* Set status word positions based on chip type. */ - - switch( psav->Chipset ) { - case S3_SAVAGE3D: - case S3_SAVAGE_MX: - psav->WaitQueue = WaitQueue3D; - psav->WaitIdle = WaitIdle3D; - psav->WaitIdleEmpty = WaitIdleEmpty3D; - psav->bciUsedMask = 0x1ffff; - psav->eventStatusReg= 1; - break; - - case S3_SAVAGE4: - case S3_PROSAVAGE: - case S3_SUPERSAVAGE: - case S3_PROSAVAGEDDR: - case S3_TWISTER: - psav->WaitQueue = WaitQueue4; - psav->WaitIdle = WaitIdle4; - psav->WaitIdleEmpty = WaitIdleEmpty4; - psav->bciUsedMask = 0x1fffff; - psav->eventStatusReg= 1; - break; - - case S3_SAVAGE2000: - psav->WaitQueue = WaitQueue2K; - psav->WaitIdle = WaitIdle2K; - psav->WaitIdleEmpty = WaitIdleEmpty2K; - psav->bciUsedMask = 0xfffff; - psav->eventStatusReg= 2; - break; - } + SavageInitStatus(pScrn); /* check for DVI/flat panel */ dvi = FALSE; @@ -2912,6 +2887,72 @@ static Bool SavageCheckAvailableRamFor3D(ScrnInfoPtr pScrn) } #endif +static void SavageInitStatus(ScrnInfoPtr pScrn) +{ + SavagePtr psav = SAVPTR(pScrn); + + switch( psav->Chipset ) { + case S3_SAVAGE3D: + case S3_SAVAGE_MX: + psav->WaitQueue = WaitQueue3D; + psav->WaitIdle = WaitIdle3D; + psav->WaitIdleEmpty = WaitIdleEmpty3D; + psav->bciUsedMask = 0x1ffff; + psav->eventStatusReg= 1; + break; + + case S3_SAVAGE4: + case S3_PROSAVAGE: + case S3_SUPERSAVAGE: + case S3_PROSAVAGEDDR: + case S3_TWISTER: + psav->WaitQueue = WaitQueue4; + psav->WaitIdle = WaitIdle4; + psav->WaitIdleEmpty = WaitIdleEmpty4; + psav->bciUsedMask = 0x1fffff; + psav->eventStatusReg= 1; + break; + + case S3_SAVAGE2000: + psav->WaitQueue = WaitQueue2K; + psav->WaitIdle = WaitIdle2K; + psav->WaitIdleEmpty = WaitIdleEmpty2K; + psav->bciUsedMask = 0xfffff; + psav->eventStatusReg= 2; + break; + } +} + +static void SavageInitShadowStatus(ScrnInfoPtr pScrn) +{ + SavagePtr psav = SAVPTR(pScrn); + + psav->ShadowStatus = psav->ConfigShadowStatus; + + SavageInitStatus(pScrn); + + if( psav->ShadowStatus ) { + psav->ShadowPhysical = + psav->FrameBufferBase + psav->CursorKByte*1024 + 4096 - 32; + + psav->ShadowVirtual = (CARD32 *) + (psav->FBBase + psav->CursorKByte*1024 + 4096 - 32); + + xf86DrvMsg( pScrn->scrnIndex, X_PROBED, + "Shadow area physical %08lx, linear %p\n", + psav->ShadowPhysical, (void *)psav->ShadowVirtual ); + + psav->WaitQueue = ShadowWaitQueue; + psav->WaitIdle = ShadowWait; + psav->WaitIdleEmpty = ShadowWait; + } + + if( psav->Chipset == S3_SAVAGE2000 ) + psav->dwBCIWait2DIdle = 0xc0040000; + else + psav->dwBCIWait2DIdle = 0xc0020000; +} + static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { @@ -2948,26 +2989,7 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, } - if( psav->ShadowStatus ) { - psav->ShadowPhysical = - psav->FrameBufferBase + psav->CursorKByte*1024 + 4096 - 32; - - psav->ShadowVirtual = (CARD32 *) - (psav->FBBase + psav->CursorKByte*1024 + 4096 - 32); - - xf86DrvMsg( pScrn->scrnIndex, X_PROBED, - "Shadow area physical %08lx, linear %p\n", - psav->ShadowPhysical, (void *)psav->ShadowVirtual ); - - psav->WaitQueue = ShadowWaitQueue; - psav->WaitIdle = ShadowWait; - psav->WaitIdleEmpty = ShadowWait; - - if( psav->Chipset == S3_SAVAGE2000 ) - psav->dwBCIWait2DIdle = 0xc0040000; - else - psav->dwBCIWait2DIdle = 0xc0020000; - } + SavageInitShadowStatus(pScrn); psav->ShadowCounter = 0; SavageSave(pScrn); @@ -3003,6 +3025,18 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, && (SavageCheckAvailableRamFor3D(pScrn))) { /* Setup DRI after visuals have been established */ psav->directRenderingEnabled = SAVAGEDRIScreenInit(pScreen); + /* If DRI init failed, reset shadow status. */ + if (!psav->directRenderingEnabled) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Resetting ShadowStatus.\n"); + SavageInitShadowStatus(pScrn); + } + /* If shadow status was enabled for DRI, hook up the shadow + * waiting functions now. */ + else if (!psav->ConfigShadowStatus) { + psav->WaitQueue = ShadowWaitQueue; + psav->WaitIdle = ShadowWait; + psav->WaitIdleEmpty = ShadowWait; + } } else psav->directRenderingEnabled = FALSE; @@ -3175,6 +3209,13 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, if (psav->directRenderingEnabled) { /* complete the DRI setup.*/ psav->directRenderingEnabled = SAVAGEDRIFinishScreenInit(pScreen); + /* If DRI initialization failed, reset shadow status and + * reinitialize 2D engine. */ + if (!psav->directRenderingEnabled) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Resetting ShadowStatus.\n"); + SavageInitShadowStatus(pScrn); + SavageInitialize2DEngine(pScrn); + } } if (psav->directRenderingEnabled) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); diff --git a/src/savage_driver.h b/src/savage_driver.h index 2a04a53..6b8ee9e 100644 --- a/src/savage_driver.h +++ b/src/savage_driver.h @@ -232,7 +232,8 @@ typedef struct _Savage { Bool UseBIOS; int rotate; double LCDClock; - Bool ShadowStatus; + Bool ConfigShadowStatus; /* from the config */ + Bool ShadowStatus; /* automatically enabled with DRI */ Bool CrtOnly; Bool TvOn; Bool PAL; -- cgit v1.2.3