summaryrefslogtreecommitdiff
path: root/src/riva_xaa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/riva_xaa.c')
-rw-r--r--src/riva_xaa.c554
1 files changed, 554 insertions, 0 deletions
diff --git a/src/riva_xaa.c b/src/riva_xaa.c
new file mode 100644
index 0000000..240e9ec
--- /dev/null
+++ b/src/riva_xaa.c
@@ -0,0 +1,554 @@
+ /***************************************************************************\
+|* *|
+|* Copyright 1993-1999 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 *|
+|* hereby granted a nonexclusive, royalty-free copyright license to *|
+|* use this code in individual and commercial software. *|
+|* *|
+|* Any use of this source code must include, in the user documenta- *|
+|* tion and internal comments to the code, notices to the end user *|
+|* as follows: *|
+|* *|
+|* Copyright 1993-1999 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" *|
+|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
+|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
+|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
+|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
+|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
+|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
+|* SULTING 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 SOURCE CODE. *|
+|* *|
+|* U.S. Government End Users. This source code is a "commercial *|
+|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
+|* consisting of "commercial computer software" and "commercial *|
+|* computer software documentation," as such terms are used in *|
+|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
+|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
+|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
+|* all U.S. Government End Users acquire the source code with only *|
+|* those rights set forth herein. *|
+|* *|
+ \***************************************************************************/
+
+/* 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/riva_xaa.c,v 1.1 2003/07/31 20:24:31 mvojkovi Exp $ */
+
+#include "riva_include.h"
+#include "xaalocal.h"
+#include "xaarop.h"
+
+#include "miline.h"
+
+static void
+RivaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
+{
+ int height = y2-y1 + 1;
+ int width = x2-x1 + 1;
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RIVA_FIFO_FREE(pRiva->riva, Clip, 2);
+ pRiva->riva.Clip->TopLeft = (y1 << 16) | (x1 & 0xffff);
+ pRiva->riva.Clip->WidthHeight = (height << 16) | width;
+}
+
+
+static void
+RivaDisableClipping(ScrnInfoPtr pScrn)
+{
+ RivaSetClippingRectangle(pScrn, 0, 0, 0x7fff, 0x7fff);
+}
+
+/*
+ * Set pattern. Internal routine. The upper bits of the colors
+ * are the ALPHA bits. 0 == transparency.
+ */
+static void
+RivaSetPattern(RivaPtr pRiva, int clr0, int clr1, int pat0, int pat1)
+{
+ RIVA_FIFO_FREE(pRiva->riva, Patt, 4);
+ pRiva->riva.Patt->Color0 = clr0;
+ pRiva->riva.Patt->Color1 = clr1;
+ pRiva->riva.Patt->Monochrome[0] = pat0;
+ pRiva->riva.Patt->Monochrome[1] = pat1;
+}
+
+/*
+ * Set ROP. Translate X rop into ROP3. Internal routine.
+ */
+static void
+RivaSetRopSolid(RivaPtr pRiva, int rop)
+{
+ if (pRiva->currentRop != rop) {
+ if (pRiva->currentRop >= 16)
+ RivaSetPattern(pRiva, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+ pRiva->currentRop = rop;
+ RIVA_FIFO_FREE(pRiva->riva, Rop, 1);
+ pRiva->riva.Rop->Rop3 = XAACopyROP[rop];
+ }
+}
+
+static void
+RivaSetRopPattern(RivaPtr pRiva, int rop)
+{
+ if (pRiva->currentRop != (rop + 16)) {
+ pRiva->currentRop = rop + 16; /* +16 is important */
+ RIVA_FIFO_FREE(pRiva->riva, Rop, 1);
+ pRiva->riva.Rop->Rop3 = XAAPatternROP[rop];
+ }
+}
+
+/*
+ * Fill solid rectangles.
+ */
+static
+void RivaSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned planemask)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RivaSetRopSolid(pRiva, rop);
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, 1);
+ pRiva->riva.Bitmap->Color1A = color;
+}
+
+static void
+RivaSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, 2);
+ pRiva->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y;
+ write_mem_barrier();
+ pRiva->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
+ write_mem_barrier();
+}
+
+/*
+ * Screen to screen BLTs.
+ */
+static void
+RivaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
+ unsigned planemask, int transparency_color)
+{
+ RivaSetRopSolid(RivaPTR(pScrn), rop);
+}
+
+static void
+RivaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int w, int h)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RIVA_FIFO_FREE(pRiva->riva, Blt, 3);
+ pRiva->riva.Blt->TopLeftSrc = (y1 << 16) | x1;
+ pRiva->riva.Blt->TopLeftDst = (y2 << 16) | x2;
+ write_mem_barrier();
+ pRiva->riva.Blt->WidthHeight = (h << 16) | w;
+ write_mem_barrier();
+}
+
+
+/*
+ * 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
+RivaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
+ int fg, int bg, int rop, unsigned planemask)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RivaSetRopPattern(pRiva, 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 |= pRiva->opaqueMonochrome;
+ bg = (bg == -1) ? 0 : bg | pRiva->opaqueMonochrome;
+ };
+ RivaSetPattern(pRiva, bg, fg, patternx, patterny);
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, 1);
+ pRiva->riva.Bitmap->Color1A = fg;
+}
+
+static void
+RivaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
+ int patternx, int patterny,
+ int x, int y, int w, int h)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, 2);
+ pRiva->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y;
+ write_mem_barrier();
+ pRiva->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
+ write_mem_barrier();
+}
+
+
+void
+RivaResetGraphics(ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ if(pRiva->NoAccel) return;
+
+ RIVA_FIFO_FREE(pRiva->riva, Patt, 1);
+ pRiva->riva.Patt->Shape = 0;
+ RivaDisableClipping(pScrn);
+ pRiva->currentRop = 16; /* to force RivaSetRopSolid to reset the pattern */
+ RivaSetRopSolid(pRiva, GXcopy);
+}
+
+
+
+/*
+ * Synchronise with graphics engine. Make sure it is idle before returning.
+ * Should attempt to yield CPU if busy for awhile.
+ */
+void RivaSync(ScrnInfoPtr pScrn)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ RIVA_BUSY(pRiva->riva);
+}
+
+/* Color expansion */
+static void
+RivaSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RivaSetRopSolid(pRiva, rop);
+
+ if ( bg == -1 )
+ {
+ /* Transparent case */
+ bg = 0x80000000;
+ pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData1C;
+ }
+ else
+ {
+ pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData01E;
+ if (pScrn->depth == 16)
+ {
+ bg = ((bg & 0x0000F800) << 8)
+ | ((bg & 0x000007E0) << 5)
+ | ((bg & 0x0000001F) << 3)
+ | 0xFF000000;
+ }
+ else
+ {
+ bg |= pRiva->opaqueMonochrome;
+ };
+ }
+ pRiva->FgColor = fg;
+ pRiva->BgColor = bg;
+}
+
+static void
+RivaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ int t = pRiva->expandWidth;
+ CARD32 *pbits = (CARD32*)pRiva->expandBuffer;
+ CARD32 *d = (CARD32*)pRiva->expandFifo;
+
+ while(t >= 16)
+ {
+ RIVA_FIFO_FREE(pRiva->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(pRiva->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++);
+ }
+
+ if (!(--pRiva->expandRows)) { /* hardware bug workaround */
+ RIVA_FIFO_FREE(pRiva->riva, Blt, 1);
+ write_mem_barrier();
+ pRiva->riva.Blt->TopLeftSrc = 0;
+ }
+ write_mem_barrier();
+}
+
+static void
+RivaSubsequentColorExpandScanlineFifo(ScrnInfoPtr pScrn, int bufno)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ if ( --pRiva->expandRows ) {
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, pRiva->expandWidth);
+ } else { /* hardware bug workaround */
+ RIVA_FIFO_FREE(pRiva->riva, Blt, 1);
+ write_mem_barrier();
+ pRiva->riva.Blt->TopLeftSrc = 0;
+ }
+ write_mem_barrier();
+}
+
+static void
+RivaSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
+ int y, int w, int h,
+ int skipleft)
+{
+ int bw;
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ bw = (w + 31) & ~31;
+ pRiva->expandWidth = bw >> 5;
+
+ if ( pRiva->BgColor == 0x80000000 )
+ {
+ /* Use faster transparent method */
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, 5);
+ pRiva->riva.Bitmap->ClipC.TopLeft = (y << 16) | ((x+skipleft)
+ & 0xFFFF);
+ pRiva->riva.Bitmap->ClipC.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
+ pRiva->riva.Bitmap->Color1C = pRiva->FgColor;
+ pRiva->riva.Bitmap->WidthHeightC = (h << 16) | bw;
+ write_mem_barrier();
+ pRiva->riva.Bitmap->PointC = (y << 16) | (x & 0xFFFF);
+ write_mem_barrier();
+ }
+ else
+ {
+ /* Opaque */
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, 7);
+ pRiva->riva.Bitmap->ClipE.TopLeft = (y << 16) | ((x+skipleft)
+ & 0xFFFF);
+ pRiva->riva.Bitmap->ClipE.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
+ pRiva->riva.Bitmap->Color0E = pRiva->BgColor;
+ pRiva->riva.Bitmap->Color1E = pRiva->FgColor;
+ pRiva->riva.Bitmap->WidthHeightInE = (h << 16) | bw;
+ pRiva->riva.Bitmap->WidthHeightOutE = (h << 16) | bw;
+ write_mem_barrier();
+ pRiva->riva.Bitmap->PointE = (y << 16) | (x & 0xFFFF);
+ write_mem_barrier();
+ }
+
+ pRiva->expandRows = h;
+
+ if(pRiva->expandWidth > (pRiva->riva.FifoEmptyCount >> 2)) {
+ pRiva->AccelInfoRec->ScanlineColorExpandBuffers = &pRiva->expandBuffer;
+ pRiva->AccelInfoRec->SubsequentColorExpandScanline =
+ RivaSubsequentColorExpandScanline;
+ } else {
+ pRiva->AccelInfoRec->ScanlineColorExpandBuffers = &pRiva->expandFifo;
+ pRiva->AccelInfoRec->SubsequentColorExpandScanline =
+ RivaSubsequentColorExpandScanlineFifo;
+ RIVA_FIFO_FREE(pRiva->riva, Bitmap, pRiva->expandWidth);
+ }
+}
+
+static void
+RivaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RivaSetRopSolid(pRiva, rop);
+ pRiva->FgColor = color;
+}
+
+static void
+RivaSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ RIVA_FIFO_FREE(pRiva->riva, Line, 3);
+ pRiva->riva.Line->Color = pRiva->FgColor;
+ pRiva->riva.Line->Lin[0].point0 = ((y << 16) | ( x & 0xffff));
+ write_mem_barrier();
+ if ( dir ==DEGREES_0 )
+ pRiva->riva.Line->Lin[0].point1 = ((y << 16) | (( x + len ) & 0xffff));
+ else
+ pRiva->riva.Line->Lin[0].point1 = (((y + len) << 16) | ( x & 0xffff));
+ write_mem_barrier();
+}
+
+static void
+RivaSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1,
+ int x2, int y2, int flags)
+{
+ RivaPtr pRiva = RivaPTR(pScrn);
+ Bool lastPoint = !(flags & OMIT_LAST);
+
+ RIVA_FIFO_FREE(pRiva->riva, Line, lastPoint ? 5 : 3);
+ pRiva->riva.Line->Color = pRiva->FgColor;
+ pRiva->riva.Line->Lin[0].point0 = ((y1 << 16) | (x1 & 0xffff));
+ write_mem_barrier();
+ pRiva->riva.Line->Lin[0].point1 = ((y2 << 16) | (x2 & 0xffff));
+ write_mem_barrier();
+ if (lastPoint)
+ {
+ pRiva->riva.Line->Lin[1].point0 = ((y2 << 16) | (x2 & 0xffff));
+ write_mem_barrier();
+ pRiva->riva.Line->Lin[1].point1 = (((y2 + 1) << 16) | (x2 & 0xffff));
+ write_mem_barrier();
+ }
+}
+
+static void
+RivaValidatePolyArc(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ if(pGC->planemask != ~0) return;
+
+ if(!pGC->lineWidth &&
+ ((pGC->alu != GXcopy) || (pGC->lineStyle != LineSolid)))
+ {
+ pGC->ops->PolyArc = miZeroPolyArc;
+ }
+}
+
+static void
+RivaValidatePolyPoint(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ pGC->ops->PolyPoint = XAAFallbackOps.PolyPoint;
+
+ if(pGC->planemask != ~0) return;
+
+ if(pGC->alu != GXcopy)
+ pGC->ops->PolyPoint = miPolyPoint;
+}
+
+/* Initialize XAA acceleration info */
+Bool
+RivaAccelInit(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoPtr;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RivaPtr pRiva = RivaPTR(pScrn);
+
+ pRiva->AccelInfoRec = infoPtr = XAACreateInfoRec();
+ if(!infoPtr) return FALSE;
+
+ /* fill out infoPtr here */
+ infoPtr->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
+
+ /* sync */
+ infoPtr->Sync = RivaSync;
+
+ /* solid fills */
+ infoPtr->SolidFillFlags = NO_PLANEMASK;
+ infoPtr->SetupForSolidFill = RivaSetupForSolidFill;
+ infoPtr->SubsequentSolidFillRect = RivaSubsequentSolidFillRect;
+
+ /* screen to screen copy */
+ infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
+ infoPtr->SetupForScreenToScreenCopy = RivaSetupForScreenToScreenCopy;
+ infoPtr->SubsequentScreenToScreenCopy = RivaSubsequentScreenToScreenCopy;
+
+ /* 8x8 mono patterns */
+ /*
+ * Set pattern opaque bits based on pixel format.
+ */
+ pRiva->opaqueMonochrome = ~((1 << pScrn->depth) - 1);
+
+ infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS |
+ NO_PLANEMASK;
+ infoPtr->SetupForMono8x8PatternFill = RivaSetupForMono8x8PatternFill;
+ infoPtr->SubsequentMono8x8PatternFillRect =
+ RivaSubsequentMono8x8PatternFillRect;
+
+ /* Color expansion */
+ infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
+ BIT_ORDER_IN_BYTE_LSBFIRST |
+ NO_PLANEMASK |
+ CPU_TRANSFER_PAD_DWORD |
+ LEFT_EDGE_CLIPPING |
+ LEFT_EDGE_CLIPPING_NEGATIVE_X;
+
+ infoPtr->NumScanlineColorExpandBuffers = 1;
+
+ infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
+ RivaSetupForScanlineCPUToScreenColorExpandFill;
+ infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
+ RivaSubsequentScanlineCPUToScreenColorExpandFill;
+
+ pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData01E;
+
+ /* Allocate buffer for color expansion and also image writes in the
+ future */
+ pRiva->expandBuffer = xnfalloc(((pScrn->virtualX*pScrn->bitsPerPixel)/8) + 8);
+
+
+ infoPtr->ScanlineColorExpandBuffers = &pRiva->expandBuffer;
+ infoPtr->SubsequentColorExpandScanline = RivaSubsequentColorExpandScanline;
+
+ infoPtr->SolidLineFlags = infoPtr->SolidFillFlags;
+ infoPtr->SetupForSolidLine = RivaSetupForSolidLine;
+ infoPtr->SubsequentSolidHorVertLine =
+ RivaSubsequentSolidHorVertLine;
+ infoPtr->SubsequentSolidTwoPointLine =
+ RivaSubsequentSolidTwoPointLine;
+ infoPtr->SetClippingRectangle = RivaSetClippingRectangle;
+ infoPtr->DisableClipping = RivaDisableClipping;
+ infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE;
+ miSetZeroLineBias(pScreen, OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6);
+
+ infoPtr->ValidatePolyArc = RivaValidatePolyArc;
+ infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask;
+ infoPtr->ValidatePolyPoint = RivaValidatePolyPoint;
+ infoPtr->PolyPointMask = GCFunction | GCPlaneMask;
+
+ RivaResetGraphics(pScrn);
+
+ return(XAAInit(pScreen, infoPtr));
+}
+