/* * Copyright 1997-2001 by Alan Hourihane, Wigan, England. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Alan Hourihane not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Alan Hourihane makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Authors: Alan Hourihane, * Dirk Hohndel, * Stefan Dirsch, * * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and * Siemens Nixdorf Informationssysteme * * Permedia accelerated options. */ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm_accel.c,v 1.24tsi Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xf86.h" #include "xf86_OSproc.h" #include "xf86PciInfo.h" #include "xf86Pci.h" #include "fb.h" #include "glint_regs.h" #include "glint.h" #include "miline.h" /* for octants */ #include "xaalocal.h" /* For replacements */ static void PermediaSync(ScrnInfoPtr pScrn); static void PermediaSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask); static void PermediaSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h); static void PermediaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask); static void PermediaSubsequentHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir); static void PermediaSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn, int x, int y, int dmaj, int dmin, int e, int len, int octant); static void PermediaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h); static void PermediaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned int planemask, int transparency_color); static void PermediaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2); static void PermediaDisableClipping(ScrnInfoPtr pScrn); static void PermediaSetupForScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask); static void PermediaSubsequentScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft); static void PermediaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno); static void PermediaWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned char *src, int srcwidth, int skipleft, int fg, int bg, int rop,unsigned int planemask); static void PermediaWritePixmap8bpp(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned char *src, int srcwidth, int rop, unsigned int planemask, int transparency_color, int bpp, int depth); static void PermediaWritePixmap16bpp(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned char *src, int srcwidth, int rop, unsigned int planemask, int transparency_color, int bpp, int depth); static void PermediaWritePixmap32bpp(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned char *src, int srcwidth, int rop, unsigned int planemask, int transparency_color, int bpp, int depth); static void PermediaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, int fg, int bg, int rop, unsigned planemask); static void PermediaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx, int patterny, int x, int y, int w, int h); static void PermediaLoadCoord(ScrnInfoPtr pScrn, int x, int y, int w, int h, int a, int d); static void PermediaPolylinesThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC, int mode, int npt, DDXPointPtr pPts); static void PermediaPolySegmentThinSolidWrapper(DrawablePtr pDraw, GCPtr pGC, int nseg, xSegment *pSeg); void PermediaInitializeEngine(ScrnInfoPtr pScrn) { GLINTPtr pGlint = GLINTPTR(pScrn); /* Initialize the Accelerator Engine to defaults */ GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ScissorMode); GLINT_SLOW_WRITE_REG(UNIT_ENABLE, FBWriteMode); GLINT_SLOW_WRITE_REG(0, dXSub); GLINT_SLOW_WRITE_REG(GWIN_DisableLBUpdate, GLINTWindow); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DitherMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, ColorDDAMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureColorMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TextureAddressMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, PMTextureReadMode); GLINT_SLOW_WRITE_REG(pGlint->pprod, LBReadMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaBlendMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, TexelLUTMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, YUVMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RouterMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FogMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AntialiasMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AlphaTestMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StencilMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, AreaStippleMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LogicalOpMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, DepthMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, StatisticMode); GLINT_SLOW_WRITE_REG(0x400, FilterMode); GLINT_SLOW_WRITE_REG(0xffffffff, FBHardwareWriteMask); GLINT_SLOW_WRITE_REG(0xffffffff, FBSoftwareWriteMask); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, RasterizerMode); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, GLINTDepth); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBSourceOffset); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBPixelOffset); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBSourceOffset); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, WindowOrigin); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, FBWindowBase); GLINT_SLOW_WRITE_REG(UNIT_DISABLE, LBWindowBase); switch (pScrn->bitsPerPixel) { case 8: GLINT_SLOW_WRITE_REG(0x0, FBReadPixel); /* 8 Bits */ GLINT_SLOW_WRITE_REG(pGlint->pprod, PMTextureMapFormat); break; case 16: GLINT_SLOW_WRITE_REG(0x1, FBReadPixel); /* 16 Bits */ GLINT_SLOW_WRITE_REG(pGlint->pprod | 1<<19, PMTextureMapFormat); break; case 32: GLINT_SLOW_WRITE_REG(0x2, FBReadPixel); /* 32 Bits */ GLINT_SLOW_WRITE_REG(pGlint->pprod | 2<<19, PMTextureMapFormat); break; } pGlint->ROP = 0xFF; pGlint->ClippingOn = FALSE; pGlint->startxsub = 0; pGlint->startxdom = 0; pGlint->starty = 0; pGlint->count = 0; pGlint->dxdom = 0; pGlint->dy = 1<<16; GLINT_WAIT(6); GLINT_WRITE_REG(0, StartXSub); GLINT_WRITE_REG(0,StartXDom); GLINT_WRITE_REG(0,StartY); GLINT_WRITE_REG(0,GLINTCount); GLINT_WRITE_REG(0,dXDom); GLINT_WRITE_REG(1<<16,dY); } Bool PermediaAccelInit(ScreenPtr pScreen) { XAAInfoRecPtr infoPtr; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; GLINTPtr pGlint = GLINTPTR(pScrn); BoxRec AvailFBArea; pGlint->AccelInfoRec = infoPtr = XAACreateInfoRec(); if (!infoPtr) return FALSE; PermediaInitializeEngine(pScrn); infoPtr->Flags = PIXMAP_CACHE | LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS; infoPtr->Sync = PermediaSync; infoPtr->SetClippingRectangle = PermediaSetClippingRectangle; infoPtr->DisableClipping = PermediaDisableClipping; infoPtr->ClippingFlags = HARDWARE_CLIP_MONO_8x8_FILL; infoPtr->SolidFillFlags = 0; infoPtr->SetupForSolidFill = PermediaSetupForFillRectSolid; infoPtr->SubsequentSolidFillRect = PermediaSubsequentFillRectSolid; infoPtr->SolidLineFlags = 0; infoPtr->PolySegmentThinSolidFlags = 0; infoPtr->PolylinesThinSolidFlags = 0; infoPtr->SetupForSolidLine = PermediaSetupForSolidLine; infoPtr->SubsequentSolidHorVertLine = PermediaSubsequentHorVertLine; if (!(pScrn->overlayFlags & OVERLAY_8_32_PLANAR)) { infoPtr->SubsequentSolidBresenhamLine = PermediaSubsequentSolidBresenhamLine; } infoPtr->PolySegmentThinSolid = PermediaPolySegmentThinSolidWrapper; infoPtr->PolylinesThinSolid = PermediaPolylinesThinSolidWrapper; infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY; infoPtr->SetupForScreenToScreenCopy = PermediaSetupForScreenToScreenCopy; infoPtr->SubsequentScreenToScreenCopy = PermediaSubsequentScreenToScreenCopy; infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_PROGRAMMED_ORIGIN | HARDWARE_PATTERN_PROGRAMMED_BITS | HARDWARE_PATTERN_SCREEN_ORIGIN; infoPtr->SetupForMono8x8PatternFill = PermediaSetupForMono8x8PatternFill; infoPtr->SubsequentMono8x8PatternFillRect = PermediaSubsequentMono8x8PatternFillRect; infoPtr->ScanlineCPUToScreenColorExpandFillFlags = #if 0 LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X | #endif BIT_ORDER_IN_BYTE_LSBFIRST; infoPtr->NumScanlineColorExpandBuffers = 1; pGlint->ScratchBuffer = xalloc(((pScrn->virtualX+62)/32*4) + (pScrn->virtualX * pScrn->bitsPerPixel / 8)); infoPtr->ScanlineColorExpandBuffers = pGlint->XAAScanlineColorExpandBuffers; pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase + OutputFIFO + 4; infoPtr->SetupForScanlineCPUToScreenColorExpandFill = PermediaSetupForScanlineCPUToScreenColorExpandFill; infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = PermediaSubsequentScanlineCPUToScreenColorExpandFill; infoPtr->SubsequentColorExpandScanline = PermediaSubsequentColorExpandScanline; infoPtr->ColorExpandRange = pGlint->FIFOSize; infoPtr->WriteBitmap = PermediaWriteBitmap; if (pScrn->bitsPerPixel == 8) infoPtr->WritePixmap = PermediaWritePixmap8bpp; else if (pScrn->bitsPerPixel == 16) infoPtr->WritePixmap = PermediaWritePixmap16bpp; else if (pScrn->bitsPerPixel == 32) infoPtr->WritePixmap = PermediaWritePixmap32bpp; AvailFBArea.x1 = 0; AvailFBArea.y1 = 0; AvailFBArea.x2 = pScrn->displayWidth; AvailFBArea.y2 = pGlint->FbMapSize / (pScrn->displayWidth * pScrn->bitsPerPixel / 8); if (AvailFBArea.y2 > 1023) AvailFBArea.y2 = 1023; xf86InitFBManager(pScreen, &AvailFBArea); return (XAAInit(pScreen, infoPtr)); } static void PermediaLoadCoord( ScrnInfoPtr pScrn, int x, int y, int w, int h, int a, int d ){ GLINTPtr pGlint = GLINTPTR(pScrn); if (w != pGlint->startxsub) { GLINT_WRITE_REG(w, StartXSub); pGlint->startxsub = w; } if (x != pGlint->startxdom) { GLINT_WRITE_REG(x,StartXDom); pGlint->startxdom = x; } if (y != pGlint->starty) { GLINT_WRITE_REG(y,StartY); pGlint->starty = y; } if (h != pGlint->count) { GLINT_WRITE_REG(h,GLINTCount); pGlint->count = h; } if (a != pGlint->dxdom) { GLINT_WRITE_REG(a,dXDom); pGlint->dxdom = a; } if (d != pGlint->dy) { GLINT_WRITE_REG(d,dY); pGlint->dy = d; } } static void PermediaSync(ScrnInfoPtr pScrn) { GLINTPtr pGlint = GLINTPTR(pScrn); CHECKCLIPPING; while (GLINT_READ_REG(DMACount) != 0); GLINT_WAIT(2); GLINT_WRITE_REG(0x400, FilterMode); GLINT_WRITE_REG(0, GlintSync); do { while(GLINT_READ_REG(OutFIFOWords) == 0); } while (GLINT_READ_REG(OutputFIFO) != Sync_tag); } static void PermediaSetClippingRectangle( ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2 ){ GLINTPtr pGlint = GLINTPTR(pScrn); GLINT_WAIT(3); GLINT_WRITE_REG (((y1&0x0FFF) << 16) | (x1&0x0FFF), ScissorMinXY); GLINT_WRITE_REG (((y2&0x0FFF) << 16) | (x2&0x0FFF), ScissorMaxXY); GLINT_WRITE_REG (1, ScissorMode); pGlint->ClippingOn = TRUE; } static void PermediaDisableClipping( ScrnInfoPtr pScrn ){ GLINTPtr pGlint = GLINTPTR(pScrn); CHECKCLIPPING; } static void PermediaSetupForScreenToScreenCopy( ScrnInfoPtr pScrn, int xdir, int ydir, int rop, unsigned int planemask, int transparency_color ){ GLINTPtr pGlint = GLINTPTR(pScrn); pGlint->BltScanDirection = 0; if (ydir == 1) pGlint->BltScanDirection |= YPositive; GLINT_WAIT(4); DO_PLANEMASK(planemask); GLINT_WRITE_REG(0, RasterizerMode); GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); if ((rop == GXset) || (rop == GXclear)) { pGlint->FrameBufferReadMode = pGlint->pprod; } else if ((rop == GXcopy) || (rop == GXcopyInverted)) { pGlint->FrameBufferReadMode = pGlint->pprod | FBRM_SrcEnable; } else { pGlint->FrameBufferReadMode = pGlint->pprod | FBRM_SrcEnable | FBRM_DstEnable; } LOADROP(rop); } static void PermediaSubsequentScreenToScreenCopy( ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2, int w, int h) { GLINTPtr pGlint = GLINTPTR(pScrn); int srcaddr; int dstaddr; char align; int direction; if (!(pGlint->BltScanDirection & YPositive)) { y1 = y1 + h - 1; y2 = y2 + h - 1; direction = -1<<16; } else { direction = 1<<16; } /* We can only use GXcopy for Packed modes, and less than 32 width * gives us speed for small blits. */ if ((w < 32) || (pGlint->ROP != GXcopy)) { GLINT_WAIT(9); PermediaLoadCoord(pScrn, x2<<16, y2<<16, (x2+w)<<16, h, 0, direction); srcaddr = x1; dstaddr = x2; GLINT_WRITE_REG(pGlint->FrameBufferReadMode, FBReadMode); } else { GLINT_WAIT(10); PermediaLoadCoord(pScrn, (x2>>pGlint->BppShift)<<16, y2<<16, ((x2+w+7)>>pGlint->BppShift)<<16, h, 0, direction); srcaddr = (x1 & ~pGlint->bppalign); dstaddr = (x2 & ~pGlint->bppalign); align = (x2 & pGlint->bppalign) - (x1 & pGlint->bppalign); GLINT_WRITE_REG(pGlint->FrameBufferReadMode | FBRM_Packed | (align&7)<<20, FBReadMode); GLINT_WRITE_REG(x2<<16|(x2+w), PackedDataLimits); } srcaddr += y1 * pScrn->displayWidth; dstaddr += y2 * pScrn->displayWidth; GLINT_WRITE_REG(srcaddr - dstaddr, FBSourceOffset); GLINT_WRITE_REG(PrimitiveTrapezoid, Render); } static void PermediaSetupForFillRectSolid( ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask ){ GLINTPtr pGlint = GLINTPTR(pScrn); REPLICATE(color); GLINT_WAIT(6); DO_PLANEMASK(planemask); GLINT_WRITE_REG(0, RasterizerMode); if (rop == GXcopy) { GLINT_WRITE_REG(pGlint->pprod, FBReadMode); GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); GLINT_WRITE_REG(color, FBBlockColor); } else { GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); GLINT_WRITE_REG(color, ConstantColor); } LOADROP(rop); } static void PermediaSubsequentFillRectSolid( ScrnInfoPtr pScrn, int x, int y, int w, int h) { GLINTPtr pGlint = GLINTPTR(pScrn); int speed = 0; if (pGlint->ROP == GXcopy) { GLINT_WAIT(7); PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16); speed = FastFillEnable; } else { GLINT_WAIT(9); GLINT_WRITE_REG(pGlint->pprod | FBRM_Packed | FBRM_DstEnable, FBReadMode); PermediaLoadCoord(pScrn, (x>>pGlint->BppShift)<<16, y<<16, ((x+w+7)>>pGlint->BppShift)<<16, h, 0, 1<<16); GLINT_WRITE_REG(x<<16|(x+w), PackedDataLimits); } GLINT_WRITE_REG(PrimitiveTrapezoid | speed, Render); } static void PermediaSetupForMono8x8PatternFill( ScrnInfoPtr pScrn, int patternx, int patterny, int fg, int bg, int rop, unsigned int planemask) { GLINTPtr pGlint = GLINTPTR(pScrn); if (bg == -1) pGlint->FrameBufferReadMode = -1; else pGlint->FrameBufferReadMode = 0; pGlint->ForeGroundColor = fg; pGlint->BackGroundColor = bg; REPLICATE(pGlint->ForeGroundColor); REPLICATE(pGlint->BackGroundColor); GLINT_WAIT(8); GLINT_WRITE_REG ((patternx & 0x000000ff), AreaStipplePattern0); GLINT_WRITE_REG ((patternx & 0x0000ff00) >> 8, AreaStipplePattern1); GLINT_WRITE_REG ((patternx & 0x00ff0000) >> 16, AreaStipplePattern2); GLINT_WRITE_REG ((patternx & 0xff000000) >> 24, AreaStipplePattern3); GLINT_WRITE_REG ((patterny & 0x000000ff), AreaStipplePattern4); GLINT_WRITE_REG ((patterny & 0x0000ff00) >> 8, AreaStipplePattern5); GLINT_WRITE_REG ((patterny & 0x00ff0000) >> 16, AreaStipplePattern6); GLINT_WRITE_REG ((patterny & 0xff000000) >> 24, AreaStipplePattern7); GLINT_WAIT(7); DO_PLANEMASK(planemask); GLINT_WRITE_REG(0, RasterizerMode); if (rop == GXcopy) { GLINT_WRITE_REG(pGlint->pprod, FBReadMode); } else { GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); } GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); GLINT_WRITE_REG(pGlint->ForeGroundColor, ConstantColor); GLINT_WRITE_REG(pGlint->BackGroundColor, Texel0); LOADROP(rop); } static void PermediaSubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn, int patternx, int patterny, int x, int y, int w, int h) { GLINTPtr pGlint = GLINTPTR(pScrn); GLINT_WAIT(8); PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16); if (pGlint->FrameBufferReadMode != -1) { GLINT_WRITE_REG(1<<20|patternx<<7|patterny<<12|UNIT_ENABLE, AreaStippleMode); GLINT_WRITE_REG(AreaStippleEnable | TextureEnable | PrimitiveTrapezoid, Render); } else { GLINT_WRITE_REG(patternx<<7|patterny<<12|UNIT_ENABLE, AreaStippleMode); GLINT_WRITE_REG(AreaStippleEnable | PrimitiveTrapezoid, Render); } } static void PermediaWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned char *src, int srcwidth, int skipleft, int fg, int bg, int rop, unsigned int planemask ){ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); GLINTPtr pGlint = GLINTPTR(pScrn); unsigned char *srcpntr; int dwords, height; register int count; register CARD32* pattern; int dobackground = 0; w += skipleft; x -= skipleft; dwords = (w + 31) >> 5; PermediaSetClippingRectangle(pScrn, x+skipleft, y, x+w, y+h); GLINT_WAIT(14); DO_PLANEMASK(planemask); LOADROP(rop); if (bg != -1) dobackground = ForceBackgroundColor; if (rop == GXcopy) { GLINT_WRITE_REG(pGlint->pprod, FBReadMode); } else { GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); } pGlint->BackGroundColor = bg; pGlint->ForeGroundColor = fg; REPLICATE(fg); REPLICATE(bg); if ((rop == GXcopy) && (pGlint->BackGroundColor == -1)) { pGlint->FrameBufferReadMode = FastFillEnable; GLINT_WRITE_REG(0, RasterizerMode); GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); GLINT_WRITE_REG(fg, FBBlockColor); } else { GLINT_WRITE_REG(BitMaskPackingEachScanline|dobackground,RasterizerMode); GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); GLINT_WRITE_REG(fg, ConstantColor); if (dobackground) { GLINT_WRITE_REG(bg, Texel0); pGlint->FrameBufferReadMode = TextureEnable; } else { pGlint->FrameBufferReadMode = 0; } } PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16); GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask, Render); height = h; srcpntr = src; while(height--) { count = dwords >> 3; pattern = (CARD32*)srcpntr; while(count--) { GLINT_WAIT(8); GLINT_WRITE_REG(*(pattern), BitMaskPattern); GLINT_WRITE_REG(*(pattern+1), BitMaskPattern); GLINT_WRITE_REG(*(pattern+2), BitMaskPattern); GLINT_WRITE_REG(*(pattern+3), BitMaskPattern); GLINT_WRITE_REG(*(pattern+4), BitMaskPattern); GLINT_WRITE_REG(*(pattern+5), BitMaskPattern); GLINT_WRITE_REG(*(pattern+6), BitMaskPattern); GLINT_WRITE_REG(*(pattern+7), BitMaskPattern); pattern+=8; } count = dwords & 0x07; GLINT_WAIT(count); while (count--) GLINT_WRITE_REG(*(pattern++), BitMaskPattern); srcpntr += srcwidth; } PermediaDisableClipping(pScrn); SET_SYNC_FLAG(infoRec); } static void PermediaSetupForScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int fg, int bg, int rop, unsigned int planemask ){ GLINTPtr pGlint = GLINTPTR(pScrn); int dobackground = 0; if (bg != -1) dobackground |= ForceBackgroundColor; pGlint->BackGroundColor = bg; pGlint->ForeGroundColor = fg; REPLICATE(fg); REPLICATE(bg); GLINT_WAIT(7); DO_PLANEMASK(planemask); if (rop == GXcopy) { GLINT_WRITE_REG(pGlint->pprod, FBReadMode); } else { GLINT_WRITE_REG(pGlint->pprod|FBRM_DstEnable, FBReadMode); } if ((rop == GXcopy) && (pGlint->BackGroundColor == -1)) { pGlint->FrameBufferReadMode = FastFillEnable; GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); GLINT_WRITE_REG(fg, FBBlockColor); GLINT_WRITE_REG(0,RasterizerMode); } else { GLINT_WRITE_REG(UNIT_ENABLE, ColorDDAMode); GLINT_WRITE_REG(fg, ConstantColor); GLINT_WRITE_REG(BitMaskPackingEachScanline|dobackground,RasterizerMode); if (dobackground) { GLINT_WRITE_REG(bg, Texel0); pGlint->FrameBufferReadMode = TextureEnable; } else { pGlint->FrameBufferReadMode = 0; } } LOADROP(rop); } static void PermediaSubsequentScanlineCPUToScreenColorExpandFill( ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft ){ GLINTPtr pGlint = GLINTPTR(pScrn); pGlint->dwords = ((w + 31) >> 5); /* dwords per scanline */ #if 0 PermediaSetClippingRectangle(pScrn, x+skipleft, y, x+w, y+h); #endif pGlint->cpucount = h; GLINT_WAIT(8); PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16); GLINT_WRITE_REG(PrimitiveTrapezoid | pGlint->FrameBufferReadMode | SyncOnBitMask, Render); #if defined(__alpha__) if (0) /* force Alpha to use indirect always */ #else if ((pGlint->dwords*h) < pGlint->FIFOSize) #endif { /* Turn on direct for less than FIFOSize dword colour expansion */ pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->IOBase+OutputFIFO+4; pGlint->ScanlineDirect = 1; GLINT_WRITE_REG(((pGlint->dwords*h)-1)<<16 | 0x0D, OutputFIFO); GLINT_WAIT(pGlint->dwords*h); } else { /* Use indirect for anything else */ pGlint->XAAScanlineColorExpandBuffers[0] = pGlint->ScratchBuffer; pGlint->ScanlineDirect = 0; } pGlint->cpucount--; } static void PermediaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) { GLINTPtr pGlint = GLINTPTR(pScrn); CARD32 *srcp = (CARD32*)pGlint->XAAScanlineColorExpandBuffers[bufno]; int dwords = pGlint->dwords; if (!pGlint->ScanlineDirect) { while(dwords >= pGlint->FIFOSize) { GLINT_WAIT(pGlint->FIFOSize); GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | 0x0D, OutputFIFO); GLINT_MoveDWORDS( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (CARD32*)srcp, pGlint->FIFOSize - 1); dwords -= pGlint->FIFOSize - 1; srcp += pGlint->FIFOSize - 1; } if(dwords) { GLINT_WAIT(dwords + 1); GLINT_WRITE_REG(((dwords - 1) << 16) | 0x0D, OutputFIFO); GLINT_MoveDWORDS( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (CARD32*)srcp, dwords); } } } static void PermediaWritePixmap8bpp( ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned char *src, int srcwidth, int rop, unsigned int planemask, int transparency_color, int bpp, int depth ) { XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); GLINTPtr pGlint = GLINTPTR(pScrn); int dwords, count; CARD32* srcp; unsigned char *srcpbyte; Bool FastTexLoad = FALSE; GLINT_WAIT(2); DO_PLANEMASK(planemask); GLINT_WRITE_REG(0, RasterizerMode); dwords = (w + 3) >> 2; if((!(x&3)) && (!(w&3))) FastTexLoad = TRUE; if((rop != GXcopy) || (planemask != ~0)) FastTexLoad = FALSE; #if 0 if (rop != GXcopy) { int skipleft; if((skipleft = (long)src & 0x03)) { skipleft /= (bpp>>3); x -= skipleft; w += skipleft; src = (unsigned char*)((long)src & ~0x03); } } #endif if(FastTexLoad) { int address; GLINT_WAIT(1); GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode); PermediaSync(pScrn); /* we are not using the rasterizer */ while(h--) { count = dwords; address = ((y * pScrn->displayWidth) + x) >> 2; srcp = (CARD32*)src; GLINT_WAIT(1); GLINT_WRITE_REG(address, TextureDownloadOffset); while(count >= infoRec->ColorExpandRange) { GLINT_WAIT(infoRec->ColorExpandRange); /* (0x11 << 4) | 0x0D is the TAG for TextureData */ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x11 << 4) | 0x0D, OutputFIFO); GLINT_MoveDWORDS( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (CARD32*)srcp, infoRec->ColorExpandRange - 1); count -= infoRec->ColorExpandRange - 1; address += infoRec->ColorExpandRange - 1; srcp += infoRec->ColorExpandRange - 1; } if(count) { GLINT_WAIT(count + 1); /* (0x11 << 4) | 0x0D is the TAG for TextureData */ GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D, OutputFIFO); GLINT_MoveDWORDS( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (CARD32*)srcp, count); } src += srcwidth; y++; } GLINT_WAIT(1); GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode); } else { GLINT_WAIT(10); if (rop == GXcopy) { GLINT_WRITE_REG(pGlint->pprod, FBReadMode); } else { GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); } PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16); GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); LOADROP(rop); GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render); { while(h--) { count = w; srcpbyte = (unsigned char *)src; while(count >= infoRec->ColorExpandRange) { GLINT_WAIT(infoRec->ColorExpandRange); /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x15 << 4) | 0x05, OutputFIFO); GLINT_MoveBYTE( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (unsigned char *)srcpbyte, infoRec->ColorExpandRange-1); count -= infoRec->ColorExpandRange - 1; srcpbyte += infoRec->ColorExpandRange - 1; } if(count) { GLINT_WAIT(count + 1); /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | 0x05, OutputFIFO); GLINT_MoveBYTE( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (unsigned char *)srcpbyte, count); } src += srcwidth; } } } SET_SYNC_FLAG(infoRec); } static void PermediaWritePixmap16bpp( ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned char *src, int srcwidth, int rop, unsigned int planemask, int transparency_color, int bpp, int depth ) { XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); GLINTPtr pGlint = GLINTPTR(pScrn); int dwords, count; CARD32* srcp; unsigned short* srcpword; Bool FastTexLoad; GLINT_WAIT(2); DO_PLANEMASK(planemask); GLINT_WRITE_REG(0, RasterizerMode); FastTexLoad = FALSE; dwords = (w + 1) >> 1; if((!(x&1)) && (!(w&1))) FastTexLoad = TRUE; if((rop != GXcopy) || (planemask != ~0)) FastTexLoad = FALSE; #if 0 if (rop != GXcopy) { int skipleft; if((skipleft = (long)src & 0x03L)) { skipleft /= (bpp>>3); x -= skipleft; w += skipleft; src = (unsigned char*)((long)src & ~0x03L); } } #endif if(FastTexLoad) { int address; GLINT_WAIT(1); GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode); PermediaSync(pScrn); /* we are not using the rasterizer */ while(h--) { count = dwords; address = ((y * pScrn->displayWidth) + x) >> 1; srcp = (CARD32*)src; GLINT_WAIT(1); GLINT_WRITE_REG(address, TextureDownloadOffset); while(count >= infoRec->ColorExpandRange) { GLINT_WAIT(infoRec->ColorExpandRange); /* (0x11 << 4) | 0x0D is the TAG for TextureData */ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x11 << 4) | 0x0D, OutputFIFO); GLINT_MoveDWORDS( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (CARD32*)srcp, infoRec->ColorExpandRange - 1); count -= infoRec->ColorExpandRange - 1; address += infoRec->ColorExpandRange - 1; srcp += infoRec->ColorExpandRange - 1; } if(count) { GLINT_WAIT(count + 1); /* (0x11 << 4) | 0x0D is the TAG for TextureData */ GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D, OutputFIFO); GLINT_MoveDWORDS( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (CARD32*)srcp, count); } src += srcwidth; y++; } GLINT_WAIT(1); GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode); } else { GLINT_WAIT(10); if (rop == GXcopy) { GLINT_WRITE_REG(pGlint->pprod, FBReadMode); } else { GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); } PermediaLoadCoord(pScrn, x<<16, y<<16, (x+w)<<16, h, 0, 1<<16); GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); LOADROP(rop); GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render); { while(h--) { count = w; srcpword = (unsigned short *)src; while(count >= infoRec->ColorExpandRange) { GLINT_WAIT(infoRec->ColorExpandRange); /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x15 << 4) | 0x05, OutputFIFO); GLINT_MoveWORDS( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (unsigned short *)srcpword,infoRec->ColorExpandRange-1); count -= infoRec->ColorExpandRange - 1; srcpword += infoRec->ColorExpandRange - 1; } if(count) { GLINT_WAIT(count + 1); /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | 0x05, OutputFIFO); GLINT_MoveWORDS( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (unsigned short *)srcpword, count); } src += srcwidth; } } } SET_SYNC_FLAG(infoRec); } static void PermediaWritePixmap32bpp( ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned char *src, int srcwidth, int rop, unsigned int planemask, int transparency_color, int bpp, int depth ) { XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); GLINTPtr pGlint = GLINTPTR(pScrn); int dwords, count; CARD32* srcp; Bool FastTexLoad; GLINT_WAIT(3); DO_PLANEMASK(planemask); GLINT_WRITE_REG(0, RasterizerMode); if (rop == GXcopy) { GLINT_WRITE_REG(pGlint->pprod, FBReadMode); } else { GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); } FastTexLoad = TRUE; dwords = w; if((rop != GXcopy) || (planemask != ~0)) FastTexLoad = FALSE; #if 0 if (!FastTexLoad) { int skipleft; if((skipleft = (long)src & 0x03L)) { skipleft /= (bpp>>3); x -= skipleft; w += skipleft; src = (unsigned char*)((long)src & ~0x03L); } } #endif if(FastTexLoad) { int address; GLINT_WAIT(1); GLINT_WRITE_REG(UNIT_DISABLE, FBWriteMode); PermediaSync(pScrn); /* we are not using the rasterizer */ while(h--) { count = dwords; address = (y * pScrn->displayWidth) + x; srcp = (CARD32*)src; GLINT_WAIT(1); GLINT_WRITE_REG(address, TextureDownloadOffset); while(count >= infoRec->ColorExpandRange) { GLINT_WAIT(infoRec->ColorExpandRange); /* (0x11 << 4) | 0x0D is the TAG for TextureData */ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x11 << 4) | 0x0D, OutputFIFO); GLINT_MoveDWORDS( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (CARD32*)srcp, infoRec->ColorExpandRange - 1); count -= infoRec->ColorExpandRange - 1; address += infoRec->ColorExpandRange - 1; srcp += infoRec->ColorExpandRange - 1; } if(count) { GLINT_WAIT(count + 1); /* (0x11 << 4) | 0x0D is the TAG for TextureData */ GLINT_WRITE_REG(((count - 1) << 16) | (0x11 << 4) | 0x0D, OutputFIFO); GLINT_MoveDWORDS( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (CARD32*)srcp, count); } src += srcwidth; y++; } GLINT_WAIT(1); GLINT_WRITE_REG(UNIT_ENABLE, FBWriteMode); } else { GLINT_WAIT(9); PermediaLoadCoord(pScrn, (x&0xFFFF)<<16, y<<16, ((x&0xFFFF)+w)<<16, h, 0, 1<<16); LOADROP(rop); GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); GLINT_WRITE_REG(PrimitiveTrapezoid | SyncOnHostData, Render); while(h--) { count = dwords; srcp = (CARD32*)src; while(count >= infoRec->ColorExpandRange) { GLINT_WAIT(infoRec->ColorExpandRange); /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ GLINT_WRITE_REG(((infoRec->ColorExpandRange - 2) << 16) | (0x15 << 4) | 0x05, OutputFIFO); GLINT_MoveDWORDS( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (CARD32*)srcp, infoRec->ColorExpandRange - 1); count -= infoRec->ColorExpandRange - 1; srcp += infoRec->ColorExpandRange - 1; } if(count) { GLINT_WAIT(count + 1); /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ GLINT_WRITE_REG(((count - 1) << 16) | (0x15 << 4) | 0x05, OutputFIFO); GLINT_MoveDWORDS( (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), (CARD32*)srcp, count); } src += srcwidth; } } SET_SYNC_FLAG(infoRec); } static void PermediaPolylinesThinSolidWrapper( DrawablePtr pDraw, GCPtr pGC, int mode, int npt, DDXPointPtr pPts ){ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); GLINTPtr pGlint = GLINTPTR(infoRec->pScrn); pGlint->CurrentGC = pGC; pGlint->CurrentDrawable = pDraw; if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn); XAAPolyLines(pDraw, pGC, mode, npt, pPts); } static void PermediaPolySegmentThinSolidWrapper( DrawablePtr pDraw, GCPtr pGC, int nseg, xSegment *pSeg ){ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); GLINTPtr pGlint = GLINTPTR(infoRec->pScrn); pGlint->CurrentGC = pGC; pGlint->CurrentDrawable = pDraw; if(infoRec->NeedToSync) (*infoRec->Sync)(infoRec->pScrn); XAAPolySegment(pDraw, pGC, nseg, pSeg); } static void PermediaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask) { GLINTPtr pGlint = GLINTPTR(pScrn); GLINT_WAIT(6); DO_PLANEMASK(planemask); GLINT_WRITE_REG(UNIT_DISABLE, ColorDDAMode); GLINT_WRITE_REG(color, GLINTColor); GLINT_WRITE_REG(0, RasterizerMode); if (rop == GXcopy) { GLINT_WRITE_REG(pGlint->pprod, FBReadMode); } else { GLINT_WRITE_REG(pGlint->pprod | FBRM_DstEnable, FBReadMode); } LOADROP(rop); } static void PermediaSubsequentHorVertLine(ScrnInfoPtr pScrn,int x,int y,int len,int dir) { GLINTPtr pGlint = GLINTPTR(pScrn); GLINT_WAIT(7); if (dir == DEGREES_0) { PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, 1<<16, 0); } else { PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, 0, 1<<16); } GLINT_WRITE_REG(PrimitiveLine, Render); } static void PermediaSubsequentSolidBresenhamLine( ScrnInfoPtr pScrn, int x, int y, int dmaj, int dmin, int e, int len, int octant) { GLINTPtr pGlint = GLINTPTR(pScrn); int dxdom, dy; if(dmaj == dmin) { GLINT_WAIT(7); if(octant & YDECREASING) { dy = -1<<16; } else { dy = 1<<16; } if(octant & XDECREASING) { dxdom = -1<<16; } else { dxdom = 1<<16; } PermediaLoadCoord(pScrn, x<<16, y<<16, 0, len, dxdom, dy); GLINT_WRITE_REG(PrimitiveLine, Render); return; } fbBres(pGlint->CurrentDrawable, pGlint->CurrentGC, 0, (octant & XDECREASING) ? -1 : 1, (octant & YDECREASING) ? -1 : 1, (octant & YMAJOR) ? Y_AXIS : X_AXIS, x, y, e, dmin, -dmaj, len); }