diff options
author | Felix Kuehling <fxkuehl@gmx.de> | 2005-03-06 01:36:10 +0000 |
---|---|---|
committer | Felix Kuehling <fxkuehl@gmx.de> | 2005-03-06 01:36:10 +0000 |
commit | 33033884e9ec07d96c70765132a2be0ebc466299 (patch) | |
tree | fdf3c29a49be1dab58b1b31c06ea5f81f7067121 /src | |
parent | 21bf49050a7b868c50831fb3951086fe9c21e8f6 (diff) |
- Support for the new DRM version 2.4 with command DMA.
- Added an option "DmaMode" to choose between vertex and command DMA.
- Allow ShadowStatus to be explicitly disabled even with DRI enabled.
- Updated the man page.
Diffstat (limited to 'src')
-rw-r--r-- | src/savage_dri.c | 209 | ||||
-rw-r--r-- | src/savage_dri.h | 5 | ||||
-rw-r--r-- | src/savage_driver.c | 47 | ||||
-rw-r--r-- | src/savage_driver.h | 3 |
4 files changed, 198 insertions, 66 deletions
diff --git a/src/savage_dri.c b/src/savage_dri.c index c7d5e63..8613fd0 100644 --- a/src/savage_dri.c +++ b/src/savage_dri.c @@ -733,6 +733,7 @@ static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen) SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; unsigned long mode; unsigned int vendor, device; + unsigned int offset; int ret; /*int size,numbuffer,i; savageAgpBufferPtr agpbuffer;*/ @@ -742,14 +743,23 @@ static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen) pSAVAGEDRIServer->agp.size = psav->agpSize * 1024 * 1024; pSAVAGEDRIServer->agp.offset = pSAVAGEDRIServer->agp.size; /* ? */ - if (psav->AgpDMA) { - pSAVAGEDRIServer->buffers.offset = 0; - pSAVAGEDRIServer->buffers.size = SAVAGE_NUM_BUFFERS * SAVAGE_BUFFER_SIZE; + offset = 0; + + if ( psav->AgpDMA ) { + if ( psav->CommandDMA ) { + pSAVAGEDRIServer->cmdDma.offset = offset; + pSAVAGEDRIServer->cmdDma.size = SAVAGE_CMDDMA_SIZE; + offset += pSAVAGEDRIServer->cmdDma.size; + } else if ( psav->VertexDMA ) { + pSAVAGEDRIServer->buffers.offset = 0; + pSAVAGEDRIServer->buffers.size = SAVAGE_NUM_BUFFERS * SAVAGE_BUFFER_SIZE; + offset += pSAVAGEDRIServer->buffers.size; + } } - pSAVAGEDRIServer->agpTextures.offset = pSAVAGEDRIServer->buffers.size; - pSAVAGEDRIServer->agpTextures.size = (pSAVAGEDRIServer->agp.size - - pSAVAGEDRIServer->buffers.size); + pSAVAGEDRIServer->agpTextures.offset = offset; + pSAVAGEDRIServer->agpTextures.size = (pSAVAGEDRIServer->agp.size - offset); + offset += pSAVAGEDRIServer->agpTextures.size; if ( drmAgpAcquire( psav->drmFD ) < 0 ) { xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not available\n" ); @@ -807,31 +817,59 @@ static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen) /* DMA buffers */ if ( psav->AgpDMA ) { - if ( drmAddMap( psav->drmFD, - pSAVAGEDRIServer->buffers.offset, - pSAVAGEDRIServer->buffers.size, - DRM_AGP, 0, - &pSAVAGEDRIServer->buffers.handle ) < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[agp] Could not add DMA buffers mapping\n" ); - return FALSE; - } - xf86DrvMsg( pScreen->myNum, X_INFO, - "[agp] DMA buffers handle = 0x%08lx\n", - pSAVAGEDRIServer->buffers.handle ); - /* not needed in the server - if ( drmMap( psav->drmFD, - pSAVAGEDRIServer->buffers.handle, - pSAVAGEDRIServer->buffers.size, - &pSAVAGEDRIServer->buffers.map ) < 0 ) { - xf86DrvMsg( pScreen->myNum, X_ERROR, - "[agp] Could not map DMA buffers\n" ); - return FALSE; + if ( psav->CommandDMA ) { + if ( drmAddMap( psav->drmFD, + pSAVAGEDRIServer->cmdDma.offset, + pSAVAGEDRIServer->cmdDma.size, + DRM_AGP, DRM_RESTRICTED | DRM_KERNEL, + &pSAVAGEDRIServer->cmdDma.handle ) < 0 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, + "[agp] Could not add command DMA mapping\n" ); + return FALSE; + } + xf86DrvMsg( pScreen->myNum, X_INFO, + "[agp] command DMA handle = 0x%08lx\n", + pSAVAGEDRIServer->cmdDma.handle ); + /* not needed in the server + if ( drmMap( psav->drmFD, + pSAVAGEDRIServer->cmdDma.handle, + pSAVAGEDRIServer->cmdDma.size, + &pSAVAGEDRIServer->cmdDma.map ) < 0 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, + "[agp] Could not map command DMA\n" ); + return FALSE; + } + xf86DrvMsg( pScreen->myNum, X_INFO, + "[agp] command DMA mapped at 0x%08lx\n", + (unsigned long)pSAVAGEDRIServer->cmdDma.map ); + */ + } else if ( psav->VertexDMA ) { + if ( drmAddMap( psav->drmFD, + pSAVAGEDRIServer->buffers.offset, + pSAVAGEDRIServer->buffers.size, + DRM_AGP, 0, + &pSAVAGEDRIServer->buffers.handle ) < 0 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, + "[agp] Could not add DMA buffers mapping\n" ); + return FALSE; + } + xf86DrvMsg( pScreen->myNum, X_INFO, + "[agp] DMA buffers handle = 0x%08lx\n", + pSAVAGEDRIServer->buffers.handle ); + /* not needed in the server + if ( drmMap( psav->drmFD, + pSAVAGEDRIServer->buffers.handle, + pSAVAGEDRIServer->buffers.size, + &pSAVAGEDRIServer->buffers.map ) < 0 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, + "[agp] Could not map DMA buffers\n" ); + return FALSE; + } + xf86DrvMsg( pScreen->myNum, X_INFO, + "[agp] DMA buffers mapped at 0x%08lx\n", + (unsigned long)pSAVAGEDRIServer->buffers.map ); + */ } - xf86DrvMsg( pScreen->myNum, X_INFO, - "[agp] DMA buffers mapped at 0x%08lx\n", - (unsigned long)pSAVAGEDRIServer->buffers.map ); - */ } /* AGP textures @@ -847,7 +885,7 @@ static Bool SAVAGEDRIAgpInit(ScreenPtr pScreen) } /* pSAVAGEDRIServer->agp_offset=pSAVAGEDRIServer->agpTexture.size;*/ xf86DrvMsg( pScreen->myNum, X_INFO, - "[agp] agpTextures microcode handle = 0x%08lx\n", + "[agp] agpTextures handle = 0x%08lx\n", pSAVAGEDRIServer->agpTextures.handle ); /* not needed in the server @@ -931,40 +969,55 @@ static Bool SAVAGEDRIMapInit( ScreenPtr pScreen ) }*/ - /* Always enable ShadowStatus for direct rendering. */ - if ( !psav->ShadowStatus ) { - psav->ShadowStatus = 1; + if ( !psav->AgpDMA && psav->CommandDMA ) { + pSAVAGEDRIServer->cmdDma.size = SAVAGE_CMDDMA_SIZE; + if ( drmAddMap( psav->drmFD, 0, pSAVAGEDRIServer->cmdDma.size, + DRM_CONSISTENT, DRM_RESTRICTED | DRM_LOCKED | + DRM_KERNEL | DRM_WRITE_COMBINING, + &pSAVAGEDRIServer->cmdDma.handle ) < 0 ) { + psav->CommandDMA = FALSE; + xf86DrvMsg( pScreen->myNum, X_WARNING, + "[drm] Could not add PCI command DMA mapping\n" ); + } else + xf86DrvMsg( pScreen->myNum, X_INFO, + "[drm] PCI command DMA handle = 0x%08lx\n", + pSAVAGEDRIServer->cmdDma.handle ); + } + + /* Enable ShadowStatus by default for direct rendering. */ + if ( !psav->ShadowStatus && !psav->ForceShadowStatus ) { + psav->ShadowStatus = TRUE; xf86DrvMsg( pScreen->myNum, X_INFO, "[drm] Enabling ShadowStatus for DRI.\n" ); - } - pSAVAGEDRIServer->status.size = 4096; /* 1 page */ + 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 ( 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 ); + 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; + psav->ShadowPhysical = pSAVAGEDRIServer->status.handle; + psav->ShadowVirtual = pSAVAGEDRIServer->status.map; + } return TRUE; } @@ -976,6 +1029,13 @@ static Bool SAVAGEDRIBuffersInit( ScreenPtr pScreen ) SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; int count; + if ( !psav->VertexDMA || psav->CommandDMA ) { + /* At this point psav->CommandDMA == TRUE means that CommandDMA + * allocation was actually successful. */ + psav->VertexDMA = FALSE; + return TRUE; + } + if ( psav->AgpDMA ) { count = drmAddBufs( psav->drmFD, SAVAGE_NUM_BUFFERS, SAVAGE_BUFFER_SIZE, @@ -1042,9 +1102,19 @@ static Bool SAVAGEDRIKernelInit( ScreenPtr pScreen ) init.texture_size = pSAVAGEDRIServer->textureSize; init.status_offset = pSAVAGEDRIServer->status.handle; - init.buffers_offset = pSAVAGEDRIServer->buffers.handle; init.agp_textures_offset = pSAVAGEDRIServer->agpTextures.handle; + /* Savage4-based chips with DRM version >= 2.4 support command DMA, + * which is preferred because it works with all vertex + * formats. Command DMA and vertex DMA don't work at the same + * time. */ + init.buffers_offset = 0; + init.cmd_dma_offset = 0; + if ( psav->CommandDMA ) + init.cmd_dma_offset = pSAVAGEDRIServer->cmdDma.handle; + else if ( psav->VertexDMA ) + init.buffers_offset = pSAVAGEDRIServer->buffers.handle; + ret = drmCommandWrite( psav->drmFD, DRM_SAVAGE_BCI_INIT, &init, sizeof(init) ); if ( ret < 0 ) { xf86DrvMsg( pScrn->scrnIndex, X_ERROR, @@ -1251,7 +1321,7 @@ Bool SAVAGEDRIScreenInit( ScreenPtr pScreen ) /* incompatible drm version */ xf86DrvMsg( pScreen->myNum, X_ERROR, "[dri] SAVAGEDRIScreenInit failed because of a version mismatch.\n" - "[dri] savage.o kernel module version is %d.%d.%d but version 2.0.x is needed.\n" + "[dri] savage.ko kernel module version is %d.%d.%d but version 2.0.x is needed.\n" "[dri] Disabling DRI.\n", version->version_major, version->version_minor, @@ -1260,6 +1330,18 @@ Bool SAVAGEDRIScreenInit( ScreenPtr pScreen ) SAVAGEDRICloseScreen( pScreen ); /* FIXME: ??? */ return FALSE; } + if ( psav->CommandDMA && version->version_minor < 4 ) { + xf86DrvMsg( pScreen->myNum, X_WARNING, + "[drm] DRM version < 2.4.0 does not support command DMA.\n"); + psav->CommandDMA = FALSE; + } + if ( !psav->VertexDMA && version->version_minor < 4 ) { + xf86DrvMsg( pScreen->myNum, X_ERROR, + "[drm] DRM version < 2.4.0 requires vertex DMA.\n"); + drmFreeVersion( version ); + SAVAGEDRICloseScreen( pScreen ); + return FALSE; + } drmFreeVersion( version ); } } @@ -1483,6 +1565,11 @@ Bool SAVAGEDRIFinishScreenInit( ScreenPtr pScreen ) xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] logAgpTextureGranularity:0x%08x\n",pSAVAGEDRIServer->logAgpTextureGranularity); + xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:handle:0x%08lx\n",pSAVAGEDRIServer->cmdDma.handle); + xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:offset:0x%08x\n",pSAVAGEDRIServer->cmdDma.offset); + xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:size:0x%08x\n",pSAVAGEDRIServer->cmdDma.size); + xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] cmdDma:map:0x%08lx\n",(unsigned long)pSAVAGEDRIServer->cmdDma.map); + xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers]pSAVAGEDRI:\n" ); xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] chipset:0x%08x\n",pSAVAGEDRI->chipset ); xf86DrvMsg( pScrn->scrnIndex, X_INFO, "[junkers] width:0x%08x\n",pSAVAGEDRI->width ); diff --git a/src/savage_dri.h b/src/savage_dri.h index 39b6564..82b4aee 100644 --- a/src/savage_dri.h +++ b/src/savage_dri.h @@ -34,6 +34,8 @@ #define SAVAGE_NUM_BUFFERS 32 #define SAVAGE_BUFFER_SIZE (1 << 16) /* 64k */ +#define SAVAGE_CMDDMA_SIZE 0x100000 /* 1MB */ + #define SAVAGE_DEFAULT_AGP_MODE 1 #define SAVAGE_MAX_AGP_MODE 4 @@ -101,6 +103,9 @@ typedef struct _server{ drmRegion agpTextures; int logAgpTextureGranularity; + /* command DMA */ + drmRegion cmdDma; + #if 0 drmBufMapPtr drmBuffers; #endif diff --git a/src/savage_driver.c b/src/savage_driver.c index 74ff6a0..5b7704e 100644 --- a/src/savage_driver.c +++ b/src/savage_driver.c @@ -213,6 +213,7 @@ typedef enum { ,OPTION_DVI ,OPTION_BUS_TYPE ,OPTION_DMA_TYPE + ,OPTION_DMA_MODE ,OPTION_AGP_MODE ,OPTION_AGP_SIZE } SavageOpts; @@ -243,6 +244,7 @@ static const OptionInfoRec SavageOptions[] = #ifdef XF86DRI { OPTION_BUS_TYPE, "BusType", OPTV_ANYSTR, {0}, FALSE }, { OPTION_DMA_TYPE, "DmaType", OPTV_ANYSTR, {0}, FALSE }, + { OPTION_DMA_MODE, "DmaMode", OPTV_ANYSTR, {0}, FALSE }, { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, #endif @@ -1223,9 +1225,12 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, "Option: LCDClock %1.2f MHz\n", psav->LCDClock ); - if( xf86GetOptValBool( psav->Options, OPTION_SHADOW_STATUS, &psav->ShadowStatus)) + if( xf86GetOptValBool( psav->Options, OPTION_SHADOW_STATUS, &psav->ShadowStatus)) { xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, - "Option: ShadowStatus enabled\n" ); + "Option: ShadowStatus %sabled\n", psav->ShadowStatus ? "en" : "dis" ); + psav->ForceShadowStatus = TRUE; + } else + psav->ForceShadowStatus = FALSE; /* If ShadowStatus is off it will be automatically enabled for DRI. * If DRI initialization fails fall back to ConfigShadowStatus. */ psav->ConfigShadowStatus = psav->ShadowStatus; @@ -1427,6 +1432,36 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) "Using %s DMA\n", psav->AgpDMA ? "AGP" : "PCI"); } + psav->CommandDMA = TRUE; + psav->VertexDMA = TRUE; + from = X_DEFAULT; + if ((s = xf86GetOptValString(psav->Options, OPTION_DMA_MODE))) { + from = X_CONFIG; + if (strcmp(s, "Command") == 0) + psav->VertexDMA = FALSE; + else if (strcmp(s, "Vertex") == 0) + psav->CommandDMA = FALSE; + else if (strcmp(s, "None") == 0) + psav->VertexDMA = psav->CommandDMA = FALSE; + else if (strcmp(s, "Any") != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid DmaMode option\n"); + from = X_DEFAULT; + } + } + psav->CommandDMA = (psav->CommandDMA && !S3_SAVAGE3D_SERIES(psav->Chipset)); + if (psav->CommandDMA && psav->VertexDMA) + xf86DrvMsg(pScrn->scrnIndex, from, + "Will try command and vertex DMA mode\n"); + else if (psav->CommandDMA && !psav->VertexDMA) + xf86DrvMsg(pScrn->scrnIndex, from, + "Will try only command DMA mode\n"); + else if (!psav->CommandDMA && psav->VertexDMA) + xf86DrvMsg(pScrn->scrnIndex, from, + "Will try only vertex DMA mode\n"); + else + xf86DrvMsg(pScrn->scrnIndex, from, + "DMA disabled\n"); + if (!psav->IsPCI) { from = X_DEFAULT; psav->agpMode = SAVAGE_DEFAULT_AGP_MODE; @@ -3026,13 +3061,14 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, /* Setup DRI after visuals have been established */ psav->directRenderingEnabled = SAVAGEDRIScreenInit(pScreen); /* If DRI init failed, reset shadow status. */ - if (!psav->directRenderingEnabled) { + if (!psav->directRenderingEnabled && + psav->ShadowStatus != psav->ConfigShadowStatus) { 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) { + else if (psav->ShadowStatus && !psav->ConfigShadowStatus) { psav->WaitQueue = ShadowWaitQueue; psav->WaitIdle = ShadowWait; psav->WaitIdleEmpty = ShadowWait; @@ -3211,7 +3247,8 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, psav->directRenderingEnabled = SAVAGEDRIFinishScreenInit(pScreen); /* If DRI initialization failed, reset shadow status and * reinitialize 2D engine. */ - if (!psav->directRenderingEnabled) { + if (!psav->directRenderingEnabled && + psav->ShadowStatus != psav->ConfigShadowStatus) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Resetting ShadowStatus.\n"); SavageInitShadowStatus(pScrn); SavageInitialize2DEngine(pScrn); diff --git a/src/savage_driver.h b/src/savage_driver.h index 6b8ee9e..a60262c 100644 --- a/src/savage_driver.h +++ b/src/savage_driver.h @@ -234,6 +234,7 @@ typedef struct _Savage { double LCDClock; Bool ConfigShadowStatus; /* from the config */ Bool ShadowStatus; /* automatically enabled with DRI */ + Bool ForceShadowStatus; /* true if explicitly set in conf */ Bool CrtOnly; Bool TvOn; Bool PAL; @@ -340,6 +341,8 @@ typedef struct _Savage { Bool IsPCI; Bool AgpDMA; + Bool VertexDMA; + Bool CommandDMA; int agpMode; drmSize agpSize; FBLinearPtr reserved; |