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