/* * Copyright 1992-2003 by Alan Hourihane, North Wales, UK. * * 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 Alan Hourihane not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Alan Hourihane makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL ALAN HOURIHANE 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: Alan Hourihane, * * CyberBladeXP4 accelerated options. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xf86.h" #include "xf86_OSproc.h" #include "xf86Pci.h" #include "miline.h" #include "trident.h" #include "trident_regs.h" #ifdef HAVE_XAA_H #include "xaarop.h" static void XP4Sync(ScrnInfoPtr pScrn); #if 0 static void XP4SetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask, int length, unsigned char *pattern); static void XP4SubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, int x, int y, int dmaj, int dmin, int e, int len, int octant, int phase); static void XP4SetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask); static void XP4SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, int x, int y, int dmaj, int dmin, int e, int len, int octant); #endif static void XP4SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir); static void XP4SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask); static void XP4SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h); static void XP4SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h); static void XP4SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned int planemask, int transparency_color); static void XP4SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, int fg, int bg, int rop, unsigned int planemask); static void XP4SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx, int patterny, int x, int y, int w, int h); static void XP4SetupForCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask); static void XP4SubsequentCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft); static int bpp; static int ropcode; static void XP4InitializeAccelerator(ScrnInfoPtr pScrn) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); int shift; /* This forces updating the clipper */ pTrident->Clipping = TRUE; CHECKCLIPPING; switch (pScrn->bitsPerPixel) { case 8: default: /* Muffle compiler */ shift = 18; break; case 16: shift = 19; break; case 32: shift = 20; break; } switch (pScrn->bitsPerPixel) { case 8: bpp = 0x40; break; case 16: bpp = 0x41; break; case 32: bpp = 0x42; break; } MMIO_OUT32(pTrident->IOBase, 0x2154, (pScrn->displayWidth) << shift); MMIO_OUT32(pTrident->IOBase, 0x2150, (pScrn->displayWidth) << shift); } #endif Bool XP4XaaInit(ScreenPtr pScreen) { #ifdef HAVE_XAA_H XAAInfoRecPtr infoPtr; ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); TRIDENTPtr pTrident = TRIDENTPTR(pScrn); if (pTrident->NoAccel) return FALSE; pTrident->AccelInfoRec = infoPtr = XAACreateInfoRec(); if (!infoPtr) return FALSE; infoPtr->Flags = PIXMAP_CACHE | OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER; pTrident->InitializeAccelerator = XP4InitializeAccelerator; XP4InitializeAccelerator(pScrn); infoPtr->Sync = XP4Sync; #if 0 /* TO DO for the XP */ infoPtr->SolidLineFlags = NO_PLANEMASK; infoPtr->SetupForSolidLine = XP4SetupForSolidLine; infoPtr->SolidBresenhamLineErrorTermBits = 12; infoPtr->SubsequentSolidBresenhamLine = XP4SubsequentSolidBresenhamLine; infoPtr->DashedLineFlags = LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | NO_PLANEMASK | LINE_PATTERN_POWER_OF_2_ONLY; infoPtr->SetupForDashedLine = XP4SetupForDashedLine; infoPtr->DashedBresenhamLineErrorTermBits = 12; infoPtr->SubsequentDashedBresenhamLine = XP4SubsequentDashedBresenhamLine; infoPtr->DashPatternMaxLength = 16; #endif infoPtr->SolidFillFlags = NO_PLANEMASK; infoPtr->SetupForSolidFill = XP4SetupForFillRectSolid; infoPtr->SubsequentSolidFillRect = XP4SubsequentFillRectSolid; #if 0 infoPtr->SubsequentSolidHorVertLine = XP4SubsequentSolidHorVertLine; #endif infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | NO_TRANSPARENCY; infoPtr->SetupForScreenToScreenCopy = XP4SetupForScreenToScreenCopy; infoPtr->SubsequentScreenToScreenCopy = XP4SubsequentScreenToScreenCopy; infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK | HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN | BIT_ORDER_IN_BYTE_MSBFIRST; infoPtr->SetupForMono8x8PatternFill = XP4SetupForMono8x8PatternFill; infoPtr->SubsequentMono8x8PatternFillRect = XP4SubsequentMono8x8PatternFillRect; #if 0 infoPtr->CPUToScreenColorExpandFillFlags = NO_PLANEMASK | BIT_ORDER_IN_BYTE_MSBFIRST; infoPtr->ColorExpandBase = pTrident->D3Base; infoPtr->ColorExpandRange = pScrn->displayWidth; infoPtr->SetupForCPUToScreenColorExpandFill = XP4SetupForCPUToScreenColorExpandFill; infoPtr->SubsequentCPUToScreenColorExpandFill = XP4SubsequentCPUToScreenColorExpandFill; #endif return(XAAInit(pScreen, infoPtr)); #else return FALSE; #endif } #ifdef HAVE_XAA_H static void XP4Sync(ScrnInfoPtr pScrn) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); int count = 0, timeout = 0; int busy; for (;;) { BLTBUSY(busy); if (busy != GE_BUSY) { return; } count++; if (count == 10000000) { ErrorF("XP: BitBLT engine time-out.\n"); count = 9990000; timeout++; if (timeout == 4) { /* Reset BitBLT Engine */ TGUI_STATUS(0x00); return; } } } } static void XP4SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned int planemask, int transparency_color) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); int dst = 0; pTrident->BltScanDirection = 0; if (xdir < 0) pTrident->BltScanDirection |= XNEG; if (ydir < 0) pTrident->BltScanDirection |= YNEG; REPLICATE(transparency_color); if (transparency_color != -1) { dst |= 3<<16; MMIO_OUT32(pTrident->IOBase, 0x2134, transparency_color); } ropcode = rop; MMIO_OUT32(pTrident->IOBase, 0x2128, pTrident->BltScanDirection | SCR2SCR); } static void XP4SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); if (pTrident->BltScanDirection & YNEG) { y1 = y1 + h - 1; y2 = y2 + h - 1; } if (pTrident->BltScanDirection & XNEG) { x1 = x1 + w - 1; x2 = x2 + w - 1; } MMIO_OUT32(pTrident->IOBase, 0x2138, x2<<16 | y2); MMIO_OUT32(pTrident->IOBase, 0x213C, x1<<16 | y1); MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h); XP4Sync(pScrn); MMIO_OUT32(pTrident->IOBase, 0x2124, XAAGetCopyROP(ropcode) << 24 | bpp << 8 | 1); } #if 0 static void XP4SetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); pTrident->BltScanDirection = 0; REPLICATE(color); TGUI_FMIX(XAAPatternROP[rop]); if (pTrident->Chipset >= PROVIDIA9685) { TGUI_FPATCOL(color); } else { TGUI_FCOLOUR(color); } } static void XP4SubsequentSolidBresenhamLine( ScrnInfoPtr pScrn, int x, int y, int dmaj, int dmin, int e, int len, int octant) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); int tmp = pTrident->BltScanDirection; if (octant & YMAJOR) tmp |= YMAJ; if (octant & XDECREASING) tmp |= XNEG; if (octant & YDECREASING) tmp |= YNEG; TGUI_DRAWFLAG(SOLIDFILL | STENCIL | tmp); XP_SRC_XY(dmin-dmaj,dmin); XP_DEST_XY(x,y); XP_DIM_XY(dmin+e,len); TGUI_COMMAND(GE_BRESLINE); XP4Sync(pScrn); } #endif static void XP4SubsequentSolidHorVertLine( ScrnInfoPtr pScrn, int x, int y, int len, int dir ){ TRIDENTPtr pTrident = TRIDENTPTR(pScrn); TGUI_DRAWFLAG(SOLIDFILL); if (dir == DEGREES_0) { XP_DIM_XY(len,1); XP_DEST_XY(x,y); } else { XP_DIM_XY(1,len); XP_DEST_XY(x,y); } TGUI_COMMAND(GE_BLT); XP4Sync(pScrn); } #if 0 void XP4SetupForDashedLine( ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask, int length, unsigned char *pattern ){ TRIDENTPtr pTrident = TRIDENTPTR(pScrn); CARD32 *DashPattern = (CARD32*)pattern; CARD32 NiceDashPattern = DashPattern[0]; NiceDashPattern = *((CARD16 *)pattern) & ((1<BltScanDirection = 0; REPLICATE(fg); if (pTrident->Chipset >= PROVIDIA9685) { TGUI_FPATCOL(fg); if (bg == -1) { pTrident->BltScanDirection |= 1<<12; TGUI_BPATCOL(~fg); } else { REPLICATE(bg); TGUI_BPATCOL(bg); } } else { TGUI_FCOLOUR(fg); if (bg == -1) { pTrident->BltScanDirection |= 1<<12; TGUI_BCOLOUR(~fg); } else { REPLICATE(bg); TGUI_BCOLOUR(bg); } } TGUI_FMIX(XAAPatternROP[rop]); pTrident->LinePattern = NiceDashPattern; } void XP4SubsequentDashedBresenhamLine(ScrnInfoPtr pScrn, int x, int y, int dmaj, int dmin, int e, int len, int octant, int phase) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); int tmp = pTrident->BltScanDirection; if (octant & YMAJOR) tmp |= YMAJ; if (octant & XDECREASING) tmp |= XNEG; if (octant & YDECREASING) tmp |= YNEG; TGUI_STYLE(((pTrident->LinePattern >> phase) | (pTrident->LinePattern << (16-phase))) & 0x0000FFFF); TGUI_DRAWFLAG(STENCIL | tmp); XP_SRC_XY(dmin-dmaj,dmin); XP_DEST_XY(x,y); XP_DIM_XY(e+dmin,len); TGUI_COMMAND(GE_BRESLINE); XP4Sync(pScrn); } #endif static void XP4SetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); ropcode = rop; REPLICATE(color); MMIO_OUT32(pTrident->IOBase, 0x2158, color); MMIO_OUT32(pTrident->IOBase, 0x2128, 1<<14); } static void XP4SubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); MMIO_OUT32(pTrident->IOBase, 0x2138, x<<16 | y); MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h); XP4Sync(pScrn); MMIO_OUT32(pTrident->IOBase, 0x2124, XAAGetPatternROP(ropcode) << 24 | bpp << 8 | 2); } #if 1 static void MoveDWORDS( register CARD32* dest, register CARD32* src, register int dwords ) { while(dwords & ~0x03) { *dest = *src; *(dest + 1) = *(src + 1); *(dest + 2) = *(src + 2); *(dest + 3) = *(src + 3); src += 4; dest += 4; dwords -= 4; } if (!dwords) return; *dest = *src; dest += 1; src += 1; if (dwords == 1) return; *dest = *src; dest += 1; src += 1; if (dwords == 2) return; *dest = *src; dest += 1; src += 1; } #endif #if 1 static void MoveDWORDS_FixedBase( register CARD32* dest, register CARD32* src, register int dwords ) { while(dwords & ~0x03) { *dest = *src; *dest = *(src + 1); *dest = *(src + 2); *dest = *(src + 3); dwords -= 4; src += 4; } if(!dwords) return; *dest = *src; if(dwords == 1) return; *dest = *(src + 1); if(dwords == 2) return; *dest = *(src + 2); } #endif static void XP4SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, int fg, int bg, int rop, unsigned int planemask) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); int drawflag = 0; REPLICATE(fg); MMIO_OUT32(pTrident->IOBase, 0x2158, fg); if (bg == -1) { drawflag |= 1<<12; MMIO_OUT32(pTrident->IOBase, 0x215C, ~fg); } else { REPLICATE(bg); MMIO_OUT32(pTrident->IOBase, 0x215C, bg); } ropcode = rop; drawflag |= 7<<18; TGUI_DRAWFLAG(PATMONO | drawflag); } static void XP4SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx, int patterny, int x, int y, int w, int h) { TRIDENTPtr pTrident = TRIDENTPTR(pScrn); MMIO_OUT32(pTrident->IOBase, 0x2180, patternx); MMIO_OUT32(pTrident->IOBase, 0x2184, patterny); MMIO_OUT32(pTrident->IOBase, 0x2138, x<<16 | y); MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h); XP4Sync(pScrn); MMIO_OUT32(pTrident->IOBase, 0x2124, XAAGetPatternROP(ropcode) << 24 | bpp << 8 | 2); } #if 1 static void XP4SetupForCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask ){ TRIDENTPtr pTrident = TRIDENTPTR(pScrn); ropcode = XAAGetCopyROP(rop); #if 0 TGUI_FMIX(XAACopyROP[rop]); #endif if (bg == -1) { TGUI_DRAWFLAG(SRCMONO | 1<<12); REPLICATE(fg); TGUI_FCOLOUR(fg); } else { TGUI_DRAWFLAG(SRCMONO); REPLICATE(fg); REPLICATE(bg); TGUI_FCOLOUR(fg); TGUI_BCOLOUR(bg); } } static void XP4SubsequentCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft ){ TRIDENTPtr pTrident = TRIDENTPTR(pScrn); MMIO_OUT32(pTrident->IOBase, 0x2138, x<<16 | y); MMIO_OUT32(pTrident->IOBase, 0x2140, w<<16 | h); XP4Sync(pScrn); MMIO_OUT32(pTrident->IOBase, 0x2124, ropcode << 24 | bpp << 8 | 2); } #endif #endif