summaryrefslogtreecommitdiff
path: root/src/nv_xaa.c
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-26 22:48:59 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-26 22:48:59 +0000
commitb56dd6bacff59e17249b5a1427f99edf93657f30 (patch)
tree35b54cb736b90c40f13185173092c178038b7e8c /src/nv_xaa.c
parent6962e55a393c6b1cddf6b23f9c39842234b4ef7d (diff)
merge latest (4.3.99.16) from XFree86 (vendor) branch
Diffstat (limited to 'src/nv_xaa.c')
-rw-r--r--src/nv_xaa.c976
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));
}