diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2008-07-29 20:02:38 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2008-07-29 20:02:38 +0000 |
commit | 6e5332d8a437b02c3bf4f4d8304340a787a32126 (patch) | |
tree | 75ef0a973b7314761afe4071b09991df60160efa /driver/xf86-video-mga/src/mga_dri.c | |
parent | bbd8ae0998e921cf909d2960f012f134ba6c598c (diff) |
update xf86-video-mga to 1.4.9
Diffstat (limited to 'driver/xf86-video-mga/src/mga_dri.c')
-rw-r--r-- | driver/xf86-video-mga/src/mga_dri.c | 306 |
1 files changed, 241 insertions, 65 deletions
diff --git a/driver/xf86-video-mga/src/mga_dri.c b/driver/xf86-video-mga/src/mga_dri.c index 103279d21..3fda62378 100644 --- a/driver/xf86-video-mga/src/mga_dri.c +++ b/driver/xf86-video-mga/src/mga_dri.c @@ -1,5 +1,3 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c,v 1.31tsi Exp $ */ - /* * Copyright 2000 VA Linux Systems Inc., Fremont, California. * All Rights Reserved. @@ -38,11 +36,6 @@ #include "xf86PciInfo.h" #include "xf86Pci.h" -#define PSZ 8 -#include "cfb.h" -#undef PSZ -#include "cfb16.h" -#include "cfb32.h" #include "miline.h" @@ -76,13 +69,6 @@ static char MGAKernelDriverName[] = "mga"; static char MGAClientDriverName[] = "mga"; -/* DRI buffer management - */ -extern void mgaDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, CARD32 index ); -extern void mgaDRIMoveBuffers( WindowPtr pParent, DDXPointRec ptOldOrg, - RegionPtr prgnSrc, CARD32 index ); - - /* 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 @@ -496,7 +482,6 @@ MGADRISwapContextShared( ScreenPtr pScreen, DRISyncType syncType, } } -#ifdef USE_XAA void MGASelectBuffer( ScrnInfoPtr pScrn, int which ) { MGAPtr pMga = MGAPTR(pScrn); @@ -518,8 +503,6 @@ void MGASelectBuffer( ScrnInfoPtr pScrn, int which ) break; } } -#endif - static unsigned int mylog2( unsigned int n ) { @@ -618,8 +601,8 @@ static Bool MGADRIBootstrapDMA(ScreenPtr pScreen) xf86DrvMsg( pScreen->myNum, X_INFO, "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", mode, vendor, device, - pMga->PciInfo->vendor, - pMga->PciInfo->chipType ); + VENDOR_ID(pMga->PciInfo), + DEVICE_ID(pMga->PciInfo)); if ( drmAgpEnable( pMga->drmFD, mode ) < 0 ) { xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n" ); @@ -766,7 +749,7 @@ static Bool MGADRIBootstrapDMA(ScreenPtr pScreen) pMGADRIServer->registers.size = MGAIOMAPSIZE; if ( drmAddMap( pMga->drmFD, - (drm_handle_t)pMga->IOAddress, + (drm_handle_t) MGA_IO_ADDRESS(pMga), pMGADRIServer->registers.size, DRM_REGISTERS, DRM_READ_ONLY, &pMGADRIServer->registers.handle ) < 0 ) { @@ -803,23 +786,16 @@ static Bool MGADRIKernelInit( ScreenPtr pScreen ) drm_mga_init_t init; int ret; + + if (!pMga->chip_attribs->dri_capable) { + return FALSE; + } + memset( &init, 0, sizeof(drm_mga_init_t) ); init.func = MGA_INIT_DMA; init.sarea_priv_offset = sizeof(XF86DRISAREARec); - - switch ( pMga->Chipset ) { - case PCI_CHIP_MGAG550: - case PCI_CHIP_MGAG400: - init.chipset = MGA_CARD_TYPE_G400; - break; - case PCI_CHIP_MGAG200: - case PCI_CHIP_MGAG200_PCI: - init.chipset = MGA_CARD_TYPE_G200; - break; - default: - return FALSE; - } + init.chipset = pMga->chip_attribs->dri_chipset; init.sgram = !pMga->HasSDRAM; init.maccess = pMga->MAccess; @@ -859,20 +835,26 @@ static Bool MGADRIKernelInit( ScreenPtr pScreen ) return TRUE; } +/* FIXME: This function uses the DRM to get the IRQ, but the pci_device + * FIXME: structure (PciInfo) already has that information. + */ static void MGADRIIrqInit(MGAPtr pMga, ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - /* version = drmGetVersion(pMga->drmFD); - if ( version ) { - if ( version->version_major != 3 || - version->version_minor < 0 ) {*/ if (!pMga->irq) { - pMga->irq = drmGetInterruptFromBusID( - pMga->drmFD, + pMga->irq = drmGetInterruptFromBusID(pMga->drmFD, +#ifdef XSERVER_LIBPCIACCESS + ((pMga->PciInfo->domain << 8) | + pMga->PciInfo->bus), + pMga->PciInfo->dev, + pMga->PciInfo->func +#else ((pciConfigPtr)pMga->PciInfo->thisCard)->busnum, ((pciConfigPtr)pMga->PciInfo->thisCard)->devnum, - ((pciConfigPtr)pMga->PciInfo->thisCard)->funcnum); + ((pciConfigPtr)pMga->PciInfo->thisCard)->funcnum +#endif + ); if((drmCtlInstHandler(pMga->drmFD, pMga->irq)) != 0) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, @@ -911,6 +893,200 @@ static Bool MGADRIBuffersInit( ScreenPtr pScreen ) return TRUE; } +#ifdef USE_XAA +static void MGADRIInitBuffersXAA(WindowPtr pWin, RegionPtr prgn, + CARD32 index) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MGAPtr pMga = MGAPTR(pScrn); + BoxPtr pbox = REGION_RECTS(prgn); + int nbox = REGION_NUM_RECTS(prgn); + XAAInfoRecPtr xaa = pMga->AccelInfoRec; + + CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn); + + xaa->SetupForSolidFill(pScrn, 0, GXcopy, -1); + + while (nbox--) { + MGASelectBuffer(pScrn, MGA_BACK); + xaa->SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, + pbox->x2-pbox->x1, pbox->y2-pbox->y1); + MGASelectBuffer(pScrn, MGA_DEPTH); + xaa->SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, + pbox->x2-pbox->x1, pbox->y2-pbox->y1); + pbox++; + } + + MGASelectBuffer(pScrn, MGA_FRONT); + + pMga->AccelInfoRec->NeedToSync = TRUE; +} +#endif + +#ifdef USE_EXA +static void MGADRIInitBuffersEXA(WindowPtr pWin, RegionPtr prgn, + CARD32 index) +{ + /* FIXME */ +} +#endif + +#ifdef USE_XAA +/* + This routine is a modified form of XAADoBitBlt with the calls to + ScreenToScreenBitBlt built in. My routine has the prgnSrc as source + instead of destination. My origin is upside down so the ydir cases + are reversed. +*/ +static void MGADRIMoveBuffersXAA(WindowPtr pParent, DDXPointRec ptOldOrg, + RegionPtr prgnSrc, CARD32 index) +{ + ScreenPtr pScreen = pParent->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MGAPtr pMga = MGAPTR(pScrn); + int nbox; + BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2; + DDXPointPtr pptTmp, pptNew1, pptNew2; + int xdir, ydir; + int dx, dy; + DDXPointPtr pptSrc; + int screenwidth = pScrn->virtualX; + int screenheight = pScrn->virtualY; + XAAInfoRecPtr xaa = pMga->AccelInfoRec; + + CHECK_DMA_QUIESCENT(pMga, pScrn); + + pbox = REGION_RECTS(prgnSrc); + nbox = REGION_NUM_RECTS(prgnSrc); + pboxNew1 = 0; + pptNew1 = 0; + pboxNew2 = 0; + pboxNew2 = 0; + pptSrc = &ptOldOrg; + + dx = pParent->drawable.x - ptOldOrg.x; + dy = pParent->drawable.y - ptOldOrg.y; + + /* If the copy will overlap in Y, reverse the order */ + if (dy>0) { + ydir = -1; + + if (nbox>1) { + /* Keep ordering in each band, reverse order of bands */ + pboxNew1 = (BoxPtr)xalloc(sizeof(BoxRec)*nbox); + if (!pboxNew1) return; + pptNew1 = (DDXPointPtr)xalloc(sizeof(DDXPointRec)*nbox); + if (!pptNew1) { + xfree(pboxNew1); + return; + } + pboxBase = pboxNext = pbox+nbox-1; + while (pboxBase >= pbox) { + while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) + pboxNext--; + pboxTmp = pboxNext+1; + pptTmp = pptSrc + (pboxTmp - pbox); + while (pboxTmp <= pboxBase) { + *pboxNew1++ = *pboxTmp++; + *pptNew1++ = *pptTmp++; + } + pboxBase = pboxNext; + } + pboxNew1 -= nbox; + pbox = pboxNew1; + pptNew1 -= nbox; + pptSrc = pptNew1; + } + } else { + /* No changes required */ + ydir = 1; + } + + /* If the regions will overlap in X, reverse the order */ + if (dx>0) { + xdir = -1; + + if (nbox > 1) { + /*reverse orderof rects in each band */ + pboxNew2 = (BoxPtr)xalloc(sizeof(BoxRec)*nbox); + pptNew2 = (DDXPointPtr)xalloc(sizeof(DDXPointRec)*nbox); + if (!pboxNew2 || !pptNew2) { + if (pptNew2) xfree(pptNew2); + if (pboxNew2) xfree(pboxNew2); + if (pboxNew1) { + xfree(pptNew1); + xfree(pboxNew1); + } + return; + } + pboxBase = pboxNext = pbox; + while (pboxBase < pbox+nbox) { + while ((pboxNext < pbox+nbox) && + (pboxNext->y1 == pboxBase->y1)) + pboxNext++; + pboxTmp = pboxNext; + pptTmp = pptSrc + (pboxTmp - pbox); + while (pboxTmp != pboxBase) { + *pboxNew2++ = *--pboxTmp; + *pptNew2++ = *--pptTmp; + } + pboxBase = pboxNext; + } + pboxNew2 -= nbox; + pbox = pboxNew2; + pptNew2 -= nbox; + pptSrc = pptNew2; + } + } else { + /* No changes are needed */ + xdir = 1; + } + + xaa->SetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1); + for ( ; nbox-- ; pbox++) { + int x1 = pbox->x1; + int y1 = pbox->y1; + int destx = x1 + dx; + int desty = y1 + dy; + int w = pbox->x2 - x1 + 1; + int h = pbox->y2 - y1 + 1; + + if ( destx < 0 ) x1 -= destx, w += destx, destx = 0; + if ( desty < 0 ) y1 -= desty, h += desty, desty = 0; + if ( destx + w > screenwidth ) w = screenwidth - destx; + if ( desty + h > screenheight ) h = screenheight - desty; + if ( w <= 0 ) continue; + if ( h <= 0 ) continue; + + MGASelectBuffer(pScrn, MGA_BACK); + xaa->SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); + MGASelectBuffer(pScrn, MGA_DEPTH); + xaa->SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); + } + MGASelectBuffer(pScrn, MGA_FRONT); + + if (pboxNew2) { + xfree(pptNew2); + xfree(pboxNew2); + } + if (pboxNew1) { + xfree(pptNew1); + xfree(pboxNew1); + } + + pMga->AccelInfoRec->NeedToSync = TRUE; + +} +#endif + +#ifdef USE_EXA +static void MGADRIMoveBuffersEXA(WindowPtr pParent, DDXPointRec ptOldOrg, + RegionPtr prgnSrc, CARD32 index) +{ + /* FIXME */ +} +#endif Bool MGADRIScreenInit( ScreenPtr pScreen ) { @@ -920,13 +1096,7 @@ Bool MGADRIScreenInit( ScreenPtr pScreen ) MGADRIPtr pMGADRI; MGADRIServerPrivatePtr pMGADRIServer; - switch(pMga->Chipset) { - case PCI_CHIP_MGAG550: - case PCI_CHIP_MGAG400: - case PCI_CHIP_MGAG200: - case PCI_CHIP_MGAG200_PCI: - break; - default: + if (!pMga->chip_attribs->dri_capable) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[drm] Direct rendering only supported with G200/G400/G450/G550.\n"); return FALSE; } @@ -983,13 +1153,19 @@ Bool MGADRIScreenInit( ScreenPtr pScreen ) } else { pDRIInfo->busIdString = xalloc(64); sprintf( pDRIInfo->busIdString, "PCI:%d:%d:%d", +#ifdef XSERVER_LIBPCIACCESS + ((pMga->PciInfo->domain << 8) | pMga->PciInfo->bus), + pMga->PciInfo->dev, pMga->PciInfo->func +#else ((pciConfigPtr)pMga->PciInfo->thisCard)->busnum, ((pciConfigPtr)pMga->PciInfo->thisCard)->devnum, - ((pciConfigPtr)pMga->PciInfo->thisCard)->funcnum ); + ((pciConfigPtr)pMga->PciInfo->thisCard)->funcnum +#endif + ); } - pDRIInfo->ddxDriverMajorVersion = MGA_MAJOR_VERSION; - pDRIInfo->ddxDriverMinorVersion = MGA_MINOR_VERSION; - pDRIInfo->ddxDriverPatchVersion = MGA_PATCHLEVEL; + pDRIInfo->ddxDriverMajorVersion = PACKAGE_VERSION_MAJOR; + pDRIInfo->ddxDriverMinorVersion = PACKAGE_VERSION_MINOR; + pDRIInfo->ddxDriverPatchVersion = PACKAGE_VERSION_PATCHLEVEL; pDRIInfo->frameBufferPhysicalAddress = (void *) pMga->FbAddress; pDRIInfo->frameBufferSize = pMga->FbMapSize; pDRIInfo->frameBufferStride = pScrn->displayWidth*(pScrn->bitsPerPixel/8); @@ -1057,8 +1233,19 @@ Bool MGADRIScreenInit( ScreenPtr pScreen ) pDRIInfo->SwapContext = MGADRISwapContext; } - pDRIInfo->InitBuffers = mgaDRIInitBuffers; - pDRIInfo->MoveBuffers = mgaDRIMoveBuffers; +#ifdef USE_EXA + if (pMga->Exa) { + pDRIInfo->InitBuffers = MGADRIInitBuffersEXA; + pDRIInfo->MoveBuffers = MGADRIMoveBuffersEXA; + } else { +#endif +#ifdef USE_XAA + pDRIInfo->InitBuffers = MGADRIInitBuffersXAA; + pDRIInfo->MoveBuffers = MGADRIMoveBuffersXAA; +#endif +#ifdef USE_EXA + } +#endif pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; @@ -1217,18 +1404,7 @@ Bool MGADRIFinishScreenInit( ScreenPtr pScreen ) MGADRIIrqInit(pMga, pScreen); - switch(pMga->Chipset) { - case PCI_CHIP_MGAG550: - case PCI_CHIP_MGAG400: - pMGADRI->chipset = MGA_CARD_TYPE_G400; - break; - case PCI_CHIP_MGAG200: - case PCI_CHIP_MGAG200_PCI: - pMGADRI->chipset = MGA_CARD_TYPE_G200; - break; - default: - return FALSE; - } + pMGADRI->chipset = pMga->chip_attribs->dri_chipset; pMGADRI->width = pScrn->virtualX; pMGADRI->height = pScrn->virtualY; pMGADRI->cpp = pScrn->bitsPerPixel / 8; |