tga_accel.c revision 7706df26
17706df26Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tga/tga_accel.c,v 1.15 2001/11/21 22:32:59 alanh Exp $ */ 27706df26Smrg 37706df26Smrg/* 47706df26Smrg * Copyright 1996,1997 by Alan Hourihane, Wigan, England. 57706df26Smrg * 67706df26Smrg * Permission to use, copy, modify, distribute, and sell this software and its 77706df26Smrg * documentation for any purpose is hereby granted without fee, provided that 87706df26Smrg * the above copyright notice appear in all copies and that both that 97706df26Smrg * copyright notice and this permission notice appear in supporting 107706df26Smrg * documentation, and that the name of Alan Hourihane not be used in 117706df26Smrg * advertising or publicity pertaining to distribution of the software without 127706df26Smrg * specific, written prior permission. Alan Hourihane makes no representations 137706df26Smrg * about the suitability of this software for any purpose. It is provided 147706df26Smrg * "as is" without express or implied warranty. 157706df26Smrg * 167706df26Smrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 177706df26Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 187706df26Smrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 197706df26Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 207706df26Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 217706df26Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 227706df26Smrg * PERFORMANCE OF THIS SOFTWARE. 237706df26Smrg * 247706df26Smrg * Author: Alan Hourihane, alanh@fairlite.demon.co.uk 257706df26Smrg * 267706df26Smrg * DEC TGA accelerated options. 277706df26Smrg */ 287706df26Smrg 297706df26Smrg#ifdef HAVE_CONFIG_H 307706df26Smrg#include "config.h" 317706df26Smrg#endif 327706df26Smrg 337706df26Smrg#include "fb.h" 347706df26Smrg#include "micmap.h" 357706df26Smrg#include "xf86.h" 367706df26Smrg#include "xf86_OSproc.h" 377706df26Smrg#include "xf86PciInfo.h" 387706df26Smrg#include "xf86Pci.h" 397706df26Smrg#include "xf86cmap.h" 407706df26Smrg#include "mipointer.h" 417706df26Smrg 427706df26Smrg#include "mibstore.h" 437706df26Smrg#include "miline.h" 447706df26Smrg 457706df26Smrg#include "tga_regs.h" 467706df26Smrg#include "BT.h" 477706df26Smrg#include "tga.h" 487706df26Smrg 497706df26Smrg/* defines */ 507706df26Smrg 517706df26Smrg#define BLIT_FORWARDS 0 527706df26Smrg#define BLIT_BACKWARDS 1 537706df26Smrg#define USE_BLOCK_FILL 2 547706df26Smrg#define USE_OPAQUE_FILL 3 557706df26Smrg#define MIX_SRC 0x03 567706df26Smrg 577706df26Smrg#define CE_BUFSIZE 256 587706df26Smrg 597706df26Smrg#define FB_OFFSET(x, y) (((long)(y) * pScrn->displayWidth * (pTga->Bpp)) + (long)(x) * pTga->Bpp) 607706df26Smrg 617706df26Smrg/* prototypes */ 627706df26Smrg 637706df26Smrgstatic void TGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, 647706df26Smrg int y2, int w); 657706df26Smrgstatic void TGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, 667706df26Smrg int y2, int w); 677706df26Smrgextern void TGASync(ScrnInfoPtr pScrn); 687706df26Smrgstatic void TGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 697706df26Smrg unsigned int planemask); 707706df26Smrgstatic void TGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h); 717706df26Smrgstatic void TGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 727706df26Smrg int rop, unsigned int planemask, 737706df26Smrg int transparency_color); 747706df26Smrgstatic void TGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, 757706df26Smrg int x2, int y2, int w, int h); 767706df26Smrgstatic void TGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, 777706df26Smrg int fg, int bg, int rop, 787706df26Smrg unsigned int planemask); 797706df26Smrgstatic void TGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, 807706df26Smrg int paty, int x, int y, int w, 817706df26Smrg int h); 827706df26Smrgstatic void TGASetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 837706df26Smrg int fg, int bg, 847706df26Smrg int rop, 857706df26Smrg unsigned int planemask); 867706df26Smrg 877706df26Smrgstatic void 887706df26SmrgTGASubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 897706df26Smrg int x, int y, int w, 907706df26Smrg int h, int skipleft); 917706df26Smrgstatic void 927706df26SmrgTGASubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); 937706df26Smrg 947706df26Smrg 957706df26Smrg/* 967706df26Smrg * The following function sets up the supported acceleration. Call it 977706df26Smrg * from the FbInit() function in the SVGA driver. 987706df26Smrg */ 997706df26SmrgBool 1007706df26SmrgDEC21030AccelInit(ScreenPtr pScreen) 1017706df26Smrg{ 1027706df26Smrg XAAInfoRecPtr TGA_AccelInfoRec; 1037706df26Smrg BoxRec AvailFBArea; 1047706df26Smrg ScrnInfoPtr pScrn; 1057706df26Smrg TGAPtr pTga; 1067706df26Smrg 1077706df26Smrg pScrn = xf86Screens[pScreen->myNum]; 1087706df26Smrg pTga = TGAPTR(pScrn); 1097706df26Smrg 1107706df26Smrg /* ErrorF("DEC21030AccelInit called!"); */ 1117706df26Smrg 1127706df26Smrg /* first, create the XAAInfoRec */ 1137706df26Smrg TGA_AccelInfoRec = XAACreateInfoRec(); 1147706df26Smrg 1157706df26Smrg /* ErrorF("XAACreateInfoRec called"); */ 1167706df26Smrg 1177706df26Smrg if(pScrn->depth == 8) { 1187706df26Smrg pTga->depthflag = BPP8PACKED; 1197706df26Smrg pTga->Bpp = 1; 1207706df26Smrg } else { 1217706df26Smrg pTga->depthflag = BPP24; 1227706df26Smrg pTga->Bpp = 4; 1237706df26Smrg } 1247706df26Smrg 1257706df26Smrg TGA_AccelInfoRec->Flags = PIXMAP_CACHE | LINEAR_FRAMEBUFFER | 1267706df26Smrg OFFSCREEN_PIXMAPS; 1277706df26Smrg 1287706df26Smrg TGA_AccelInfoRec->Sync = TGASync; 1297706df26Smrg 1307706df26Smrg /* solid fill */ 1317706df26Smrg 1327706df26Smrg TGA_AccelInfoRec->SolidFillFlags = 0; 1337706df26Smrg TGA_AccelInfoRec->SetupForSolidFill = TGASetupForSolidFill; 1347706df26Smrg TGA_AccelInfoRec->SubsequentSolidFillRect = TGASubsequentSolidFillRect; 1357706df26Smrg 1367706df26Smrg /* screen to screen copy */ 1377706df26Smrg TGA_AccelInfoRec->ScreenToScreenCopyFlags = NO_TRANSPARENCY; 1387706df26Smrg TGA_AccelInfoRec->SetupForScreenToScreenCopy = 1397706df26Smrg TGASetupForScreenToScreenCopy; 1407706df26Smrg TGA_AccelInfoRec->SubsequentScreenToScreenCopy = 1417706df26Smrg TGASubsequentScreenToScreenCopy; 1427706df26Smrg 1437706df26Smrg /* mono 8x8 pattern fill */ 1447706df26Smrg 1457706df26Smrg TGA_AccelInfoRec->Mono8x8PatternFillFlags = 1467706df26Smrg HARDWARE_PATTERN_PROGRAMMED_BITS | BIT_ORDER_IN_BYTE_LSBFIRST; 1477706df26Smrg TGA_AccelInfoRec->SetupForMono8x8PatternFill = 1487706df26Smrg TGASetupForMono8x8PatternFill; 1497706df26Smrg TGA_AccelInfoRec->SubsequentMono8x8PatternFillRect = 1507706df26Smrg TGASubsequentMono8x8PatternFillRect; 1517706df26Smrg 1527706df26Smrg /* color expand */ 1537706df26Smrg /* does not work for 32bpp (yet) */ 1547706df26Smrg TGA_AccelInfoRec->ScanlineCPUToScreenColorExpandFillFlags = 1557706df26Smrg BIT_ORDER_IN_BYTE_LSBFIRST; 1567706df26Smrg 1577706df26Smrg TGA_AccelInfoRec->NumScanlineColorExpandBuffers = 1; 1587706df26Smrg pTga->buffers[0] = (CARD32 *)xnfalloc(CE_BUFSIZE); 1597706df26Smrg TGA_AccelInfoRec->ScanlineColorExpandBuffers = 1607706df26Smrg (unsigned char **)pTga->buffers; 1617706df26Smrg TGA_AccelInfoRec->SetupForScanlineCPUToScreenColorExpandFill = 1627706df26Smrg TGASetupForScanlineCPUToScreenColorExpandFill; 1637706df26Smrg TGA_AccelInfoRec->SubsequentScanlineCPUToScreenColorExpandFill = 1647706df26Smrg TGASubsequentScanlineCPUToScreenColorExpandFill; 1657706df26Smrg TGA_AccelInfoRec->SubsequentColorExpandScanline = 1667706df26Smrg TGASubsequentColorExpandScanline; 1677706df26Smrg 1687706df26Smrg /* lines */ 1697706df26Smrg 1707706df26Smrg TGA_AccelInfoRec->PolylinesThinSolid = TGAPolyLines; 1717706df26Smrg if(pTga->NoXaaPolySegment == FALSE) 1727706df26Smrg TGA_AccelInfoRec->PolySegmentThinSolid = TGAPolySegment; 1737706df26Smrg TGA_AccelInfoRec->PolylinesThinSolidFlags = 0x0; 1747706df26Smrg TGA_AccelInfoRec->PolySegmentThinSolidFlags = 0x0; 1757706df26Smrg 1767706df26Smrg TGA_AccelInfoRec->PolylinesThinDashed = TGAPolyLinesDashed; 1777706df26Smrg if(pTga->NoXaaPolySegment == FALSE) 1787706df26Smrg TGA_AccelInfoRec->PolySegmentThinDashed = TGAPolySegmentDashed; 1797706df26Smrg TGA_AccelInfoRec->PolylinesThinDashedFlags = 0x0; 1807706df26Smrg TGA_AccelInfoRec->PolySegmentThinDashedFlags = 0x0; 1817706df26Smrg TGA_AccelInfoRec->DashedLineFlags = LINE_PATTERN_LSBFIRST_LSBJUSTIFIED; 1827706df26Smrg TGA_AccelInfoRec->DashPatternMaxLength = 16; 1837706df26Smrg 1847706df26Smrg /* initialize the pixmap cache */ 1857706df26Smrg 1867706df26Smrg AvailFBArea.x1 = 0; 1877706df26Smrg AvailFBArea.y1 = 0; /* these gotta be 0 */ 1887706df26Smrg AvailFBArea.x2 = pScrn->displayWidth; 1897706df26Smrg AvailFBArea.y2 = (pScrn->videoRam * 1024) / (pScrn->displayWidth * 1907706df26Smrg pTga->Bpp); 1917706df26Smrg xf86InitFBManager(pScreen, &AvailFBArea); 1927706df26Smrg 1937706df26Smrg TGA_AccelInfoRec->PixmapCacheFlags = 0; 1947706df26Smrg 1957706df26Smrg /* initialize XAA */ 1967706df26Smrg return(XAAInit(pScreen, TGA_AccelInfoRec)); 1977706df26Smrg} 1987706df26Smrg 1997706df26Smrgstatic void 2007706df26SmrgTGASetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 2017706df26Smrg int fg, int bg, int rop, 2027706df26Smrg unsigned int planemask) 2037706df26Smrg{ 2047706df26Smrg#ifdef PROFILE 2057706df26Smrg unsigned int start, stop; 2067706df26Smrg#endif 2077706df26Smrg TGAPtr pTga = NULL; 2087706df26Smrg unsigned int fgcolor = 0, bgcolor = 0, pmask = 0; 2097706df26Smrg TGA_DECL(); 2107706df26Smrg 2117706df26Smrg pTga = TGAPTR(pScrn); 2127706df26Smrg TGA_GET_IOBASE(); 2137706df26Smrg TGA_GET_OFFSET(); 2147706df26Smrg 2157706df26Smrg/* ErrorF("TGASetupForScanlineCPUToScreenColorExpandFill called\n"); */ 2167706df26Smrg if(pTga->depthflag == BPP8PACKED) { 2177706df26Smrg fgcolor = (fg | (fg << 8) | (fg << 16) | (fg << 24)); 2187706df26Smrg bgcolor = bg | (bg << 8) | (bg << 16) | (bg << 24); 2197706df26Smrg pmask = planemask | (planemask << 8) | (planemask << 16) 2207706df26Smrg | (planemask << 24); 2217706df26Smrg } 2227706df26Smrg else { 2237706df26Smrg bgcolor = bg; 2247706df26Smrg fgcolor = fg; 2257706df26Smrg pmask = planemask; 2267706df26Smrg } 2277706df26Smrg pTga->current_rop = rop | pTga->depthflag; 2287706df26Smrg 2297706df26Smrg if(bg == -1) { 2307706df26Smrg pTga->transparent_pattern_p = 1; 2317706df26Smrg if(rop == MIX_SRC) { 2327706df26Smrg pTga->block_or_opaque_p = USE_BLOCK_FILL; 2337706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG); 2347706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG); 2357706df26Smrg if(pTga->depthflag == BPP24) { 2367706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG); 2377706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG); 2387706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG); 2397706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG); 2407706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG); 2417706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG); 2427706df26Smrg } 2437706df26Smrg } 2447706df26Smrg else { 2457706df26Smrg pTga->block_or_opaque_p = USE_OPAQUE_FILL; 2467706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 2477706df26Smrg } 2487706df26Smrg } 2497706df26Smrg else { 2507706df26Smrg pTga->transparent_pattern_p = 0; 2517706df26Smrg TGA_FAST_WRITE_REG(bgcolor, TGA_BACKGROUND_REG); 2527706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 2537706df26Smrg } 2547706df26Smrg TGA_FAST_WRITE_REG(pmask, TGA_PLANEMASK_REG); /* we know when to 2557706df26Smrg reset this */ 2567706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 2577706df26Smrg 2587706df26Smrg TGA_SAVE_OFFSET(); 2597706df26Smrg 2607706df26Smrg return; 2617706df26Smrg} 2627706df26Smrg 2637706df26Smrgstatic void 2647706df26SmrgTGASubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, 2657706df26Smrg int x, int y, int w, 2667706df26Smrg int h, int skipleft) 2677706df26Smrg{ 2687706df26Smrg#ifdef PROFILE 2697706df26Smrg unsigned int start, stop; 2707706df26Smrg#endif 2717706df26Smrg TGAPtr pTga; 2727706df26Smrg TGA_DECL(); 2737706df26Smrg 2747706df26Smrg pTga = TGAPTR(pScrn); 2757706df26Smrg TGA_GET_IOBASE(); 2767706df26Smrg TGA_GET_OFFSET(); 2777706df26Smrg 2787706df26Smrg/* ErrorF("TGASubsequentScanlineCPUToScreenColorExpandFill called\n"); */ 2797706df26Smrg/* ErrorF("w = %d, h = %d\n", w, h); */ 2807706df26Smrg 2817706df26Smrg pTga->ce_height = h; 2827706df26Smrg pTga->ce_width = w; 2837706df26Smrg pTga->ce_x = x; 2847706df26Smrg pTga->ce_y = y; 2857706df26Smrg pTga->ce_skipleft = skipleft; 2867706df26Smrg/* ErrorF("skipleft is %d\n", skipleft); */ 2877706df26Smrg 2887706df26Smrg if(pTga->transparent_pattern_p) { 2897706df26Smrg if(pTga->block_or_opaque_p == USE_BLOCK_FILL) 2907706df26Smrg TGA_FAST_WRITE_REG(BLOCKSTIPPLE | X11 | pTga->depthflag, 2917706df26Smrg TGA_MODE_REG); 2927706df26Smrg else 2937706df26Smrg TGA_FAST_WRITE_REG(TRANSPARENTSTIPPLE | X11 | pTga->depthflag, 2947706df26Smrg TGA_MODE_REG); 2957706df26Smrg/* ErrorF("transparent stipple with x = %d, y = %d, w = %d, h = %d\n", */ 2967706df26Smrg/* x, y, w, h); */ 2977706df26Smrg } 2987706df26Smrg else 2997706df26Smrg TGA_FAST_WRITE_REG(OPAQUESTIPPLE | X11 | pTga->depthflag, 3007706df26Smrg TGA_MODE_REG); 3017706df26Smrg 3027706df26Smrg TGA_SAVE_OFFSET(); 3037706df26Smrg return; 3047706df26Smrg} 3057706df26Smrg 3067706df26Smrgstatic void 3077706df26SmrgTGASubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) 3087706df26Smrg{ 3097706df26Smrg#ifdef PROFILE 3107706df26Smrg unsigned int start, stop; 3117706df26Smrg#endif 3127706df26Smrg TGAPtr pTga; 3137706df26Smrg unsigned char *p = NULL; 3147706df26Smrg int width = 0; 3157706df26Smrg unsigned int addr; 3167706df26Smrg unsigned int pixelmask = 0; 3177706df26Smrg unsigned int stipple; 3187706df26Smrg unsigned int align_mask; 3197706df26Smrg int align = 0; 3207706df26Smrg int skipleft; 3217706df26Smrg 3227706df26Smrg CARD32 c = 0, d = 0; 3237706df26Smrg CARD32 *e = NULL; 3247706df26Smrg int i = 0, num_dwords = 0; 3257706df26Smrg TGA_DECL(); 3267706df26Smrg 3277706df26Smrg pTga = TGAPTR(pScrn); 3287706df26Smrg TGA_GET_IOBASE(); 3297706df26Smrg TGA_GET_OFFSET(); 3307706df26Smrg 3317706df26Smrg align_mask = (pTga->depthflag == BPP24) ? 0x0f : 0x03; 3327706df26Smrg 3337706df26Smrg#if 0 3347706df26Smrg ErrorF("TGASubsequentColorExpandScanline called\n"); 3357706df26Smrg if(pTga->transparent_pattern_p) 3367706df26Smrg ErrorF("transparent color expand\n"); 3377706df26Smrg#endif 3387706df26Smrg 3397706df26Smrg p = (unsigned char *)pTga->buffers[0]; 3407706df26Smrg addr = FB_OFFSET(pTga->ce_x, pTga->ce_y); 3417706df26Smrg width = pTga->ce_width; 3427706df26Smrg skipleft = pTga->ce_skipleft; 3437706df26Smrg 3447706df26Smrg while(width > 0) { 3457706df26Smrg if(!pTga->transparent_pattern_p) 3467706df26Smrg pixelmask = 0xFFFFFFFF; 3477706df26Smrg 3487706df26Smrg align = (addr & align_mask) / pTga->Bpp; /* no. pixels out of align */ 3497706df26Smrg if (align) { 3507706df26Smrg if (!pTga->transparent_pattern_p) 3517706df26Smrg pixelmask <<= align; 3527706df26Smrg/* ErrorF("alignment is %d\n", align); */ 3537706df26Smrg addr -= align * pTga->Bpp; 3547706df26Smrg width += align; 3557706df26Smrg 3567706df26Smrg e = (CARD32 *)p; 3577706df26Smrg num_dwords = (width / 32) + 1; 3587706df26Smrg if(num_dwords > (CE_BUFSIZE / 4)) { /* shouldn't happen */ 3597706df26Smrg ErrorF("TGASubsequentColorExpandScanline passed scanline %d bytes long, truncating\n", num_dwords * 4); 3607706df26Smrg num_dwords = CE_BUFSIZE / 4; 3617706df26Smrg } 3627706df26Smrg for(i = 0; i < num_dwords; i++) { 3637706df26Smrg c = e[i]; 3647706df26Smrg if(i == 0) 3657706df26Smrg e[i] = c << align; 3667706df26Smrg else 3677706df26Smrg e[i] = (d >> (32 - align)) | (c << align); 3687706df26Smrg d = c; 3697706df26Smrg } 3707706df26Smrg } 3717706df26Smrg 3727706df26Smrg if (!pTga->transparent_pattern_p) { 3737706df26Smrg if (skipleft) { 3747706df26Smrg pixelmask <<= skipleft; 3757706df26Smrg skipleft = 0; 3767706df26Smrg } 3777706df26Smrg if (width < 32) { 3787706df26Smrg pixelmask &= (0xFFFFFFFF >> (32 - width)); 3797706df26Smrg } 3807706df26Smrg TGA_FAST_WRITE_REG(pixelmask, TGA_PIXELMASK_REG); 3817706df26Smrg } 3827706df26Smrg else { 3837706df26Smrg unsigned int *i = NULL; 3847706df26Smrg 3857706df26Smrg/* ErrorF("transparent scanline with x = %d, y = %d, w = %d, h = %d\n", pTga->ce_x, pTga->ce_y, pTga->ce_width, pTga->ce_height); */ 3867706df26Smrg if (skipleft) { 3877706df26Smrg i = (unsigned int *)p; 3887706df26Smrg *i &= (0xFFFFFFFF << skipleft); 3897706df26Smrg skipleft = 0; 3907706df26Smrg } 3917706df26Smrg if (width < 32) { 3927706df26Smrg i = (unsigned int *)p; 3937706df26Smrg *i &= (0xFFFFFFFF >> (32 - width)); 3947706df26Smrg } 3957706df26Smrg } 3967706df26Smrg 3977706df26Smrg stipple = *((unsigned int *)p); 3987706df26Smrg switch (pTga->Chipset) { 3997706df26Smrg case PCI_CHIP_TGA2: 4007706df26Smrg *(unsigned int *)(pTga->FbBase + addr) = stipple; WMB; 4017706df26Smrg break; 4027706df26Smrg case PCI_CHIP_DEC21030: 4037706df26Smrg TGA_FAST_WRITE_REG(addr, TGA_ADDRESS_REG); 4047706df26Smrg TGA_FAST_WRITE_REG(stipple, TGA_CONTINUE_REG); 4057706df26Smrg } 4067706df26Smrg addr += 32 * pTga->Bpp; 4077706df26Smrg p += 4; 4087706df26Smrg width -= 32; 4097706df26Smrg } 4107706df26Smrg pTga->ce_height--; 4117706df26Smrg if(pTga->ce_height == 0) { 4127706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, 4137706df26Smrg TGA_MODE_REG); 4147706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 4157706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 4167706df26Smrg } 4177706df26Smrg else 4187706df26Smrg pTga->ce_y += 1; 4197706df26Smrg 4207706df26Smrg TGA_SAVE_OFFSET(); 4217706df26Smrg return; 4227706df26Smrg} 4237706df26Smrg 4247706df26Smrg/* Block Fill mode is faster, but only works for certain rops. So we will 4257706df26Smrg have to implement Opaque Fill anyway, so we will do that first, then 4267706df26Smrg do Block Fill for the special cases 4277706df26Smrg*/ 4287706df26Smrgvoid 4297706df26SmrgTGASetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 4307706df26Smrg unsigned int planemask) 4317706df26Smrg{ 4327706df26Smrg#ifdef PROFILE 4337706df26Smrg unsigned int start, stop; 4347706df26Smrg#endif 4357706df26Smrg TGAPtr pTga; 4367706df26Smrg unsigned int fgcolor = 0, pmask = 0; 4377706df26Smrg TGA_DECL(); 4387706df26Smrg 4397706df26Smrg pTga = TGAPTR(pScrn); 4407706df26Smrg TGA_GET_IOBASE(); 4417706df26Smrg TGA_GET_OFFSET(); 4427706df26Smrg /* ErrorF("TGASetupForSolidFill called"); */ 4437706df26Smrg 4447706df26Smrg if(pTga->depthflag == BPP8PACKED) { 4457706df26Smrg fgcolor = color | (color << 8) | (color << 16) | (color << 24); 4467706df26Smrg pmask = planemask | (planemask << 8) | (planemask << 16) | 4477706df26Smrg (planemask << 24); 4487706df26Smrg } 4497706df26Smrg else { 4507706df26Smrg fgcolor = color; 4517706df26Smrg pmask = planemask; 4527706df26Smrg } 4537706df26Smrg 4547706df26Smrg 4557706df26Smrg if(rop == MIX_SRC) { /* we can just do a block copy */ 4567706df26Smrg pTga->block_or_opaque_p = USE_BLOCK_FILL; 4577706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG); 4587706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG); 4597706df26Smrg if(pTga->depthflag == BPP24) { 4607706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG); 4617706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG); 4627706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG); 4637706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG); 4647706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG); 4657706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG); 4667706df26Smrg } 4677706df26Smrg } 4687706df26Smrg else { 4697706df26Smrg pTga->block_or_opaque_p = USE_OPAQUE_FILL; 4707706df26Smrg pTga->current_rop = rop | pTga->depthflag; 4717706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 4727706df26Smrg/* ErrorF("opaque fill called\n"); */ 4737706df26Smrg } 4747706df26Smrg 4757706df26Smrg pTga->current_planemask = pmask; 4767706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_DATA_REG); 4777706df26Smrg TGA_SAVE_OFFSET(); 4787706df26Smrg return; 4797706df26Smrg} 4807706df26Smrg 4817706df26Smrgvoid 4827706df26SmrgTGASubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 4837706df26Smrg{ 4847706df26Smrg unsigned int mode_reg = 0; 4857706df26Smrg int i = 0; 4867706df26Smrg unsigned int pixel_count = 0; /* the actual # of pixels to be written */ 4877706df26Smrg unsigned int write_data = 0; /* the actual data written */ 4887706df26Smrg int a1 = 0; 4897706df26Smrg#ifdef PROFILE 4907706df26Smrg unsigned int stop, start; 4917706df26Smrg#endif 4927706df26Smrg TGAPtr pTga; 4937706df26Smrg TGA_DECL(); 4947706df26Smrg 4957706df26Smrg pTga = TGAPTR(pScrn); 4967706df26Smrg TGA_GET_IOBASE(); 4977706df26Smrg TGA_GET_OFFSET(); 4987706df26Smrg 4997706df26Smrg /* ErrorF("TGASubsequentFillRectSolid called\n"); */ 5007706df26Smrg 5017706df26Smrg if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) { 5027706df26Smrg mode_reg = OPAQUEFILL | X11 | pTga->depthflag; 5037706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 5047706df26Smrg /* we have to set this to GXCOPY every time before we exit */ 5057706df26Smrg } 5067706df26Smrg else 5077706df26Smrg mode_reg = BLOCKFILL | X11 | pTga->depthflag; 5087706df26Smrg 5097706df26Smrg TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG); 5107706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 5117706df26Smrg 5127706df26Smrg if(w > 2048) { 5137706df26Smrg ErrorF("TGASubsequentSolidFillRect called with w = %d, truncating.\n", w); 5147706df26Smrg w = 2048; 5157706df26Smrg } 5167706df26Smrg pixel_count = w - 1; 5177706df26Smrg 5187706df26Smrg for(i = 0; i < h; i++) { 5197706df26Smrg a1 = FB_OFFSET(x, y + i); 5207706df26Smrg if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) 5217706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG); 5227706df26Smrg write_data = pixel_count; 5237706df26Smrg TGA_FAST_WRITE_REG(a1, TGA_ADDRESS_REG); 5247706df26Smrg TGA_FAST_WRITE_REG(write_data, TGA_CONTINUE_REG); 5257706df26Smrg } 5267706df26Smrg 5277706df26Smrg mode_reg = SIMPLE | X11 | pTga->depthflag; 5287706df26Smrg TGA_FAST_WRITE_REG(mode_reg, TGA_MODE_REG); 5297706df26Smrg if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) 5307706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, 5317706df26Smrg TGA_RASTEROP_REG); /* GXCOPY */ 5327706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 5337706df26Smrg 5347706df26Smrg TGA_SAVE_OFFSET(); 5357706df26Smrg return; 5367706df26Smrg} 5377706df26Smrg 5387706df26Smrg/* we only need to calculate the direction of a move once per move, 5397706df26Smrg so we do it in the setup function and leave it */ 5407706df26Smrg 5417706df26Smrgvoid 5427706df26SmrgTGASetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, 5437706df26Smrg int rop, unsigned int planemask, 5447706df26Smrg int transparency_color) 5457706df26Smrg /* xdir 1 = left-to-right, -1 = right to left 5467706df26Smrg ydir 1 = top-to-bottom, -1 = bottom to top 5477706df26Smrg */ 5487706df26Smrg{ 5497706df26Smrg#ifdef PROFILE 5507706df26Smrg unsigned int start, stop; 5517706df26Smrg#endif 5527706df26Smrg TGAPtr pTga; 5537706df26Smrg unsigned int pmask = 0; 5547706df26Smrg TGA_DECL(); 5557706df26Smrg 5567706df26Smrg pTga = TGAPTR(pScrn); 5577706df26Smrg TGA_GET_IOBASE(); 5587706df26Smrg TGA_GET_OFFSET(); 5597706df26Smrg 5607706df26Smrg /* see section 6.2.9 */ 5617706df26Smrg 5627706df26Smrg if (pTga->depthflag == BPP8PACKED) { 5637706df26Smrg pmask = planemask | (planemask << 8) | (planemask << 16) | 5647706df26Smrg (planemask << 24); 5657706df26Smrg } 5667706df26Smrg else 5677706df26Smrg pmask = planemask; 5687706df26Smrg 5697706df26Smrg pTga->current_planemask = pmask; 5707706df26Smrg TGA_FAST_WRITE_REG(pmask, TGA_PLANEMASK_REG); 5717706df26Smrg 5727706df26Smrg pTga->current_rop = rop | pTga->depthflag; 5737706df26Smrg 5747706df26Smrg /* do we copy a rectangle from top to bottom or bottom to top? */ 5757706df26Smrg if (ydir == -1) { 5767706df26Smrg pTga->blitdir = BLIT_FORWARDS; 5777706df26Smrg } 5787706df26Smrg else { 5797706df26Smrg pTga->blitdir = BLIT_BACKWARDS; 5807706df26Smrg } 5817706df26Smrg TGA_SAVE_OFFSET(); 5827706df26Smrg return; 5837706df26Smrg} 5847706df26Smrg 5857706df26Smrg/* 5867706df26Smrg * This is the implementation of the SubsequentForScreenToScreenCopy 5877706df26Smrg * that sends commands to the coprocessor to perform a screen-to-screen 5887706df26Smrg * copy of the specified areas, with the parameters from the SetUp call. 5897706df26Smrg */ 5907706df26Smrgvoid 5917706df26SmrgTGASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, 5927706df26Smrg int y2, int w, int h) 5937706df26Smrg{ 5947706df26Smrg /* x1, y1 = source coords 5957706df26Smrg x2, y2 = destination coords 5967706df26Smrg w = width 5977706df26Smrg h = height 5987706df26Smrg */ 5997706df26Smrg 6007706df26Smrg int i = 0; 6017706df26Smrg void (*copy_func)(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w); 6027706df26Smrg#ifdef PROFILE 6037706df26Smrg unsigned int stop, start; 6047706df26Smrg#endif 6057706df26Smrg TGAPtr pTga; 6067706df26Smrg TGA_DECL(); 6077706df26Smrg 6087706df26Smrg pTga = TGAPTR(pScrn); 6097706df26Smrg TGA_GET_IOBASE(); 6107706df26Smrg TGA_GET_OFFSET(); 6117706df26Smrg#if 0 6127706df26Smrg ErrorF("TGASubsequentScreenToScreenCopy(,%d,%d,%d,%d,%d,%d):" 6137706df26Smrg " COPY %s BLIT %s\n", 6147706df26Smrg x1, y1, x2, y2, w, h, (x2 > x1 && (x1 + w) > x2)?"BWD":"FWD", 6157706df26Smrg (pTga->blitdir == BLIT_FORWARDS)?"FWD":"BWD"); 6167706df26Smrg#endif 6177706df26Smrg TGASync(pScrn); /* ?? */ 6187706df26Smrg 6197706df26Smrg TGA_FAST_WRITE_REG(COPY | X11 | pTga->depthflag, TGA_MODE_REG); 6207706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 6217706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 6227706df26Smrg 6237706df26Smrg if(x2 > x1 && (x1 + w) > x2) 6247706df26Smrg copy_func = TGACopyLineBackwards; 6257706df26Smrg else 6267706df26Smrg copy_func = TGACopyLineForwards; 6277706df26Smrg 6287706df26Smrg TGA_SAVE_OFFSET(); 6297706df26Smrg if(pTga->blitdir == BLIT_FORWARDS) { 6307706df26Smrg for(i = h - 1; i >= 0; i--) { /* copy from bottom to top */ 6317706df26Smrg (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w); 6327706df26Smrg } 6337706df26Smrg } 6347706df26Smrg else { 6357706df26Smrg for(i = 0; i < h; i++) { 6367706df26Smrg (*copy_func)(pScrn, x1, y1 + i, x2, y2 + i, w); 6377706df26Smrg } 6387706df26Smrg } 6397706df26Smrg 6407706df26Smrg TGASync(pScrn); /* ?? */ 6417706df26Smrg 6427706df26Smrg TGA_GET_OFFSET(); 6437706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 6447706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 6457706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 6467706df26Smrg TGA_SAVE_OFFSET(); 6477706df26Smrg 6487706df26Smrg return; 6497706df26Smrg} 6507706df26Smrg 6517706df26Smrg 6527706df26Smrgvoid 6537706df26SmrgTGACopyLineForwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w) 6547706df26Smrg{ 6557706df26Smrg /* copy a line of width w from x1,y1 to x2,y2 using copy mode */ 6567706df26Smrg int read; 6577706df26Smrg unsigned long source_address, destination_address; 6587706df26Smrg unsigned int mask_source, mask_destination; 6597706df26Smrg int cando; 6607706df26Smrg unsigned int cando_mask; 6617706df26Smrg int source_align, destination_align; 6627706df26Smrg int pixel_shift; 6637706df26Smrg#ifdef PROFILE 6647706df26Smrg unsigned int start, stop; 6657706df26Smrg#endif 6667706df26Smrg TGAPtr pTga; 6677706df26Smrg TGA_DECL(); 6687706df26Smrg 6697706df26Smrg pTga = TGAPTR(pScrn); 6707706df26Smrg TGA_GET_IOBASE(); 6717706df26Smrg TGA_GET_OFFSET(); 6727706df26Smrg 6737706df26Smrg cando = 32; 6747706df26Smrg cando_mask = 0xFFFFFFFFU; 6757706df26Smrg if (pTga->Chipset == PCI_CHIP_DEC21030 && pTga->depthflag == BPP24) { 6767706df26Smrg cando = 16; 6777706df26Smrg cando_mask = 0x0000FFFFU; 6787706df26Smrg } 6797706df26Smrg 6807706df26Smrg source_address = FB_OFFSET(x1, y1); 6817706df26Smrg destination_address = FB_OFFSET(x2, y2); 6827706df26Smrg#if 0 6837706df26Smrg ErrorF("CPY-FWD(,%d,%d,%d,%d,%d): sadr = 0x%lx, dadr = 0x%lx\n", 6847706df26Smrg x1, y1, x2, y2, w, source_address, destination_address); 6857706df26Smrg#endif 6867706df26Smrg read = 0; 6877706df26Smrg while (read < w) { 6887706df26Smrg 6897706df26Smrg mask_source = cando_mask; 6907706df26Smrg if ((w - read) >= cando) 6917706df26Smrg mask_destination = cando_mask; 6927706df26Smrg else 6937706df26Smrg mask_destination = cando_mask >> (cando - (w - read)); 6947706df26Smrg 6957706df26Smrg source_align = source_address & 0x07; 6967706df26Smrg source_address -= source_align; 6977706df26Smrg mask_source <<= source_align / pTga->Bpp; 6987706df26Smrg /* mask_source &= cando_mask; */ 6997706df26Smrg 7007706df26Smrg destination_align = destination_address & 0x07; 7017706df26Smrg destination_address -= destination_align; 7027706df26Smrg mask_destination <<= destination_align / pTga->Bpp; 7037706df26Smrg /* mask_destination &= cando_mask; */ 7047706df26Smrg 7057706df26Smrg if (destination_align >= source_align) 7067706df26Smrg pixel_shift = destination_align - source_align; 7077706df26Smrg else { 7087706df26Smrg pixel_shift = 8 - (source_align - destination_align); 7097706df26Smrg /* we need to prime the residue register in this case */ 7107706df26Smrg destination_address -= 8; 7117706df26Smrg mask_destination <<= 8 / pTga->Bpp; 7127706df26Smrg mask_destination &= cando_mask;/* ?? */ 7137706df26Smrg } 7147706df26Smrg 7157706df26Smrg TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG); 7167706df26Smrg switch (pTga->Chipset) { 7177706df26Smrg case PCI_CHIP_TGA2: 7187706df26Smrg *(unsigned int *)(pTga->FbBase + source_address) = mask_source; WMB; 7197706df26Smrg *(unsigned int *)(pTga->FbBase + destination_address) = mask_destination; WMB; 7207706df26Smrg break; 7217706df26Smrg case PCI_CHIP_DEC21030: 7227706df26Smrg /* use GADR and GCTR */ 7237706df26Smrg TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG); 7247706df26Smrg TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG); 7257706df26Smrg TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG); 7267706df26Smrg TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG); 7277706df26Smrg break; 7287706df26Smrg } 7297706df26Smrg 7307706df26Smrg source_address += (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp; 7317706df26Smrg destination_address += cando * pTga->Bpp; 7327706df26Smrg 7337706df26Smrg read += cando; 7347706df26Smrg read -= destination_align / pTga->Bpp; /* "read" is perhaps better 7357706df26Smrg called "written"... */ 7367706df26Smrg if (destination_align < source_align) { 7377706df26Smrg read -= 8 / pTga->Bpp; 7387706df26Smrg } 7397706df26Smrg } 7407706df26Smrg 7417706df26Smrg TGA_SAVE_OFFSET(); 7427706df26Smrg return; 7437706df26Smrg} 7447706df26Smrg 7457706df26Smrg 7467706df26Smrgvoid 7477706df26SmrgTGACopyLineBackwards(ScrnInfoPtr pScrn, int x1, int y1, int x2, 7487706df26Smrg int y2, int w) 7497706df26Smrg /* x1, y1 = source 7507706df26Smrg x2, y2 = destination 7517706df26Smrg w = width 7527706df26Smrg */ 7537706df26Smrg{ 7547706df26Smrg unsigned long a1, a2; 7557706df26Smrg unsigned long source_address, destination_address; 7567706df26Smrg unsigned int mask_source, mask_destination; 7577706df26Smrg int cando; 7587706df26Smrg unsigned int cando_mask; 7597706df26Smrg int source_align, destination_align; 7607706df26Smrg int pixel_shift; 7617706df26Smrg int read; 7627706df26Smrg#ifdef PROFILE 7637706df26Smrg unsigned int start, stop; 7647706df26Smrg#endif 7657706df26Smrg TGAPtr pTga; 7667706df26Smrg TGA_DECL(); 7677706df26Smrg 7687706df26Smrg pTga = TGAPTR(pScrn); 7697706df26Smrg TGA_GET_IOBASE(); 7707706df26Smrg TGA_GET_OFFSET(); 7717706df26Smrg 7727706df26Smrg cando = 32; 7737706df26Smrg cando_mask = 0xFFFFFFFFU; 7747706df26Smrg if (pTga->Chipset == PCI_CHIP_DEC21030 && pTga->depthflag == BPP24) { 7757706df26Smrg cando = 16; 7767706df26Smrg cando_mask = 0x0000FFFFU; 7777706df26Smrg } 7787706df26Smrg 7797706df26Smrg a1 = FB_OFFSET(x1, y1); 7807706df26Smrg a2 = FB_OFFSET(x2, y2); 7817706df26Smrg 7827706df26Smrg source_address = FB_OFFSET((x1 + w) - cando, y1); 7837706df26Smrg destination_address = FB_OFFSET((x2 + w) - cando, y2); 7847706df26Smrg 7857706df26Smrg#if 0 7867706df26Smrg ErrorF("CPY-BWD(,%d,%d,%d,%d,%d): sadr = 0x%lx, dadr = 0x%lx" 7877706df26Smrg " a1 0x%lx a2 0x%lx\n", 7887706df26Smrg x1, y1, x2, y2, w, source_address, destination_address, a1, a2); 7897706df26Smrg#endif 7907706df26Smrg 7917706df26Smrg read = 0; 7927706df26Smrg while (read < w) { 7937706df26Smrg mask_source = cando_mask; 7947706df26Smrg if ((w - read) >= cando) 7957706df26Smrg mask_destination = cando_mask; 7967706df26Smrg else { 7977706df26Smrg mask_destination = ((unsigned int)cando_mask) << (cando - (w - read)); 7987706df26Smrg mask_destination &= cando_mask; /* esp. for cando==16 */ 7997706df26Smrg } 8007706df26Smrg 8017706df26Smrg source_align = source_address & 0x07; 8027706df26Smrg destination_align = destination_address & 0x07; 8037706df26Smrg 8047706df26Smrg if (read == 0 && destination_align && 8057706df26Smrg (source_align > destination_align)) { 8067706df26Smrg /* we want to take out all the destination_align pixels in one 8077706df26Smrg little copy first, then move on to the main stuff */ 8087706df26Smrg unsigned long tmp_src, tmp_dest; 8097706df26Smrg unsigned int tmp_src_mask, tmp_dest_mask; 8107706df26Smrg 8117706df26Smrg tmp_src = a1 + (w - (source_align / pTga->Bpp)) * pTga->Bpp; 8127706df26Smrg tmp_dest = a2 + (w - (destination_align / pTga->Bpp) - (8 / pTga->Bpp)) * pTga->Bpp; 8137706df26Smrg tmp_src_mask = cando_mask; 8147706df26Smrg tmp_dest_mask = ((unsigned int)0x000000FF) >> (8 - destination_align) / pTga->Bpp; 8157706df26Smrg tmp_dest_mask <<= 8 / pTga->Bpp; 8167706df26Smrg pixel_shift = (8 - source_align) + destination_align; 8177706df26Smrg#if 0 8187706df26Smrg ErrorF("CPY-BWD - preliminary copy: sa = %d, da = %d, ps =%d\n", 8197706df26Smrg source_align, destination_align, pixel_shift); 8207706df26Smrg#endif 8217706df26Smrg TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG); 8227706df26Smrg switch (pTga->Chipset) 8237706df26Smrg { 8247706df26Smrg case PCI_CHIP_TGA2: 8257706df26Smrg *(unsigned int *)(pTga->FbBase + tmp_src) = tmp_src_mask; WMB; 8267706df26Smrg *(unsigned int *)(pTga->FbBase + tmp_dest) = tmp_dest_mask; WMB; 8277706df26Smrg break; 8287706df26Smrg case PCI_CHIP_DEC21030: 8297706df26Smrg /* use GADR and GCTR */ 8307706df26Smrg TGA_FAST_WRITE_REG(tmp_src, TGA_ADDRESS_REG); 8317706df26Smrg TGA_FAST_WRITE_REG(tmp_src_mask, TGA_CONTINUE_REG); 8327706df26Smrg TGA_FAST_WRITE_REG(tmp_dest, TGA_ADDRESS_REG); 8337706df26Smrg TGA_FAST_WRITE_REG(tmp_dest_mask, TGA_CONTINUE_REG); 8347706df26Smrg break; 8357706df26Smrg } 8367706df26Smrg 8377706df26Smrg source_address += (8 - source_align); 8387706df26Smrg mask_source >>= (8 - source_align) / pTga->Bpp; 8397706df26Smrg mask_source >>= destination_align / pTga->Bpp; 8407706df26Smrg mask_destination >>= destination_align / pTga->Bpp; 8417706df26Smrg } 8427706df26Smrg else if (read == 0 && (source_align != destination_align)) { 8437706df26Smrg source_address += (8 - source_align); 8447706df26Smrg /* mask_source >>= (8 - source_align); */ 8457706df26Smrg /* if we uncomment this, it breaks...TGA tries to 8467706df26Smrg optimize away a read of our last pixels... */ 8477706df26Smrg } 8487706df26Smrg else if (source_align) { 8497706df26Smrg source_address += (8 - source_align); 8507706df26Smrg mask_source >>= (8 - source_align) / pTga->Bpp; 8517706df26Smrg } 8527706df26Smrg 8537706df26Smrg if (destination_align) { 8547706df26Smrg destination_address += (8 - destination_align); 8557706df26Smrg mask_destination >>= (8 - destination_align) / pTga->Bpp; 8567706df26Smrg } 8577706df26Smrg 8587706df26Smrg if (destination_align >= source_align) 8597706df26Smrg pixel_shift = destination_align - source_align; 8607706df26Smrg else { 8617706df26Smrg pixel_shift = (8 - source_align) + destination_align; 8627706df26Smrg if (destination_align) { 8637706df26Smrg source_address += 8; 8647706df26Smrg mask_source >>= 8 / pTga->Bpp; 8657706df26Smrg } 8667706df26Smrg } 8677706df26Smrg 8687706df26Smrg#if 0 8697706df26Smrg ErrorF("CPY-BWD - normal: sadr 0x%lx sm 0x%x dadr 0x%lx dm 0x%x" 8707706df26Smrg " sa %d da %d ps %d read %d\n", 8717706df26Smrg source_address, mask_source, 8727706df26Smrg destination_address, mask_destination, 8737706df26Smrg source_align, destination_align, pixel_shift, read); 8747706df26Smrg#endif 8757706df26Smrg TGA_FAST_WRITE_REG(pixel_shift, TGA_PIXELSHIFT_REG); 8767706df26Smrg switch (pTga->Chipset) { 8777706df26Smrg case PCI_CHIP_TGA2: 8787706df26Smrg *(unsigned int *)(pTga->FbBase + source_address) = mask_source; WMB; 8797706df26Smrg *(unsigned int *)(pTga->FbBase + destination_address) = mask_destination; WMB; 8807706df26Smrg break; 8817706df26Smrg case PCI_CHIP_DEC21030: 8827706df26Smrg /* use GADR and GCTR */ 8837706df26Smrg TGA_FAST_WRITE_REG(source_address, TGA_ADDRESS_REG); 8847706df26Smrg TGA_FAST_WRITE_REG(mask_source, TGA_CONTINUE_REG); 8857706df26Smrg TGA_FAST_WRITE_REG(destination_address, TGA_ADDRESS_REG); 8867706df26Smrg TGA_FAST_WRITE_REG(mask_destination, TGA_CONTINUE_REG); 8877706df26Smrg break; 8887706df26Smrg } 8897706df26Smrg 8907706df26Smrg/* if(read == 0) */ 8917706df26Smrg/* ErrorF("sa = %d, da = %d, ps = %d\n", source_align, destination_align, */ 8927706df26Smrg/* pixel_shift); */ 8937706df26Smrg 8947706df26Smrg if (destination_align > source_align) { 8957706df26Smrg source_address -= cando * pTga->Bpp - 8; 8967706df26Smrg destination_address -= (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp; 8977706df26Smrg if (read == 0) 8987706df26Smrg read += (cando - 8 / pTga->Bpp) + source_align / pTga->Bpp; 8997706df26Smrg else 9007706df26Smrg read += cando - 8 / pTga->Bpp; 9017706df26Smrg } 9027706df26Smrg else if (destination_align == source_align) { 9037706df26Smrg source_address -= cando * pTga->Bpp; 9047706df26Smrg destination_address -= cando * pTga->Bpp; 9057706df26Smrg if (read == 0 && destination_align) 9067706df26Smrg read += (cando - (8 - destination_align) / pTga->Bpp); 9077706df26Smrg else 9087706df26Smrg read += cando; 9097706df26Smrg } 9107706df26Smrg else if (source_align > destination_align) { 9117706df26Smrg source_address -= cando * pTga->Bpp - 8; 9127706df26Smrg destination_address -= (cando - (pixel_shift / pTga->Bpp)) * pTga->Bpp; 9137706df26Smrg /* only happens when read == 0 */ 9147706df26Smrg if (destination_align) 9157706df26Smrg read += (cando - 16 / pTga->Bpp) + source_align / pTga->Bpp; 9167706df26Smrg else 9177706df26Smrg read += cando - pixel_shift / pTga->Bpp; 9187706df26Smrg } 9197706df26Smrg } 9207706df26Smrg 9217706df26Smrg TGA_SAVE_OFFSET(); 9227706df26Smrg return; 9237706df26Smrg} 9247706df26Smrg 9257706df26Smrgvoid 9267706df26SmrgTGASetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, 9277706df26Smrg int fg, int bg, int rop, unsigned int planemask) 9287706df26Smrg{ 9297706df26Smrg#ifdef PROFILE 9307706df26Smrg unsigned int start, stop; 9317706df26Smrg#endif 9327706df26Smrg TGAPtr pTga; 9337706df26Smrg unsigned int fgcolor = 0, bgcolor = 0, pmask = 0; 9347706df26Smrg TGA_DECL(); 9357706df26Smrg 9367706df26Smrg pTga = TGAPTR(pScrn); 9377706df26Smrg TGA_GET_IOBASE(); 9387706df26Smrg TGA_GET_OFFSET(); 9397706df26Smrg 9407706df26Smrg/* ErrorF("TGASetupForMono8x8PatternFill called with patx = %d, paty = %d, fg = %d, bg = %d, rop = %d, planemask = %d\n", */ 9417706df26Smrg/* patx, paty, fg, bg, rop, planemask); */ 9427706df26Smrg 9437706df26Smrg if(bg == -1) /* we are transparent */ 9447706df26Smrg pTga->transparent_pattern_p = 1; 9457706df26Smrg else 9467706df26Smrg pTga->transparent_pattern_p = 0; 9477706df26Smrg 9487706df26Smrg if(rop == MIX_SRC) 9497706df26Smrg pTga->block_or_opaque_p = USE_BLOCK_FILL; 9507706df26Smrg else 9517706df26Smrg pTga->block_or_opaque_p = USE_OPAQUE_FILL; 9527706df26Smrg 9537706df26Smrg if(pTga->depthflag == BPP8PACKED) { 9547706df26Smrg fgcolor = fg | (fg << 8) | (fg << 16) | (fg << 24); 9557706df26Smrg bgcolor = bg | (bg << 8) | (bg << 16) | (bg << 24); 9567706df26Smrg pmask = planemask | (planemask << 8) | (planemask << 16) | 9577706df26Smrg (planemask << 24); 9587706df26Smrg } 9597706df26Smrg else { 9607706df26Smrg fgcolor = fg; 9617706df26Smrg bgcolor = bg; 9627706df26Smrg pmask = planemask; 9637706df26Smrg } 9647706df26Smrg 9657706df26Smrg 9667706df26Smrg if(pTga->transparent_pattern_p && 9677706df26Smrg pTga->block_or_opaque_p == USE_BLOCK_FILL) { 9687706df26Smrg /* we can use block fill mode to draw a transparent stipple */ 9697706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR0_REG); 9707706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR1_REG); 9717706df26Smrg if(pTga->depthflag == BPP24) { 9727706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR2_REG); 9737706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR3_REG); 9747706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR4_REG); 9757706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR5_REG); 9767706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR6_REG); 9777706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_BLOCK_COLOR7_REG); 9787706df26Smrg } 9797706df26Smrg } 9807706df26Smrg else if(pTga->transparent_pattern_p) { 9817706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 9827706df26Smrg } 9837706df26Smrg else { 9847706df26Smrg TGA_FAST_WRITE_REG(bgcolor, TGA_BACKGROUND_REG); 9857706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 9867706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PIXELMASK_REG); 9877706df26Smrg } 9887706df26Smrg pTga->current_rop = rop; 9897706df26Smrg pTga->current_planemask = pmask; 9907706df26Smrg TGA_SAVE_OFFSET(); 9917706df26Smrg return; 9927706df26Smrg} 9937706df26Smrg 9947706df26Smrgvoid 9957706df26SmrgTGASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty, 9967706df26Smrg int x, int y, int w, int h) 9977706df26Smrg/* patx and paty = first & second dwords of pattern to be rendered, packed */ 9987706df26Smrg{ 9997706df26Smrg TGAPtr pTga; 10007706df26Smrg int i, j; 10017706df26Smrg unsigned int stipple_mask[8], align, tmp; 10027706df26Smrg#ifdef PROFILE 10037706df26Smrg register unsigned int stop, start; 10047706df26Smrg#endif 10057706df26Smrg TGA_DECL(); 10067706df26Smrg 10077706df26Smrg 10087706df26Smrg/* ErrorF("TGASubsequentMono8x8PatternFillRect called with x = %d, y = %d, w = %d, h = %d\n", x, y, w, h); */ 10097706df26Smrg 10107706df26Smrg pTga = TGAPTR(pScrn); 10117706df26Smrg TGA_GET_IOBASE(); 10127706df26Smrg TGA_GET_OFFSET(); 10137706df26Smrg 10147706df26Smrg if(w > 2048) 10157706df26Smrg ErrorF("TGASubsequentMono8x8PatternFillRect called with w > 2048, truncating\n"); 10167706df26Smrg if(pTga->block_or_opaque_p == USE_OPAQUE_FILL) 10177706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 10187706df26Smrg 10197706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 10207706df26Smrg if(pTga->depthflag == BPP8PACKED) 10217706df26Smrg align = FB_OFFSET(x, y) % 4; 10227706df26Smrg else 10237706df26Smrg align = x % 4; 10247706df26Smrg 10257706df26Smrg for(i = 0; i < 4; i++) { 10267706df26Smrg tmp = (patx >> (i * 8)) & 0xFF; 10277706df26Smrg stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24)); 10287706df26Smrg } 10297706df26Smrg for(i = 4; i < 8; i++) { 10307706df26Smrg tmp = (paty >> ((i - 4) * 8)) & 0xFF; 10317706df26Smrg stipple_mask[i] = (tmp | (tmp << 8) | (tmp << 16) | (tmp << 24)); 10327706df26Smrg } 10337706df26Smrg if(align) { /* stipples must be aligned to four bytes */ 10347706df26Smrg for(i = 0; i < 8; i++) { 10357706df26Smrg stipple_mask[i] = (stipple_mask[i] << align) | 10367706df26Smrg ((stipple_mask[i] & 0xFF000000) >> (32 - align)); 10377706df26Smrg } 10387706df26Smrg } 10397706df26Smrg 10407706df26Smrg if((pTga->block_or_opaque_p == USE_BLOCK_FILL) && pTga->transparent_pattern_p) { 10417706df26Smrg /* use block fill */ 10427706df26Smrg TGA_FAST_WRITE_REG(BLOCKFILL | X11 | pTga->depthflag, TGA_MODE_REG); 10437706df26Smrg 10447706df26Smrg for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { 10457706df26Smrg TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG); 10467706df26Smrg TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG); 10477706df26Smrg TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG); 10487706df26Smrg } 10497706df26Smrg } 10507706df26Smrg else if(pTga->transparent_pattern_p) { 10517706df26Smrg /* if we can't use block fill, we'll use transparent fill */ 10527706df26Smrg TGA_FAST_WRITE_REG(TRANSPARENTFILL | X11 | pTga->depthflag, TGA_MODE_REG); 10537706df26Smrg for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { 10547706df26Smrg TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG); 10557706df26Smrg TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG); 10567706df26Smrg TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG); 10577706df26Smrg } 10587706df26Smrg } 10597706df26Smrg else { /* use opaque fill mode */ 10607706df26Smrg/* ErrorF("Using opaque fill mode\n"); */ 10617706df26Smrg TGA_FAST_WRITE_REG(OPAQUEFILL | X11 | pTga->depthflag, TGA_MODE_REG); 10627706df26Smrg for(i = 0, j = 0; i < h; i++, (j == 7) ? (j = 0) : (j++)) { 10637706df26Smrg TGA_FAST_WRITE_REG(stipple_mask[j], TGA_DATA_REG); 10647706df26Smrg TGA_FAST_WRITE_REG(FB_OFFSET(x, y + i), TGA_ADDRESS_REG); 10657706df26Smrg TGA_FAST_WRITE_REG(w - 1, TGA_CONTINUE_REG); 10667706df26Smrg } 10677706df26Smrg } 10687706df26Smrg 10697706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 10707706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 10717706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 10727706df26Smrg 10737706df26Smrg TGA_SAVE_OFFSET(); 10747706df26Smrg 10757706df26Smrg return; 10767706df26Smrg} 10777706df26Smrg 10787706df26Smrgvoid 10797706df26SmrgTGASetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, 10807706df26Smrg unsigned int planemask) 10817706df26Smrg{ 10827706df26Smrg#ifdef PROFILE 10837706df26Smrg unsigned int start, stop; 10847706df26Smrg#endif 10857706df26Smrg TGAPtr pTga = NULL; 10867706df26Smrg unsigned int fgcolor = 0, pmask = 0; 10877706df26Smrg TGA_DECL(); 10887706df26Smrg 10897706df26Smrg pTga = TGAPTR(pScrn); 10907706df26Smrg TGA_GET_IOBASE(); 10917706df26Smrg TGA_GET_OFFSET(); 10927706df26Smrg/* ErrorF("TGASetupForSolidLine called\n"); */ 10937706df26Smrg 10947706df26Smrg if(pTga->depthflag == BPP8PACKED) { 10957706df26Smrg fgcolor = color | (color << 8) | (color << 16) | (color << 24); 10967706df26Smrg pmask = planemask | (planemask << 8) | (planemask << 16) | 10977706df26Smrg (planemask << 24); 10987706df26Smrg } 10997706df26Smrg else { 11007706df26Smrg fgcolor = color; 11017706df26Smrg pmask = planemask; 11027706df26Smrg } 11037706df26Smrg 11047706df26Smrg 11057706df26Smrg pTga->current_rop = rop | pTga->depthflag; 11067706df26Smrg TGA_FAST_WRITE_REG(fgcolor, TGA_FOREGROUND_REG); 11077706df26Smrg pTga->current_planemask = pmask; 11087706df26Smrg TGA_FAST_WRITE_REG(0xFFFF, TGA_DATA_REG); 11097706df26Smrg TGA_FAST_WRITE_REG(pScrn->displayWidth, TGA_WIDTH_REG); 11107706df26Smrg TGA_SAVE_OFFSET(); 11117706df26Smrg 11127706df26Smrg return; 11137706df26Smrg} 11147706df26Smrg 11157706df26Smrgvoid 11167706df26SmrgTGASubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, 11177706df26Smrg int dir) 11187706df26Smrg{ 11197706df26Smrg if(dir == DEGREES_0) /* line is to the right */ 11207706df26Smrg TGASubsequentSolidLine(pScrn, x, y, x + len, y, 0x0, OMIT_LAST); 11217706df26Smrg else if(dir == DEGREES_270) /* line is down */ 11227706df26Smrg TGASubsequentSolidLine(pScrn, x, y, x, y + len, YMAJOR, OMIT_LAST); 11237706df26Smrg else 11247706df26Smrg ErrorF("TGASubsequentSolidHorVertLine passed dir %d!\n", dir); 11257706df26Smrg 11267706df26Smrg return; 11277706df26Smrg} 11287706df26Smrg 11297706df26Smrgvoid 11307706df26SmrgTGASubsequentSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, 11317706df26Smrg int octant, int flags) 11327706df26Smrg{ 11337706df26Smrg#ifdef PROFILE 11347706df26Smrg unsigned int start, stop; 11357706df26Smrg#endif 11367706df26Smrg TGAPtr pTga = NULL; 11377706df26Smrg CARD32 abs_dx = 0, abs_dy = 0, address = 0, octant_reg = 0; 11387706df26Smrg int length = 0; 11397706df26Smrg TGA_DECL(); 11407706df26Smrg 11417706df26Smrg pTga = TGAPTR(pScrn); 11427706df26Smrg TGA_GET_IOBASE(); 11437706df26Smrg TGA_GET_OFFSET(); 11447706df26Smrg/* ErrorF("TGASubsequentSolidLine called\n"); */ 11457706df26Smrg 11467706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 11477706df26Smrg TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag | 11487706df26Smrg ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), TGA_MODE_REG); 11497706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 11507706df26Smrg 11517706df26Smrg address = FB_OFFSET(x1, y1); 11527706df26Smrg TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); 11537706df26Smrg abs_dx = abs(x2 - x1); 11547706df26Smrg abs_dy = abs(y2 - y1); 11557706df26Smrg if(octant & YMAJOR) 11567706df26Smrg length = abs_dy; 11577706df26Smrg else 11587706df26Smrg length = abs_dx; 11597706df26Smrg 11607706df26Smrg if(octant & YMAJOR) { 11617706df26Smrg if(octant & YDECREASING) { 11627706df26Smrg if(octant & XDECREASING) 11637706df26Smrg octant_reg = TGA_SLOPE0_REG; 11647706df26Smrg else 11657706df26Smrg octant_reg = TGA_SLOPE2_REG; 11667706df26Smrg } 11677706df26Smrg else { 11687706df26Smrg if(octant & XDECREASING) 11697706df26Smrg octant_reg = TGA_SLOPE1_REG; 11707706df26Smrg else 11717706df26Smrg octant_reg = TGA_SLOPE3_REG; 11727706df26Smrg } 11737706df26Smrg } 11747706df26Smrg else { 11757706df26Smrg if(octant & YDECREASING) { 11767706df26Smrg if(octant & XDECREASING) 11777706df26Smrg octant_reg = TGA_SLOPE4_REG; 11787706df26Smrg else 11797706df26Smrg octant_reg = TGA_SLOPE6_REG; 11807706df26Smrg } 11817706df26Smrg else { 11827706df26Smrg if(octant & XDECREASING) 11837706df26Smrg octant_reg = TGA_SLOPE5_REG; 11847706df26Smrg else 11857706df26Smrg octant_reg = TGA_SLOPE7_REG; 11867706df26Smrg } 11877706df26Smrg } 11887706df26Smrg 11897706df26Smrg TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg); 11907706df26Smrg if(length > 16 && length % 16) 11917706df26Smrg length -= length % 16; 11927706df26Smrg else 11937706df26Smrg length -= 16; 11947706df26Smrg 11957706df26Smrg while(length > 0) { 11967706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_CONTINUE_REG); 11977706df26Smrg length -= 16; 11987706df26Smrg } 11997706df26Smrg 12007706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 12017706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 12027706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 12037706df26Smrg 12047706df26Smrg TGA_SAVE_OFFSET(); 12057706df26Smrg 12067706df26Smrg return; 12077706df26Smrg} 12087706df26Smrg 12097706df26Smrgvoid 12107706df26SmrgTGASetupForClippedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, 12117706df26Smrg int octant) 12127706df26Smrg{ 12137706df26Smrg#ifdef PROFILE 12147706df26Smrg unsigned int start, stop; 12157706df26Smrg#endif 12167706df26Smrg TGAPtr pTga = NULL; 12177706df26Smrg CARD32 abs_dx = 0, abs_dy = 0, octant_reg = 0; 12187706df26Smrg TGA_DECL(); 12197706df26Smrg 12207706df26Smrg pTga = TGAPTR(pScrn); 12217706df26Smrg TGA_GET_IOBASE(); 12227706df26Smrg TGA_GET_OFFSET(); 12237706df26Smrg/* ErrorF("TGASetupForClippedLine called\n"); */ 12247706df26Smrg 12257706df26Smrg/* TGA_FAST_WRITE_REG(pTga->current_rop | BPP8PACKED, TGA_RASTEROP_REG); */ 12267706df26Smrg/* TGA_FAST_WRITE_REG(OPAQUELINE | X11 | BPP8PACKED, TGA_MODE_REG); */ 12277706df26Smrg 12287706df26Smrg abs_dx = abs(x2 - x1); 12297706df26Smrg abs_dy = abs(y2 - y1); 12307706df26Smrg 12317706df26Smrg if(octant & YMAJOR) { 12327706df26Smrg if(octant & YDECREASING) { 12337706df26Smrg if(octant & XDECREASING) 12347706df26Smrg octant_reg = TGA_NOSLOPE0_REG; 12357706df26Smrg else 12367706df26Smrg octant_reg = TGA_NOSLOPE2_REG; 12377706df26Smrg } 12387706df26Smrg else { 12397706df26Smrg if(octant & XDECREASING) 12407706df26Smrg octant_reg = TGA_NOSLOPE1_REG; 12417706df26Smrg else 12427706df26Smrg octant_reg = TGA_NOSLOPE3_REG; 12437706df26Smrg } 12447706df26Smrg } 12457706df26Smrg else { 12467706df26Smrg if(octant & YDECREASING) { 12477706df26Smrg if(octant & XDECREASING) 12487706df26Smrg octant_reg = TGA_NOSLOPE4_REG; 12497706df26Smrg else 12507706df26Smrg octant_reg = TGA_NOSLOPE6_REG; 12517706df26Smrg } 12527706df26Smrg else { 12537706df26Smrg if(octant & XDECREASING) 12547706df26Smrg octant_reg = TGA_NOSLOPE5_REG; 12557706df26Smrg else 12567706df26Smrg octant_reg = TGA_NOSLOPE7_REG; 12577706df26Smrg } 12587706df26Smrg } 12597706df26Smrg 12607706df26Smrg TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg); 12617706df26Smrg 12627706df26Smrg TGA_SAVE_OFFSET(); 12637706df26Smrg return; 12647706df26Smrg} 12657706df26Smrg 12667706df26Smrgvoid 12677706df26SmrgTGASubsequentClippedSolidLine(ScrnInfoPtr pScrn, int x1, int y1, int len, 12687706df26Smrg int err) 12697706df26Smrg /* we are already in line mode, now we need to 12707706df26Smrg 1) write starting pixel address to gaddr 12717706df26Smrg 2) write initial error and line length to bresenham 3 12727706df26Smrg 3) write the gctr to draw the line, and repeat for lines > 16 pixels 12737706df26Smrg 4) set mode back to simple mode 12747706df26Smrg */ 12757706df26Smrg{ 12767706df26Smrg#ifdef PROFILE 12777706df26Smrg unsigned int start, stop; 12787706df26Smrg#endif 12797706df26Smrg TGAPtr pTga = NULL; 12807706df26Smrg CARD32 address = 0; 12817706df26Smrg int length = 0; 12827706df26Smrg TGA_DECL(); 12837706df26Smrg 12847706df26Smrg pTga = TGAPTR(pScrn); 12857706df26Smrg TGA_GET_IOBASE(); 12867706df26Smrg TGA_GET_OFFSET(); 12877706df26Smrg/* ErrorF("TGASubsequentClippedSolidLine called\n"); */ 12887706df26Smrg 12897706df26Smrg address = FB_OFFSET(x1, y1); 12907706df26Smrg TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); 12917706df26Smrg 12927706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop | pTga->depthflag, TGA_RASTEROP_REG); 12937706df26Smrg TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag, TGA_MODE_REG); 12947706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 12957706df26Smrg 12967706df26Smrg length = len; 12977706df26Smrg TGA_FAST_WRITE_REG((err << 15) | (length & 0xF), TGA_BRES3_REG); 12987706df26Smrg 12997706df26Smrg while(length > 0) { 13007706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_CONTINUE_REG); 13017706df26Smrg if(length > 16 && length % 16) 13027706df26Smrg length -= length % 16; 13037706df26Smrg else 13047706df26Smrg length -= 16; 13057706df26Smrg } 13067706df26Smrg 13077706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 13087706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 13097706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 13107706df26Smrg 13117706df26Smrg TGA_SAVE_OFFSET(); 13127706df26Smrg 13137706df26Smrg return; 13147706df26Smrg 13157706df26Smrg} 13167706df26Smrg 13177706df26Smrgvoid 13187706df26SmrgTGASetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, 13197706df26Smrg unsigned int planemask, int length, 13207706df26Smrg unsigned char *pattern) 13217706df26Smrg{ 13227706df26Smrg#ifdef PROFILE 13237706df26Smrg unsigned int start = 0, stop = 0; 13247706df26Smrg#endif 13257706df26Smrg TGAPtr pTga = NULL; 13267706df26Smrg unsigned int color1 = 0, color2 = 0, pmask = 0; 13277706df26Smrg TGA_DECL(); 13287706df26Smrg 13297706df26Smrg pTga = TGAPTR(pScrn); 13307706df26Smrg TGA_GET_IOBASE(); 13317706df26Smrg TGA_GET_OFFSET(); 13327706df26Smrg/* ErrorF("TGASetupForDashedLine called\n"); */ 13337706df26Smrg 13347706df26Smrg if(pTga->depthflag == BPP8PACKED) { 13357706df26Smrg color1 = fg | (fg << 8) | (fg << 16) | (fg << 24); 13367706df26Smrg color2 = bg | (bg << 8) | (bg << 16) | (bg << 24); 13377706df26Smrg pmask = planemask | (planemask << 8) | (planemask << 16) 13387706df26Smrg | (planemask << 24); 13397706df26Smrg } 13407706df26Smrg else { 13417706df26Smrg color1 = fg; 13427706df26Smrg color2 = fg; 13437706df26Smrg pmask = planemask; 13447706df26Smrg } 13457706df26Smrg 13467706df26Smrg pTga->current_rop = rop | pTga->depthflag; 13477706df26Smrg TGA_FAST_WRITE_REG(color1, TGA_FOREGROUND_REG); 13487706df26Smrg pTga->current_planemask = pmask; 13497706df26Smrg if(bg == -1) /* transparent line */ 13507706df26Smrg pTga->transparent_pattern_p = 1; 13517706df26Smrg else { 13527706df26Smrg pTga->transparent_pattern_p = 0; 13537706df26Smrg TGA_FAST_WRITE_REG(color2, TGA_BACKGROUND_REG); 13547706df26Smrg } 13557706df26Smrg 13567706df26Smrg pTga->line_pattern = pattern[0] | (pattern[1] << 8); 13577706df26Smrg pTga->line_pattern_length = length; 13587706df26Smrg 13597706df26Smrg TGA_FAST_WRITE_REG(pScrn->displayWidth, TGA_WIDTH_REG); 13607706df26Smrg TGA_SAVE_OFFSET(); 13617706df26Smrg 13627706df26Smrg return; 13637706df26Smrg} 13647706df26Smrg 13657706df26Smrgvoid 13667706df26SmrgTGASubsequentDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, 13677706df26Smrg int y2, int octant, int flags, int phase) 13687706df26Smrg{ 13697706df26Smrg#ifdef PROFILE 13707706df26Smrg unsigned int start, stop; 13717706df26Smrg#endif 13727706df26Smrg TGAPtr pTga = NULL; 13737706df26Smrg CARD32 abs_dx = 0, abs_dy = 0, address = 0, octant_reg = 0; 13747706df26Smrg int length = 0; 13757706df26Smrg CARD16 line_mask = 0; 13767706df26Smrg int pattern_overflow = 0; 13777706df26Smrg int l = 0; 13787706df26Smrg TGA_DECL(); 13797706df26Smrg 13807706df26Smrg pTga = TGAPTR(pScrn); 13817706df26Smrg TGA_GET_IOBASE(); 13827706df26Smrg TGA_GET_OFFSET(); 13837706df26Smrg/* ErrorF("TGASubsequentDashedLine called\n"); */ 13847706df26Smrg 13857706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 13867706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 13877706df26Smrg if(pTga->transparent_pattern_p) 13887706df26Smrg TGA_FAST_WRITE_REG(TRANSPARENTLINE | X11 | pTga->depthflag | 13897706df26Smrg ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), 13907706df26Smrg TGA_MODE_REG); 13917706df26Smrg else 13927706df26Smrg TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag | 13937706df26Smrg ((flags & OMIT_LAST) ? 0x0 : CAP_ENDS), 13947706df26Smrg TGA_MODE_REG); 13957706df26Smrg 13967706df26Smrg address = FB_OFFSET(x1, y1); 13977706df26Smrg TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); 13987706df26Smrg abs_dx = abs(x2 - x1); 13997706df26Smrg abs_dy = abs(y2 - y1); 14007706df26Smrg if(abs_dx > abs_dy) 14017706df26Smrg length = abs_dx; 14027706df26Smrg else 14037706df26Smrg length = abs_dy; 14047706df26Smrg 14057706df26Smrg if(octant & YMAJOR) { 14067706df26Smrg if(octant & YDECREASING) { 14077706df26Smrg if(octant & XDECREASING) 14087706df26Smrg octant_reg = TGA_SLOPE0_REG; 14097706df26Smrg else 14107706df26Smrg octant_reg = TGA_SLOPE2_REG; 14117706df26Smrg } 14127706df26Smrg else { 14137706df26Smrg if(octant & XDECREASING) 14147706df26Smrg octant_reg = TGA_SLOPE1_REG; 14157706df26Smrg else 14167706df26Smrg octant_reg = TGA_SLOPE3_REG; 14177706df26Smrg } 14187706df26Smrg } 14197706df26Smrg else { 14207706df26Smrg if(octant & YDECREASING) { 14217706df26Smrg if(octant & XDECREASING) 14227706df26Smrg octant_reg = TGA_SLOPE4_REG; 14237706df26Smrg else 14247706df26Smrg octant_reg = TGA_SLOPE6_REG; 14257706df26Smrg } 14267706df26Smrg else { 14277706df26Smrg if(octant & XDECREASING) 14287706df26Smrg octant_reg = TGA_SLOPE5_REG; 14297706df26Smrg else 14307706df26Smrg octant_reg = TGA_SLOPE7_REG; 14317706df26Smrg } 14327706df26Smrg } 14337706df26Smrg /* set up our first pattern with phase. Keep track of if we overflow the 14347706df26Smrg pattern by pattern_overflow, and correct on the next write */ 14357706df26Smrg 14367706df26Smrg if(phase) { 14377706df26Smrg line_mask = pTga->line_pattern >> phase; 14387706df26Smrg l = (pTga->line_pattern_length - phase); 14397706df26Smrg } 14407706df26Smrg else { 14417706df26Smrg line_mask = pTga->line_pattern; 14427706df26Smrg l = pTga->line_pattern_length; 14437706df26Smrg } 14447706df26Smrg 14457706df26Smrg while(l < 16) { 14467706df26Smrg line_mask |= pTga->line_pattern << l; 14477706df26Smrg l += pTga->line_pattern_length; 14487706df26Smrg } 14497706df26Smrg pattern_overflow = l - 16; 14507706df26Smrg 14517706df26Smrg TGA_FAST_WRITE_REG(line_mask, TGA_DATA_REG); 14527706df26Smrg 14537706df26Smrg TGA_FAST_WRITE_REG(abs_dx | (abs_dy << 16), octant_reg); 14547706df26Smrg 14557706df26Smrg if(length > 16 && length % 16) 14567706df26Smrg length -= length % 16; 14577706df26Smrg else 14587706df26Smrg length -= 16; 14597706df26Smrg 14607706df26Smrg while(length > 0) { 14617706df26Smrg 14627706df26Smrg if(pattern_overflow) { 14637706df26Smrg line_mask = pTga->line_pattern >> (pTga->line_pattern_length - 14647706df26Smrg pattern_overflow); 14657706df26Smrg l = pattern_overflow; 14667706df26Smrg } 14677706df26Smrg else { 14687706df26Smrg line_mask = pTga->line_pattern; 14697706df26Smrg l = pTga->line_pattern_length; 14707706df26Smrg } 14717706df26Smrg while(l < 16) { 14727706df26Smrg line_mask |= (pTga->line_pattern << l); 14737706df26Smrg l += pTga->line_pattern_length; 14747706df26Smrg } 14757706df26Smrg pattern_overflow = l - 16; 14767706df26Smrg 14777706df26Smrg TGA_FAST_WRITE_REG(line_mask, TGA_CONTINUE_REG); 14787706df26Smrg length -= 16; 14797706df26Smrg } 14807706df26Smrg 14817706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 14827706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 14837706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 14847706df26Smrg 14857706df26Smrg TGA_SAVE_OFFSET(); 14867706df26Smrg 14877706df26Smrg return; 14887706df26Smrg} 14897706df26Smrg 14907706df26Smrgvoid 14917706df26SmrgTGASubsequentClippedDashedLine(ScrnInfoPtr pScrn, int x1, int y1, int len, 14927706df26Smrg int err, int phase) 14937706df26Smrg{ 14947706df26Smrg#ifdef PROFILE 14957706df26Smrg unsigned int start, stop; 14967706df26Smrg#endif 14977706df26Smrg TGAPtr pTga = NULL; 14987706df26Smrg CARD32 address = 0; 14997706df26Smrg int length = 0; 15007706df26Smrg CARD16 line_mask = 0; 15017706df26Smrg int pattern_overflow = 0; 15027706df26Smrg int l = 0; 15037706df26Smrg TGA_DECL(); 15047706df26Smrg 15057706df26Smrg pTga = TGAPTR(pScrn); 15067706df26Smrg TGA_GET_IOBASE(); 15077706df26Smrg TGA_GET_OFFSET(); 15087706df26Smrg /* ErrorF("TGASubsequentClippedDashedLine called\n"); */ 15097706df26Smrg 15107706df26Smrg address = FB_OFFSET(x1, y1); 15117706df26Smrg TGA_FAST_WRITE_REG(address, TGA_ADDRESS_REG); 15127706df26Smrg 15137706df26Smrg TGA_FAST_WRITE_REG(pTga->current_rop, TGA_RASTEROP_REG); 15147706df26Smrg TGA_FAST_WRITE_REG(pTga->current_planemask, TGA_PLANEMASK_REG); 15157706df26Smrg 15167706df26Smrg if(pTga->transparent_pattern_p) 15177706df26Smrg TGA_FAST_WRITE_REG(TRANSPARENTLINE | X11 | pTga->depthflag, TGA_MODE_REG); 15187706df26Smrg else 15197706df26Smrg TGA_FAST_WRITE_REG(OPAQUELINE | X11 | pTga->depthflag, TGA_MODE_REG); 15207706df26Smrg 15217706df26Smrg length = len; 15227706df26Smrg TGA_FAST_WRITE_REG((err << 15) | (length & 0xF), TGA_BRES3_REG); 15237706df26Smrg 15247706df26Smrg 15257706df26Smrg if(phase) { 15267706df26Smrg line_mask = pTga->line_pattern >> phase; 15277706df26Smrg l = (pTga->line_pattern_length - phase); 15287706df26Smrg } 15297706df26Smrg else { 15307706df26Smrg line_mask = pTga->line_pattern; 15317706df26Smrg l = pTga->line_pattern_length; 15327706df26Smrg } 15337706df26Smrg 15347706df26Smrg while(l < 16) { 15357706df26Smrg line_mask |= pTga->line_pattern << l; 15367706df26Smrg l += pTga->line_pattern_length; 15377706df26Smrg } 15387706df26Smrg pattern_overflow = l - 16; 15397706df26Smrg 15407706df26Smrg 15417706df26Smrg while(length > 0) { 15427706df26Smrg TGA_FAST_WRITE_REG(line_mask, TGA_CONTINUE_REG); 15437706df26Smrg 15447706df26Smrg if(pattern_overflow) { 15457706df26Smrg line_mask = pTga->line_pattern >> (pTga->line_pattern_length - 15467706df26Smrg pattern_overflow); 15477706df26Smrg l = pattern_overflow; 15487706df26Smrg } 15497706df26Smrg else { 15507706df26Smrg line_mask = pTga->line_pattern; 15517706df26Smrg l = pTga->line_pattern_length; 15527706df26Smrg } 15537706df26Smrg while(l < 16) { 15547706df26Smrg line_mask |= (pTga->line_pattern << l); 15557706df26Smrg l += pTga->line_pattern_length; 15567706df26Smrg } 15577706df26Smrg pattern_overflow = l - 16; 15587706df26Smrg 15597706df26Smrg if(length > 16 && length % 16) 15607706df26Smrg length -= length % 16; 15617706df26Smrg else 15627706df26Smrg length -= 16; 15637706df26Smrg } 15647706df26Smrg 15657706df26Smrg TGA_FAST_WRITE_REG(SIMPLE | X11 | pTga->depthflag, TGA_MODE_REG); 15667706df26Smrg TGA_FAST_WRITE_REG(MIX_SRC | pTga->depthflag, TGA_RASTEROP_REG); 15677706df26Smrg TGA_FAST_WRITE_REG(0xFFFFFFFF, TGA_PLANEMASK_REG); 15687706df26Smrg 15697706df26Smrg TGA_SAVE_OFFSET(); 15707706df26Smrg 15717706df26Smrg return; 15727706df26Smrg} 1573