diff options
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c')
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c | 1047 |
1 files changed, 794 insertions, 253 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c index 2e0c8ae2c..8db9d49c2 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c @@ -1,14 +1,33 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c,v 1.12 2002/04/04 14:05:47 eich Exp $ */ - +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c,v 1.14 2003/01/29 15:42:16 eich Exp $ */ /* + * 2D Acceleration for SiS300, SiS540, SiS630, SiS730, SiS530, SiS620 + * + * Copyright Xavier Ducoin <x.ducoin@lectra.com> + * Copyright 2002 by Thomas Winischhofer, Vienna, Austria + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. * - * Acceleration for SiS300 SiS630 SiS540. - * It is done in a separate file because the register formats are - * very different from the previous chips. + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. * + * Authors: * - * * Xavier Ducoin <x.ducoin@lectra.com> + * Thomas Winischhofer <thomas@winischhofer.net> + * */ #if 0 #define DEBUG @@ -25,11 +44,19 @@ #include "sis.h" #include "sis300_accel.h" -#ifdef DEBUG -static void MMIODump(ScrnInfoPtr pScrn); +#ifdef SISDUALHEAD +/* TW: This is the offset to the memory for each head */ +#define HEADOFFSET (pSiS->dhmOffset) #endif -Bool SiS300AccelInit(ScreenPtr pScreen); +#undef STSCE /* TW: Use/Don't use ScreenToScreenColorExpand - does not work */ + +#undef TRAP /* TW: Use/Don't use Trapezoid Fills - does not work - XAA provides + * illegal trapezoid data (left and right edges cross each other + * sometimes) which causes drawing errors. Further, I have not found + * out how to draw polygones with a height greater than 127... + */ + static void SiSInitializeAccelerator(ScrnInfoPtr pScrn); static void SiSSync(ScrnInfoPtr pScrn); static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, @@ -42,6 +69,11 @@ static void SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask); static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); +#ifdef TRAP +static void SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR); +#endif static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask); static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, @@ -60,6 +92,13 @@ static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn, static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn, int patx, int paty, int x, int y, int w, int h); +#ifdef TRAP +static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn, + int patx, int paty, + int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR ); +#endif #if 0 static void SiSSetupForColorPatternFill(ScrnInfoPtr pScrn, int patx, int paty, int rop, @@ -68,11 +107,15 @@ static void SiSSetupForColorPatternFill(ScrnInfoPtr pScrn, static void SiSSubsequentColorPatternFill(ScrnInfoPtr pScrn, int patx, int paty, int x, int y, int w, int h); +#endif +#if 0 static void SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask); static void SiSSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft); +#endif +#ifdef STSCE static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask); @@ -80,20 +123,18 @@ static void SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn, int x, int y, int w, int h, int srcx, int srcy, int skipleft); #endif -static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, - int fg, int bg, int rop, +static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, unsigned int planemask); static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, - int x, int y, int w, int h, + int x, int y, int w, int h, int skipleft); static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); -#if 0 -static void SiSSetupForImageWrite(ScrnInfoPtr pScrn, int rop, - unsigned int planemask, int trans_color, - int bpp, int depth); -static void SiSSubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y, - int w, int h, int skipleft); + +#ifdef SISDUALHEAD +static void SiSRestoreAccelState(ScrnInfoPtr pScrn); #endif + static void SiSInitializeAccelerator(ScrnInfoPtr pScrn) { @@ -116,71 +157,74 @@ SiS300AccelInit(ScreenPtr pScreen) int i; pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec(); - if (!infoPtr) - return FALSE; + if (!infoPtr) return FALSE; SiSInitializeAccelerator(pScrn); infoPtr->Flags = LINEAR_FRAMEBUFFER | - OFFSCREEN_PIXMAPS | - PIXMAP_CACHE; + OFFSCREEN_PIXMAPS | + PIXMAP_CACHE; /* sync */ infoPtr->Sync = SiSSync; - if ((pScrn->bitsPerPixel != 8) && (pScrn->bitsPerPixel != 16) && - (pScrn->bitsPerPixel != 32)) return FALSE; + /* Acceleration only supported at 8, 16 and 32 bpp */ + if((pScrn->bitsPerPixel != 8) && (pScrn->bitsPerPixel != 16) && + (pScrn->bitsPerPixel != 32)) + return FALSE; - /* BitBlt */ + /* screen to screen copy - TW: We now support transparent copies */ infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy; infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy; - infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY; + infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | + TRANSPARENCY_GXCOPY_ONLY; /* solid fills */ infoPtr->SetupForSolidFill = SiSSetupForSolidFill; infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect; +#ifdef TRAP + infoPtr->SubsequentSolidFillTrap = SiSSubsequentSolidFillTrap; +#endif infoPtr->SolidFillFlags = NO_PLANEMASK; /* solid line */ infoPtr->SetupForSolidLine = SiSSetupForSolidLine; infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine; infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine; - infoPtr->SolidFillFlags = NO_PLANEMASK; + infoPtr->SolidLineFlags = NO_PLANEMASK; /* dashed line */ infoPtr->SetupForDashedLine = SiSSetupForDashedLine; infoPtr->SubsequentDashedTwoPointLine = SiSSubsequentDashedTwoPointLine; infoPtr->DashPatternMaxLength = 64; - infoPtr->DashedLineFlags = NO_PLANEMASK | - LINE_PATTERN_MSBFIRST_LSBJUSTIFIED; + infoPtr->DashedLineFlags = NO_PLANEMASK | + LINE_PATTERN_MSBFIRST_LSBJUSTIFIED; /* 8x8 mono pattern fill */ infoPtr->SetupForMono8x8PatternFill = SiSSetupForMonoPatternFill; - infoPtr->SubsequentMono8x8PatternFillRect = - SiSSubsequentMonoPatternFill; + infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMonoPatternFill; +#ifdef TRAP + infoPtr->SubsequentMono8x8PatternFillTrap = SiSSubsequentMonoPatternFillTrap; +#endif infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | - HARDWARE_PATTERN_SCREEN_ORIGIN | - HARDWARE_PATTERN_PROGRAMMED_BITS | - NO_TRANSPARENCY | - BIT_ORDER_IN_BYTE_MSBFIRST ; - -#if 0 - /* 8x8 color pattern fill ---seems not useful by xaa */ - infoPtr->SetupForColor8x8PatternFill = - SiSSetupForColorPatternFill; - infoPtr->SubsequentColor8x8PatternFillRect = - SiSSubsequentColorPatternFill; - infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK | - HARDWARE_PATTERN_SCREEN_ORIGIN | - HARDWARE_PATTERN_PROGRAMMED_BITS ; + HARDWARE_PATTERN_SCREEN_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_BITS | + NO_TRANSPARENCY | + BIT_ORDER_IN_BYTE_MSBFIRST ; +#ifdef STSCE /* Screen To Screen Color Expand */ + /* TW: The hardware does support this the way we need it */ infoPtr->SetupForScreenToScreenColorExpandFill = - SiSSetupForScreenToScreenColorExpand; + SiSSetupForScreenToScreenColorExpand; infoPtr->SubsequentScreenToScreenColorExpandFill = - SiSSubsequentScreenToScreenColorExpand; - - /* CPU To Screen Color Expand ---implement another instead of this one! */ + SiSSubsequentScreenToScreenColorExpand; + infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK | + BIT_ORDER_IN_BYTE_MSBFIRST ; +#endif + +#if 0 + /* CPU To Screen Color Expand --- implement another instead of this one! */ infoPtr->SetupForCPUToScreenColorExpandFill = SiSSetupForCPUToScreenColorExpand; infoPtr->SubsequentCPUToScreenColorExpandFill = @@ -195,62 +239,55 @@ SiS300AccelInit(ScreenPtr pScreen) HARDWARE_PATTERN_PROGRAMMED_BITS ; #endif - /* per-scanline color expansion*/ - pSiS->ColorExpandBufferNumber = 16; - pSiS->ColorExpandBufferCountMask = 0x0F; - pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4; + /* per-scanline color expansion (using indirect method) */ + if(pSiS->VGAEngine == SIS_530_VGA) { + pSiS->ColorExpandBufferNumber = 4; + pSiS->ColorExpandBufferCountMask = 0x03; + } else { + pSiS->ColorExpandBufferNumber = 16; + pSiS->ColorExpandBufferCountMask = 0x0F; + } + pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4; infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber; infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0]; - infoPtr->SetupForScanlineCPUToScreenColorExpandFill = SiSSetupForScanlineCPUToScreenColorExpandFill; - infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = SiSSubsequentScanlineCPUToScreenColorExpandFill; - infoPtr->SubsequentColorExpandScanline = SiSSubsequentColorExpandScanline; + + infoPtr->SetupForScanlineCPUToScreenColorExpandFill = + SiSSetupForScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = + SiSSubsequentScanlineCPUToScreenColorExpandFill; + infoPtr->SubsequentColorExpandScanline = + SiSSubsequentColorExpandScanline; infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING; - -#if 0 - divider = ((pScrn->virtualX*pScrn->bitsPerPixel)/8)+8; - pSiS->ImageWriteBufferSize = (((12*1024)+divider-1)/divider)*divider; - infoPtr->SetupForImageWrite = SiSSetupForImageWrite; - infoPtr->SubsequentImageWriteRect = SiSSubsequentImageWriteRect; - infoPtr->ImageWriteFlags = CPU_TRANSFER_PAD_DWORD | - SCANLINE_PAD_DWORD | - LEFT_EDGE_CLIPPING | - NO_PLANEMASK| - NO_TRANSPARENCY | - NO_GXCOPY | - SYNC_AFTER_IMAGE_WRITE; + +#ifdef SISDUALHEAD + if (pSiS->DualHeadMode) { + infoPtr->RestoreAccelState = SiSRestoreAccelState; + } #endif /* init Frame Buffer Manager */ - - /* TW: check if maxxfbmem must contain TurboQueue and HWCursor */ topFB = pSiS->maxxfbmem; - if ((topFB) - >= (pSiS->FbMapSize) - - ((pSiS->TurboQueue) ? (1024*512) : 0) - - ((pSiS->HWCursor) ? 4096 : 0)) { - topFB = pSiS->FbMapSize; - /* TurboQueue len is always 512k */ - if (pSiS->TurboQueue) topFB -= 1024*512; - /* HWCursor len is always 4096 */ - if (pSiS->HWCursor) topFB -= 4096; - } - reservedFbSize = (pSiS->ColorExpandBufferNumber - * pSiS->PerColorExpandBufferSize); - /* TW: New for MaxXFBmem Option */ - UsableFbSize = topFB - reservedFbSize; - /* Layout: - * |--------------++++++++++++++++++++^******==========~~~~~~~~~~~~| - * UsableFbSize ColorExpandBuffers | Heap HWCursor TurboQueue - * topFB + + reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize; + + UsableFbSize = topFB - reservedFbSize; + + /* Layout: (Sizes do not reflect correct proportions) + * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~| + * UsableFbSize ColorExpandBuffers | DRI-Heap | HWCursor TurboQueue 300/310/325 series + * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~| + * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor 530/620 + * topFB */ + AvailBufBase = pSiS->FbBase + UsableFbSize; for (i = 0; i < pSiS->ColorExpandBufferNumber; i++) { - pSiS->ColorExpandBufferAddr[i] = AvailBufBase + + pSiS->ColorExpandBufferAddr[i] = AvailBufBase + i * pSiS->PerColorExpandBufferSize; pSiS->ColorExpandBufferScreenOffset[i] = UsableFbSize + i * pSiS->PerColorExpandBufferSize; @@ -258,17 +295,30 @@ SiS300AccelInit(ScreenPtr pScreen) Avail.x1 = 0; Avail.y1 = 0; Avail.x2 = pScrn->displayWidth; - Avail.y2 = UsableFbSize - / (pScrn->displayWidth * pScrn->bitsPerPixel/8) - 1; - if (Avail.y2 < 0) - Avail.y2 = 32767; - + Avail.y2 = (UsableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel/8)) - 1; + + if(Avail.y2 < 0) Avail.y2 = 32767; + + if(Avail.y2 < pScrn->currentMode->VDisplay) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Not enough video RAM for accelerator. At least " + "%dKB needed, %dKB available\n", + ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* TW: +8 for make it sure */ + * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8, + pSiS->maxxfbmem/1024); + pSiS->NoAccel = TRUE; + pSiS->NoXvideo = TRUE; + XAADestroyInfoRec(pSiS->AccelInfoPtr); + pSiS->AccelInfoPtr = NULL; + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Frame Buffer From (%d,%d) To (%d,%d)\n", Avail.x1, Avail.y1, Avail.x2, Avail.y2); - + xf86InitFBManager(pScreen, &Avail); - + return(XAAInit(pScreen, infoPtr)); } @@ -284,7 +334,26 @@ SiSSync(ScrnInfoPtr pScrn) SiSIdle } -static int sisALUConv[] = +#ifdef SISDUALHEAD +static void +SiSRestoreAccelState(ScrnInfoPtr pScrn) +{ + SISPtr pSiS = SISPTR(pScrn); + + /* TW: We don't need to do anything special here; forcing the + * other head to re-read the CmdQueLen is not necessary: + * After the Sync in RestoreAccelState(), the real queue + * length is always larger than (or at least equal to) + * the amount stored in CmdQueueLen of the other head, + * so the only thing that might happen is one unnecessary + * Sync on the other head. I think we can live with that. + */ + pSiS->DoColorExpand = FALSE; + SiSIdle +} +#endif + +static const int sisALUConv[] = { 0x00, /* dest = 0; 0, GXclear, 0 */ 0x88, /* dest &= src; DSa, GXand, 0x1 */ @@ -304,7 +373,7 @@ static int sisALUConv[] = 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ }; /* same ROP but with Pattern as Source */ -static int sisPatALUConv[] = +static const int sisPatALUConv[] = { 0x00, /* dest = 0; 0, GXclear, 0 */ 0xA0, /* dest &= src; DPa, GXand, 0x1 */ @@ -329,58 +398,25 @@ static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, unsigned int planemask, int trans_color) { SISPtr pSiS = SISPTR(pScrn); -/* XAAInfoRecPtr pXAA = XAAPTR(pScrn);*/ PDEBUG(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n", xdir, ydir, rop, planemask, trans_color)); -/* - ErrorF("XAAInfoPtr->UsingPixmapCache = %s\n" - "XAAInfoPtr->CanDoMono8x8 = %s\n" - "XAAInfoPtr->CanDoColor8x8 = %s\n" - "XAAInfoPtr->CachePixelGranularity = %d\n" - "XAAInfoPtr->MaxCacheableTileWidth = %d\n" - "XAAInfoPtr->MaxCacheableTileHeight = %d\n" - "XAAInfoPtr->MaxCacheableStippleWidth = %d\n" - "XAAInfoPtr->MaxCacheableStippleHeight = %d\n" - "XAAInfoPtr->MonoPatternPitch = %d\n" - "XAAInfoPtr->CacheWidthMono8x8Pattern = %d\n" - "XAAInfoPtr->CacheHeightMono8x8Pattern = %d\n" - "XAAInfoPtr->ColorPatternPitch = %d\n" - "XAAInfoPtr->CacheWidthColor8x8Pattern = %d\n" - "XAAInfoPtr->CacheHeightColor8x8Pattern = %d\n" - "XAAInfoPtr->CacheColorExpandDensity = %d\n" - "XAAInfoPtr->maxOffPixWidth = %d\n" - "XAAInfoPtr->maxOffPixHeight= %d\n" - "XAAInfoPtr->NeedToSync = %s\n" - "\n", - pXAA->UsingPixmapCache ? "True" : "False", - pXAA->CanDoMono8x8 ? "True" : "False", - pXAA->CanDoColor8x8 ? "True" : "False", - pXAA->CachePixelGranularity, - pXAA->MaxCacheableTileWidth, - pXAA->MaxCacheableTileHeight, - pXAA->MaxCacheableStippleWidth, - pXAA->MaxCacheableStippleHeight, - pXAA->MonoPatternPitch, - pXAA->CacheWidthMono8x8Pattern, - pXAA->CacheHeightMono8x8Pattern, - pXAA->ColorPatternPitch, - pXAA->CacheWidthColor8x8Pattern, - pXAA->CacheHeightColor8x8Pattern, - pXAA->CacheColorExpandDensity, - pXAA->maxOffPixWidth, - pXAA->maxOffPixHeight, - pXAA->NeedToSync ? "True" : "False"); -*/ - - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupSRCPitch(pSiS->scrnOffset) SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupROP(sisALUConv[rop]) - if (xdir > 0) { + + if(trans_color != -1) { + SiSSetupROP(0x0A) + SiSSetupSRCTrans(trans_color) + SiSSetupCMDFlag(TRANSPARENT_BITBLT) + } else { + SiSSetupROP(sisALUConv[rop]) + } + if(xdir > 0) { SiSSetupCMDFlag(X_INC) } - if (ydir > 0) { + if(ydir > 0) { SiSSetupCMDFlag(Y_INC) } } @@ -396,27 +432,35 @@ static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, src_x, src_y, dst_x, dst_y, width, height)); srcbase = dstbase = 0; - if (src_y >= 2048) { + if(src_y >= 2048) { srcbase = pSiS->scrnOffset * src_y; src_y = 0; - } - if (dst_y >= pScrn->virtualY) { - dstbase = pSiS->scrnOffset*dst_y; + } + if( (dst_y >= pScrn->virtualY) || (dst_y >= 2048) ) { + dstbase = pSiS->scrnOffset * dst_y; dst_y = 0; - } + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + srcbase += HEADOFFSET; + dstbase += HEADOFFSET; + } +#endif SiSSetupSRCBase(srcbase); SiSSetupDSTBase(dstbase); - if (!(pSiS->CommandReg & X_INC)) { + + if(!(pSiS->CommandReg & X_INC)) { src_x += width-1; dst_x += width-1; } - if (!(pSiS->CommandReg & Y_INC)) { + if(!(pSiS->CommandReg & Y_INC)) { src_y += height-1; dst_y += height-1; } SiSSetupRect(width, height) SiSSetupSRCXY(src_x, src_y) SiSSetupDSTXY(dst_x, dst_y) + SiSDoCMD } @@ -430,11 +474,10 @@ SiSSetupForSolidFill(ScrnInfoPtr pScrn, color, rop, planemask)); SiSSetupPATFG(color) -/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupROP(sisPatALUConv[rop]) - SiSSetupCMDFlag(X_INC | Y_INC | PATFG | BITBLT) + /* SiSSetupCMDFlag(PATFG) - is zero */ } static void @@ -447,15 +490,136 @@ SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn, PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n", x, y, w, h)); dstbase = 0; - if (y >= 2048) { - dstbase=pSiS->scrnOffset*y; + + if (y >= 2048) { + dstbase = pSiS->scrnOffset * y; y = 0; } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif SiSSetupDSTBase(dstbase) SiSSetupDSTXY(x,y) SiSSetupRect(w,h) + /* Clear commandReg because Setup can be used for Rect and Trap */ + pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | + T_L_X_INC | T_L_Y_INC | + T_R_X_INC | T_R_Y_INC | + TRAPAZOID_FILL); + SiSSetupCMDFlag(X_INC | Y_INC | BITBLT) + + SiSDoCMD +} + +/* TW: Trapezoid */ +/* This would work better if XAA would provide us with valid trapezoids. + * In fact, with small trapezoids the left and the right edge often cross + * each other or result in a line length of 0 which causes drawing errors + * (filling over whole scanline). + * Furthermore, I have not found out how to draw trapezoids with a height + * greater than 127. + */ +#ifdef TRAP +static void +SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR ) +{ + SISPtr pSiS = SISPTR(pScrn); + long dstbase; +#if 0 + float kL, kR; +#endif + + dstbase = 0; + if (y >= 2048) { + dstbase=pSiS->scrnOffset*y; + y = 0; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif + SiSSetupDSTBase(dstbase) + /* SiSSetupRect(w,h) */ + +#if 1 + SiSSetupPATFG(0xff0000) /* FOR TESTING */ +#endif + + /* Clear CommandReg because SetUp can be used for Rect and Trap */ + pSiS->CommandReg &= ~(T_L_X_INC | T_L_Y_INC | + T_R_X_INC | T_R_Y_INC | + T_XISMAJORL | T_XISMAJORR | + BITBLT); + + xf86DrvMsg(0, X_INFO, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n", + left, right, y, h, dxL, dyL, eL, dxR, dyR, eR); + + /* Unfortunately, we must check if the right and the left edge + * cross each other... INCOMPLETE (line equation wrong) + */ +#if 0 + if (dxL == 0) kL = 0; + else kL = (float)dyL / (float)dxL; + if (dxR == 0) kR = 0; + else kR = (float)dyR / (float)dxR; + xf86DrvMsg(0, X_INFO, "kL %f kR %f!\n", kL, kR); + if ( (kR != kL) && + (!(kR == 0 && kL == 0)) && + (!(kR < 0 && kL > 0)) ) { + xf86DrvMsg(0, X_INFO, "Inside if (%f - %d)\n", ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - left) + y), h+y); + if ( ( ( kL * ( ( ((float)right - (float)left) / (kL - kR) ) - (float)left) + (float)y) < (h + y) ) ) { + xf86DrvMsg(0, X_INFO, "Cross detected!\n"); + } + } +#endif + + /* Determine egde angles */ + if (dxL < 0) { dxL = -dxL; } + else { SiSSetupCMDFlag(T_L_X_INC) } + if (dxR < 0) { dxR = -dxR; } + else { SiSSetupCMDFlag(T_R_X_INC) } + + /* (Y direction always positive - do this anyway) */ + if (dyL < 0) { dyL = -dyL; } + else { SiSSetupCMDFlag(T_L_Y_INC) } + if (dyR < 0) { dyR = -dyR; } + else { SiSSetupCMDFlag(T_R_Y_INC) } + + /* Determine major axis */ + if (dxL >= dyL) { /* X is major axis */ + SiSSetupCMDFlag(T_XISMAJORL) + } + if (dxR >= dyR) { /* X is major axis */ + SiSSetupCMDFlag(T_XISMAJORR) + } + + /* Set up deltas */ + SiSSetupdL(dxL, dyL) + SiSSetupdR(dxR, dyR) + +#if 0 /* Could it be that this crappy engine can only draw trapezoids up to 127 pixels high? */ + h &= 0x7F; + if (h == 0) h = 10; +#endif + + /* Set up y, h, left, right */ + SiSSetupYH(y,h) + SiSSetupLR(left,right) + + /* Set up initial error term */ + SiSSetupEL(eL) + SiSSetupER(eR) + + SiSSetupCMDFlag(TRAPAZOID_FILL); + SiSDoCMD } +#endif static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, @@ -468,9 +632,8 @@ SiSSetupForSolidLine(ScrnInfoPtr pScrn, SiSSetupLineCount(1) SiSSetupPATFG(color) -/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupROP(sisPatALUConv[rop]) SiSSetupCMDFlag(PATFG | LINE) } @@ -488,17 +651,26 @@ SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, dstbase = 0; miny = (y1 > y2) ? y2 : y1; maxy = (y1 > y2) ? y1 : y2; - if (maxy >= 2048) { - dstbase = pSiS->scrnOffset*miny; + if(maxy >= 2048) { + dstbase = pSiS->scrnOffset * miny; y1 -= miny; y2 -= miny; } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif SiSSetupDSTBase(dstbase) SiSSetupX0Y0(x1,y1) SiSSetupX1Y1(x2,y2) - if (flags & OMIT_LAST) + if (flags & OMIT_LAST) { SiSSetupCMDFlag(NO_LAST_PIXEL) + } else { + pSiS->CommandReg &= ~(NO_LAST_PIXEL); + } + SiSDoCMD } @@ -512,20 +684,26 @@ SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn, PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n", x, y, len, dir)); len--; /* starting point is included! */ + dstbase = 0; - if ((y >= 2048) || ((y + len) >= 2048)) { + if((y >= 2048) || ((y + len) >= 2048)) { dstbase = pSiS->scrnOffset * y; y = 0; } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif SiSSetupDSTBase(dstbase) SiSSetupX0Y0(x,y) if (dir == DEGREES_0) { SiSSetupX1Y1(x + len, y); - } - else { + } else { SiSSetupX1Y1(x, y + len); } + SiSDoCMD } @@ -540,15 +718,19 @@ SiSSetupForDashedLine(ScrnInfoPtr pScrn, fg, bg, rop, planemask, length, *(pattern+4), *pattern)); SiSSetupLineCount(1) -/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupStyleLow(*pattern) SiSSetupStyleHigh(*(pattern+4)) + SiSSetupStylePeriod(length-1); /* TW: This was missing!!! */ SiSSetupROP(sisPatALUConv[rop]) SiSSetupPATFG(fg) - if (bg != -1) + SiSSetupCMDFlag(LINE | LINE_STYLE) /* TW: This was missing!!! */ + if(bg != -1) { SiSSetupPATBG(bg) + } else { + SiSSetupCMDFlag(TRANSPARENT); /* TW: This was missing!!! */ + } } static void @@ -563,20 +745,28 @@ SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, x1, y1, x2, y2, flags, phase)); dstbase = 0; - miny=(y1 > y2) ? y2 : y1; - maxy=(y1 > y2) ? y1 : y2; - if (maxy >= 2048) { + miny = (y1 > y2) ? y2 : y1; + maxy = (y1 > y2) ? y1 : y2; + if(maxy >= 2048) { dstbase = pSiS->scrnOffset * miny; y1 -= miny; y2 -= miny; } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif SiSSetupDSTBase(dstbase) SiSSetupX0Y0(x1,y1) SiSSetupX1Y1(x2,y2) - if (flags & OMIT_LAST) { + if(flags & OMIT_LAST) { SiSSetupCMDFlag(NO_LAST_PIXEL) + } else { + pSiS->CommandReg &= ~(NO_LAST_PIXEL); } + SiSDoCMD } @@ -589,13 +779,12 @@ SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn, PDEBUG(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n", patx, paty, fg, bg, rop, planemask)); - SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupMONOPAT(patx,paty) SiSSetupPATFG(fg) SiSSetupROP(sisPatALUConv[rop]) - SiSSetupCMDFlag(PATMONO | X_INC | Y_INC) + SiSSetupCMDFlag(PATMONO) SiSSetupPATBG(bg) } @@ -610,18 +799,103 @@ SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn, PDEBUG(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n", patx, paty, x, y, w, h)); dstbase = 0; - if (y >= 2048) { + + if (y >= 2048) { dstbase = pSiS->scrnOffset * y; y = 0; } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif + SiSSetupDSTBase(dstbase) + SiSSetupDSTXY(x, y) + SiSSetupRect(w, h) + /* Clear commandReg because Setup can be used for Rect and Trap */ + pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | + T_L_X_INC | T_L_Y_INC | + T_R_X_INC | T_R_Y_INC | + TRAPAZOID_FILL); + SiSSetupCMDFlag(X_INC | Y_INC) + + SiSDoCMD +} +/* Trapezoid */ +#ifdef TRAP +static void +SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn, + int patx, int paty, + int y, int h, + int left, int dxL, int dyL, int eL, + int right, int dxR, int dyR, int eR ) +{ + SISPtr pSiS = SISPTR(pScrn); + long dstbase; + + PDEBUG(ErrorF("Subsequent Mono8x8PatternFillTrap(%d, %d, %d - %d %d/%d %d/%d)\n", + y, h, left, right, dxL, dxR, eL, eR)); + + dstbase = 0; + if (y >= 2048) { + dstbase=pSiS->scrnOffset*y; + y = 0; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif SiSSetupDSTBase(dstbase) - SiSSetupDSTXY(x,y) - SiSSetupRect(w,h) + + /* Clear CommandReg because SetUp can be used for Rect and Trap */ + pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR | + T_L_X_INC | T_L_Y_INC | + T_R_X_INC | T_R_Y_INC | + BITBLT); + + if (dxL < 0) { dxL = -dxL; } + else { SiSSetupCMDFlag(T_L_X_INC) } + if (dxR < 0) { dxR = -dxR; } + else { SiSSetupCMDFlag(T_R_X_INC) } + + if (dyL < 0) { dyL = -dyL; } + else { SiSSetupCMDFlag(T_L_Y_INC) } + if (dyR < 0) { dyR = -dyR; } + else { SiSSetupCMDFlag(T_R_Y_INC) } + + /* Determine major axis */ + if (dxL >= dyL) { /* X is major axis */ + SiSSetupCMDFlag(T_XISMAJORL) + } + if (dxR >= dyR) { /* X is major axis */ + SiSSetupCMDFlag(T_XISMAJORR) + } + + SiSSetupYH(y,h) + SiSSetupLR(left,right) + + SiSSetupdL(dxL, dyL) + SiSSetupdR(dxR, dyR) + + SiSSetupEL(eL) + SiSSetupER(eR) + + SiSSetupCMDFlag(TRAPAZOID_FILL); + SiSDoCMD } +#endif + #if 0 + +/* TW: The following (already commented) functions have NOT been adapted for dual-head mode */ + + +/* ------- Color Pattern Fill --- is not useful for XAA -------------- */ + static void SiSSetupForColorPatternFill(ScrnInfoPtr pScrn, int patx, int paty, int rop, @@ -635,7 +909,7 @@ SiSSetupForColorPatternFill(ScrnInfoPtr pScrn, /* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupROP(sisPatALUConv[rop]) SiSSetupCMDFlag(PATPATREG | X_INC | Y_INC) } @@ -662,6 +936,11 @@ SiSSubsequentColorPatternFill(ScrnInfoPtr pScrn, SiSDoCMD } +/* ----- CPU To Screen Color Expand (single task) ------------------------- */ + +/* This does not work. Assumingly for the same + * reason why STSColorExpand does not work either. + */ static void SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn, int fg, int bg, @@ -674,7 +953,7 @@ SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn, /* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); + SiSSetupDSTColorDepth(pSiS->DstColor); SiSSetupSRCXY(0,0) SiSSetupSRCFG(fg) SiSSetupROP(sisPatALUConv[rop]) @@ -711,7 +990,13 @@ SiSSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn, /* SiSDoCMD*/ pSiS->DoColorExpand = TRUE; } +#endif +/* ------ Screen To Screen Color Expand ------------------------------- */ + +/* TW: The hareware does not seem to support this the way we need it */ + +#ifdef STSCE static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn, int fg, int bg, @@ -722,135 +1007,391 @@ SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn, PDEBUG(ErrorF("Setup ScreenToScreen ColorExp(0x%x,0x%x, 0x%x)\n", fg, bg, rop)); - SiSSetupDSTBase(0) -/* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/ + SiSSetupDSTColorDepth(pSiS->DstColor) SiSSetupDSTRect(pSiS->scrnOffset, -1) - SiSSetupDSTColorDepth(SISPTR(pScrn)->DstColor); - SiSSetupSRCFG(fg) - SiSSetupSRCBG(bg) - SiSSetupSRCXY(0,0) SiSSetupROP(sisALUConv[rop]) - SiSSetupCMDFlag(X_INC | Y_INC | ENCOLOREXP) + SiSSetupSRCFG(fg) + /* SiSSetupSRCXY(0,0) */ + + if(bg == -1) { + SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | X_INC | + Y_INC | SRCVIDEO); + } else { + SiSSetupSRCBG(bg); + SiSSetupCMDFlag(ENCOLOREXP | X_INC | Y_INC | + SRCVIDEO); + }; } +#endif + +/* TW. This method blits in a single task; this does not seem to work + * because the hardware does not use the source pitch as scanline + * offset but only to calculate pattern address from source X and Y. + * XAA provides the pattern bitmap with scrnOffset (displayWidth * bpp/8) + * offset, but this does not seem to be supported by the hardware. + */ +#ifdef STSCE + +/* For testing, these are the methods: (use only one at a time!) */ + +#undef npitch /* Normal: Use srcx/y as srcx/y, use scrnOffset as source pitch + * This would work if the hareware used the source pitch for + * incrementing the source address after each scanline - but + * it doesn't do this! The first line of the area is correctly + * color expanded, but since the source pitch is ignored and + * the source address not incremented correctly, the following + * lines are color expanded with any bit pattern that is left + * in the unused space of the source bitmap (which is organized + * with the depth of the screen framebuffer hence with a pitch + * of scrnOffset). + */ + +#undef pitchdw /* Use source pitch "displayWidth / 8" instead + * of scrnOffset (=displayWidth * bpp / 8) + * This can't work, because the pitch of the source + * bitmap is scrnoffset! + */ + +#define nopitch /* Calculate srcbase with srcx and srcy, set the + * pitch to scrnOffset (which IS the correct pitch + * for the source bitmap) and set srcx and srcy both + * to 0. + * This would work if the hareware used the source pitch for + * incrementing the source address after each scanline - but + * it doesn't do this! Again: The first line of the area is + * correctly color expanded, but since the source pitch is + * ignored for scanline address incremention, the following + * lines are not correctly color expanded. + * WHATEVER I write to source pitch is ignored! + */ static void SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn, int x, int y, int w, int h, int srcx, int srcy, int skipleft) { - SISPtr pSiS = SISPTR(pScrn); + SISPtr pSiS = SISPTR(pScrn); + long srcbase, dstbase; +#if 0 + int _x0, _y0, _x1, _y1; +#endif +#ifdef pitchdw + int newsrcx, newsrcy; - PDEBUG(ErrorF("Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n", - x, y, w, h, srcx, srcy, skipleft)); + /* srcx and srcy are provided based on a scrnOffset pitch ( = displayWidth * bpp / 8 ) + * We recalulate srcx and srcy based on pitch = displayWidth / 8 + */ + newsrcy = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) / + (pScrn->displayWidth/8); + newsrcx = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) % + (pScrn->displayWidth/8); +#endif + xf86DrvMsg(0, X_INFO, "Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n", + x, y, w, h, srcx, srcy, skipleft); + + srcbase = dstbase = 0; + +#ifdef pitchdw + if (newsrcy >= 2048) { + srcbase = (pScrn->displayWidth / 8) * newsrcy; + newsrcy = 0; + } +#endif +#ifdef nopitch + srcbase = (pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8)); +#endif +#ifdef npitch + if (srcy >= 2048) { + srcbase = pSiS->scrnOffset * srcy; + srcy = 0; + } +#endif + if (y >= 2048) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + srcbase += HEADOFFSET; + dstbase += HEADOFFSET; + } +#endif + SiSSetupSRCBase(srcbase) + SiSSetupDSTBase(dstbase) + +#ifdef pitchdw + SiSSetupSRCPitch(pScrn->displayWidth/8) +#endif +#ifdef nopitch + SiSSetupSRCPitch(pSiS->scrnOffset) + /* SiSSetupSRCPitch(100) */ /* For test - has NO effect WHATSOEVER */ +#endif +#ifdef npitch + SiSSetupSRCPitch(pSiS->scrnOffset) +#endif - SiSSetupSRCPitch(((w+31)&0xFFE0)/8) - SiSSetupDSTXY(x,y) SiSSetupRect(w,h) + +#if 0 /* How do I implement the offset? Not this way, that's for sure.. */ + if (skipleft > 0) { + _x0 = x+skipleft; + _y0 = y; + _x1 = x+w; + _y1 = y+h; + SiSSetupClipLT(_x0, _y0); + SiSSetupClipRB(_x1, _y1); + SiSSetupCMDFlag(CLIPENABLE); + } +#endif +#ifdef pitchdw + SiSSetupSRCXY(newsrcx, newsrcy) +#endif +#ifdef nopitch + SiSSetupSRCXY(0,0) +#endif +#ifdef npitch + SiSSetupSRCXY(srcx, srcy) +#endif + + SiSSetupDSTXY(x,y) + SiSDoCMD } #endif -static void -SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask) +/* TW: TEST: Do it scanline-wise because the other way does not seem to + * be supported by the hardware. (The source pitch seems to be + * displayWidth * (bbp/8) as opposed by the XAA HOWTO, where + * it is stated that the pitch would be displayWidth pixels; + * besides, the hardware seems to ignore the source pitch + * for address increments.) + * Apart from this (which can be solved by doing the color + * expand scanline-wise), I don't know how to implement the + * offset argument. The current method (which uses hardware + * clipping) does not work. + * + * THIS DOES NOT WORK IN THE CURRENT STATE. + */ +#if 0 +static void +SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn, + int x, int y, int w, int h, + int srcx, int srcy, int offset) +{ + SISPtr pSiS = SISPTR(pScrn); + long srcbase, dstbase; + int _x0, _y0, _x1, _y1; + + int newsrcx, newsrcy; + + newsrcy = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) / + (((((w+7)/8)+3) >> 2) * 4); + /* (pScrn->displayWidth/8); */ + newsrcx = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) % + (((((w+7)/8)+3) >> 2) * 4); + /* (pScrn->displayWidth/8); */ + + xf86DrvMsg(0, X_INFO, "Sub STS CE(%d,%d, %d,%d, %d,%d, %d)\n", + x, y, w, h, srcx, srcy, skipleft); + + srcbase = dstbase = 0; + if (newsrcy >= 2048) { + srcbase = (((((w+7)/8)+3) >> 2) * 4) * newsrcy; + /* (pScrn->displayWidth/8) * newsrcy; */ + /* pSiS->scrnOffset * srcy; */ + newsrcy = 0; + } + if (y >= 2048) { + dstbase = pSiS->scrnOffset * y; + y = 0; + } +#ifdef SISDUALHEAD + srcbase += HEADOFFSET; + dstbase += HEADOFFSET; +#endif + SiSSetupDSTBase(dstbase) + + SiSSetupRect(w, 1) + + SiSSetupSRCXY(newsrcx, newsrcy) + + /* SiSSetupSRCPitch(pScrn->displayWidth/8) */ /* old: (((w+31)&0xFFE0)/8) */ + SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4) +#if 1 + if (offset > 0) { + SiSSetupCMDFlag(CLIPENABLE) + } else + pSiS->CommandReg &= ~CLIPENABLE; +#endif + + while (h) { + + SiSSetupSRCBase(srcbase) +#if 1 + if (offset > 0) { + _x0 = x+skipleft; + _y0 = y; + _x1 = x+w; + _y1 = y+h; + SiSSetupClipLT(_x0, _y0); + SiSSetupClipRB(_x1, _y1); + } +#endif + SiSSetupDSTXY(x,y) + + SiSDoCMD + + srcbase += ((((w+7)/8)+3) >> 2) * 4 * 8* ((pScrn->bitsPerPixel+7)/8); + /* pSiS->scrnOffset; */ + y++; + h--; + } +} +#endif + + +/* ----- CPU To Screen Color Expand (scanline-wise) ----------------- */ + +/* We do it using the indirect method */ + +static void +SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, + int fg, int bg, int rop, unsigned int planemask) { SISPtr pSiS=SISPTR(pScrn); - - while ((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x1F00)!=0) {} + + /* TW: Make sure that current CPU-driven BitBlt buffer stage is 0 + * This is required!!! (Otherwise -> drawing errors) + */ + while((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x1F00) != 0) {} /* WDR: == 0x10 */ + +#if 0 /* TW: This is obviously not needed */ pSiS->ColorExpandRingHead = 0; pSiS->ColorExpandRingTail = pSiS->ColorExpandBufferNumber - 1; +#endif + SiSSetupSRCXY(0,0); SiSSetupROP(sisALUConv[rop]); SiSSetupSRCFG(fg); SiSSetupDSTRect(pSiS->scrnOffset, -1); SiSSetupDSTColorDepth(pSiS->DstColor); - if (bg == -1) { - SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | X_INC | - Y_INC|SRCSYSTEM); - } - else { + if(bg == -1) { + SiSSetupCMDFlag(TRANSPARENT | + ENCOLOREXP | + X_INC | Y_INC | + SRCCPUBLITBUF); + } else { SiSSetupSRCBG(bg); - SiSSetupCMDFlag(ENCOLOREXP | X_INC | Y_INC | - SRCSYSTEM); - }; + SiSSetupCMDFlag(ENCOLOREXP | + X_INC | Y_INC | + SRCCPUBLITBUF); + } } -static void SiSSubsequentScanlineCPUToScreenColorExpandFill( - ScrnInfoPtr pScrn, int x, int y, int w, + +static void +SiSSubsequentScanlineCPUToScreenColorExpandFill( + ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft) { SISPtr pSiS = SISPTR(pScrn); -static int srcpitch; int _x0, _y0, _x1, _y1; long dstbase; dstbase = 0; if (y >= 2048) { - dstbase = pSiS->scrnOffset*y; + dstbase = pSiS->scrnOffset * y; y = 0; } +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + dstbase += HEADOFFSET; + } +#endif + + /* TW: Wait until there is no color expansion command in queue + * (This solves the OpenOffice.org window-move bug) + * Added Idle-check - bit 23 is set sometimes, although + * engine is actually idle! + * Update: Bit 23 is not reliable. After heavy 3D engine + * action, this bit never gets cleared again. So do + * SiSIdle instead. + */ + if((MMIO_IN16(pSiS->IOBase, 0x8242) & 0xe000) != 0xe000) { + /* while ((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x0080) != 0) {} */ + SiSIdle + } + SiSSetupDSTBase(dstbase) if (skipleft > 0) { - _x0 = x+skipleft; + _x0 = x + skipleft; _y0 = y; - _x1 = x+w; - _y1 = y+h; + _x1 = x + w; + _y1 = y + h; SiSSetupClipLT(_x0, _y0); SiSSetupClipRB(_x1, _y1); - SiSSetupCMDFlag(CLIPENABLE); - } + SiSSetupCMDFlag(CLIPENABLE); + } else { + pSiS->CommandReg &= (~CLIPENABLE); + } + SiSSetupRect(w, 1); - srcpitch = ((((w+7)/8)+3) >> 2) * 4; - SiSSetupSRCPitch(srcpitch); - pSiS->ycurrent = y; + SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4); pSiS->xcurrent = x; + pSiS->ycurrent = y; } -static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +static void +SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) { - SISPtr pSiS=SISPTR(pScrn); + SISPtr pSiS=SISPTR(pScrn); +#if 0 int newhead,bltbufstage,newtail; +#endif + long cbo; - SiSSetupSRCBase(pSiS->ColorExpandBufferScreenOffset[bufno]); - SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent); - pSiS->ycurrent++; - SiSDoCMD - newhead = pSiS->ColorExpandRingHead = (bufno + 1) & - pSiS->ColorExpandBufferCountMask; - while (newhead == pSiS->ColorExpandRingTail) { - bltbufstage = (int)((MMIO_IN16(pSiS->IOBase,0x8242) & - 0x1F00)>>8); - newtail = newhead - (bltbufstage + 1); - pSiS->ColorExpandRingTail = (newtail >= 0) ? - newtail: (pSiS->ColorExpandBufferNumber+newtail); + cbo = pSiS->ColorExpandBufferScreenOffset[bufno]; +#ifdef SISDUALHEAD + if(pSiS->VGAEngine != SIS_530_VGA) { + cbo += HEADOFFSET; } -} +#endif -#if 0 -static void SiSSetupForImageWrite(ScrnInfoPtr pScrn, int rop, - unsigned int planemask, int trans_color, int bpp, int depth) -{ - return; -} + /* TW: Wait until there is no color expansion command in queue + * (This solves the GTK-big-font bug) + * Added Idle-check - bit 23 is set sometimes, although + * engine is actually idle! + * Update: Bit 23 is not reliable. After heavy 3D engine + * action, this bit never gets cleared again. So do + * SiSIdle instead. + */ + if((MMIO_IN16(pSiS->IOBase, 0x8242) & 0xe000) != 0xe000) { + /* while ((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x0080) != 0) {} */ + SiSIdle + } -static void SiSSubsequentImageWriteRect(ScrnInfoPtr pScrn, - int x, int y, int w, int h, int skipleft) -{ - return; -} -#endif + SiSSetupSRCBase(cbo); -#ifdef DEBUG -static void -MMIODump(ScrnInfoPtr pScrn) -{ - SISPtr pSiS = SISPTR(pScrn); - int i; + SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent); - SiSIdle - for (i=0x8200; i <= 0x823c; i += 4) { - ErrorF("[%x] %0X \n", i, - MMIO_IN32(pSiS->IOBase,i)); + SiSDoCMD + + pSiS->ycurrent++; + + if(pSiS->VGAEngine == SIS_530_VGA) { + while(MMIO_IN8(pSiS->IOBase, 0x8242) & 0x80) {} + } + +#if 0 /* TW: What is this good for? The Head/Tail data is never ever used elsewhere! */ + pSiS->ColorExpandRingHead = newhead = + (bufno + 1) & pSiS->ColorExpandBufferCountMask; + while (newhead == pSiS->ColorExpandRingTail) { + bltbufstage = (int)((MMIO_IN16(pSiS->IOBase,0x8242) & 0x1F00) >> 8); + newtail = newhead - (bltbufstage + 1); + pSiS->ColorExpandRingTail = (newtail >= 0) ? + newtail : (pSiS->ColorExpandBufferNumber + newtail); } -} #endif +} + |