diff options
Diffstat (limited to 'src/nv_xaa.c')
-rw-r--r-- | src/nv_xaa.c | 976 |
1 files changed, 559 insertions, 417 deletions
diff --git a/src/nv_xaa.c b/src/nv_xaa.c index e4400b6..e237abb 100644 --- a/src/nv_xaa.c +++ b/src/nv_xaa.c @@ -1,7 +1,6 @@ -/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */ /***************************************************************************\ |* *| -|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *| +|* Copyright 2003 NVIDIA, Corporation. All rights reserved. *| |* *| |* NOTICE TO USER: The source code is copyrighted under U.S. and *| |* international laws. Users and possessors of this source code are *| @@ -12,7 +11,7 @@ |* tion and internal comments to the code, notices to the end user *| |* as follows: *| |* *| -|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *| +|* Copyright 2003 NVIDIA, Corporation. All rights reserved. *| |* *| |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *| |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *| @@ -38,357 +37,540 @@ |* *| \***************************************************************************/ -/* Hacked together from mga driver and 3.3.4 NVIDIA driver by - Jarno Paananen <jpaana@s2.org> */ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c,v 1.29 2003/02/12 21:26:27 mvojkovi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c,v 1.34 2003/10/15 20:28:31 mvojkovi Exp $ */ #include "nv_include.h" #include "xaalocal.h" -#include "xaarop.h" - #include "miline.h" +#include "nv_dma.h" -static void -NVSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) +static const int NVCopyROP[16] = { - int height = y2-y1 + 1; - int width = x2-x1 + 1; - NVPtr pNv = NVPTR(pScrn); + 0x00, /* GXclear */ + 0x88, /* GXand */ + 0x44, /* GXandReverse */ + 0xCC, /* GXcopy */ + 0x22, /* GXandInverted */ + 0xAA, /* GXnoop */ + 0x66, /* GXxor */ + 0xEE, /* GXor */ + 0x11, /* GXnor */ + 0x99, /* GXequiv */ + 0x55, /* GXinvert*/ + 0xDD, /* GXorReverse */ + 0x33, /* GXcopyInverted */ + 0xBB, /* GXorInverted */ + 0x77, /* GXnand */ + 0xFF /* GXset */ +}; + +static const int NVCopyROP_PM[16] = +{ + 0x0A, /* GXclear */ + 0x8A, /* GXand */ + 0x4A, /* GXandReverse */ + 0xCA, /* GXcopy */ + 0x2A, /* GXandInverted */ + 0xAA, /* GXnoop */ + 0x6A, /* GXxor */ + 0xEA, /* GXor */ + 0x1A, /* GXnor */ + 0x9A, /* GXequiv */ + 0x5A, /* GXinvert*/ + 0xDA, /* GXorReverse */ + 0x3A, /* GXcopyInverted */ + 0xBA, /* GXorInverted */ + 0x7A, /* GXnand */ + 0xFA /* GXset */ +}; + +static const int NVPatternROP[16] = +{ + 0x00, + 0xA0, + 0x50, + 0xF0, + 0x0A, + 0xAA, + 0x5A, + 0xFA, + 0x05, + 0xA5, + 0x55, + 0xF5, + 0x0F, + 0xAF, + 0x5F, + 0xFF +}; - RIVA_FIFO_FREE(pNv->riva, Clip, 2); - pNv->riva.Clip->TopLeft = (y1 << 16) | (x1 & 0xffff); - pNv->riva.Clip->WidthHeight = (height << 16) | width; +void +NVDmaKickoff(NVPtr pNv) +{ + if(pNv->dmaCurrent != pNv->dmaPut) { + pNv->dmaPut = pNv->dmaCurrent; + WRITE_PUT(pNv, pNv->dmaPut); + } } -static void -NVDisableClipping(ScrnInfoPtr pScrn) -{ - NVSetClippingRectangle(pScrn, 0, 0, 0x7fff, 0x7fff); +/* There is a HW race condition with videoram command buffers. + You can't jump to the location of your put offset. We write put + at the jump offset + SKIPS dwords with noop padding in between + to solve this problem */ +#define SKIPS 8 + +void +NVDmaWait ( + NVPtr pNv, + int size +){ + int dmaGet; + + size++; + + while(pNv->dmaFree < size) { + dmaGet = READ_GET(pNv); + + if(pNv->dmaPut >= dmaGet) { + pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; + if(pNv->dmaFree < size) { + NVDmaNext(pNv, 0x20000000); + if(dmaGet <= SKIPS) { + if(pNv->dmaPut <= SKIPS) /* corner case - will be idle */ + WRITE_PUT(pNv, SKIPS + 1); + do { dmaGet = READ_GET(pNv); } + while(dmaGet <= SKIPS); + } + WRITE_PUT(pNv, SKIPS); + pNv->dmaCurrent = pNv->dmaPut = SKIPS; + pNv->dmaFree = dmaGet - (SKIPS + 1); + } + } else + pNv->dmaFree = dmaGet - pNv->dmaCurrent - 1; + } } -/* - * Set pattern. Internal routine. The upper bits of the colors - * are the ALPHA bits. 0 == transparency. - */ -static void -NVSetPattern(NVPtr pNv, int clr0, int clr1, int pat0, int pat1) +/* + currentRop = 0-15 solid fill + 16-31 8x8 pattern fill + 32-47 solid fill with planemask +*/ + +static void +NVSetPattern( + ScrnInfoPtr pScrn, + CARD32 clr0, + CARD32 clr1, + CARD32 pat0, + CARD32 pat1 +) { - RIVA_FIFO_FREE(pNv->riva, Patt, 5); - pNv->riva.Patt->Shape = 0; /* 0 = 8X8, 1 = 64X1, 2 = 1X64 */ - pNv->riva.Patt->Color0 = clr0; - pNv->riva.Patt->Color1 = clr1; - pNv->riva.Patt->Monochrome[0] = pat0; - pNv->riva.Patt->Monochrome[1] = pat1; + NVPtr pNv = NVPTR(pScrn); + + NVDmaStart(pNv, PATTERN_COLOR_0, 4); + NVDmaNext (pNv, clr0); + NVDmaNext (pNv, clr1); + NVDmaNext (pNv, pat0); + NVDmaNext (pNv, pat1); } -/* - * Set ROP. Translate X rop into ROP3. Internal routine. - */ -static void -NVSetRopSolid(NVPtr pNv, int rop) -{ - if (pNv->currentRop != rop) - { - if (pNv->currentRop > 16) - NVSetPattern(pNv, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); +static void +NVSetRopSolid(ScrnInfoPtr pScrn, CARD32 rop, CARD32 planemask) +{ + NVPtr pNv = NVPTR(pScrn); + + if(planemask != ~0) { + NVSetPattern(pScrn, 0, planemask, ~0, ~0); + if(pNv->currentRop != (rop + 32)) { + NVDmaStart(pNv, ROP_SET, 1); + NVDmaNext (pNv, NVCopyROP_PM[rop]); + pNv->currentRop = rop + 32; + } + } else + if (pNv->currentRop != rop) { + if(pNv->currentRop >= 16) + NVSetPattern(pScrn, ~0, ~0, ~0, ~0); + NVDmaStart(pNv, ROP_SET, 1); + NVDmaNext (pNv, NVCopyROP[rop]); pNv->currentRop = rop; - RIVA_FIFO_FREE(pNv->riva, Rop, 1); - pNv->riva.Rop->Rop3 = XAACopyROP[rop]; } } -static void -NVSetRopPattern(NVPtr pNv, int rop) +void NVResetGraphics(ScrnInfoPtr pScrn) { - if (pNv->currentRop != rop + 16) - { - pNv->currentRop = rop + 16; /* +16 is important */ - RIVA_FIFO_FREE(pNv->riva, Rop, 1); - pNv->riva.Rop->Rop3 = XAAPatternROP[rop]; + NVPtr pNv = NVPTR(pScrn); + CARD32 surfaceFormat, patternFormat, rectFormat, lineFormat; + int pitch, i; + + if(pNv->NoAccel) return; + + pitch = pNv->CurrentLayout.displayWidth * + (pNv->CurrentLayout.bitsPerPixel >> 3); + + pNv->dmaBase = (CARD32*)(&pNv->FbStart[pNv->FbUsableSize]); + + for(i = 0; i < SKIPS; i++) + pNv->dmaBase[i] = 0x00000000; + + pNv->dmaBase[0x0 + SKIPS] = 0x00040000; + pNv->dmaBase[0x1 + SKIPS] = 0x80000010; + pNv->dmaBase[0x2 + SKIPS] = 0x00042000; + pNv->dmaBase[0x3 + SKIPS] = 0x80000011; + pNv->dmaBase[0x4 + SKIPS] = 0x00044000; + pNv->dmaBase[0x5 + SKIPS] = 0x80000012; + pNv->dmaBase[0x6 + SKIPS] = 0x00046000; + pNv->dmaBase[0x7 + SKIPS] = 0x80000013; + pNv->dmaBase[0x8 + SKIPS] = 0x00048000; + pNv->dmaBase[0x9 + SKIPS] = 0x80000014; + pNv->dmaBase[0xA + SKIPS] = 0x0004A000; + pNv->dmaBase[0xB + SKIPS] = 0x80000015; + pNv->dmaBase[0xC + SKIPS] = 0x0004C000; + pNv->dmaBase[0xD + SKIPS] = 0x80000016; + pNv->dmaBase[0xE + SKIPS] = 0x0004E000; + pNv->dmaBase[0xF + SKIPS] = 0x80000017; + + pNv->dmaPut = 0; + pNv->dmaCurrent = 16 + SKIPS; + pNv->dmaMax = 8191; + pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; + + switch(pNv->CurrentLayout.depth) { + case 24: + surfaceFormat = SURFACE_FORMAT_DEPTH24; + patternFormat = PATTERN_FORMAT_DEPTH24; + rectFormat = RECT_FORMAT_DEPTH24; + lineFormat = LINE_FORMAT_DEPTH24; + break; + case 16: + case 15: + surfaceFormat = SURFACE_FORMAT_DEPTH16; + patternFormat = PATTERN_FORMAT_DEPTH16; + rectFormat = RECT_FORMAT_DEPTH16; + lineFormat = LINE_FORMAT_DEPTH16; + break; + default: + surfaceFormat = SURFACE_FORMAT_DEPTH8; + patternFormat = PATTERN_FORMAT_DEPTH8; + rectFormat = RECT_FORMAT_DEPTH8; + lineFormat = LINE_FORMAT_DEPTH8; + break; } + + NVDmaStart(pNv, SURFACE_FORMAT, 4); + NVDmaNext (pNv, surfaceFormat); + NVDmaNext (pNv, pitch | (pitch << 16)); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, 0); + + NVDmaStart(pNv, PATTERN_FORMAT, 1); + NVDmaNext (pNv, patternFormat); + + NVDmaStart(pNv, RECT_FORMAT, 1); + NVDmaNext (pNv, rectFormat); + + NVDmaStart(pNv, LINE_FORMAT, 1); + NVDmaNext (pNv, lineFormat); + + pNv->currentRop = ~0; /* set to something invalid */ + NVSetRopSolid(pScrn, GXcopy, ~0); + + NVDmaKickoff(pNv); } -/* - * Fill solid rectangles. - */ -static -void NVSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, - unsigned planemask) +void NVSync(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - NVSetRopSolid(pNv, rop); - RIVA_FIFO_FREE(pNv->riva, Bitmap, 1); - pNv->riva.Bitmap->Color1A = color; + if(pNv->DMAKickoffCallback) + (*pNv->DMAKickoffCallback)(pScrn); + + while(READ_GET(pNv) != pNv->dmaPut); + + while(pNv->PGRAPH[0x0700/4]); } static void -NVSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) +NVDMAKickoffCallback (ScrnInfoPtr pScrn) { - NVPtr pNv = NVPTR(pScrn); - - RIVA_FIFO_FREE(pNv->riva, Bitmap, 2); - pNv->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y; - write_mem_barrier(); - pNv->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h; - write_mem_barrier(); + NVPtr pNv = NVPTR(pScrn); + + NVDmaKickoff(pNv); + pNv->DMAKickoffCallback = NULL; } -/* - * Screen to screen BLTs. - */ + static void -NVSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, - unsigned planemask, int transparency_color) +NVSetupForScreenToScreenCopy( + ScrnInfoPtr pScrn, + int xdir, int ydir, + int rop, + unsigned planemask, + int transparency_color +) { - NVSetRopSolid(NVPTR(pScrn), rop); + NVPtr pNv = NVPTR(pScrn); + + planemask |= ~0 << pNv->CurrentLayout.depth; + + NVSetRopSolid(pScrn, rop, planemask); + + pNv->DMAKickoffCallback = NVDMAKickoffCallback; } static void -NVSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, - int x2, int y2, int w, int h) +NVSubsequentScreenToScreenCopy( + ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2, + int w, int h +) { NVPtr pNv = NVPTR(pScrn); - RIVA_FIFO_FREE(pNv->riva, Blt, 3); - pNv->riva.Blt->TopLeftSrc = (y1 << 16) | x1; - pNv->riva.Blt->TopLeftDst = (y2 << 16) | x2; - write_mem_barrier(); - pNv->riva.Blt->WidthHeight = (h << 16) | w; - write_mem_barrier(); -} + NVDmaStart(pNv, BLIT_POINT_SRC, 3); + NVDmaNext (pNv, (y1 << 16) | x1); + NVDmaNext (pNv, (y2 << 16) | x2); + NVDmaNext (pNv, (h << 16) | w); + if((w * h) >= 512) + NVDmaKickoff(pNv); +} -/* - * Fill 8x8 monochrome pattern rectangles. patternx and patterny are - * the overloaded pattern bits themselves. The pattern colors don't - * support 565, only 555. Hack around it. - */ static void -NVSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, - int fg, int bg, int rop, unsigned planemask) +NVSetupForSolidFill( + ScrnInfoPtr pScrn, + int color, + int rop, + unsigned planemask +) { - NVPtr pNv = NVPTR(pScrn); + NVPtr pNv = NVPTR(pScrn); - NVSetRopPattern(pNv, rop); - if (pScrn->depth == 16) - { - fg = ((fg & 0x0000F800) << 8) - | ((fg & 0x000007E0) << 5) - | ((fg & 0x0000001F) << 3) - | 0xFF000000; - if (bg != -1) - bg = ((bg & 0x0000F800) << 8) - | ((bg & 0x000007E0) << 5) - | ((bg & 0x0000001F) << 3) - | 0xFF000000; - else - bg = 0; - } - else - { - fg |= pNv->opaqueMonochrome; - bg = (bg == -1) ? 0 : bg | pNv->opaqueMonochrome; - }; - NVSetPattern(pNv, bg, fg, patternx, patterny); - RIVA_FIFO_FREE(pNv->riva, Bitmap, 1); - pNv->riva.Bitmap->Color1A = fg; + planemask |= ~0 << pNv->CurrentLayout.depth; + + NVSetRopSolid(pScrn, rop, planemask); + NVDmaStart(pNv, RECT_SOLID_COLOR, 1); + NVDmaNext (pNv, color); + + pNv->DMAKickoffCallback = NVDMAKickoffCallback; } static void -NVSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, - int patternx, int patterny, - int x, int y, int w, int h) +NVSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) { - NVPtr pNv = NVPTR(pScrn); + NVPtr pNv = NVPTR(pScrn); - RIVA_FIFO_FREE(pNv->riva, Bitmap, 2); - pNv->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y; - write_mem_barrier(); - pNv->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h; - write_mem_barrier(); -} + NVDmaStart(pNv, RECT_SOLID_RECTS(0), 2); + NVDmaNext (pNv, (x << 16) | y); + NVDmaNext (pNv, (w << 16) | h); + if((w * h) >= 512) + NVDmaKickoff(pNv); +} -void -NVResetGraphics(ScrnInfoPtr pScrn) +static void +NVSetupForMono8x8PatternFill ( + ScrnInfoPtr pScrn, + int patternx, int patterny, + int fg, int bg, + int rop, + unsigned planemask +) { - NVPtr pNv = NVPTR(pScrn); + NVPtr pNv = NVPTR(pScrn); - if(pNv->NoAccel) return; + planemask = ~0 << pNv->CurrentLayout.depth; - pNv->currentRop = -1; - NVSetRopPattern(pNv, GXcopy); -} + fg |= planemask; + if(bg == -1) bg = 0; + else bg |= planemask; + if (pNv->currentRop != (rop + 16)) { + NVDmaStart(pNv, ROP_SET, 1); + NVDmaNext (pNv, NVPatternROP[rop]); + pNv->currentRop = rop + 16; + } + NVSetPattern(pScrn, bg, fg, patternx, patterny); + NVDmaStart(pNv, RECT_SOLID_COLOR, 1); + NVDmaNext (pNv, fg); -/* - * Synchronise with graphics engine. Make sure it is idle before returning. - * Should attempt to yield CPU if busy for awhile. - */ -void NVSync(ScrnInfoPtr pScrn) -{ - NVPtr pNv = NVPTR(pScrn); - RIVA_BUSY(pNv->riva); + pNv->DMAKickoffCallback = NVDMAKickoffCallback; } -/* Color expansion */ static void -NVSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, - int fg, int bg, int rop, - unsigned int planemask) +NVSubsequentMono8x8PatternFillRect( + ScrnInfoPtr pScrn, + int patternx, int patterny, + int x, int y, + int w, int h +) { - NVPtr pNv = NVPTR(pScrn); + NVPtr pNv = NVPTR(pScrn); - NVSetRopSolid(pNv, rop); + NVDmaStart(pNv, RECT_SOLID_RECTS(0), 2); + NVDmaNext (pNv, (x << 16) | y); + NVDmaNext (pNv, (w << 16) | h); - if ( bg == -1 ) - { - /* Transparent case */ - bg = 0x80000000; - pNv->expandFifo = (unsigned char*)&pNv->riva.Bitmap->MonochromeData1C; - } - else - { - pNv->expandFifo = (unsigned char*)&pNv->riva.Bitmap->MonochromeData01E; - if (pScrn->depth == 16) - { - bg = ((bg & 0x0000F800) << 8) - | ((bg & 0x000007E0) << 5) - | ((bg & 0x0000001F) << 3) - | 0xFF000000; - } - else - { - bg |= pNv->opaqueMonochrome; - }; - } - pNv->FgColor = fg; - pNv->BgColor = bg; + if((w * h) >= 512) + NVDmaKickoff(pNv); } +static CARD32 _bg_pixel; +static CARD32 _fg_pixel; +static Bool _transparent; +static CARD32 _color_expand_dwords; +static CARD32 _color_expand_offset; +static int _remaining; +static unsigned char *_storage_buffer[1]; + static void -NVSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) +NVSetupForScanlineCPUToScreenColorExpandFill ( + ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask +) { - NVPtr pNv = NVPTR(pScrn); + NVPtr pNv = NVPTR(pScrn); - int t = pNv->expandWidth; - CARD32 *pbits = (CARD32*)pNv->expandBuffer; - CARD32 *d = (CARD32*)pNv->expandFifo; - - while(t >= 16) - { - RIVA_FIFO_FREE(pNv->riva, Bitmap, 16); - d[0] = pbits[0]; - d[1] = pbits[1]; - d[2] = pbits[2]; - d[3] = pbits[3]; - d[4] = pbits[4]; - d[5] = pbits[5]; - d[6] = pbits[6]; - d[7] = pbits[7]; - d[8] = pbits[8]; - d[9] = pbits[9]; - d[10] = pbits[10]; - d[11] = pbits[11]; - d[12] = pbits[12]; - d[13] = pbits[13]; - d[14] = pbits[14]; - d[15] = pbits[15]; - t -= 16; pbits += 16; - } - if(t) { - RIVA_FIFO_FREE(pNv->riva, Bitmap, t); - while(t >= 4) - { - d[0] = pbits[0]; - d[1] = pbits[1]; - d[2] = pbits[2]; - d[3] = pbits[3]; - t -= 4; pbits += 4; - } - while(t--) - *(d++) = *(pbits++); - } + CARD32 mask = ~0 << pNv->CurrentLayout.depth; - if (!(--pNv->expandRows)) { /* hardware bug workaround */ - RIVA_FIFO_FREE(pNv->riva, Blt, 1); - write_mem_barrier(); - pNv->riva.Blt->TopLeftSrc = 0; - } - write_mem_barrier(); + planemask |= mask; + _fg_pixel = fg | mask; + + if(bg == -1) { + _transparent = TRUE; + } else { + _transparent = FALSE; + _bg_pixel = bg | mask; + } + + NVSetRopSolid (pScrn, rop, planemask); } static void -NVSubsequentColorExpandScanlineFifo(ScrnInfoPtr pScrn, int bufno) +NVSubsequentScanlineCPUToScreenColorExpandFill ( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft +) { - NVPtr pNv = NVPTR(pScrn); + NVPtr pNv = NVPTR(pScrn); + int bw = (w + 31) & ~31; + + _color_expand_dwords = bw >> 5; + _remaining = h; + + if(_transparent) { + NVDmaStart(pNv, RECT_EXPAND_ONE_COLOR_CLIP, 5); + NVDmaNext (pNv, (y << 16) | ((x + skipleft) & 0xFFFF)); + NVDmaNext (pNv, ((y + h) << 16) | ((x + w) & 0xFFFF)); + NVDmaNext (pNv, _fg_pixel); + NVDmaNext (pNv, (h << 16) | bw); + NVDmaNext (pNv, (y << 16) | (x & 0xFFFF)); + _color_expand_offset = RECT_EXPAND_ONE_COLOR_DATA(0); + } else { + NVDmaStart(pNv, RECT_EXPAND_TWO_COLOR_CLIP, 7); + NVDmaNext (pNv, (y << 16) | ((x + skipleft) & 0xFFFF)); + NVDmaNext (pNv, ((y + h) << 16) | ((x + w) & 0xFFFF)); + NVDmaNext (pNv, _bg_pixel); + NVDmaNext (pNv, _fg_pixel); + NVDmaNext (pNv, (h << 16) | bw); + NVDmaNext (pNv, (h << 16) | bw); + NVDmaNext (pNv, (y << 16) | (x & 0xFFFF)); + _color_expand_offset = RECT_EXPAND_TWO_COLOR_DATA(0); + } - if ( --pNv->expandRows ) { - RIVA_FIFO_FREE(pNv->riva, Bitmap, pNv->expandWidth); - } else { /* hardware bug workaround */ - RIVA_FIFO_FREE(pNv->riva, Blt, 1); - write_mem_barrier(); - pNv->riva.Blt->TopLeftSrc = 0; - } - write_mem_barrier(); + NVDmaStart(pNv, _color_expand_offset, _color_expand_dwords); + _storage_buffer[0] = (unsigned char*)&pNv->dmaBase[pNv->dmaCurrent]; } static void -NVSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, - int y, int w, int h, - int skipleft) +NVSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) { - int bw; - NVPtr pNv = NVPTR(pScrn); - - bw = (w + 31) & ~31; - pNv->expandWidth = bw >> 5; - - if ( pNv->BgColor == 0x80000000 ) - { - /* Use faster transparent method */ - RIVA_FIFO_FREE(pNv->riva, Bitmap, 5); - pNv->riva.Bitmap->ClipC.TopLeft = (y << 16) | ((x+skipleft) - & 0xFFFF); - pNv->riva.Bitmap->ClipC.BottomRight = ((y+h) << 16) | ((x+w)&0xffff); - pNv->riva.Bitmap->Color1C = pNv->FgColor; - pNv->riva.Bitmap->WidthHeightC = (h << 16) | bw; - write_mem_barrier(); - pNv->riva.Bitmap->PointC = (y << 16) | (x & 0xFFFF); - write_mem_barrier(); - } - else - { - /* Opaque */ - RIVA_FIFO_FREE(pNv->riva, Bitmap, 7); - pNv->riva.Bitmap->ClipE.TopLeft = (y << 16) | ((x+skipleft) - & 0xFFFF); - pNv->riva.Bitmap->ClipE.BottomRight = ((y+h) << 16) | ((x+w)&0xffff); - pNv->riva.Bitmap->Color0E = pNv->BgColor; - pNv->riva.Bitmap->Color1E = pNv->FgColor; - pNv->riva.Bitmap->WidthHeightInE = (h << 16) | bw; - pNv->riva.Bitmap->WidthHeightOutE = (h << 16) | bw; - write_mem_barrier(); - pNv->riva.Bitmap->PointE = (y << 16) | (x & 0xFFFF); - write_mem_barrier(); - } + NVPtr pNv = NVPTR(pScrn); + + pNv->dmaCurrent += _color_expand_dwords; + + if(--_remaining) { + NVDmaStart(pNv, _color_expand_offset, _color_expand_dwords); + _storage_buffer[0] = (unsigned char*)&pNv->dmaBase[pNv->dmaCurrent]; + } else { + /* hardware bug workaround */ + NVDmaStart(pNv, BLIT_POINT_SRC, 1); + NVDmaNext (pNv, 0); + NVDmaKickoff(pNv); + } +} - pNv->expandRows = h; +static void +NVSetupForScanlineImageWrite( + ScrnInfoPtr pScrn, int rop, + unsigned int planemask, + int trans_color, + int bpp, int depth +) +{ + NVPtr pNv = NVPTR(pScrn); - if(pNv->expandWidth > (pNv->riva.FifoEmptyCount >> 2)) { - pNv->AccelInfoRec->ScanlineColorExpandBuffers = &pNv->expandBuffer; - pNv->AccelInfoRec->SubsequentColorExpandScanline = - NVSubsequentColorExpandScanline; - } else { - pNv->AccelInfoRec->ScanlineColorExpandBuffers = &pNv->expandFifo; - pNv->AccelInfoRec->SubsequentColorExpandScanline = - NVSubsequentColorExpandScanlineFifo; - RIVA_FIFO_FREE(pNv->riva, Bitmap, pNv->expandWidth); - } + planemask |= ~0 << pNv->CurrentLayout.depth; + + NVSetRopSolid (pScrn, rop, planemask); +} + +static CARD32 _image_size; +static CARD32 _image_srcpoint; +static CARD32 _image_dstpoint; +static CARD32 _image_dstpitch; + +static void +NVSubsequentScanlineImageWriteRect( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft +) +{ + NVPtr pNv = NVPTR(pScrn); + int Bpp = pNv->CurrentLayout.bitsPerPixel >> 3; + int image_srcpitch; + + _image_size = (1 << 16) | (w - skipleft); + _image_srcpoint = skipleft; + _image_dstpoint = (y << 16) | (x + skipleft); + _remaining = h; + _image_dstpitch = pNv->CurrentLayout.displayWidth * Bpp; + image_srcpitch = ((w * Bpp) + 63) & ~63; + _storage_buffer[0] = pNv->FbStart + pNv->ScratchBufferStart; + + NVSync(pScrn); + + NVDmaStart(pNv, SURFACE_PITCH, 2); + NVDmaNext (pNv, (_image_dstpitch << 16) | image_srcpitch); + NVDmaNext (pNv, pNv->ScratchBufferStart); +} + +static void NVSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) +{ + NVPtr pNv = NVPTR(pScrn); + + NVDmaStart(pNv, BLIT_POINT_SRC, 3); + NVDmaNext (pNv, _image_srcpoint); + NVDmaNext (pNv, _image_dstpoint); + NVDmaNext (pNv, _image_size); + NVDmaKickoff(pNv); + + if(--_remaining) { + _image_dstpoint += (1 << 16); + NVSync(pScrn); + } else { + NVDmaStart(pNv, SURFACE_PITCH, 2); + NVDmaNext (pNv, _image_dstpitch | (_image_dstpitch << 16)); + NVDmaNext (pNv, 0); + } } static void @@ -396,8 +578,13 @@ NVSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask) { NVPtr pNv = NVPTR(pScrn); - NVSetRopSolid(pNv, rop); - pNv->FgColor = color; + planemask |= ~0 << pNv->CurrentLayout.depth; + + NVSetRopSolid(pScrn, rop, planemask); + + _fg_pixel = color; + + pNv->DMAKickoffCallback = NVDMAKickoffCallback; } static void @@ -405,169 +592,124 @@ NVSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir) { NVPtr pNv = NVPTR(pScrn); - RIVA_FIFO_FREE(pNv->riva, Line, 3); - pNv->riva.Line->Color = pNv->FgColor; - pNv->riva.Line->Lin[0].point0 = ((y << 16) | ( x & 0xffff)); - write_mem_barrier(); - if ( dir ==DEGREES_0 ) - pNv->riva.Line->Lin[0].point1 = ((y << 16) | (( x + len ) & 0xffff)); - else - pNv->riva.Line->Lin[0].point1 = (((y + len) << 16) | ( x & 0xffff)); - write_mem_barrier(); + NVDmaStart(pNv, LINE_COLOR, 1); + NVDmaNext (pNv, _fg_pixel); + NVDmaStart(pNv, LINE_LINES(0), 2); + NVDmaNext (pNv, (y << 16) | ( x & 0xffff)); + if(dir == DEGREES_0) { + NVDmaNext (pNv, (y << 16) | ((x + len) & 0xffff)); + } else { + NVDmaNext (pNv, ((y + len) << 16) | (x & 0xffff)); + } } static void -NVSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, - int x2, int y2, int flags) +NVSubsequentSolidTwoPointLine( + ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2, + int flags +) { NVPtr pNv = NVPTR(pScrn); - Bool lastPoint = !(flags & OMIT_LAST); - - RIVA_FIFO_FREE(pNv->riva, Line, lastPoint ? 5 : 3); - pNv->riva.Line->Color = pNv->FgColor; - pNv->riva.Line->Lin[0].point0 = ((y1 << 16) | (x1 & 0xffff)); - write_mem_barrier(); - pNv->riva.Line->Lin[0].point1 = ((y2 << 16) | (x2 & 0xffff)); - write_mem_barrier(); - if (lastPoint) - { - pNv->riva.Line->Lin[1].point0 = ((y2 << 16) | (x2 & 0xffff)); - write_mem_barrier(); - pNv->riva.Line->Lin[1].point1 = (((y2 + 1) << 16) | (x2 & 0xffff)); - write_mem_barrier(); + Bool drawLast = !(flags & OMIT_LAST); + + NVDmaStart(pNv, LINE_COLOR, 1); + NVDmaNext (pNv, _fg_pixel); + NVDmaStart(pNv, LINE_LINES(0), drawLast ? 4 : 2); + NVDmaNext (pNv, (y1 << 16) | (x1 & 0xffff)); + NVDmaNext (pNv, (y2 << 16) | (x2 & 0xffff)); + if(drawLast) { + NVDmaNext (pNv, (y2 << 16) | (x2 & 0xffff)); + NVDmaNext (pNv, ((y2 + 1) << 16) | (x2 & 0xffff)); } } static void -NVValidatePolyArc( - GCPtr pGC, - unsigned long changes, - DrawablePtr pDraw -){ - if(pGC->planemask != ~0) return; +NVSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) +{ + NVPtr pNv = NVPTR(pScrn); + int h = y2 - y1 + 1; + int w = x2 - x1 + 1; - if(!pGC->lineWidth && - ((pGC->alu != GXcopy) || (pGC->lineStyle != LineSolid))) - { - pGC->ops->PolyArc = miZeroPolyArc; - } + NVDmaStart(pNv, CLIP_POINT, 2); + NVDmaNext (pNv, (y1 << 16) | x1); + NVDmaNext (pNv, (h << 16) | w); } static void -NVValidatePolyPoint( - GCPtr pGC, - unsigned long changes, - DrawablePtr pDraw -){ - pGC->ops->PolyPoint = XAAFallbackOps.PolyPoint; - - if(pGC->planemask != ~0) return; +NVDisableClipping(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); - if(pGC->alu != GXcopy) - pGC->ops->PolyPoint = miPolyPoint; + NVDmaStart(pNv, CLIP_POINT, 2); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, 0x7FFF7FFF); } + /* Initialize XAA acceleration info */ Bool NVAccelInit(ScreenPtr pScreen) { - XAAInfoRecPtr infoPtr; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - NVPtr pNv = NVPTR(pScrn); - Bool lowClocks; - - /* The hardware POSTs with clocks too low to support some acceleration - on NV20 and higher and we don't know enough about timing particulars - to raise them */ - - lowClocks = ((pNv->Chipset & 0x0ff0) >= 0x0200); - - pNv->AccelInfoRec = infoPtr = XAACreateInfoRec(); - if(!infoPtr) return FALSE; - - /* fill out infoPtr here */ - infoPtr->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS; - - /* sync */ - infoPtr->Sync = NVSync; - - /* solid fills */ - infoPtr->SolidFillFlags = NO_PLANEMASK; - infoPtr->SetupForSolidFill = NVSetupForSolidFill; - infoPtr->SubsequentSolidFillRect = NVSubsequentSolidFillRect; - - if(lowClocks) - infoPtr->SolidFillFlags |= GXCOPY_ONLY; - - /* screen to screen copy */ - infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK; - infoPtr->SetupForScreenToScreenCopy = NVSetupForScreenToScreenCopy; - infoPtr->SubsequentScreenToScreenCopy = NVSubsequentScreenToScreenCopy; - - /* 8x8 mono patterns */ - /* - * Set pattern opaque bits based on pixel format. - */ - pNv->opaqueMonochrome = ~((1 << pScrn->depth) - 1); - - pNv->currentRop = -1; - - infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN | - HARDWARE_PATTERN_PROGRAMMED_BITS | - NO_PLANEMASK; - infoPtr->SetupForMono8x8PatternFill = NVSetupForMono8x8PatternFill; - infoPtr->SubsequentMono8x8PatternFillRect = - NVSubsequentMono8x8PatternFillRect; - - /* Color expansion */ - infoPtr->ScanlineCPUToScreenColorExpandFillFlags = -#if X_BYTE_ORDER == X_BIG_ENDIAN - BIT_ORDER_IN_BYTE_MSBFIRST | -#else - BIT_ORDER_IN_BYTE_LSBFIRST | -#endif - NO_PLANEMASK | - CPU_TRANSFER_PAD_DWORD | - LEFT_EDGE_CLIPPING | - LEFT_EDGE_CLIPPING_NEGATIVE_X; - - infoPtr->NumScanlineColorExpandBuffers = 1; - - if(!lowClocks) { - infoPtr->SetupForScanlineCPUToScreenColorExpandFill = - NVSetupForScanlineCPUToScreenColorExpandFill; - infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = - NVSubsequentScanlineCPUToScreenColorExpandFill; - } - - pNv->expandFifo = (unsigned char*)&pNv->riva.Bitmap->MonochromeData01E; - - /* Allocate buffer for color expansion and also image writes in the - future */ - pNv->expandBuffer = xnfalloc(((pScrn->virtualX*pScrn->bitsPerPixel)/8) + 8); - - - infoPtr->ScanlineColorExpandBuffers = &pNv->expandBuffer; - infoPtr->SubsequentColorExpandScanline = NVSubsequentColorExpandScanline; - - infoPtr->SolidLineFlags = infoPtr->SolidFillFlags; - infoPtr->SetupForSolidLine = NVSetupForSolidLine; - infoPtr->SubsequentSolidHorVertLine = - NVSubsequentSolidHorVertLine; - infoPtr->SubsequentSolidTwoPointLine = - NVSubsequentSolidTwoPointLine; - infoPtr->SetClippingRectangle = NVSetClippingRectangle; - infoPtr->DisableClipping = NVDisableClipping; - infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE; - miSetZeroLineBias(pScreen, OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6); - - infoPtr->ValidatePolyArc = NVValidatePolyArc; - infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask; - infoPtr->ValidatePolyPoint = NVValidatePolyPoint; - infoPtr->PolyPointMask = GCFunction | GCPlaneMask; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + NVPtr pNv = NVPTR(pScrn); + XAAInfoRecPtr accel; + + accel = pNv->AccelInfoRec = XAACreateInfoRec(); + if(!accel) return FALSE; + + accel->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS; + accel->Sync = NVSync; + + accel->ScreenToScreenCopyFlags = NO_TRANSPARENCY; + accel->SetupForScreenToScreenCopy = NVSetupForScreenToScreenCopy; + accel->SubsequentScreenToScreenCopy = NVSubsequentScreenToScreenCopy; + + accel->SolidFillFlags = 0; + accel->SetupForSolidFill = NVSetupForSolidFill; + accel->SubsequentSolidFillRect = NVSubsequentSolidFillRect; + + accel->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN | + HARDWARE_PATTERN_PROGRAMMED_BITS | + NO_PLANEMASK; + accel->SetupForMono8x8PatternFill = NVSetupForMono8x8PatternFill; + accel->SubsequentMono8x8PatternFillRect = NVSubsequentMono8x8PatternFillRect; + + accel->ScanlineCPUToScreenColorExpandFillFlags = + BIT_ORDER_IN_BYTE_LSBFIRST | + CPU_TRANSFER_PAD_DWORD | + LEFT_EDGE_CLIPPING | + LEFT_EDGE_CLIPPING_NEGATIVE_X; + accel->NumScanlineColorExpandBuffers = 1; + accel->SetupForScanlineCPUToScreenColorExpandFill = + NVSetupForScanlineCPUToScreenColorExpandFill; + accel->SubsequentScanlineCPUToScreenColorExpandFill = + NVSubsequentScanlineCPUToScreenColorExpandFill; + accel->SubsequentColorExpandScanline = + NVSubsequentColorExpandScanline; + accel->ScanlineColorExpandBuffers = _storage_buffer; + + accel->ScanlineImageWriteFlags = NO_GXCOPY | + NO_TRANSPARENCY | + LEFT_EDGE_CLIPPING | + LEFT_EDGE_CLIPPING_NEGATIVE_X; + accel->NumScanlineImageWriteBuffers = 1; + accel->SetupForScanlineImageWrite = NVSetupForScanlineImageWrite; + accel->SubsequentScanlineImageWriteRect = NVSubsequentScanlineImageWriteRect; + accel->SubsequentImageWriteScanline = NVSubsequentImageWriteScanline; + accel->ScanlineImageWriteBuffers = _storage_buffer; + + accel->SolidLineFlags = 0; + accel->SetupForSolidLine = NVSetupForSolidLine; + accel->SubsequentSolidHorVertLine = NVSubsequentSolidHorVertLine; + accel->SubsequentSolidTwoPointLine = NVSubsequentSolidTwoPointLine; + accel->SetClippingRectangle = NVSetClippingRectangle; + accel->DisableClipping = NVDisableClipping; + accel->ClippingFlags = HARDWARE_CLIP_SOLID_LINE; - NVDisableClipping(pScrn); + miSetZeroLineBias(pScreen, OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6); - return(XAAInit(pScreen, infoPtr)); + return (XAAInit(pScreen, accel)); } |