diff options
author | Alex Deucher <agd5f@yahoo.com> | 2006-04-30 17:51:15 +0000 |
---|---|---|
committer | Alex Deucher <agd5f@yahoo.com> | 2006-04-30 17:51:15 +0000 |
commit | 6d688c993ec7baf8f00df59764dd3e04bab24e09 (patch) | |
tree | 81f74a3b06394f6f42679cb53fe3ecd706a39f11 /src | |
parent | ef46fb29088e7cc50c6072d66c6ac1fe5cd398bd (diff) |
- Add exa support (solid, copy, UTS)
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/savage_accel.c | 1133 | ||||
-rw-r--r-- | src/savage_bci.h | 5 | ||||
-rw-r--r-- | src/savage_driver.c | 82 | ||||
-rw-r--r-- | src/savage_driver.h | 14 | ||||
-rw-r--r-- | src/savage_exa.c | 481 | ||||
-rw-r--r-- | src/savage_image.c | 204 | ||||
-rw-r--r-- | src/savage_video.c | 163 | ||||
-rw-r--r-- | src/savage_xaa.c | 1022 |
9 files changed, 1754 insertions, 1353 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 3bdb452..8ae8051 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,6 +30,8 @@ savage_drv_ladir = @moduledir@/drivers savage_drv_la_SOURCES = \ savage_accel.c \ + savage_xaa.c \ + savage_exa.c \ savage_bci.h \ savage_common.h \ savage_cursor.c \ @@ -38,7 +40,6 @@ savage_drv_la_SOURCES = \ savage_driver.h \ savage_drm.h \ savage_i2c.c \ - savage_image.c \ savage_regs.h \ savage_sarea.h \ savage_shadow.c \ diff --git a/src/savage_accel.c b/src/savage_accel.c index cbeece6..c80dfa0 100644 --- a/src/savage_accel.c +++ b/src/savage_accel.c @@ -20,11 +20,6 @@ #include "config.h" #endif -#include <X11/Xarch.h> -#include "xaalocal.h" -#include "xaarop.h" -#include "miline.h" - #include "savage_driver.h" #include "savage_regs.h" #include "savage_bci.h" @@ -39,182 +34,6 @@ extern int gSavageEntityIndex; /* Forward declaration of functions used in the driver */ -static void SavageSetupForScreenToScreenCopy( - ScrnInfoPtr pScrn, - int xdir, - int ydir, - int rop, - unsigned planemask, - int transparency_color); - -static void SavageSubsequentScreenToScreenCopy( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2, - int w, - int h); - -static void SavageSetupForSolidFill( - ScrnInfoPtr pScrn, - int color, - int rop, - unsigned int planemask); - -static void SavageSubsequentSolidFillRect( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h); - -static void SavageSubsequentSolidBresenhamLine( - ScrnInfoPtr pScrn, - int x1, - int y1, - int e1, - int e2, - int err, - int length, - int octant); - -#if 0 -static void SavageSubsequentSolidTwoPointLine( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2, - int bias); -#endif - -#if 0 -static void SavageSetupForScreenToScreenColorExpand( - ScrnInfoPtr pScrn, - int bg, - int fg, - int rop, - unsigned int planemask); - -static void SavageSubsequentScreenToScreenColorExpand( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, - int skipleft); -#endif - -static void SavageSetupForCPUToScreenColorExpandFill( - ScrnInfoPtr pScrn, - int fg, - int bg, - int rop, - unsigned int planemask); - -static void SavageSubsequentScanlineCPUToScreenColorExpandFill( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, - int skipleft); - -static void SavageSubsequentColorExpandScanline( - ScrnInfoPtr pScrn, - int buffer_no); - -static void SavageSetupForMono8x8PatternFill( - ScrnInfoPtr pScrn, - int patternx, - int patterny, - int fg, - int bg, - int rop, - unsigned int planemask); - -static void SavageSubsequentMono8x8PatternFillRect( - ScrnInfoPtr pScrn, - int pattern0, - int pattern1, - int x, - int y, - int w, - int h); - -#if 0 -static void SavageSetupForColor8x8PatternFill( - ScrnInfoPtr pScrn, - int patternx, - int patterny, - int rop, - unsigned planemask, - int trans_col); - -static void SavageSubsequentColor8x8PatternFillRect( - ScrnInfoPtr pScrn, - int pattern0, - int pattern1, - int x, - int y, - int w, - int h); -#endif - -static void SavageSetClippingRectangle( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2); - -static void SavageDisableClipping( ScrnInfoPtr ); - -#if 0 -static void SavageSubsequentSolidFillTrap( - ScrnInfoPtr pScrn, - int y, - int h, - int left, - int dxl, - int dyl, - int el, - int right, - int dxr, - int dyr, - int er); -#endif - -/* from savage_image.c: */ - -void SavageSetupForImageWrite( - ScrnInfoPtr pScrn, - int rop, - unsigned int planemask, - int transparency_color, - int bpp, - int depth); - -void SavageSubsequentImageWriteRect( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, - int skipleft); - -void SavageWriteBitmapCPUToScreenColorExpand ( - ScrnInfoPtr pScrn, - int x, int y, int w, int h, - unsigned char * src, - int srcwidth, - int skipleft, - int fg, int bg, - int rop, - unsigned int planemask -); - unsigned long writedw( unsigned long addr, unsigned long value ); unsigned long readdw( unsigned long addr ); unsigned long readfb( unsigned long addr ); @@ -1034,7 +853,7 @@ void SavageSetGBD_M7(ScrnInfoPtr pScrn) else if (pScrn->bitsPerPixel == 16) { psav->GlobalBD.bd1.HighPart.ResBWTile = tile16;/* 16 bit */ - ulTmp = ((psav->lDelta / 2) >> 6) << 24; + ulTmp = ((psav->lDelta / 2) >> 6) << 24; if (psav->IsSecondary) OUTREG32(TILED_SURFACE_REGISTER_1,ulTmp | TILED_SURF_BPP16 | pScrn->fbOffset); else @@ -1043,7 +862,7 @@ void SavageSetGBD_M7(ScrnInfoPtr pScrn) else if (pScrn->bitsPerPixel == 32) { psav->GlobalBD.bd1.HighPart.ResBWTile = tile32;/* 32 bit */ - ulTmp = ((psav->lDelta / 4) >> 5) << 24; + ulTmp = ((psav->lDelta / 4) >> 5) << 24; if (psav->IsSecondary) OUTREG32(TILED_SURFACE_REGISTER_1,ulTmp | TILED_SURF_BPP32 | pScrn->fbOffset); else @@ -1289,7 +1108,7 @@ void SavageSetGBD_PM(ScrnInfoPtr pScrn) /* program the GBD and SBDs */ OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart ); OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart - | bci_enable | S3_LITTLE_ENDIAN | 0x10000000 | S3_BD64)); + | bci_enable | S3_LITTLE_ENDIAN | S3_BD64)); OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart); OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart); OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart); @@ -1427,7 +1246,7 @@ void SavageSetGBD_2000(ScrnInfoPtr pScrn) /* program the GBD and SBDs */ OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart ); OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart - | bci_enable | S3_LITTLE_ENDIAN | 0x10000000 | S3_BD64)); + | bci_enable | S3_LITTLE_ENDIAN | S3_BD64)); OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart); OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart); OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart); @@ -1456,213 +1275,6 @@ SavageInitAccel(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; SavagePtr psav = SAVPTR(pScrn); - XAAInfoRecPtr xaaptr; - BoxRec AvailFBArea; - - /* Set-up our GE command primitive */ - - if (pScrn->depth == 8) { - psav->PlaneMask = 0xFF; - } - else if (pScrn->depth == 15) { - psav->PlaneMask = 0x7FFF; - } - else if (pScrn->depth == 16) { - psav->PlaneMask = 0xFFFF; - } - else if (pScrn->depth == 24) { - psav->PlaneMask = 0xFFFFFF; - } - - /* General acceleration flags */ - - if (!(xaaptr = psav->AccelInfoRec = XAACreateInfoRec())) - return FALSE; - - xaaptr->Flags = 0 - | PIXMAP_CACHE - | OFFSCREEN_PIXMAPS - | LINEAR_FRAMEBUFFER - ; - - /* Clipping */ - - xaaptr->SetClippingRectangle = SavageSetClippingRectangle; - xaaptr->DisableClipping = SavageDisableClipping; - xaaptr->ClippingFlags = 0 -#if 0 - | HARDWARE_CLIP_SOLID_FILL - | HARDWARE_CLIP_SOLID_LINE - | HARDWARE_CLIP_DASHED_LINE -#endif - | HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY - | HARDWARE_CLIP_MONO_8x8_FILL - | HARDWARE_CLIP_COLOR_8x8_FILL - ; - - xaaptr->Sync = SavageAccelSync; - - if(xf86IsEntityShared(pScrn->entityList[0])) - { - DevUnion* pPriv; - SavageEntPtr pEnt; - pPriv = xf86GetEntityPrivate(pScrn->entityList[0], - gSavageEntityIndex); - pEnt = pPriv->ptr; - - /*if there are more than one devices sharing this entity, we - have to assign this call back, otherwise the XAA will be - disabled */ - if(pEnt->HasSecondary) - xaaptr->RestoreAccelState = SavageRestoreAccelState; - } - - /* ScreenToScreen copies */ - -#if 1 - - xaaptr->SetupForScreenToScreenCopy = SavageSetupForScreenToScreenCopy; - xaaptr->SubsequentScreenToScreenCopy = SavageSubsequentScreenToScreenCopy; - xaaptr->ScreenToScreenCopyFlags = 0 - | NO_TRANSPARENCY - | NO_PLANEMASK - | ROP_NEEDS_SOURCE; - -#endif - - - /* Solid filled rectangles */ - -#if 1 - xaaptr->SetupForSolidFill = SavageSetupForSolidFill; - xaaptr->SubsequentSolidFillRect = SavageSubsequentSolidFillRect; - xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; -#endif - - /* Mono 8x8 pattern fills */ - -#if 1 - xaaptr->SetupForMono8x8PatternFill = SavageSetupForMono8x8PatternFill; - xaaptr->SubsequentMono8x8PatternFillRect - = SavageSubsequentMono8x8PatternFillRect; - xaaptr->Mono8x8PatternFillFlags = 0 - | HARDWARE_PATTERN_PROGRAMMED_BITS - | HARDWARE_PATTERN_SCREEN_ORIGIN - | BIT_ORDER_IN_BYTE_MSBFIRST - | ROP_NEEDS_SOURCE - ; - if( psav->Chipset == S3_SAVAGE4 ) - xaaptr->Mono8x8PatternFillFlags |= NO_TRANSPARENCY; -#endif - - /* Color 8x8 pattern fills */ - - /* - * With the exception of the Savage3D and Savage4, all of the Savage - * chips require that bitmap descriptors have a stride that is a - * multiple of 16 pixels. This includes any descriptor used for - * color pattern fills, which COMPLETELY screws the XAA 8x8 color - * pattern support. - * - * We could double the width ourselves into a reserved frame buffer - * section, but since I went 18 months with only ONE report of this - * error, it seems hardly worth the trouble. - */ - -#if 0 - if( (psav->Chipset == S3_SAVAGE3D) || (psav->Chipset == S3_SAVAGE4) ) - { - xaaptr->SetupForColor8x8PatternFill = - SavageSetupForColor8x8PatternFill; - xaaptr->SubsequentColor8x8PatternFillRect = - SavageSubsequentColor8x8PatternFillRect; - xaaptr->Color8x8PatternFillFlags = 0 - | NO_TRANSPARENCY - | HARDWARE_PATTERN_PROGRAMMED_BITS - | HARDWARE_PATTERN_PROGRAMMED_ORIGIN - ; - } -#endif - - /* Solid lines */ - -#if 1 - xaaptr->SolidLineFlags = NO_PLANEMASK; - xaaptr->SetupForSolidLine = SavageSetupForSolidFill; - xaaptr->SubsequentSolidBresenhamLine = SavageSubsequentSolidBresenhamLine; -#if 0 - xaaptr->SubsequentSolidFillTrap = SavageSubsequentSolidFillTrap; -#endif - - xaaptr->SolidBresenhamLineErrorTermBits = 13; -#endif - - /* ImageWrite */ - - xaaptr->ImageWriteFlags = 0 - | NO_PLANEMASK - | CPU_TRANSFER_PAD_DWORD - | SCANLINE_PAD_DWORD - | BIT_ORDER_IN_BYTE_MSBFIRST - | LEFT_EDGE_CLIPPING - ; - xaaptr->SetupForImageWrite = SavageSetupForImageWrite; - xaaptr->SubsequentImageWriteRect = SavageSubsequentImageWriteRect; - xaaptr->NumScanlineImageWriteBuffers = 1; - xaaptr->ImageWriteBase = psav->BciMem; - xaaptr->ImageWriteRange = 120 * 1024; - - /* WriteBitmap color expand */ - -#if 0 - xaaptr->WriteBitmapFlags = NO_PLANEMASK; - xaaptr->WriteBitmap = SavageWriteBitmapCPUToScreenColorExpand; -#endif - - /* Screen to Screen color expansion. Not implemented. */ - -#if 0 - xaaptr->SetupForScreenToScreenColorExpand = - SavageSetupForScreenToScreenColorExpand; - xaaptr->SubsequentScreenToScreenColorExpand = - SavageSubsequentCPUToScreenColorExpand; -#endif - - /* CPU to Screen color expansion */ - - xaaptr->ScanlineCPUToScreenColorExpandFillFlags = 0 - | NO_PLANEMASK - | CPU_TRANSFER_PAD_DWORD - | SCANLINE_PAD_DWORD - | BIT_ORDER_IN_BYTE_MSBFIRST - | LEFT_EDGE_CLIPPING - | ROP_NEEDS_SOURCE - ; - - xaaptr->SetupForScanlineCPUToScreenColorExpandFill = - SavageSetupForCPUToScreenColorExpandFill; - xaaptr->SubsequentScanlineCPUToScreenColorExpandFill = - SavageSubsequentScanlineCPUToScreenColorExpandFill; - xaaptr->SubsequentColorExpandScanline = - SavageSubsequentColorExpandScanline; - xaaptr->ColorExpandBase = psav->BciMem; - xaaptr->ScanlineColorExpandBuffers = &xaaptr->ColorExpandBase; - xaaptr->NumScanlineColorExpandBuffers = 1; - - /* Set up screen parameters. */ - - psav->Bpp = pScrn->bitsPerPixel / 8; - psav->Bpl = pScrn->displayWidth * psav->Bpp; - psav->ScissB = (psav->CursorKByte << 10) / psav->Bpl; - if (psav->ScissB > 2047) - psav->ScissB = 2047; - - /* - * Finally, we set up the video memory space available to the pixmap - * cache. In this case, all memory from the end of the virtual screen - * to the end of the command overflow buffer can be used. If you haven't - * enabled the PIXMAP_CACHE flag, then these lines can be omitted. - */ #ifdef XF86DRI if (psav->directRenderingEnabled) { @@ -1882,52 +1494,7 @@ SavageInitAccel(ScreenPtr pScreen) psav->cyMemory = 0x7FFF; } - MemBox.x1 = 0; - MemBox.y1 = 0; - MemBox.x2 = psav->cxMemory; - MemBox.y2 = psav->cyMemory; - - if (!xf86InitFBManager(pScreen, &MemBox)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Memory manager initialization to (%d,%d) (%d,%d) failed\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 ); - return FALSE; - } else { - int tmp,width, height; - - xf86DrvMsg( pScrn->scrnIndex, X_INFO, - "Memory manager initialized to (%d,%d) (%d,%d)\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 ); - /* - * because the alignment requirement,the on-screen need more memory - * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract - * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so - * here,we should reserve some memory for on-screen - */ - tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY) - + psav->cxMemory -1) / (psav->cxMemory); - if (tmp) - xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL); - - if (xf86QueryLargestOffscreenArea(pScreen, &width, - &height, 0, 0, 0 ) ) { - xf86DrvMsg( pScrn->scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height ); - } - } - psav->reserved = 0; - - if(tiledBufferSize > bufferSize) - { - psav->reserved = xf86AllocateOffscreenLinear(pScreen, - (tiledBufferSize - bufferSize),1,0,0,0); - - } - if(psav->reserved) - xf86DrvMsg( pScrn->scrnIndex, X_INFO, - "Reserved for tiled front buffer at offset 0x%08x ,size:0x%08x\n", - psav->reserved->offset, psav->reserved->size); + psav->EXAendfb = pSAVAGEDRIServer->backOffset & ~SAVAGE_BUFFER_ALIGN; xf86DrvMsg( pScrn->scrnIndex, X_INFO, "Reserved back buffer at offset 0x%x\n", @@ -1943,7 +1510,6 @@ SavageInitAccel(ScreenPtr pScreen) else #endif { - int tmp; /* * why this code? because BoxRec members are short int @@ -1952,687 +1518,26 @@ SavageInitAccel(ScreenPtr pScreen) if (psav->cyMemory > 0x7FFF) { psav->cyMemory = 0x7FFF; } - - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = psav->cxMemory; - AvailFBArea.y2 = psav->cyMemory; - xf86InitFBManager(pScreen, &AvailFBArea); - /* - * because the alignment requirement,the on-screen need more memory - * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract - * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so - * here,we should reserver some memory for on-screen - */ - tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY) - + psav->cxMemory -1) / (psav->cxMemory); - if (tmp) - xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d lines for offscreen memory.\n", - psav->cyMemory - pScrn->virtualY ); - } - -#if 0 - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = psav->ScissB; - xf86InitFBManager(pScreen, &AvailFBArea); - xf86DrvMsg( pScrn->scrnIndex, X_INFO, - "Using %d lines for offscreen memory.\n", - psav->ScissB - pScrn->virtualY ); -#endif - - - return XAAInit(pScreen, xaaptr); -} - - - - -/* The sync function for the GE */ -void -SavageAccelSync(ScrnInfoPtr pScrn) -{ - SavagePtr psav = SAVPTR(pScrn); - psav->WaitIdleEmpty(psav); -} - - -/* - * The XAA ROP helper routines all assume that a solid color is a - * "pattern". The Savage chips, however, apply a non-stippled solid - * color as "source". Thus, we use a slightly customized version. - */ - -static int -SavageHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, unsigned int pm, int *rop) -{ - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); - int ret = 0; - - pm &= infoRec->FullPlanemask; - - if(pm == infoRec->FullPlanemask) { - if(!NO_SRC_ROP(*rop)) - ret |= ROP_PAT; - *rop = XAAGetCopyROP(*rop); - } else { - switch(*rop) { - case GXnoop: - break; - case GXset: - case GXclear: - case GXinvert: - ret |= ROP_PAT; - *fg = pm; - if(*bg != -1) - *bg = pm; - break; - default: - ret |= ROP_PAT | ROP_SRC; - break; - } - *rop = XAAGetCopyROP_PM(*rop); - } - - return ret; -} - -static int -SavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg, unsigned int pm, int *rop) -{ - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); - int ret = 0; - - pm &= infoRec->FullPlanemask; - - if(pm == infoRec->FullPlanemask) { - if(!NO_SRC_ROP(*rop)) - ret |= ROP_PAT; - *rop = XAAGetCopyROP(*rop); - } else { - switch(*rop) { - case GXnoop: - break; - case GXset: - case GXclear: - case GXinvert: - ret |= ROP_PAT; - *fg = pm; - break; - default: - ret |= ROP_PAT | ROP_SRC; - break; + if (psav->IsPrimary) { + psav->EXAendfb = psav->videoRambytes - + 4096 - /* hw cursor*/ + 0x200000; + } else { + psav->EXAendfb = psav->videoRambytes - + 4096 - /* hw cursor*/ + psav->cobSize - /*COB*/ + 0x200000; } - *rop = XAAGetCopyROP_PM(*rop); - } - - return ret; -} - - - -/* These are the ScreenToScreen bitblt functions. We support all ROPs, all - * directions, and a planemask by adjusting the ROP and using the mono pattern - * registers. - * - * (That's a lie; we don't really support planemask.) - */ - -static void -SavageSetupForScreenToScreenCopy( - ScrnInfoPtr pScrn, - int xdir, - int ydir, - int rop, - unsigned planemask, - int transparency_color) -{ - SavagePtr psav = SAVPTR(pScrn); - int cmd; - - cmd = BCI_CMD_RECT | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SBD_COLOR_NEW; - - BCI_CMD_SET_ROP( cmd, XAAGetCopyROP(rop) ); - if (transparency_color != -1) - cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_SRC_TRANSPARENT; - - if (xdir == 1 ) cmd |= BCI_CMD_RECT_XP; - if (ydir == 1 ) cmd |= BCI_CMD_RECT_YP; - - psav->SavedBciCmd = cmd; - psav->SavedBgColor = transparency_color; -} - -static void -SavageSubsequentScreenToScreenCopy( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2, - int w, - int h) -{ - SavagePtr psav = SAVPTR(pScrn); - - BCI_GET_PTR; - - if (!w || !h) return; - - if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) { - w --; - x1 += w; - x2 += w; - w ++; - } - if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) { - h --; - y1 += h; - y2 += h; - h ++; - } - - psav->WaitQueue(psav,9); - - - BCI_SEND(psav->SavedBciCmd); - - BCI_SEND(psav->GlobalBD.bd2.LoPart); - BCI_SEND(psav->GlobalBD.bd2.HiPart); - - BCI_SEND(psav->GlobalBD.bd2.LoPart); - BCI_SEND(psav->GlobalBD.bd2.HiPart); - - if (psav->SavedBgColor != 0xffffffff) - BCI_SEND(psav->SavedBgColor); - BCI_SEND(BCI_X_Y(x1, y1)); - BCI_SEND(BCI_X_Y(x2, y2)); - BCI_SEND(BCI_W_H(w, h)); -} - - -/* - * SetupForSolidFill is also called to set up for lines. - */ - -static void -SavageSetupForSolidFill( - ScrnInfoPtr pScrn, - int color, - int rop, - unsigned int planemask) -{ - SavagePtr psav = SAVPTR(pScrn); - XAAInfoRecPtr xaaptr = GET_XAAINFORECPTR_FROM_SCRNINFOPTR( pScrn ); - int cmd; - int mix; - - cmd = BCI_CMD_RECT - | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP - | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SOLID; - - /* Don't send a color if we don't have to. */ - - if( rop == GXcopy ) - { - if( color == 0 ) - rop = GXclear; - else if( (unsigned int)color == xaaptr->FullPlanemask ) - rop = GXset; - } - - mix = SavageHelpSolidROP( pScrn, &color, planemask, &rop ); - - if( mix & ROP_PAT ) - cmd |= BCI_CMD_SEND_COLOR; - - BCI_CMD_SET_ROP( cmd, rop ); - - psav->SavedBciCmd = cmd; - psav->SavedFgColor = color; -} - - -static void -SavageSubsequentSolidFillRect( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h) -{ - SavagePtr psav = SAVPTR(pScrn); - BCI_GET_PTR; - - if( !w || !h ) - return; - - psav->WaitQueue(psav,7); - - BCI_SEND(psav->SavedBciCmd); - - BCI_SEND(psav->GlobalBD.bd2.LoPart); - BCI_SEND(psav->GlobalBD.bd2.HiPart); - - if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR ) - BCI_SEND(psav->SavedFgColor); - BCI_SEND(BCI_X_Y(x, y)); - BCI_SEND(BCI_W_H(w, h)); -} - -#if 0 -static void -SavageSetupForScreenToScreenColorExpand( - ScrnInfoPtr pScrn, - int bg, - int fg, - int rop, - unsigned int planemask) -{ -/* SavagePtr psav = SAVPTR(pScrn); */ -} - -static void -SavageSubsequentScreenToScreenColorExpand( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, - int skipleft) -{ -/* SavagePtr psav = SAVPTR(pScrn); */ -} -#endif - - -static void -SavageSetupForCPUToScreenColorExpandFill( - ScrnInfoPtr pScrn, - int fg, - int bg, - int rop, - unsigned int planemask) -{ - SavagePtr psav = SAVPTR(pScrn); - int cmd; - int mix; - - cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP - | BCI_CMD_CLIP_LR - | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_MONO; - - mix = SavageHelpPatternROP( pScrn, &fg, &bg, planemask, &rop ); - - if( mix & ROP_PAT ) - cmd |= BCI_CMD_SEND_COLOR; - - BCI_CMD_SET_ROP( cmd, rop ); - - if (bg != -1) - cmd |= BCI_CMD_SEND_COLOR; - else - cmd |= BCI_CMD_SRC_TRANSPARENT; - - psav->SavedBciCmd = cmd; - psav->SavedFgColor = fg; - psav->SavedBgColor = bg; -} - - -static void -SavageSubsequentScanlineCPUToScreenColorExpandFill( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, - int skipleft) -{ - SavagePtr psav = SAVPTR(pScrn); - BCI_GET_PTR; - - /* XAA will be sending bitmap data next. */ - /* We should probably wait for empty/idle here. */ - - psav->WaitQueue(psav,22); - - BCI_SEND(psav->SavedBciCmd); - - BCI_SEND(psav->GlobalBD.bd2.LoPart); - BCI_SEND(psav->GlobalBD.bd2.HiPart); - - BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1)); - w = (w + 31) & ~31; - if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR ) - BCI_SEND(psav->SavedFgColor); - if( psav->SavedBgColor != 0xffffffff ) - BCI_SEND(psav->SavedBgColor); - BCI_SEND(BCI_X_Y(x, y)); - BCI_SEND(BCI_W_H(w, 1)); - - psav->Rect.x = x; - psav->Rect.y = y + 1; - psav->Rect.width = w; - psav->Rect.height = h - 1; -} - -static void -SavageSubsequentColorExpandScanline( - ScrnInfoPtr pScrn, - int buffer_no) -{ - /* This gets call after each scanline's image data has been sent. */ - SavagePtr psav = SAVPTR(pScrn); - xRectangle xr = psav->Rect; - BCI_GET_PTR; - - if( xr.height ) - { - psav->WaitQueue(psav,20); - BCI_SEND(BCI_X_Y( xr.x, xr.y)); - BCI_SEND(BCI_W_H( xr.width, 1 )); - psav->Rect.height--; - psav->Rect.y++; - } -} - - -/* - * The meaning of the two pattern paremeters to Setup & Subsequent for - * Mono8x8Patterns varies depending on the flag bits. We specify - * HW_PROGRAMMED_BITS, which means our hardware can handle 8x8 patterns - * without caching in the frame buffer. Thus, Setup gets the pattern bits. - * There is no way with BCI to rotate an 8x8 pattern, so we do NOT specify - * HW_PROGRAMMED_ORIGIN. XAA wil rotate it for us and pass the rotated - * pattern to both Setup and Subsequent. If we DID specify PROGRAMMED_ORIGIN, - * then Setup would get the unrotated pattern, and Subsequent gets the - * origin values. - */ - -static void -SavageSetupForMono8x8PatternFill( - ScrnInfoPtr pScrn, - int patternx, - int patterny, - int fg, - int bg, - int rop, - unsigned int planemask) -{ - SavagePtr psav = SAVPTR(pScrn); - int cmd; - int mix; - - mix = XAAHelpPatternROP( pScrn, &fg, &bg, planemask, &rop ); - - cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP - | BCI_CMD_DEST_PBD_NEW; - - if( mix & ROP_PAT ) - cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_PAT_MONO; - - if (bg == -1) - cmd |= BCI_CMD_PAT_TRANSPARENT; - - BCI_CMD_SET_ROP(cmd, rop); - - psav->SavedBciCmd = cmd; - psav->SavedFgColor = fg; - psav->SavedBgColor = bg; -} - - -static void -SavageSubsequentMono8x8PatternFillRect( - ScrnInfoPtr pScrn, - int pattern0, - int pattern1, - int x, - int y, - int w, - int h) -{ - SavagePtr psav = SAVPTR(pScrn); - BCI_GET_PTR; - - /* - * I didn't think it was my job to do trivial rejection, but - * miFillGeneralPolygon definitely generates null spans, and XAA - * just passes them through. - */ - - if( !w || !h ) - return; - - psav->WaitQueue(psav,9); - BCI_SEND(psav->SavedBciCmd); - - BCI_SEND(psav->GlobalBD.bd2.LoPart); - BCI_SEND(psav->GlobalBD.bd2.HiPart); - - if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR ) - BCI_SEND(psav->SavedFgColor); - if( psav->SavedBgColor != 0xffffffff ) - BCI_SEND(psav->SavedBgColor); - BCI_SEND(BCI_X_Y(x, y)); - BCI_SEND(BCI_W_H(w, h)); - if( psav->SavedBciCmd & BCI_CMD_PAT_MONO ) - { - BCI_SEND(pattern0); - BCI_SEND(pattern1); - } -} - - -#if 0 -static void -SavageSetupForColor8x8PatternFill( - ScrnInfoPtr pScrn, - int patternx, - int patterny, - int rop, - unsigned planemask, - int trans_col) -{ - SavagePtr psav = SAVPTR(pScrn); - - int cmd; - unsigned int bd; - int pat_offset; - - /* ViRGEs and Savages do not support transparent color patterns. */ - /* We set the NO_TRANSPARENCY bit, so we should never receive one. */ - - pat_offset = (int) (patternx * psav->Bpp + patterny * psav->Bpl); - - cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP - | BCI_CMD_DEST_GBD | BCI_CMD_PAT_PBD_COLOR_NEW; - - (void) XAAHelpSolidROP( pScrn, &trans_col, planemask, &rop ); - - BCI_CMD_SET_ROP(cmd, rop); - bd = BCI_BD_BW_DISABLE; - BCI_BD_SET_BPP(bd, pScrn->bitsPerPixel); - BCI_BD_SET_STRIDE(bd, 8); - - psav->SavedBciCmd = cmd; - psav->SavedSbdOffset = pat_offset; - psav->SavedSbd = bd; - psav->SavedBgColor = trans_col; -} - - -static void -SavageSubsequentColor8x8PatternFillRect( - ScrnInfoPtr pScrn, - int patternx, - int patterny, - int x, - int y, - int w, - int h) -{ - SavagePtr psav = SAVPTR(pScrn); - BCI_GET_PTR; - - if( !w || !h ) - return; - - psav->WaitQueue(psav,6); - BCI_SEND(psav->SavedBciCmd); - BCI_SEND(psav->SavedSbdOffset); - BCI_SEND(psav->SavedSbd); - BCI_SEND(BCI_X_Y(patternx,patterny)); - BCI_SEND(BCI_X_Y(x, y)); - BCI_SEND(BCI_W_H(w, h)); -} -#endif - - -static void -SavageSubsequentSolidBresenhamLine( - ScrnInfoPtr pScrn, - int x1, - int y1, - int e1, - int e2, - int err, - int length, - int octant) -{ - SavagePtr psav = SAVPTR(pScrn); - BCI_GET_PTR; - int cmd; - - cmd = (psav->SavedBciCmd & 0x00ffffff); - cmd |= BCI_CMD_LINE_LAST_PIXEL; - -#ifdef DEBUG_EXTRA - ErrorF("BresenhamLine, (%4d,%4d), len %4d, oct %d, err %4d,%4d,%4d clr %08x\n", - x1, y1, length, octant, e1, e2, err, psav->SavedFgColor ); -#endif - - psav->WaitQueue(psav, 7 ); - BCI_SEND(cmd); - - BCI_SEND(psav->GlobalBD.bd2.LoPart); - BCI_SEND(psav->GlobalBD.bd2.HiPart); - - if( cmd & BCI_CMD_SEND_COLOR ) - BCI_SEND( psav->SavedFgColor ); - BCI_SEND(BCI_LINE_X_Y(x1, y1)); - BCI_SEND(BCI_LINE_STEPS(e2-e1, e2)); - BCI_SEND(BCI_LINE_MISC(length, - (octant & YMAJOR), - !(octant & XDECREASING), - !(octant & YDECREASING), - e2+err)); -} - -#if 0 -static void -SavageSubsequentSolidTwoPointLine( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2, - int bias) -{ - SavagePtr psav = SAVPTR(pScrn); - BCI_GET_PTR; - - int cmd; - int dx, dy; - int min, max, xp, yp, ym; - - dx = x2 - x1; - dy = y2 - y1; - -#ifdef DEBUG_EXTRA - ErrorF("TwoPointLine, (%4d,%4d)-(%4d,%4d), clr %08x, last pt %s\n", - x1, y1, x2, y2, psav->SavedFgColor, (bias & 0x100)?"NO ":"YES"); -#endif - - xp = (dx >= 0); - if( !xp ) { - dx = -dx; - } - - yp = (dy >= 0); - if( !yp ) { - dy = -dy; - } - - ym = (dy > dx); - if( ym ) { - max = dy; - min = dx; - } - else { - max = dx; - min = dy; - } - - if( !(bias & 0x100) ) { - max++; + } - cmd = (psav->SavedBciCmd & 0x00ffffff); - cmd |= BCI_CMD_LINE_LAST_PIXEL; - - psav->WaitQueue(psav,5); - BCI_SEND( cmd ); - if( cmd & BCI_CMD_SEND_COLOR ) - BCI_SEND( psav->SavedFgColor ); - BCI_SEND( BCI_LINE_X_Y( x1, y1 ) ); - BCI_SEND( BCI_LINE_STEPS( 2 * (min - max), 2 * min ) ); - BCI_SEND( BCI_LINE_MISC( max, ym, xp, yp, 2 * min - max ) ); -} -#endif - - -static void -SavageSetClippingRectangle( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2) -{ - SavagePtr psav = SAVPTR(pScrn); - BCI_GET_PTR; - int cmd; - -#ifdef DEBUG_EXTRA - ErrorF("ClipRect, (%4d,%4d)-(%4d,%4d) \n", x1, y1, x2, y2 ); -#endif - - cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; - psav->WaitQueue(psav,3); - BCI_SEND(cmd); - BCI_SEND(BCI_CLIP_TL(y1, x1)); - BCI_SEND(BCI_CLIP_BR(y2, x2)); - psav->SavedBciCmd |= BCI_CMD_CLIP_CURRENT; -} - - -static void SavageDisableClipping( ScrnInfoPtr pScrn ) -{ - SavagePtr psav = SAVPTR(pScrn); -#ifdef DEBUG_EXTRA - ErrorF("Kill ClipRect\n"); -#endif - psav->SavedBciCmd &= ~BCI_CMD_CLIP_CURRENT; + if (psav->useEXA) + return SavageEXAInit(pScreen); + else + return SavageXAAInit(pScreen); } - /* Routines for debugging. */ diff --git a/src/savage_bci.h b/src/savage_bci.h index 4fabcb7..833a55d 100644 --- a/src/savage_bci.h +++ b/src/savage_bci.h @@ -107,12 +107,17 @@ #define BCI_BD_TILE_NONE 0x00000000 #define BCI_BD_TILE_16 0x02000000 #define BCI_BD_TILE_32 0x03000000 +#define BCI_BD_TILE_DESTINATION 0x01000000 + #define BCI_BD_GET_BPP(bd) (((bd) >> 16) & 0xFF) #define BCI_BD_SET_BPP(bd, bpp) ((bd) |= (((bpp) & 0xFF) << 16)) #define BCI_BD_GET_STRIDE(bd) ((bd) & 0xFFFF) #define BCI_BD_SET_STRIDE(bd, st) ((bd) |= ((st) & 0xFFFF)) #define BCI_SET_REGISTER 0x96000000 +#define BCI_SET_REGISTER_COUNT(count) ((count) << 16) +#define BCI_BITPLANE_WRITE_MASK 0xD7 +#define BCI_BITPLANE_READ_MASK 0xD8 #define BCI_W_H(w, h) ((((h) << 16) | (w)) & 0x0FFF0FFF) #define BCI_X_Y(x, y) ((((y) << 16) | (x)) & 0x0FFF0FFF) diff --git a/src/savage_driver.c b/src/savage_driver.c index 019e879..8d5646c 100644 --- a/src/savage_driver.c +++ b/src/savage_driver.c @@ -193,6 +193,7 @@ typedef enum { OPTION_PCI_BURST ,OPTION_PCI_RETRY ,OPTION_NOACCEL + ,OPTION_ACCELMETHOD ,OPTION_LCD_CENTER ,OPTION_LCDCLOCK ,OPTION_MCLK @@ -226,6 +227,7 @@ typedef enum { static const OptionInfoRec SavageOptions[] = { { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE }, { OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, @@ -403,6 +405,18 @@ static const char *xaaSymbols[] = { NULL }; +static const char *exaSymbols[] = { + "exaDriverAlloc", + "exaDriverInit", + "exaDriverFini", + "exaOffscreenAlloc", + "exaOffscreenFree", + "exaGetPixmapOffset", + "exaGetPixmapPitch", + "exaGetPixmapSize", + NULL +}; + static const char *shadowSymbols[] = { "ShadowFBInit", NULL @@ -446,7 +460,9 @@ static pointer SavageSetup(pointer module, pointer opts, int *errmaj, setupDone = TRUE; xf86AddDriver(&SAVAGE, module, 0); LoaderRefSymLists(vgaHWSymbols, fbSymbols, ramdacSymbols, - xaaSymbols, shadowSymbols, vbeSymbols, vbeOptSymbols, + xaaSymbols, + exaSymbols, + shadowSymbols, vbeSymbols, vbeOptSymbols, #ifdef XF86DRI drmSymbols, driSymbols, #endif @@ -1154,6 +1170,22 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) psav->NoAccel = TRUE; } + if(!psav->NoAccel) { + from = X_DEFAULT; + char *strptr; + if((strptr = (char *)xf86GetOptValString(psav->Options, OPTION_ACCELMETHOD))) { + if(!xf86NameCmp(strptr,"XAA")) { + from = X_CONFIG; + psav->useEXA = FALSE; + } else if(!xf86NameCmp(strptr,"EXA")) { + from = X_CONFIG; + psav->useEXA = TRUE; + } + } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture\n", + psav->useEXA ? "EXA" : "XAA"); + } + if ((s = xf86GetOptValString(psav->Options, OPTION_OVERLAY))) { if (psav->shadowFB) { @@ -1980,13 +2012,40 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) xf86LoaderReqSymLists(fbSymbols, NULL); if( !psav->NoAccel ) { - if( !xf86LoadSubModule(pScrn, "xaa") ) { - SavageFreeRec(pScrn); - vbeFree(psav->pVbe); - psav->pVbe = NULL; - return FALSE; + + char *modName = NULL; + const char **symNames = NULL; + + if (psav->useEXA) { + modName = "exa"; + symNames = exaSymbols; + XF86ModReqInfo req; + int errmaj, errmin; + memset(&req, 0, sizeof(req)); + req.majorversion = 2; + req.minorversion = 0; + + if( !LoadSubModule(pScrn->module, modName, + NULL, NULL, NULL, &req, &errmaj, &errmin) ) { + LoaderErrorMsg(NULL, modName, errmaj, errmin); + SavageFreeRec(pScrn); + vbeFree(psav->pVbe); + psav->pVbe = NULL; + return FALSE; + } + } else { + modName = "xaa"; + symNames = xaaSymbols; + if( !xf86LoadSubModule(pScrn, modName) ) { + SavageFreeRec(pScrn); + vbeFree(psav->pVbe); + psav->pVbe = NULL; + return FALSE; + } } - xf86LoaderReqSymLists(xaaSymbols, NULL ); + + xf86LoaderReqSymLists(symNames, NULL ); + } if (psav->hwcursor) { @@ -2806,7 +2865,7 @@ static Bool SavageMapFB(ScrnInfoPtr pScrn) } if (psav->IsSecondary) psav->FBStart = psav->FBBase + 0x1000000; - else + else psav->FBStart = psav->FBBase; } @@ -3188,7 +3247,7 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); - if( !psav->shadowFB ) + if( !psav->shadowFB && !psav->useEXA ) SavageDGAInit(pScreen); miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); @@ -3752,6 +3811,11 @@ static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen) } #endif + if (psav->EXADriverPtr) { + exaDriverFini(pScreen); + psav->EXADriverPtr = NULL; + } + if( psav->AccelInfoRec ) { XAADestroyInfoRec( psav->AccelInfoRec ); psav->AccelInfoRec = NULL; diff --git a/src/savage_driver.h b/src/savage_driver.h index 31a930a..d571771 100644 --- a/src/savage_driver.h +++ b/src/savage_driver.h @@ -24,6 +24,7 @@ #include "xf86cmap.h" #include "vbe.h" #include "xaa.h" +#include "exa.h" #include "xf86xv.h" #include "savage_regs.h" @@ -345,6 +346,15 @@ typedef struct _Savage { int ShadowPitch; void (*PointerMoved)(int index, int x, int y); + /* support for EXA */ + ExaDriverPtr EXADriverPtr; + Bool useEXA; + unsigned long EXAendfb; + unsigned long pbd_offset; + unsigned long sbd_offset; + unsigned long pbd_high; + unsigned long sbd_high; + /* Support for XAA acceleration */ XAAInfoRecPtr AccelInfoRec; xRectangle Rect; @@ -534,6 +544,10 @@ void SavageSetGBD(ScrnInfoPtr); void SavageAccelSync(ScrnInfoPtr); /*int SavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop);*/ +/* XAA and EXA */ +Bool SavageXAAInit(ScreenPtr); +Bool SavageEXAInit(ScreenPtr); + /* In savage_i2c.c. */ Bool SavageI2CInit(ScrnInfoPtr pScrn); diff --git a/src/savage_exa.c b/src/savage_exa.c new file mode 100644 index 0000000..1cb2711 --- /dev/null +++ b/src/savage_exa.c @@ -0,0 +1,481 @@ +/* + * The exa accel file for the Savage driver. + * + * Created 2005-2006 by Alex Deucher + * Revision: + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "savage_driver.h" +#include "savage_regs.h" +#include "savage_bci.h" +#include "savage_streams.h" + +#ifdef XF86DRI +#define _XF86DRI_SERVER_ +#include "savage_dri.h" +#endif + +static void +SavageEXASync(ScreenPtr pScreen, int marker); + +static Bool +SavagePrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg); + +static void +SavageSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2); + +static void +SavageDoneSolid(PixmapPtr pPixmap); + +static Bool +SavagePrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, + int alu, Pixel planemask); + +static void +SavageCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height); + +static void +SavageDoneCopy(PixmapPtr pDstPixmap); + +Bool +SavageUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch); + +#if 0 +Bool +SavageDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch); +#endif + +#if 0 +#define GXclear 0x00 +#define GXand 0x88 +#define GXandReverse 0x44 +#define GXcopy 0xCC +#define GXandInverted 0x22 +#define GXnoop 0xAA +#define GXxor 0x66 +#define GXor 0xEE +#define GXnor 0x11 +#define GXequiv 0x99 +#define GXinvert 0x55 +#define GXorReverse 0xDD +#define GXcopyInverted 0x33 +#define GXorInverted 0xBB +#define GXnand 0x77 +#define GXset 0xFF +#endif + +static int SavageGetCopyROP(int rop) { + + int ALUCopyROP[16] = + { + 0x00, /*ROP_0 GXclear */ + 0x88, /*ROP_DSa GXand */ + 0x44, /*ROP_SDna GXandReverse */ + 0xCC, /*ROP_S GXcopy */ + 0x22, /*ROP_DSna GXandInverted */ + 0xAA, /*ROP_D GXnoop */ + 0x66, /*ROP_DSx GXxor */ + 0xEE, /*ROP_DSo GXor */ + 0x11, /*ROP_DSon GXnor */ + 0x99, /*ROP_DSxn GXequiv */ + 0x55, /*ROP_Dn GXinvert*/ + 0xDD, /*ROP_SDno GXorReverse */ + 0x33, /*ROP_Sn GXcopyInverted */ + 0xBB, /*ROP_DSno GXorInverted */ + 0x77, /*ROP_DSan GXnand */ + 0xFF, /*ROP_1 GXset */ + }; + + return (ALUCopyROP[rop]); + +} + +static int SavageGetCopyROP_PM(int rop) { + + int ALUCopyROP_PM[16] = + { + 0x00, /*ROP_0*/ /* not used */ + 0x75, /*ROP_DSPnoa*/ + 0x45, /*ROP_DPSnaon*/ + 0xCA, /*ROP_DPSDxax*/ + 0xD5, /*ROP_DPSana*/ + 0xAA, /*ROP_D*/ /* not used */ + 0x6A, /*ROP_DPSax*/ + 0xEA, /*ROP_DPSao*/ + 0x15, /*ROP_DPSaon*/ + 0x95, /*ROP_DPSaxn*/ + 0x55, /*ROP_Dn*/ /* not used */ + 0xD5, /*ROP_DPSanan*/ + 0x2E, /*ROP_PSDPxox*/ /* is that correct ? */ + 0xBA, /*ROP_DPSnao*/ + 0x75, /*ROP_DSPnoan*/ + 0xFF, /*ROP_1*/ /* not used */ + }; + + return (ALUCopyROP_PM[rop]); + +} + +Bool +SavageEXAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SavagePtr psav = SAVPTR(pScrn); + + if (!(psav->EXADriverPtr = exaDriverAlloc())) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate EXADriverRec.\n"); + return FALSE; + } + + /*ErrorF("in SavageEXAinit\n");*/ + + psav->EXADriverPtr->exa_major = 2; + psav->EXADriverPtr->exa_minor = 0; + + /* use the linear aperture */ + psav->EXADriverPtr->memoryBase = psav->FBBase + pScrn->fbOffset; + + psav->EXADriverPtr->memorySize = psav->EXAendfb; + + + if (psav->bTiled) { + if (pScrn->bitsPerPixel == 16) { + psav->EXADriverPtr->offScreenBase = + ((pScrn->virtualX+63)/64)*((pScrn->virtualY+15)/16) * 2048; + } else { + psav->EXADriverPtr->offScreenBase = + ((pScrn->virtualX+31)/32)*((pScrn->virtualY+15)/16) * 2048; + } + } else { + psav->EXADriverPtr->offScreenBase = + ((pScrn->virtualY * psav->lDelta + SAVAGE_BUFFER_ALIGN) & ~SAVAGE_BUFFER_ALIGN); + } + + if (psav->EXADriverPtr->memorySize > psav->EXADriverPtr->offScreenBase) { + psav->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Not enough video RAM for EXA offscreen memory manager.\n"); + } + + if (psav->bTiled) { + psav->EXADriverPtr->pixmapPitchAlign = 128; /* ~127 */ + } else { + psav->EXADriverPtr->pixmapPitchAlign = 32; /* ~31 */ + } + + if (psav->Chipset == S3_SAVAGE2000 || + psav->Chipset == S3_SUPERSAVAGE) { + psav->EXADriverPtr->pixmapOffsetAlign = 128; /* octword */ + } else { + psav->EXADriverPtr->pixmapOffsetAlign = 64; /* qword */ + } + + /* engine has 12 bit coordinates */ + psav->EXADriverPtr->maxX = 4095; + psav->EXADriverPtr->maxY = 4095; + + /* Sync */ + psav->EXADriverPtr->WaitMarker = SavageEXASync; +#if 1 + /* Solid fill */ + psav->EXADriverPtr->PrepareSolid = SavagePrepareSolid; + psav->EXADriverPtr->Solid = SavageSolid; + psav->EXADriverPtr->DoneSolid = SavageDoneSolid; + + /* Copy */ + psav->EXADriverPtr->PrepareCopy = SavagePrepareCopy; + psav->EXADriverPtr->Copy = SavageCopy; + psav->EXADriverPtr->DoneCopy = SavageDoneCopy; +#endif + /* Composite not implemented yet */ + /* savage3d series only have one tmu */ + +#if 1 + /* host data blit */ + psav->EXADriverPtr->UploadToScreen = SavageUploadToScreen; +#endif +#if 0 + psav->EXADriverPtr->accel.DownloadFromScreen = SavageDownloadFromScreen; +#endif + + if(!exaDriverInit(pScreen, psav->EXADriverPtr)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "exaDriverinit failed.\n"); + return FALSE; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Savage EXA Acceleration enabled.\n"); + return TRUE; + } + +} +static void +SavageEXASync(ScreenPtr pScreen, int marker) +{ + SavagePtr psav = SAVPTR(xf86Screens[pScreen->myNum]); + psav->WaitIdleEmpty(psav); +} + +static unsigned int +SavageSetBD(SavagePtr psav, PixmapPtr pPixmap) +{ + unsigned int pixpitch, bd = 0; + unsigned int tile16, tile32; + + /* front buffer can be tiled */ + if (psav->bTiled && exaGetPixmapOffset(pPixmap) == 0) { + switch( psav->Chipset ) { + case S3_SAVAGE3D: + case S3_SAVAGE_MX: + case S3_SAVAGE4: + tile16 = BCI_BD_TILE_16; + tile32 = BCI_BD_TILE_32; + break; + case S3_TWISTER: + case S3_PROSAVAGE: + case S3_PROSAVAGEDDR: + case S3_SUPERSAVAGE: + case S3_SAVAGE2000: + default: + tile16 = BCI_BD_TILE_DESTINATION; + tile32 = BCI_BD_TILE_DESTINATION; + break; + } + } else { + tile16 = BCI_BD_TILE_NONE; + tile32 = BCI_BD_TILE_NONE; + } + + /* HW uses width */ + pixpitch = exaGetPixmapPitch(pPixmap) / (pPixmap->drawable.bitsPerPixel >> 3); + + BCI_BD_SET_BPP(bd, pPixmap->drawable.bitsPerPixel); + BCI_BD_SET_STRIDE(bd, pixpitch); + + if (pPixmap->drawable.bitsPerPixel == 32) + bd |= BCI_BD_BW_DISABLE | tile32; + else + bd |= BCI_BD_BW_DISABLE | tile16; + + return bd; + +} + +static Bool +SavagePrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + SavagePtr psav = SAVPTR(pScrn); + int cmd; + BCI_GET_PTR; + + /*ErrorF("in preparesolid\n");*/ + + cmd = BCI_CMD_RECT + | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SOLID + | BCI_CMD_SEND_COLOR; + + BCI_CMD_SET_ROP( cmd, SavageGetCopyROP(alu) ); + + psav->pbd_offset = exaGetPixmapOffset(pPixmap); + psav->pbd_high = SavageSetBD(psav, pPixmap); + + psav->SavedBciCmd = cmd; + psav->SavedFgColor = fg; + + psav->WaitQueue(psav,6); + + BCI_SEND(BCI_SET_REGISTER + | BCI_SET_REGISTER_COUNT(1) + | BCI_BITPLANE_WRITE_MASK); + BCI_SEND(planemask); + + BCI_SEND(psav->SavedBciCmd); + BCI_SEND(psav->pbd_offset); + BCI_SEND(psav->pbd_high); + BCI_SEND(psav->SavedFgColor); + + return TRUE; +} + +static void +SavageSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + SavagePtr psav = SAVPTR(pScrn); + int w = x2 - x1; + int h = y2 - y1; + BCI_GET_PTR; + + if( !w || !h ) + return; + + psav->WaitQueue(psav,2); + BCI_SEND(BCI_X_Y(x1, y1)); + BCI_SEND(BCI_W_H(w, h)); + +} + +static void +SavageDoneSolid(PixmapPtr pPixmap) +{ +} + +static Bool +SavagePrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, + int alu, Pixel planemask) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + SavagePtr psav = SAVPTR(pScrn); + int cmd; + BCI_GET_PTR; + + /*ErrorF("in preparecopy\n");*/ + + cmd = BCI_CMD_RECT | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SBD_COLOR_NEW; + + BCI_CMD_SET_ROP( cmd, SavageGetCopyROP(alu) ); + + if (xdir > 0 ) cmd |= BCI_CMD_RECT_XP; + if (ydir > 0 ) cmd |= BCI_CMD_RECT_YP; + + psav->sbd_offset = exaGetPixmapOffset(pSrcPixmap); + psav->pbd_offset = exaGetPixmapOffset(pDstPixmap); + + psav->sbd_high = SavageSetBD(psav, pSrcPixmap); + psav->pbd_high = SavageSetBD(psav, pDstPixmap); + + psav->SavedBciCmd = cmd; + + psav->WaitQueue(psav,7); + + BCI_SEND(BCI_SET_REGISTER + | BCI_SET_REGISTER_COUNT(1) + | BCI_BITPLANE_WRITE_MASK); + BCI_SEND(planemask); + + BCI_SEND(psav->SavedBciCmd); + /* src */ + BCI_SEND(psav->sbd_offset); + BCI_SEND(psav->sbd_high); + /* dst */ + BCI_SEND(psav->pbd_offset); + BCI_SEND(psav->pbd_high); + + return TRUE; +} + +static void +SavageCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + + if (!width || !height) return; + + if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) { + width --; + srcX += width; + dstX += width; + width ++; + } + if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) { + height --; + srcY += height; + dstY += height; + height ++; + } + + psav->WaitQueue(psav,4); + BCI_SEND(BCI_X_Y(srcX, srcY)); + BCI_SEND(BCI_X_Y(dstX, dstY)); + BCI_SEND(BCI_W_H(width, height)); + +} + +static void +SavageDoneCopy(PixmapPtr pDstPixmap) +{ +} + +Bool +SavageUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + int i, j, dwords, Bpp; + unsigned int cmd; + CARD32 * srcp; + + Bpp = pDst->drawable.bitsPerPixel / 8; + dwords = ((w * Bpp) + 3) >> 2; + + psav->sbd_offset = exaGetPixmapOffset(pDst); + psav->sbd_high = SavageSetBD(psav, pDst); + + cmd = BCI_CMD_RECT + | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_DEST_SBD_NEW + | BCI_CMD_SRC_COLOR; /* host color data */ + + BCI_CMD_SET_ROP( cmd, 0xCC ); /* GXcopy */ + + /*ErrorF("in UTS\n");*/ + + psav->WaitQueue(psav, 5); + BCI_SEND(cmd); + + /* dst */ + BCI_SEND(psav->sbd_offset); + BCI_SEND(psav->sbd_high); + + BCI_SEND(BCI_X_Y(x, y)); + BCI_SEND(BCI_W_H(w, h)); + + for (i = 0; i < h; i++) { + srcp = (CARD32 *)src; + BCI_RESET; + for (j = dwords; j > 0; j--) { + CARD32 dw = *srcp; + BCI_SEND(dw); + srcp++; + } + src += src_pitch; + } + + return TRUE; +} + +#if 0 +Bool +SavageDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; + unsigned char *src; + int src_pitch = exaGetPixmapPitch(pSrc); + int bpp = pSrc->drawable.bitsPerPixel; + + /* do the copy */ + src = pSrc->devPrivate.ptr; + src += (x * bpp / 8) + (y * src_pitch); + w *= bpp / 8; + + while (h--) { + memcpy(dst, src, w); + src += src_pitch; + dst += dst_pitch; + } + return TRUE; +} + +#endif diff --git a/src/savage_image.c b/src/savage_image.c deleted file mode 100644 index 766c810..0000000 --- a/src/savage_image.c +++ /dev/null @@ -1,204 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_image.c,v 1.4 2001/05/18 23:35:32 dawes Exp $ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "savage_driver.h" -#include "xaarop.h" -#include "savage_bci.h" - -void SavageSubsequentImageWriteRect ( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, - int skipleft); - -void SavageSetupForImageWrite ( - ScrnInfoPtr pScrn, - int rop, - unsigned planemask, - int transparency_color, - int bpp, - int depth); - -void SavageWriteBitmapCPUToScreenColorExpand ( - ScrnInfoPtr pScrn, - int x, int y, int w, int h, - unsigned char * src, - int srcwidth, - int skipleft, - int fg, int bg, - int rop, - unsigned int planemask); - -#if 0 -void SavageWriteBitmapScreenToScreenColorExpand( - ScrnPtr pScrn, - int x, - int y, - int w, - int h, - unsigned char * src, - int srcwidth, - int srcx, - int srcy, - int bg, - int fg, - int rop, - unsigned int planemask -) -{ - SavagePtr psav = SAVPTR(pScrn); - BCI_GET_PTR; - unsigned int cmd; - unsigned char * bd_offset; - unsigned int bd; - - cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP - | BCI_CMD_SEND_COLOR - | BCI_CMD_DEST_GBD | BCI_CMD_SRC_SBD_MONO_NEW; - cmd |= (bg != -1) ? BCI_CMD_SEND_COLOR : BCI_CMD_SRC_TRANSPARENT; - cmd |= s3vAlu[rop]; - - bd |= BCI_BD_BW_DISABLE; - BCI_BD_SET_BPP(bd, 1); - BCI_BD_SET_STRIDE(bd, srcwidth); - bd_offset = srcwidth * srcy + (srcx >> 3) + src; - - psav->WaitQueue(psav,10); - BCI_SEND(cmd); - BCI_SEND((unsigned int)bd_offset); - BCI_SEND(bd); - BCI_SEND(fg); - BCI_SEND((bg != -1) ? bg : 0); - BCI_SEND(BCI_X_Y(srcx, srcy)); - BCI_SEND(BCI_X_Y(x, y)); - BCI_SEND(BCI_W_H(w, h)); -} -#endif - -void -SavageWriteBitmapCPUToScreenColorExpand ( - ScrnInfoPtr pScrn, - int x, int y, int w, int h, - unsigned char * src, - int srcwidth, - int skipleft, - int fg, int bg, - int rop, - unsigned int planemask -) -{ - SavagePtr psav = SAVPTR(pScrn); - BCI_GET_PTR; - int i, j, count, reset; - unsigned int cmd; - CARD32 * srcp; - -/* We aren't using planemask at all here... */ - - if( !srcwidth ) - return; - - cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP - | BCI_CMD_SEND_COLOR | BCI_CMD_CLIP_LR - | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_MONO; - cmd |= XAAGetCopyROP(rop) << 16; - - if( bg == -1 ) - cmd |= BCI_CMD_SRC_TRANSPARENT; - - BCI_SEND(cmd); - - BCI_SEND(psav->GlobalBD.bd2.LoPart); - BCI_SEND(psav->GlobalBD.bd2.HiPart); - - BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1)); - BCI_SEND(fg); - if( bg != -1 ) - BCI_SEND(bg); - - /* Bitmaps come in in units of DWORDS, LSBFirst. This is exactly */ - /* reversed of what we expect. */ - - count = (w + 31) / 32; -/* src += ((srcx & ~31) / 8); */ - - /* The BCI region is 128k bytes. A screen-sized mono bitmap can */ - /* exceed that. */ - - reset = 65536 / count; - - for (j = 0; j < h; j ++) { - BCI_SEND(BCI_X_Y(x, y+j)); - BCI_SEND(BCI_W_H(w, 1)); - srcp = (CARD32 *) src; - for (i = count; i > 0; srcp ++, i --) { - /* We have to invert the bits in each byte. */ - CARD32 u = *srcp; - u = ((u & 0x0f0f0f0f) << 4) | ((u & 0xf0f0f0f0) >> 4); - u = ((u & 0x33333333) << 2) | ((u & 0xcccccccc) >> 2); - u = ((u & 0x55555555) << 1) | ((u & 0xaaaaaaaa) >> 1); - BCI_SEND(u); - } - src += srcwidth; - if( !--reset ) { - BCI_RESET; - reset = 65536 / count; - } - } -} - -void -SavageSetupForImageWrite( - ScrnInfoPtr pScrn, - int rop, - unsigned planemask, - int transparency_color, - int bpp, - int depth) -{ - SavagePtr psav = SAVPTR(pScrn); - int cmd; - - cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP - | BCI_CMD_CLIP_LR - | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_COLOR; - - cmd |= XAAGetCopyROP(rop) << 16; - - if( transparency_color != -1 ) - cmd |= BCI_CMD_SRC_TRANSPARENT; - - psav->SavedBciCmd = cmd; - psav->SavedBgColor = transparency_color; -} - - -void SavageSubsequentImageWriteRect -( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, - int skipleft) -{ - SavagePtr psav = SAVPTR(pScrn); - BCI_GET_PTR; - - psav->WaitQueue( psav, 8 ); - BCI_SEND(psav->SavedBciCmd); - - BCI_SEND(psav->GlobalBD.bd2.LoPart); - BCI_SEND(psav->GlobalBD.bd2.HiPart); - - BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1)); - if( psav->SavedBgColor != 0xffffffff ) - BCI_SEND(psav->SavedBgColor); - BCI_SEND(BCI_X_Y(x, y)); - BCI_SEND(BCI_W_H(w, h)); -} diff --git a/src/savage_video.c b/src/savage_video.c index 65f1ff9..f953787 100644 --- a/src/savage_video.c +++ b/src/savage_video.c @@ -38,6 +38,7 @@ static int SavagePutImage( ScrnInfoPtr, DrawablePtr); static int SavageQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, unsigned short *, int *, int *); +static void SavageFreeMemory(ScrnInfoPtr pScrn, void *mem_struct); void SavageResetVideo(ScrnInfoPtr pScrn); @@ -206,13 +207,18 @@ typedef struct { int hue; /* -128 .. 127 */ Bool interpolation; /* on/off */ - FBAreaPtr area; + /*FBAreaPtr area;*/ RegionRec clip; CARD32 colorKey; CARD32 videoStatus; Time offTime; Time freeTime; int lastKnownPitch; + + int size; + void *video_memory; + int video_offset; + } SavagePortPrivRec, *SavagePortPrivPtr; @@ -1005,10 +1011,10 @@ SavageStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) if(shutdown) { /*SavageClipVWindow(pScrn);*/ SavageStreamsOff( pScrn ); - if(pPriv->area) { - xf86FreeOffscreenArea(pPriv->area); - pPriv->area = NULL; - } + if (pPriv->video_memory != NULL) { + SavageFreeMemory(pScrn, pPriv->video_memory); + pPriv->video_memory = NULL; + } pPriv->videoStatus = 0; } else { if(pPriv->videoStatus & CLIENT_VIDEO_ON) { @@ -1266,15 +1272,87 @@ SavageCopyPlanarData( } } -static FBAreaPtr +static void +SavageVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SavagePtr psav = SAVPTR(pScrn); + SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; + + if (pPriv->video_memory == area) + pPriv->video_memory = NULL; +} + +static CARD32 SavageAllocateMemory( ScrnInfoPtr pScrn, - FBAreaPtr area, - int numlines + void **mem_struct, + int size ){ - ScreenPtr pScreen; - FBAreaPtr new_area; + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + SavagePtr psav = SAVPTR(pScrn); + int offset = 0; + + if (psav->useEXA) { + ExaOffscreenArea *area = *mem_struct; + + if (area != NULL) { + if (area->size >= size) + return area->offset; + + exaOffscreenFree(pScrn->pScreen, area); + } + + area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE, SavageVideoSave, + NULL); + *mem_struct = area; + if (area == NULL) + return 0; + offset = area->offset; + } + + if (!psav->useEXA) { + FBLinearPtr linear = *mem_struct; + int cpp = pScrn->bitsPerPixel / 8; + + /* XAA allocates in units of pixels at the screen bpp, so adjust size + * appropriately. + */ + size = (size + cpp - 1) / cpp; + + if (linear) { + if(linear->size >= size) + return linear->offset * cpp; + + if(xf86ResizeOffscreenLinear(linear, size)) + return linear->offset * cpp; + xf86FreeOffscreenLinear(linear); + } + + linear = xf86AllocateOffscreenLinear(pScreen, size, 16, + NULL, NULL, NULL); + *mem_struct = linear; + + if (!linear) { + int max_size; + + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, + PRIORITY_EXTREME); + + if(max_size < size) + return 0; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + linear = xf86AllocateOffscreenLinear(pScreen, size, 16, + NULL, NULL, NULL); + *mem_struct = linear; + if (!linear) + return 0; + } + offset = linear->offset * cpp; + } +#if 0 if(area) { if((area->box.y2 - area->box.y1) >= numlines) return area; @@ -1306,6 +1384,29 @@ SavageAllocateMemory( } return new_area; +#endif + return offset; +} + +static void +SavageFreeMemory( + ScrnInfoPtr pScrn, + void *mem_struct +){ + SavagePtr psav = SAVPTR(pScrn); + + if (psav->useEXA) { + ExaOffscreenArea *area = mem_struct; + + if (area != NULL) + exaOffscreenFree(pScrn->pScreen, area); + } + if (!psav->useEXA) { + FBLinearPtr linear = mem_struct; + + if (linear != NULL) + xf86FreeOffscreenLinear(linear); + } } static void @@ -1752,7 +1853,7 @@ SavagePutImage( ScreenPtr pScreen = pScrn->pScreen; INT32 x1, x2, y1, y2; unsigned char *dst_start; - int pitch, new_h, offset, offsetV=0, offsetU=0; + int pitch, new_size, offset, offsetV=0, offsetU=0; int srcPitch, srcPitch2=0, dstPitch; int top, left, npixels, nlines; BoxRec dstBox; @@ -1790,7 +1891,8 @@ SavagePutImage( pitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; dstPitch = ((width << 1) + 15) & ~15; - new_h = ((dstPitch * height) + pitch - 1) / pitch; + /*new_h = ((dstPitch * height) + pitch - 1) / pitch;*/ + new_size = dstPitch * height; switch(id) { case FOURCC_Y211: /* Y211 */ @@ -1816,8 +1918,12 @@ SavagePutImage( break; } - if(!(pPriv->area = SavageAllocateMemory(pScrn, pPriv->area, new_h))) - return BadAlloc; +/* if(!(pPriv->area = SavageAllocateMemory(pScrn, pPriv->area, new_h))) + return BadAlloc;*/ + pPriv->video_offset = SavageAllocateMemory(pScrn, &pPriv->video_memory, + new_size); + if (pPriv->video_offset == 0) + return BadAlloc; /* copy data */ top = y1 >> 16; @@ -1825,8 +1931,8 @@ SavagePutImage( npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; left <<= 1; - /*offset = ((pPriv->area->box.y1 * pitch)) + (top * dstPitch);*/ - offset = pPriv->area->box.y1 * psav->lDelta; + offset = (pPriv->video_offset) + (top * dstPitch); + /*offset = pPriv->area->box.y1 * psav->lDelta;*/ dst_start = (psav->FBBase + ((offset + left) & ~BASE_PAD)); switch(id) { @@ -1837,8 +1943,7 @@ SavagePutImage( offsetU += tmp; offsetV += tmp; nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; - if (S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv - /*&& (!psav->disableCOB)*/) { + if (S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv) { SavageCopyPlanarDataBCI( pScrn, buf + (top * srcPitch) + (left >> 1), @@ -1938,7 +2043,7 @@ SavageQueryImageAttributes( /****************** Offscreen stuff ***************/ typedef struct { - FBAreaPtr area; + void *surface_memory; Bool isOn; } OffscreenPrivRec, * OffscreenPrivPtr; @@ -1950,8 +2055,9 @@ SavageAllocateSurface( unsigned short h, XF86SurfacePtr surface ){ - FBAreaPtr area; + int offset, size; int pitch, fbpitch, numlines; + void *surface_memory = NULL; OffscreenPrivPtr pPriv; if((w > 1024) || (h > 1024)) @@ -1961,32 +2067,38 @@ SavageAllocateSurface( pitch = ((w << 1) + 15) & ~15; fbpitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; numlines = ((pitch * h) + fbpitch - 1) / fbpitch; + size = pitch * h; - if(!(area = SavageAllocateMemory(pScrn, NULL, numlines))) + offset = SavageAllocateMemory(pScrn, &surface_memory, size); + if (offset == 0) return BadAlloc; surface->width = w; surface->height = h; - if(!(surface->pitches = xalloc(sizeof(int)))) + if(!(surface->pitches = xalloc(sizeof(int)))) { + SavageFreeMemory(pScrn, surface_memory); return BadAlloc; + } if(!(surface->offsets = xalloc(sizeof(int)))) { xfree(surface->pitches); + SavageFreeMemory(pScrn, surface_memory); return BadAlloc; } if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { xfree(surface->pitches); xfree(surface->offsets); + SavageFreeMemory(pScrn, surface_memory); return BadAlloc; } - pPriv->area = area; + pPriv->surface_memory = surface_memory; pPriv->isOn = FALSE; surface->pScrn = pScrn; surface->id = id; surface->pitches[0] = pitch; - surface->offsets[0] = area->box.y1 * fbpitch; + surface->offsets[0] = offset; /*area->box.y1 * fbpitch;*/ surface->devPrivate.ptr = (pointer)pPriv; return Success; @@ -2014,11 +2126,12 @@ static int SavageFreeSurface( XF86SurfacePtr surface ){ + ScrnInfoPtr pScrn = surface->pScrn; OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; if(pPriv->isOn) SavageStopSurface(surface); - xf86FreeOffscreenArea(pPriv->area); + SavageFreeMemory(pScrn, pPriv->surface_memory); xfree(surface->pitches); xfree(surface->offsets); xfree(surface->devPrivate.ptr); diff --git a/src/savage_xaa.c b/src/savage_xaa.c new file mode 100644 index 0000000..4565ffd --- /dev/null +++ b/src/savage_xaa.c @@ -0,0 +1,1022 @@ +/* + * The accel file for the Savage driver. + * + * Created 20/03/97 by Sebastien Marineau for 3.3.6 + * Modified 17-Nov-2000 by Tim Roberts for 4.0.1 + * Modified Feb-2004 by Alex Deucher - integrating DRI support + * Modified 2005-2006 by Alex Deucher - adding exa support + * Revision: + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <X11/Xarch.h> +#include "xaalocal.h" +#include "xaarop.h" +#include "miline.h" +#include "savage_driver.h" +#include "savage_bci.h" + +extern int gSavageEntityIndex; + +static void SavageSetupForScreenToScreenCopy( + ScrnInfoPtr pScrn, + int xdir, + int ydir, + int rop, + unsigned planemask, + int transparency_color); + +static void SavageSubsequentScreenToScreenCopy( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2, + int w, + int h); + +static void SavageSetupForSolidFill( + ScrnInfoPtr pScrn, + int color, + int rop, + unsigned int planemask); + +static void SavageSubsequentSolidFillRect( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h); + +static void SavageSubsequentSolidBresenhamLine( + ScrnInfoPtr pScrn, + int x1, + int y1, + int e1, + int e2, + int err, + int length, + int octant); + +static void SavageSetupForCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, + int bg, + int rop, + unsigned int planemask); + +static void SavageSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft); + +static void SavageSubsequentColorExpandScanline( + ScrnInfoPtr pScrn, + int buffer_no); + +static void SavageSetupForMono8x8PatternFill( + ScrnInfoPtr pScrn, + int patternx, + int patterny, + int fg, + int bg, + int rop, + unsigned int planemask); + +static void SavageSubsequentMono8x8PatternFillRect( + ScrnInfoPtr pScrn, + int pattern0, + int pattern1, + int x, + int y, + int w, + int h); + +static void SavageSetClippingRectangle( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2); + +static void SavageDisableClipping( ScrnInfoPtr ); + +/* from savage_image.c: */ + +void SavageSetupForImageWrite( + ScrnInfoPtr pScrn, + int rop, + unsigned int planemask, + int transparency_color, + int bpp, + int depth); + +void SavageSubsequentImageWriteRect( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft); + +void SavageWriteBitmapCPUToScreenColorExpand ( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char * src, + int srcwidth, + int skipleft, + int fg, int bg, + int rop, + unsigned int planemask +); + +static +void SavageRestoreAccelState(ScrnInfoPtr pScrn) +{ + SavagePtr psav = SAVPTR(pScrn); + + psav->WaitIdleEmpty(psav); + + return; +} + + +Bool +SavageXAAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + SavagePtr psav = SAVPTR(pScrn); + XAAInfoRecPtr xaaptr; + BoxRec AvailFBArea; + int tmp; + + /* Set-up our GE command primitive */ + + if (pScrn->depth == 8) { + psav->PlaneMask = 0xFF; + } + else if (pScrn->depth == 15) { + psav->PlaneMask = 0x7FFF; + } + else if (pScrn->depth == 16) { + psav->PlaneMask = 0xFFFF; + } + else if (pScrn->depth == 24) { + psav->PlaneMask = 0xFFFFFF; + } + + /* General acceleration flags */ + + if (!(xaaptr = psav->AccelInfoRec = XAACreateInfoRec())) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate XAAInfoRec.\n"); + return FALSE; + } + + xaaptr->Flags = 0 + | PIXMAP_CACHE + | OFFSCREEN_PIXMAPS + | LINEAR_FRAMEBUFFER + ; + + + if(xf86IsEntityShared(pScrn->entityList[0])) + { + DevUnion* pPriv; + SavageEntPtr pEnt; + pPriv = xf86GetEntityPrivate(pScrn->entityList[0], + gSavageEntityIndex); + pEnt = pPriv->ptr; + + /*if there are more than one devices sharing this entity, we + have to assign this call back, otherwise the XAA will be + disabled */ + if(pEnt->HasSecondary) + xaaptr->RestoreAccelState = SavageRestoreAccelState; + } + + /* Clipping */ + + xaaptr->SetClippingRectangle = SavageSetClippingRectangle; + xaaptr->DisableClipping = SavageDisableClipping; + xaaptr->ClippingFlags = 0 +#if 0 + | HARDWARE_CLIP_SOLID_FILL + | HARDWARE_CLIP_SOLID_LINE + | HARDWARE_CLIP_DASHED_LINE +#endif + | HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY + | HARDWARE_CLIP_MONO_8x8_FILL + | HARDWARE_CLIP_COLOR_8x8_FILL + ; + + xaaptr->Sync = SavageAccelSync; + + /* ScreenToScreen copies */ + +#if 1 + + xaaptr->SetupForScreenToScreenCopy = SavageSetupForScreenToScreenCopy; + xaaptr->SubsequentScreenToScreenCopy = SavageSubsequentScreenToScreenCopy; + xaaptr->ScreenToScreenCopyFlags = 0 + | NO_TRANSPARENCY + | NO_PLANEMASK + | ROP_NEEDS_SOURCE; + +#endif + + + /* Solid filled rectangles */ + +#if 1 + xaaptr->SetupForSolidFill = SavageSetupForSolidFill; + xaaptr->SubsequentSolidFillRect = SavageSubsequentSolidFillRect; + xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; +#endif + + /* Mono 8x8 pattern fills */ + +#if 1 + xaaptr->SetupForMono8x8PatternFill = SavageSetupForMono8x8PatternFill; + xaaptr->SubsequentMono8x8PatternFillRect + = SavageSubsequentMono8x8PatternFillRect; + xaaptr->Mono8x8PatternFillFlags = 0 + | HARDWARE_PATTERN_PROGRAMMED_BITS + | HARDWARE_PATTERN_SCREEN_ORIGIN + | BIT_ORDER_IN_BYTE_MSBFIRST + | ROP_NEEDS_SOURCE + ; + if( psav->Chipset == S3_SAVAGE4 ) + xaaptr->Mono8x8PatternFillFlags |= NO_TRANSPARENCY; +#endif + + /* Solid lines */ + +#if 1 + xaaptr->SolidLineFlags = NO_PLANEMASK; + xaaptr->SetupForSolidLine = SavageSetupForSolidFill; + xaaptr->SubsequentSolidBresenhamLine = SavageSubsequentSolidBresenhamLine; +#if 0 + xaaptr->SubsequentSolidFillTrap = SavageSubsequentSolidFillTrap; +#endif + + xaaptr->SolidBresenhamLineErrorTermBits = 13; +#endif + + /* ImageWrite */ + + xaaptr->ImageWriteFlags = 0 + | NO_PLANEMASK + | CPU_TRANSFER_PAD_DWORD + | SCANLINE_PAD_DWORD + | BIT_ORDER_IN_BYTE_MSBFIRST + | LEFT_EDGE_CLIPPING + ; + xaaptr->SetupForImageWrite = SavageSetupForImageWrite; + xaaptr->SubsequentImageWriteRect = SavageSubsequentImageWriteRect; + xaaptr->NumScanlineImageWriteBuffers = 1; + xaaptr->ImageWriteBase = psav->BciMem; + xaaptr->ImageWriteRange = 120 * 1024; + + + /* CPU to Screen color expansion */ + + xaaptr->ScanlineCPUToScreenColorExpandFillFlags = 0 + | NO_PLANEMASK + | CPU_TRANSFER_PAD_DWORD + | SCANLINE_PAD_DWORD + | BIT_ORDER_IN_BYTE_MSBFIRST + | LEFT_EDGE_CLIPPING + | ROP_NEEDS_SOURCE + ; + + xaaptr->SetupForScanlineCPUToScreenColorExpandFill = + SavageSetupForCPUToScreenColorExpandFill; + xaaptr->SubsequentScanlineCPUToScreenColorExpandFill = + SavageSubsequentScanlineCPUToScreenColorExpandFill; + xaaptr->SubsequentColorExpandScanline = + SavageSubsequentColorExpandScanline; + xaaptr->ColorExpandBase = psav->BciMem; + xaaptr->ScanlineColorExpandBuffers = &xaaptr->ColorExpandBase; + xaaptr->NumScanlineColorExpandBuffers = 1; + + /* Set up screen parameters. */ + + psav->Bpp = pScrn->bitsPerPixel / 8; + psav->Bpl = pScrn->displayWidth * psav->Bpp; + psav->ScissB = (psav->CursorKByte << 10) / psav->Bpl; + if (psav->ScissB > 2047) + psav->ScissB = 2047; + + /* + * Finally, we set up the video memory space available to the pixmap + * cache. In this case, all memory from the end of the virtual screen + * to the end of the command overflow buffer can be used. If you haven't + * enabled the PIXMAP_CACHE flag, then these lines can be omitted. + */ + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = psav->cxMemory; + AvailFBArea.y2 = psav->cyMemory; + xf86InitFBManager(pScreen, &AvailFBArea); + /* + * because the alignment requirement,the on-screen need more memory + * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract + * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so + * here,we should reserver some memory for on-screen + */ + tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY) + + psav->cxMemory -1) / (psav->cxMemory); + if (tmp) + xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d lines for offscreen memory.\n", + psav->cyMemory - pScrn->virtualY ); + + + return XAAInit(pScreen, xaaptr); + +} + +/* The sync function for the GE */ +void +SavageAccelSync(ScrnInfoPtr pScrn) +{ + SavagePtr psav = SAVPTR(pScrn); + psav->WaitIdleEmpty(psav); +} + + +/* + * The XAA ROP helper routines all assume that a solid color is a + * "pattern". The Savage chips, however, apply a non-stippled solid + * color as "source". Thus, we use a slightly customized version. + */ + +static int +SavageHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, unsigned int pm, int *rop) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + int ret = 0; + + pm &= infoRec->FullPlanemask; + + if(pm == infoRec->FullPlanemask) { + if(!NO_SRC_ROP(*rop)) + ret |= ROP_PAT; + *rop = XAAGetCopyROP(*rop); + } else { + switch(*rop) { + case GXnoop: + break; + case GXset: + case GXclear: + case GXinvert: + ret |= ROP_PAT; + *fg = pm; + if(*bg != -1) + *bg = pm; + break; + default: + ret |= ROP_PAT | ROP_SRC; + break; + } + *rop = XAAGetCopyROP_PM(*rop); + } + + return ret; +} + + +static int +SavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg, unsigned int pm, int *rop) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + int ret = 0; + + pm &= infoRec->FullPlanemask; + + if(pm == infoRec->FullPlanemask) { + if(!NO_SRC_ROP(*rop)) + ret |= ROP_PAT; + *rop = XAAGetCopyROP(*rop); + } else { + switch(*rop) { + case GXnoop: + break; + case GXset: + case GXclear: + case GXinvert: + ret |= ROP_PAT; + *fg = pm; + break; + default: + ret |= ROP_PAT | ROP_SRC; + break; + } + *rop = XAAGetCopyROP_PM(*rop); + } + + return ret; +} + + + +/* These are the ScreenToScreen bitblt functions. We support all ROPs, all + * directions, and a planemask by adjusting the ROP and using the mono pattern + * registers. + * + * (That's a lie; we don't really support planemask.) + */ + +static void +SavageSetupForScreenToScreenCopy( + ScrnInfoPtr pScrn, + int xdir, + int ydir, + int rop, + unsigned planemask, + int transparency_color) +{ + SavagePtr psav = SAVPTR(pScrn); + int cmd; + + cmd = BCI_CMD_RECT | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SBD_COLOR_NEW; + + BCI_CMD_SET_ROP( cmd, XAAGetCopyROP(rop) ); + if (transparency_color != -1) + cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_SRC_TRANSPARENT; + + if (xdir == 1 ) cmd |= BCI_CMD_RECT_XP; + if (ydir == 1 ) cmd |= BCI_CMD_RECT_YP; + + psav->SavedBciCmd = cmd; + psav->SavedBgColor = transparency_color; +} + +static void +SavageSubsequentScreenToScreenCopy( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2, + int w, + int h) +{ + SavagePtr psav = SAVPTR(pScrn); + + BCI_GET_PTR; + + if (!w || !h) return; + + if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) { + w --; + x1 += w; + x2 += w; + w ++; + } + if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) { + h --; + y1 += h; + y2 += h; + h ++; + } + + psav->WaitQueue(psav,9); + + + BCI_SEND(psav->SavedBciCmd); + + BCI_SEND(psav->GlobalBD.bd2.LoPart); + BCI_SEND(psav->GlobalBD.bd2.HiPart); + + BCI_SEND(psav->GlobalBD.bd2.LoPart); + BCI_SEND(psav->GlobalBD.bd2.HiPart); + + if (psav->SavedBgColor != 0xffffffff) + BCI_SEND(psav->SavedBgColor); + BCI_SEND(BCI_X_Y(x1, y1)); + BCI_SEND(BCI_X_Y(x2, y2)); + BCI_SEND(BCI_W_H(w, h)); +} + + +/* + * SetupForSolidFill is also called to set up for lines. + */ + +static void +SavageSetupForSolidFill( + ScrnInfoPtr pScrn, + int color, + int rop, + unsigned int planemask) +{ + SavagePtr psav = SAVPTR(pScrn); + XAAInfoRecPtr xaaptr = GET_XAAINFORECPTR_FROM_SCRNINFOPTR( pScrn ); + int cmd; + int mix; + + cmd = BCI_CMD_RECT + | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SOLID; + + /* Don't send a color if we don't have to. */ + + if( rop == GXcopy ) + { + if( color == 0 ) + rop = GXclear; + else if( (unsigned int)color == xaaptr->FullPlanemask ) + rop = GXset; + } + + mix = SavageHelpSolidROP( pScrn, &color, planemask, &rop ); + + if( mix & ROP_PAT ) + cmd |= BCI_CMD_SEND_COLOR; + + BCI_CMD_SET_ROP( cmd, rop ); + + psav->SavedBciCmd = cmd; + psav->SavedFgColor = color; +} + + +static void +SavageSubsequentSolidFillRect( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + + if( !w || !h ) + return; + + psav->WaitQueue(psav,7); + + BCI_SEND(psav->SavedBciCmd); + + BCI_SEND(psav->GlobalBD.bd2.LoPart); + BCI_SEND(psav->GlobalBD.bd2.HiPart); + + if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR ) + BCI_SEND(psav->SavedFgColor); + BCI_SEND(BCI_X_Y(x, y)); + BCI_SEND(BCI_W_H(w, h)); +} + +static void +SavageSetupForCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int fg, + int bg, + int rop, + unsigned int planemask) +{ + SavagePtr psav = SAVPTR(pScrn); + int cmd; + int mix; + + cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_CLIP_LR + | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_MONO; + + mix = SavageHelpPatternROP( pScrn, &fg, &bg, planemask, &rop ); + + if( mix & ROP_PAT ) + cmd |= BCI_CMD_SEND_COLOR; + + BCI_CMD_SET_ROP( cmd, rop ); + + if (bg != -1) + cmd |= BCI_CMD_SEND_COLOR; + else + cmd |= BCI_CMD_SRC_TRANSPARENT; + + psav->SavedBciCmd = cmd; + psav->SavedFgColor = fg; + psav->SavedBgColor = bg; +} + + +static void +SavageSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + + /* XAA will be sending bitmap data next. */ + /* We should probably wait for empty/idle here. */ + + psav->WaitQueue(psav,22); + + BCI_SEND(psav->SavedBciCmd); + + BCI_SEND(psav->GlobalBD.bd2.LoPart); + BCI_SEND(psav->GlobalBD.bd2.HiPart); + + BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1)); + w = (w + 31) & ~31; + if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR ) + BCI_SEND(psav->SavedFgColor); + if( psav->SavedBgColor != 0xffffffff ) + BCI_SEND(psav->SavedBgColor); + BCI_SEND(BCI_X_Y(x, y)); + BCI_SEND(BCI_W_H(w, 1)); + + psav->Rect.x = x; + psav->Rect.y = y + 1; + psav->Rect.width = w; + psav->Rect.height = h - 1; +} + +static void +SavageSubsequentColorExpandScanline( + ScrnInfoPtr pScrn, + int buffer_no) +{ + /* This gets call after each scanline's image data has been sent. */ + SavagePtr psav = SAVPTR(pScrn); + xRectangle xr = psav->Rect; + BCI_GET_PTR; + + if( xr.height ) + { + psav->WaitQueue(psav,20); + BCI_SEND(BCI_X_Y( xr.x, xr.y)); + BCI_SEND(BCI_W_H( xr.width, 1 )); + psav->Rect.height--; + psav->Rect.y++; + } +} + + +/* + * The meaning of the two pattern paremeters to Setup & Subsequent for + * Mono8x8Patterns varies depending on the flag bits. We specify + * HW_PROGRAMMED_BITS, which means our hardware can handle 8x8 patterns + * without caching in the frame buffer. Thus, Setup gets the pattern bits. + * There is no way with BCI to rotate an 8x8 pattern, so we do NOT specify + * HW_PROGRAMMED_ORIGIN. XAA wil rotate it for us and pass the rotated + * pattern to both Setup and Subsequent. If we DID specify PROGRAMMED_ORIGIN, + * then Setup would get the unrotated pattern, and Subsequent gets the + * origin values. + */ + +static void +SavageSetupForMono8x8PatternFill( + ScrnInfoPtr pScrn, + int patternx, + int patterny, + int fg, + int bg, + int rop, + unsigned int planemask) +{ + SavagePtr psav = SAVPTR(pScrn); + int cmd; + int mix; + + mix = XAAHelpPatternROP( pScrn, &fg, &bg, planemask, &rop ); + + cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_DEST_PBD_NEW; + + if( mix & ROP_PAT ) + cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_PAT_MONO; + + if (bg == -1) + cmd |= BCI_CMD_PAT_TRANSPARENT; + + BCI_CMD_SET_ROP(cmd, rop); + + psav->SavedBciCmd = cmd; + psav->SavedFgColor = fg; + psav->SavedBgColor = bg; +} + + +static void +SavageSubsequentMono8x8PatternFillRect( + ScrnInfoPtr pScrn, + int pattern0, + int pattern1, + int x, + int y, + int w, + int h) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + + /* + * I didn't think it was my job to do trivial rejection, but + * miFillGeneralPolygon definitely generates null spans, and XAA + * just passes them through. + */ + + if( !w || !h ) + return; + + psav->WaitQueue(psav,9); + BCI_SEND(psav->SavedBciCmd); + + BCI_SEND(psav->GlobalBD.bd2.LoPart); + BCI_SEND(psav->GlobalBD.bd2.HiPart); + + if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR ) + BCI_SEND(psav->SavedFgColor); + if( psav->SavedBgColor != 0xffffffff ) + BCI_SEND(psav->SavedBgColor); + BCI_SEND(BCI_X_Y(x, y)); + BCI_SEND(BCI_W_H(w, h)); + if( psav->SavedBciCmd & BCI_CMD_PAT_MONO ) + { + BCI_SEND(pattern0); + BCI_SEND(pattern1); + } +} + + +#if 0 +static void +SavageSetupForColor8x8PatternFill( + ScrnInfoPtr pScrn, + int patternx, + int patterny, + int rop, + unsigned planemask, + int trans_col) +{ + SavagePtr psav = SAVPTR(pScrn); + + int cmd; + unsigned int bd; + int pat_offset; + + /* ViRGEs and Savages do not support transparent color patterns. */ + /* We set the NO_TRANSPARENCY bit, so we should never receive one. */ + + pat_offset = (int) (patternx * psav->Bpp + patterny * psav->Bpl); + + cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_DEST_GBD | BCI_CMD_PAT_PBD_COLOR_NEW; + + (void) XAAHelpSolidROP( pScrn, &trans_col, planemask, &rop ); + + BCI_CMD_SET_ROP(cmd, rop); + bd = BCI_BD_BW_DISABLE; + BCI_BD_SET_BPP(bd, pScrn->bitsPerPixel); + BCI_BD_SET_STRIDE(bd, 8); + + psav->SavedBciCmd = cmd; + psav->SavedSbdOffset = pat_offset; + psav->SavedSbd = bd; + psav->SavedBgColor = trans_col; +} + + +static void +SavageSubsequentColor8x8PatternFillRect( + ScrnInfoPtr pScrn, + int patternx, + int patterny, + int x, + int y, + int w, + int h) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + + if( !w || !h ) + return; + + psav->WaitQueue(psav,6); + BCI_SEND(psav->SavedBciCmd); + BCI_SEND(psav->SavedSbdOffset); + BCI_SEND(psav->SavedSbd); + BCI_SEND(BCI_X_Y(patternx,patterny)); + BCI_SEND(BCI_X_Y(x, y)); + BCI_SEND(BCI_W_H(w, h)); +} +#endif + +static void +SavageSubsequentSolidBresenhamLine( + ScrnInfoPtr pScrn, + int x1, + int y1, + int e1, + int e2, + int err, + int length, + int octant) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + int cmd; + + cmd = (psav->SavedBciCmd & 0x00ffffff); + cmd |= BCI_CMD_LINE_LAST_PIXEL; + +#ifdef DEBUG_EXTRA + ErrorF("BresenhamLine, (%4d,%4d), len %4d, oct %d, err %4d,%4d,%4d clr %08x\n", + x1, y1, length, octant, e1, e2, err, psav->SavedFgColor ); +#endif + + psav->WaitQueue(psav, 7 ); + BCI_SEND(cmd); + + BCI_SEND(psav->GlobalBD.bd2.LoPart); + BCI_SEND(psav->GlobalBD.bd2.HiPart); + + if( cmd & BCI_CMD_SEND_COLOR ) + BCI_SEND( psav->SavedFgColor ); + BCI_SEND(BCI_LINE_X_Y(x1, y1)); + BCI_SEND(BCI_LINE_STEPS(e2-e1, e2)); + BCI_SEND(BCI_LINE_MISC(length, + (octant & YMAJOR), + !(octant & XDECREASING), + !(octant & YDECREASING), + e2+err)); +} + +static void +SavageSetClippingRectangle( + ScrnInfoPtr pScrn, + int x1, + int y1, + int x2, + int y2) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + int cmd; + +#ifdef DEBUG_EXTRA + ErrorF("ClipRect, (%4d,%4d)-(%4d,%4d) \n", x1, y1, x2, y2 ); +#endif + + cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW; + psav->WaitQueue(psav,3); + BCI_SEND(cmd); + BCI_SEND(BCI_CLIP_TL(y1, x1)); + BCI_SEND(BCI_CLIP_BR(y2, x2)); + psav->SavedBciCmd |= BCI_CMD_CLIP_CURRENT; +} + + +static void SavageDisableClipping( ScrnInfoPtr pScrn ) +{ + SavagePtr psav = SAVPTR(pScrn); +#ifdef DEBUG_EXTRA + ErrorF("Kill ClipRect\n"); +#endif + psav->SavedBciCmd &= ~BCI_CMD_CLIP_CURRENT; +} + +void +SavageWriteBitmapCPUToScreenColorExpand ( + ScrnInfoPtr pScrn, + int x, int y, int w, int h, + unsigned char * src, + int srcwidth, + int skipleft, + int fg, int bg, + int rop, + unsigned int planemask +) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + int i, j, count, reset; + unsigned int cmd; + CARD32 * srcp; + +/* We aren't using planemask at all here... */ + + if( !srcwidth ) + return; + + cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_SEND_COLOR | BCI_CMD_CLIP_LR + | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_MONO; + cmd |= XAAGetCopyROP(rop) << 16; + + if( bg == -1 ) + cmd |= BCI_CMD_SRC_TRANSPARENT; + + BCI_SEND(cmd); + + BCI_SEND(psav->GlobalBD.bd2.LoPart); + BCI_SEND(psav->GlobalBD.bd2.HiPart); + + BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1)); + BCI_SEND(fg); + if( bg != -1 ) + BCI_SEND(bg); + + /* Bitmaps come in in units of DWORDS, LSBFirst. This is exactly */ + /* reversed of what we expect. */ + + count = (w + 31) / 32; +/* src += ((srcx & ~31) / 8); */ + + /* The BCI region is 128k bytes. A screen-sized mono bitmap can */ + /* exceed that. */ + + reset = 65536 / count; + + for (j = 0; j < h; j ++) { + BCI_SEND(BCI_X_Y(x, y+j)); + BCI_SEND(BCI_W_H(w, 1)); + srcp = (CARD32 *) src; + for (i = count; i > 0; srcp ++, i --) { + /* We have to invert the bits in each byte. */ + CARD32 u = *srcp; + u = ((u & 0x0f0f0f0f) << 4) | ((u & 0xf0f0f0f0) >> 4); + u = ((u & 0x33333333) << 2) | ((u & 0xcccccccc) >> 2); + u = ((u & 0x55555555) << 1) | ((u & 0xaaaaaaaa) >> 1); + BCI_SEND(u); + } + src += srcwidth; + if( !--reset ) { + BCI_RESET; + reset = 65536 / count; + } + } +} + +void +SavageSetupForImageWrite( + ScrnInfoPtr pScrn, + int rop, + unsigned planemask, + int transparency_color, + int bpp, + int depth) +{ + SavagePtr psav = SAVPTR(pScrn); + int cmd; + + cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP + | BCI_CMD_CLIP_LR + | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_COLOR; + + cmd |= XAAGetCopyROP(rop) << 16; + + if( transparency_color != -1 ) + cmd |= BCI_CMD_SRC_TRANSPARENT; + + psav->SavedBciCmd = cmd; + psav->SavedBgColor = transparency_color; +} + + +void SavageSubsequentImageWriteRect +( + ScrnInfoPtr pScrn, + int x, + int y, + int w, + int h, + int skipleft) +{ + SavagePtr psav = SAVPTR(pScrn); + BCI_GET_PTR; + + psav->WaitQueue( psav, 8 ); + BCI_SEND(psav->SavedBciCmd); + + BCI_SEND(psav->GlobalBD.bd2.LoPart); + BCI_SEND(psav->GlobalBD.bd2.HiPart); + + BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1)); + if( psav->SavedBgColor != 0xffffffff ) + BCI_SEND(psav->SavedBgColor); + BCI_SEND(BCI_X_Y(x, y)); + BCI_SEND(BCI_W_H(w, h)); +} + |