diff options
-rw-r--r-- | src/mga_dri.c | 219 | ||||
-rw-r--r-- | src/mga_exa.c | 77 | ||||
-rw-r--r-- | src/mga_storm.c | 182 |
3 files changed, 284 insertions, 194 deletions
diff --git a/src/mga_dri.c b/src/mga_dri.c index 231dda9..731c354 100644 --- a/src/mga_dri.c +++ b/src/mga_dri.c @@ -76,13 +76,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 +489,6 @@ MGADRISwapContextShared( ScreenPtr pScreen, DRISyncType syncType, } } -#ifdef USE_XAA void MGASelectBuffer( ScrnInfoPtr pScrn, int which ) { MGAPtr pMga = MGAPTR(pScrn); @@ -518,8 +510,6 @@ void MGASelectBuffer( ScrnInfoPtr pScrn, int which ) break; } } -#endif - static unsigned int mylog2( unsigned int n ) { @@ -911,6 +901,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)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); + if (!pboxNew1) return; + pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); + if (!pptNew1) { + DEALLOCATE_LOCAL(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)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); + pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); + if (!pboxNew2 || !pptNew2) { + if (pptNew2) DEALLOCATE_LOCAL(pptNew2); + if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2); + if (pboxNew1) { + DEALLOCATE_LOCAL(pptNew1); + DEALLOCATE_LOCAL(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) { + DEALLOCATE_LOCAL(pptNew2); + DEALLOCATE_LOCAL(pboxNew2); + } + if (pboxNew1) { + DEALLOCATE_LOCAL(pptNew1); + DEALLOCATE_LOCAL(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 ) { @@ -1057,8 +1241,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; diff --git a/src/mga_exa.c b/src/mga_exa.c index b22716d..6c39f97 100644 --- a/src/mga_exa.c +++ b/src/mga_exa.c @@ -741,6 +741,80 @@ mgaWaitMarker(ScreenPtr pScreen, int marker) while (INREG (MGAREG_Status) & 0x10000); } +static void +init_dri(ScrnInfoPtr pScrn) +{ + MGAPtr pMga = MGAPTR(pScrn); + MGADRIServerPrivatePtr dri = pMga->DRIServerInfo; + int cpp = pScrn->bitsPerPixel / 8; + int widthBytes = pScrn->displayWidth * cpp; + int bufferSize = ((pScrn->virtualY * widthBytes + MGA_BUFFER_ALIGN) + & ~MGA_BUFFER_ALIGN); + int maxlines, mb; + + switch (pMga->Chipset) { + case PCI_CHIP_MGAG200_SE_A_PCI: + case PCI_CHIP_MGAG200_SE_B_PCI: + mb = 1; + break; + default: + mb = 16; + break; + } + + maxlines = (min(pMga->FbUsableSize, mb * 1024 * 1024)) / + (pScrn->displayWidth * pMga->CurrentLayout.bitsPerPixel / 8); + + dri->frontOffset = 0; + dri->frontPitch = widthBytes; + + /* Try for front, back, depth, and two framebuffers worth of + * pixmap cache. Should be enough for a fullscreen background + * image plus some leftovers. + */ + dri->textureSize = pMga->FbMapSize - 5 * 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 + * performance than playing nicely, and you'll get around a full + * framebuffer's worth of pixmap cache anyway. + */ + if (dri->textureSize < (int)pMga->FbMapSize / 2) { + dri->textureSize = pMga->FbMapSize - 4 * bufferSize; + } + + /* Check to see if there is more room available after the maximum + * scanline for textures. + */ + if ((int) pMga->FbMapSize - maxlines * widthBytes - bufferSize * 2 + > dri->textureSize) { + dri->textureSize = pMga->FbMapSize - maxlines * widthBytes - + bufferSize * 2; + } + + /* Set a minimum usable local texture heap size. This will fit + * two 256x256x32bpp textures. + */ + if (dri->textureSize < 512 * 1024) { + dri->textureOffset = 0; + dri->textureSize = 0; + } + + /* Reserve space for textures */ + dri->textureOffset = (pMga->FbMapSize - dri->textureSize + + MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN; + + /* Reserve space for the shared depth buffer */ + dri->depthOffset = (dri->textureOffset - bufferSize + + MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN; + dri->depthPitch = widthBytes; + + /* Reserve space for the shared back buffer */ + dri->backOffset = (dri->depthOffset - bufferSize + + MGA_BUFFER_ALIGN) & ~MGA_BUFFER_ALIGN; + dri->backPitch = widthBytes; +} + Bool mgaExaInit(ScreenPtr pScreen) { @@ -799,5 +873,8 @@ mgaExaInit(ScreenPtr pScreen) pExa->UploadToScreen = mgaUploadToScreen; + if (pMga->directRenderingEnabled) + init_dri(pScrn); + return exaDriverInit(pScreen, pExa); } diff --git a/src/mga_storm.c b/src/mga_storm.c index ccc17b3..67338d9 100644 --- a/src/mga_storm.c +++ b/src/mga_storm.c @@ -143,12 +143,6 @@ static void mgaSubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, static void mgaRestoreAccelState( ScrnInfoPtr pScrn ); -#ifdef XF86DRI -void mgaDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index); -void mgaDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, - RegionPtr prgnSrc, CARD32 index); -#endif - static void MGASetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2); static void MGADisableClipping(ScrnInfoPtr pScrn); @@ -2570,179 +2564,3 @@ MGAFillCacheBltRects( SET_SYNC_FLAG(infoRec); } - - -#if defined(XF86DRI) -void -mgaDRIInitBuffers(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); - - CHECK_DMA_QUIESCENT(MGAPTR(pScrn), pScrn); - - mgaSetupForSolidFill(pScrn, 0, GXcopy, -1); - while (nbox--) { - MGASelectBuffer(pScrn, MGA_BACK); - mgaSubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, - pbox->x2-pbox->x1, pbox->y2-pbox->y1); - MGASelectBuffer(pScrn, MGA_DEPTH); - mgaSubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, - pbox->x2-pbox->x1, pbox->y2-pbox->y1); - pbox++; - } - MGASelectBuffer(pScrn, MGA_FRONT); - - pMga->AccelInfoRec->NeedToSync = TRUE; -} - -/* - 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. -*/ - -void -mgaDRIMoveBuffers(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; - - CHECK_DMA_QUIESCENT(MGAPTR(pScrn), 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)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); - if (!pboxNew1) return; - pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); - if (!pptNew1) { - DEALLOCATE_LOCAL(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)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); - pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); - if (!pboxNew2 || !pptNew2) { - if (pptNew2) DEALLOCATE_LOCAL(pptNew2); - if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2); - if (pboxNew1) { - DEALLOCATE_LOCAL(pptNew1); - DEALLOCATE_LOCAL(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; - } - - mgaSetupForScreenToScreenCopy(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); - mgaSubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); - MGASelectBuffer(pScrn, MGA_DEPTH); - mgaSubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); - } - MGASelectBuffer(pScrn, MGA_FRONT); - - if (pboxNew2) { - DEALLOCATE_LOCAL(pptNew2); - DEALLOCATE_LOCAL(pboxNew2); - } - if (pboxNew1) { - DEALLOCATE_LOCAL(pptNew1); - DEALLOCATE_LOCAL(pboxNew1); - } - - pMga->AccelInfoRec->NeedToSync = TRUE; -} - -#endif /* XF86DRI */ |