/* * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved. * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_accel.c,v 1.10 2004/01/27 02:38:15 dawes Exp $ */ /************************************************************************* * * File: via_accel.c * Content: 2D acceleration function for VIA/S3G UniChrom * ************************************************************************/ #include "Xarch.h" #include "xaalocal.h" #include "xaarop.h" #include "miline.h" #include "via_driver.h" #include "via_regs.h" /* Forward declaration of functions used in the driver */ static void VIASetupForScreenToScreenCopy( ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned planemask, int trans_color); static void VIASubsequentScreenToScreenCopy( ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h); static void VIASetupForSolidFill( ScrnInfoPtr pScrn, int color, int rop, unsigned planemask); static void VIASubsequentSolidFillRect( ScrnInfoPtr pScrn, int x, int y, int w, int h); static void VIASetupForMono8x8PatternFill( ScrnInfoPtr pScrn, int pattern0, int pattern1, int fg, int bg, int rop, unsigned planemask); static void VIASubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn, int patOffx, int patOffy, int x, int y, int w, int h); static void VIASetupForColor8x8PatternFill( ScrnInfoPtr pScrn, int patternx, int patterny, int rop, unsigned planemask, int trans_color); static void VIASubsequentColor8x8PatternFillRect( ScrnInfoPtr pScrn, int patOffx, int patOffy, int x, int y, int w, int h); static void VIASetupForCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned planemask); static void VIASubsequentScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft); static void VIASetupForScreenToScreenColorExpand( ScrnInfoPtr pScrn, int bg, int fg, int rop, unsigned planemask); static void VIASubsequentScreenToScreenColorExpand( ScrnInfoPtr pScrn, int x, int y, int w, int h, int srcx, int srcy, int offset); static void VIASetupForImageWrite( ScrnInfoPtr pScrn, int rop, unsigned planemask, int trans_color, int bpp, int depth); static void VIASubsequentImageWriteRect( ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft); static void VIASetupForSolidLine( ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask); static void VIASubsequentSolidTwoPointLine( ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int flags); static void VIASubsequentSolidHorVertLine( ScrnInfoPtr pScrn, int x, int y, int len, int dir); static void VIASetupForDashedLine( ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask, int length, unsigned char *pattern); static void VIASubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int flags, int phase); static void VIASetClippingRectangle( ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2); static void VIADisableClipping( ScrnInfoPtr ); void VIAInitialize2DEngine(ScrnInfoPtr pScrn) { VIAPtr pVia = VIAPTR(pScrn); CARD32 dwVQStartAddr, dwVQEndAddr; CARD32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH; CARD32 dwGEMode; /* init 2D engine regs to reset 2D engine */ VIASETREG(0x04, 0x0); VIASETREG(0x08, 0x0); VIASETREG(0x0c, 0x0); VIASETREG(0x10, 0x0); VIASETREG(0x14, 0x0); VIASETREG(0x18, 0x0); VIASETREG(0x1c, 0x0); VIASETREG(0x20, 0x0); VIASETREG(0x24, 0x0); VIASETREG(0x28, 0x0); VIASETREG(0x2c, 0x0); VIASETREG(0x30, 0x0); VIASETREG(0x34, 0x0); VIASETREG(0x38, 0x0); VIASETREG(0x3c, 0x0); VIASETREG(0x40, 0x0); /* Init AGP and VQ regs */ VIASETREG(0x43c, 0x00100000); VIASETREG(0x440, 0x00000000); VIASETREG(0x440, 0x00333004); VIASETREG(0x440, 0x60000000); VIASETREG(0x440, 0x61000000); VIASETREG(0x440, 0x62000000); VIASETREG(0x440, 0x63000000); VIASETREG(0x440, 0x64000000); VIASETREG(0x440, 0x7D000000); VIASETREG(0x43c, 0xfe020000); VIASETREG(0x440, 0x00000000); if (pVia->VQStart != 0) { /* Enable VQ */ dwVQStartAddr = pVia->VQStart; dwVQEndAddr = pVia->VQEnd; dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF); dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF); dwVQStartEndH = 0x52000000 | ((dwVQStartAddr & 0xFF000000) >> 24) | ((dwVQEndAddr & 0xFF000000) >> 16); dwVQLen = 0x53000000 | (VIA_VQ_SIZE >> 3); VIASETREG(0x43c, 0x00fe0000); VIASETREG(0x440, 0x080003fe); VIASETREG(0x440, 0x0a00027c); VIASETREG(0x440, 0x0b000260); VIASETREG(0x440, 0x0c000274); VIASETREG(0x440, 0x0d000264); VIASETREG(0x440, 0x0e000000); VIASETREG(0x440, 0x0f000020); VIASETREG(0x440, 0x1000027e); VIASETREG(0x440, 0x110002fe); VIASETREG(0x440, 0x200f0060); VIASETREG(0x440, 0x00000006); VIASETREG(0x440, 0x40008c0f); VIASETREG(0x440, 0x44000000); VIASETREG(0x440, 0x45080c04); VIASETREG(0x440, 0x46800408); VIASETREG(0x440, dwVQStartEndH); VIASETREG(0x440, dwVQStartL); VIASETREG(0x440, dwVQEndL); VIASETREG(0x440, dwVQLen); } else { /* Diable VQ */ VIASETREG(0x43c, 0x00fe0000); VIASETREG(0x440, 0x00000004); VIASETREG(0x440, 0x40008c0f); VIASETREG(0x440, 0x44000000); VIASETREG(0x440, 0x45080c04); VIASETREG(0x440, 0x46800408); } dwGEMode = 0; switch (pScrn->bitsPerPixel) { case 16: dwGEMode |= VIA_GEM_16bpp; break; case 32: dwGEMode |= VIA_GEM_32bpp; default: dwGEMode |= VIA_GEM_8bpp; break; } #if 0 switch (pScrn->displayWidth) { case 800: dwGEMode |= VIA_GEM_800; break; case 1024: dwGEMode |= VIA_GEM_1024; break; case 1280: dwGEMode |= VIA_GEM_1280; break; case 1600: dwGEMode |= VIA_GEM_1600; break; case 2048: dwGEMode |= VIA_GEM_2048; break; default: dwGEMode |= VIA_GEM_640; break; } #endif /* Set BPP and Pitch */ VIASETREG(VIA_REG_GEMODE, dwGEMode); /* Set Src and Dst base address and pitch, pitch is qword */ VIASETREG(VIA_REG_SRCBASE, 0x0); VIASETREG(VIA_REG_DSTBASE, 0x0); VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); } /* Acceleration init function, sets up pointers to our accelerated functions */ Bool VIAInitAccel(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; VIAPtr pVia = VIAPTR(pScrn); XAAInfoRecPtr xaaptr; BoxRec AvailFBArea; unsigned long cacheEnd; unsigned long cacheEndDRI; pVia->VQStart = 0; if (((pVia->FBFreeEnd - pVia->FBFreeStart) >= VIA_VQ_SIZE) && pVia->VQEnable) { /* Reserved space for VQ */ pVia->VQStart = pVia->FBFreeEnd - VIA_VQ_SIZE; pVia->VQEnd = pVia->VQStart + VIA_VQ_SIZE - 1; pVia->FBFreeEnd -= VIA_VQ_SIZE; } if (pVia->hwcursor) { pVia->FBFreeEnd -= VIA_CURSOR_SIZE; } VIAInitialize2DEngine(pScrn); if (pScrn->depth == 8) { pVia->PlaneMask = 0xFF; } else if (pScrn->depth == 15) { pVia->PlaneMask = 0x7FFF; } else if (pScrn->depth == 16) { pVia->PlaneMask = 0xFFFF; } else if (pScrn->depth == 24) { pVia->PlaneMask = 0xFFFFFF; } /* General acceleration flags */ if (!(xaaptr = pVia->AccelInfoRec = XAACreateInfoRec())) return FALSE; xaaptr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER | MICROSOFT_ZERO_LINE_BIAS | 0; if (pScrn->bitsPerPixel == 8) xaaptr->CachePixelGranularity = 128; /* Clipping */ xaaptr->SetClippingRectangle = VIASetClippingRectangle; xaaptr->DisableClipping = VIADisableClipping; xaaptr->ClippingFlags = HARDWARE_CLIP_SOLID_FILL | HARDWARE_CLIP_SOLID_LINE | HARDWARE_CLIP_DASHED_LINE | HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | HARDWARE_CLIP_MONO_8x8_FILL | HARDWARE_CLIP_COLOR_8x8_FILL | HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND | 0; xaaptr->Sync = VIAAccelSync; /* ScreenToScreen copies */ xaaptr->SetupForScreenToScreenCopy = VIASetupForScreenToScreenCopy; xaaptr->SubsequentScreenToScreenCopy = VIASubsequentScreenToScreenCopy; xaaptr->ScreenToScreenCopyFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; /* Solid filled rectangles */ xaaptr->SetupForSolidFill = VIASetupForSolidFill; xaaptr->SubsequentSolidFillRect = VIASubsequentSolidFillRect; xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; /* Mono 8x8 pattern fills */ xaaptr->SetupForMono8x8PatternFill = VIASetupForMono8x8PatternFill; xaaptr->SubsequentMono8x8PatternFillRect = VIASubsequentMono8x8PatternFillRect; xaaptr->Mono8x8PatternFillFlags = NO_PLANEMASK | HARDWARE_PATTERN_PROGRAMMED_BITS | ROP_NEEDS_SOURCE | BIT_ORDER_IN_BYTE_MSBFIRST | 0; /* Color 8x8 pattern fills */ xaaptr->SetupForColor8x8PatternFill = VIASetupForColor8x8PatternFill; xaaptr->SubsequentColor8x8PatternFillRect = VIASubsequentColor8x8PatternFillRect; xaaptr->Color8x8PatternFillFlags = NO_PLANEMASK | NO_TRANSPARENCY | HARDWARE_PATTERN_PROGRAMMED_BITS | ROP_NEEDS_SOURCE | 0; /*=* This function is only used in drawing check box when use RedHat 7.2 * Raleigh Theme. The behavior is a little strange, so we temporarily * disable this function. *=*/ /* Screen to Screen color expansion. */ xaaptr->SetupForScreenToScreenColorExpandFill = VIASetupForScreenToScreenColorExpand; xaaptr->SubsequentScreenToScreenColorExpandFill = VIASubsequentScreenToScreenColorExpand; xaaptr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK | BIT_ORDER_IN_BYTE_MSBFIRST | ROP_NEEDS_SOURCE | 0; /* Solid lines */ xaaptr->SetupForSolidLine = VIASetupForSolidLine; xaaptr->SubsequentSolidTwoPointLine = VIASubsequentSolidTwoPointLine; xaaptr->SubsequentSolidHorVertLine = VIASubsequentSolidHorVertLine; xaaptr->SolidBresenhamLineErrorTermBits = 14; xaaptr->SolidLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; /* dashed line */ xaaptr->SetupForDashedLine = VIASetupForDashedLine; xaaptr->SubsequentDashedTwoPointLine = VIASubsequentDashedTwoPointLine; xaaptr->DashPatternMaxLength = 8; xaaptr->DashedLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE | LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | 0; /* CPU to Screen color expansion */ xaaptr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | 0; xaaptr->SetupForScanlineCPUToScreenColorExpandFill = VIASetupForCPUToScreenColorExpandFill; xaaptr->SubsequentScanlineCPUToScreenColorExpandFill = VIASubsequentScanlineCPUToScreenColorExpandFill; xaaptr->ColorExpandBase = pVia->BltBase; xaaptr->ColorExpandRange = VIA_MMIO_BLTSIZE; /* ImageWrite */ xaaptr->ImageWriteFlags = NO_PLANEMASK | CPU_TRANSFER_PAD_DWORD | SCANLINE_PAD_DWORD | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | /*NO_GXCOPY |*/ /*SYNC_AFTER_IMAGE_WRITE |*/ 0; xaaptr->SetupForImageWrite = VIASetupForImageWrite; xaaptr->SubsequentImageWriteRect = VIASubsequentImageWriteRect; xaaptr->ImageWriteBase = pVia->BltBase; xaaptr->ImageWriteRange = VIA_MMIO_BLTSIZE; /* We reserve space for pixel cache */ cacheEnd = pVia->FBFreeEnd / pVia->Bpl; cacheEndDRI = (pVia->FBFreeStart + VIA_PIXMAP_CACHE_SIZE + pVia->Bpl-1) / pVia->Bpl; /* * Old DRI has some assumptions here that we need to work through * and fix * UPDATE: These assumptions are that pVia->FBFreestart should * point to a free region in the framebuffer where it can place it's * allocator. */ if(cacheEnd > cacheEndDRI) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clipping pixmap cache for old DRI/DRM module.\n"); cacheEnd = cacheEndDRI; } /* * Clip to the blitter limit */ pVia->ScissB = cacheEnd;; if (pVia->ScissB > 2047) pVia->ScissB = 2047; /* * The free start IS where the cache Ends. We should not add here. */ pVia->FBFreeStart = (pVia->ScissB + 1) *pVia->Bpl; /* * Finally, we set up the video memory space available to the pixmap * cache */ AvailFBArea.x1 = 0; AvailFBArea.y1 = 0; AvailFBArea.x2 = pScrn->displayWidth; AvailFBArea.y2 = pVia->ScissB; /* * The pixmap cache must stay within the lowest 2048 lines due * to hardware blitting limits. The rest is available for offscreen * allocations unless DRI stole it. */ xf86InitFBManager(pScreen, &AvailFBArea); DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %d lines for offscreen memory.\n", AvailFBArea.y2 - pScrn->virtualY )); return XAAInit(pScreen, xaaptr); } void VIAInitLinear(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; VIAPtr pVia = VIAPTR(pScrn); #ifdef XFREE86_44 /* * In the 44 path we must take care not to truncate offset and size so * that we get overlaps. If there is available memory below line 2048 * we use it. */ unsigned long offset = (pVia->FBFreeStart + pVia->Bpp - 1 ) / pVia->Bpp; unsigned long size = pVia->FBFreeEnd / pVia->Bpp - offset; if (size > 0) xf86InitFBManagerLinear(pScreen, offset, size); #else /* * In the 43 path we don't have to care about truncation. just use * all available memory, also below line 2048. The drm module uses * pVia->FBFreeStart as offscreen available start. We do it to. */ unsigned long offset = pVia->FBFreeStart; unsigned long size = pVia->FBFreeEnd - offset; if (size > 0 ) VIAInitPool(pVia, offset, size); #endif } /* The sync function for the GE */ void VIAAccelSync(ScrnInfoPtr pScrn) { VIAPtr pVia = VIAPTR(pScrn); WaitIdle(); } /* These are the ScreenToScreen bitblt functions. We support all ROPs, all * directions. * */ static void VIASetupForScreenToScreenCopy( ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned planemask, int trans_color) { VIAPtr pVia = VIAPTR(pScrn); int cmd; cmd = VIA_GEC_BLT | (XAAGetCopyROP(rop) << 24); if (xdir < 0) cmd |= VIA_GEC_DECX; if (ydir < 0) cmd |= VIA_GEC_DECY; pVia->SavedCmd = cmd; if (trans_color != -1) { /* Transparent Bitblt */ VIASETREG(VIA_REG_SRCCOLORKEY, trans_color); VIASETREG(VIA_REG_KEYCONTROL, 0x4000); } else { /* Disable Transparent Bitblt */ VIASETREG(VIA_REG_KEYCONTROL, 0x0); } } static void VIASubsequentScreenToScreenCopy( ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h) { VIAPtr pVia = VIAPTR(pScrn); if (!w || !h) return; if (pVia->SavedCmd & VIA_GEC_DECX) { x1 += (w - 1); x2 += (w - 1); } if (pVia->SavedCmd & VIA_GEC_DECY) { y1 += (h - 1); y2 += (h - 1); } /* Set Src and Dst base address and pitch, pitch is qword */ VIASETREG(VIA_REG_SRCBASE, 0x0); VIASETREG(VIA_REG_DSTBASE, 0x0); VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); VIASETREG(VIA_REG_SRCPOS, ((y1 << 16) | x1)); VIASETREG(VIA_REG_DSTPOS, ((y2 << 16) | x2)); VIASETREG(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); VIASETREG(VIA_REG_GECMD, pVia->SavedCmd); } /* * SetupForSolidFill is also called to set up for lines. */ static void VIASetupForSolidFill( ScrnInfoPtr pScrn, int color, int rop, unsigned planemask) { VIAPtr pVia = VIAPTR(pScrn); int cmd; cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | (XAAGetPatternROP(rop) << 24); pVia->SavedCmd = cmd; pVia->SavedFgColor = color; } static void VIASubsequentSolidFillRect( ScrnInfoPtr pScrn, int x, int y, int w, int h) { VIAPtr pVia = VIAPTR(pScrn); if (!w || !h) return; /* Set Src and Dst base address and pitch, pitch is qword */ VIASETREG(VIA_REG_SRCBASE, 0x0); VIASETREG(VIA_REG_DSTBASE, 0x0); VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); VIASETREG(VIA_REG_DSTPOS, ((y << 16) | x)); VIASETREG(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); VIASETREG(VIA_REG_FGCOLOR, pVia->SavedFgColor); VIASETREG(VIA_REG_GECMD, pVia->SavedCmd); } /* * 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 VIASetupForMono8x8PatternFill( ScrnInfoPtr pScrn, int pattern0, int pattern1, int fg, int bg, int rop, unsigned planemask) { VIAPtr pVia = VIAPTR(pScrn); int cmd; cmd = VIA_GEC_BLT | VIA_GEC_PAT_REG | VIA_GEC_PAT_MONO | (XAAGetPatternROP(rop) << 24); if (bg == -1) { /* transparent mono pattern */ cmd |= VIA_GEC_MPAT_TRANS; } pVia->SavedCmd = cmd; pVia->SavedFgColor = fg; pVia->SavedBgColor = bg; pVia->SavedPattern0 = pattern0; pVia->SavedPattern1 = pattern1; } static void VIASubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn, int patOffx, int patOffy, int x, int y, int w, int h) { VIAPtr pVia = VIAPTR(pScrn); CARD32 dwPatOffset; if (!w || !h) return; dwPatOffset = ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26); /* Set Src and Dst base address and pitch, pitch is qword */ VIASETREG(VIA_REG_SRCBASE, 0x0); VIASETREG(VIA_REG_DSTBASE, 0x0); VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); VIASETREG(VIA_REG_DSTPOS, ((y << 16) | x)); VIASETREG(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); VIASETREG(VIA_REG_PATADDR, dwPatOffset); VIASETREG(VIA_REG_FGCOLOR, pVia->SavedFgColor); VIASETREG(VIA_REG_BGCOLOR, pVia->SavedBgColor); VIASETREG(VIA_REG_MONOPAT0, pVia->SavedPattern0); VIASETREG(VIA_REG_MONOPAT1, pVia->SavedPattern1); VIASETREG(VIA_REG_GECMD, pVia->SavedCmd); } static void VIASetupForColor8x8PatternFill( ScrnInfoPtr pScrn, int patternx, int patterny, int rop, unsigned planemask, int trans_color) { VIAPtr pVia = VIAPTR(pScrn); int cmd; cmd = VIA_GEC_BLT | (XAAGetPatternROP(rop) << 24); pVia->SavedCmd = cmd; pVia->SavedPatternAddr = (patternx * pVia->Bpp + patterny * pVia->Bpl); } static void VIASubsequentColor8x8PatternFillRect( ScrnInfoPtr pScrn, int patOffx, int patOffy, int x, int y, int w, int h) { VIAPtr pVia = VIAPTR(pScrn); CARD32 dwPatAddr; if (!w || !h) return; dwPatAddr = (pVia->SavedPatternAddr >> 3) | ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26); /* Set Src and Dst base address and pitch, pitch is qword */ VIASETREG(VIA_REG_SRCBASE, 0x0); VIASETREG(VIA_REG_DSTBASE, 0x0); VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); VIASETREG(VIA_REG_DSTPOS, ((y << 16) | x)); VIASETREG(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); VIASETREG(VIA_REG_PATADDR, dwPatAddr); VIASETREG(VIA_REG_GECMD, pVia->SavedCmd); } static void VIASetupForCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned planemask) { VIAPtr pVia = VIAPTR(pScrn); int cmd; cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIA_GEC_SRC_MONO | (XAAGetCopyROP(rop) << 24); if (bg == -1) { cmd |= VIA_GEC_MSRC_TRANS; } pVia->SavedCmd = cmd; pVia->SavedFgColor = fg; pVia->SavedBgColor = bg; /* Disable Transparent Bitblt */ VIASETREG(VIA_REG_KEYCONTROL, 0x0); } static void VIASubsequentScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft) { VIAPtr pVia = VIAPTR(pScrn); /* XAA will be sending bitmap data next. */ /* We should probably wait for empty/idle here. */ if (skipleft) { VIASetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), (y + h -1)); } /* Set Src and Dst base address and pitch, pitch is qword */ VIASETREG(VIA_REG_SRCBASE, 0x0); VIASETREG(VIA_REG_DSTBASE, 0x0); VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); VIASETREG(VIA_REG_SRCPOS, 0); VIASETREG(VIA_REG_DSTPOS, ((y << 16) | x)); VIASETREG(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); VIASETREG(VIA_REG_FGCOLOR, pVia->SavedFgColor); VIASETREG(VIA_REG_BGCOLOR, pVia->SavedBgColor); VIASETREG(VIA_REG_GECMD, pVia->SavedCmd); } static void VIASetupForScreenToScreenColorExpand( ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask) { VIAPtr pVia = VIAPTR(pScrn); int cmd; cmd = VIA_GEC_BLT | VIA_GEC_SRC_MONO | (XAAGetCopyROP(rop) << 24); if (bg == -1) { cmd |= VIA_GEC_MSRC_TRANS; } pVia->SavedCmd = cmd; pVia->SavedFgColor = fg; pVia->SavedBgColor = bg; /* Disable Transparent Bitblt */ VIASETREG(VIA_REG_KEYCONTROL, 0x0); } static void VIASubsequentScreenToScreenColorExpand( ScrnInfoPtr pScrn, int x, int y, int w, int h, int srcx, int srcy, int offset) { VIAPtr pVia = VIAPTR(pScrn); /* Set Src and Dst base address and pitch, pitch is qword */ VIASETREG(VIA_REG_SRCBASE, 0x0); VIASETREG(VIA_REG_DSTBASE, 0x0); VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); VIASETREG(VIA_REG_SRCBASE, ((((srcy * pScrn->displayWidth) + srcx) * (pScrn->bitsPerPixel >> 3)) >> 3)); srcy = 0; srcx = 0; VIASETREG(VIA_REG_SRCPOS, ((srcy << 16) | (srcx * pScrn->bitsPerPixel + offset))); VIASETREG(VIA_REG_DSTPOS, ((y << 16) | x)); VIASETREG(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); VIASETREG(VIA_REG_FGCOLOR, pVia->SavedFgColor); VIASETREG(VIA_REG_BGCOLOR, pVia->SavedBgColor); VIASETREG(VIA_REG_GECMD, pVia->SavedCmd); VIASETREG(VIA_REG_SRCBASE, 0x0); } static void VIASetupForImageWrite( ScrnInfoPtr pScrn, int rop, unsigned planemask, int trans_color, int bpp, int depth) { VIAPtr pVia = VIAPTR(pScrn); int cmd; /* We don't record bpp and depth because we assume bpp is equal to bpp of screen. Is this assume correct ? */ cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | (XAAGetCopyROP(rop) << 24); pVia->SavedCmd = cmd; if (trans_color != -1) { /* Transparent Bitblt */ VIASETREG(VIA_REG_SRCCOLORKEY, trans_color); VIASETREG(VIA_REG_KEYCONTROL, 0x4000); } else { /* Disable Transparent Bitblt */ VIASETREG(VIA_REG_KEYCONTROL, 0x0); } } static void VIASubsequentImageWriteRect( ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft) { VIAPtr pVia = VIAPTR(pScrn); if (skipleft) { VIASetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), (y + h -1)); } /* Set Src and Dst base address and pitch, pitch is qword */ VIASETREG(VIA_REG_SRCBASE, 0x0); VIASETREG(VIA_REG_DSTBASE, 0x0); VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); VIASETREG(VIA_REG_SRCPOS, 0); VIASETREG(VIA_REG_DSTPOS, ((y << 16) | x)); VIASETREG(VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); VIASETREG(VIA_REG_GECMD, pVia->SavedCmd); } /* Setup for XAA solid lines. */ static void VIASetupForSolidLine( ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask) { VIAPtr pVia = VIAPTR(pScrn); int cmd; /* we move VIA_GEC_LINE from here to the place firing command */ cmd = VIA_GEC_FIXCOLOR_PAT | (XAAGetPatternROP(rop) << 24); pVia->SavedCmd = cmd; pVia->SavedFgColor = color; /* set solid line pattern */ VIASETREG(VIA_REG_MONOPAT0, 0xFF); VIASETREG(VIA_REG_FGCOLOR, pVia->SavedFgColor); } static void VIASubsequentSolidTwoPointLine( ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int flags) { VIAPtr pVia = VIAPTR(pScrn); int dx, dy, cmd, tmp, error = 1; cmd = pVia->SavedCmd | VIA_GEC_LINE; dx = x2 - x1; if (dx < 0) { dx = -dx; cmd |= VIA_GEC_DECX; /* line will be drawn from right */ error = 0; } dy = y2 - y1; if (dy < 0) { dy = -dy; cmd |= VIA_GEC_DECY; /* line will be drawn from bottom */ } if (dy > dx) { tmp = dy; dy = dx; dx = tmp; /* Swap 'dx' and 'dy' */ cmd |= VIA_GEC_Y_MAJOR; /* Y major line */ } if (flags & OMIT_LAST) { cmd |= VIA_GEC_LASTPIXEL_OFF; } /* Set Src and Dst base address and pitch, pitch is qword */ VIASETREG(VIA_REG_SRCBASE, 0x0); VIASETREG(VIA_REG_DSTBASE, 0x0); VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); /* major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1) */ /* K1 = 2*dmin K2 = 2*(dmin - dmax) */ /* Error Term = (StartXdisplayWidth * pScrn->bitsPerPixel >> 3) >> 3) | (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); if (dir == DEGREES_0) { VIASETREG(VIA_REG_DSTPOS, ((y << 16) | x)); VIASETREG(VIA_REG_DIMENSION, (len - 1)); VIASETREG(VIA_REG_GECMD, pVia->SavedCmd | VIA_GEC_BLT); } else { VIASETREG(VIA_REG_DSTPOS, ((y << 16) | x)); VIASETREG(VIA_REG_DIMENSION, ((len - 1) << 16)); VIASETREG(VIA_REG_GECMD, pVia->SavedCmd | VIA_GEC_BLT); } } static void VIASetupForDashedLine( ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask, int length, unsigned char *pattern) { VIAPtr pVia = VIAPTR(pScrn); int cmd; CARD32 pat = *(CARD32 *)pattern; cmd = VIA_GEC_LINE | VIA_GEC_FIXCOLOR_PAT | (XAAGetPatternROP(rop) << 24); if (bg == -1) { /* transparent mono pattern */ cmd |= VIA_GEC_MPAT_TRANS; } pVia->SavedCmd = cmd; pVia->SavedFgColor = fg; pVia->SavedBgColor = bg; switch (length) { case 2: pat |= pat << 2; /* fall through */ case 4: pat |= pat << 4; /* fall through */ case 8: pat |= pat << 8; /* fall through */ case 16: pat |= pat << 16; } pVia->SavedPattern0 = pat; VIASETREG(VIA_REG_FGCOLOR, pVia->SavedFgColor); VIASETREG(VIA_REG_BGCOLOR, pVia->SavedBgColor); VIASETREG(VIA_REG_MONOPAT0, pVia->SavedPattern0); } static void VIASubsequentDashedTwoPointLine( ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int flags, int phase) { VIAPtr pVia = VIAPTR(pScrn); int dx, dy, cmd, tmp, error = 1; cmd = pVia->SavedCmd; dx = x2 - x1; if (dx < 0) { dx = -dx; cmd |= VIA_GEC_DECX; /* line will be drawn from right */ error = 0; } dy = y2 - y1; if (dy < 0) { dy = -dy; cmd |= VIA_GEC_DECY; /* line will be drawn from bottom */ } if (dy > dx) { tmp = dy; dy = dx; dx = tmp; /* Swap 'dx' and 'dy' */ cmd |= VIA_GEC_Y_MAJOR; /* Y major line */ } if (flags & OMIT_LAST) { cmd |= VIA_GEC_LASTPIXEL_OFF; } /* Set Src and Dst base address and pitch, pitch is qword */ VIASETREG(VIA_REG_SRCBASE, 0x0); VIASETREG(VIA_REG_DSTBASE, 0x0); VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE | ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); /* major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1) */ /* K1 = 2*dmin K2 = 2*(dmin - dmax) */ /* Error Term = (StartXSavedCmd |= VIA_GEC_CLIP_ENABLE; } static void VIADisableClipping(ScrnInfoPtr pScrn) { VIAPtr pVia = VIAPTR(pScrn); #ifdef DEBUG_EXTRA ErrorF("Kill ClipRect\n"); #endif pVia->SavedCmd &= ~VIA_GEC_CLIP_ENABLE; }