1 /***************************************************************************\
3 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
5 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
6 |* international laws. Users and possessors of this source code are *|
7 |* hereby granted a nonexclusive, royalty-free copyright license to *|
8 |* use this code in individual and commercial software. *|
10 |* Any use of this source code must include, in the user documenta- *|
11 |* tion and internal comments to the code, notices to the end user *|
14 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
16 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
17 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
18 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
19 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
20 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
21 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
22 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
23 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
24 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
25 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
26 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
28 |* U.S. Government End Users. This source code is a "commercial *|
29 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
30 |* consisting of "commercial computer software" and "commercial *|
31 |* computer software documentation," as such terms are used in *|
32 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
33 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
34 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
35 |* all U.S. Government End Users acquire the source code with only *|
36 |* those rights set forth herein. *|
38 \***************************************************************************/
40 /* Hacked together from mga driver and 3.3.4 NVIDIA driver by
41 Jarno Paananen <jpaana@s2.org> */
43 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_xaa.c $ */
49 #include "riva_include.h"
56 RivaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
58 int height = y2-y1 + 1;
59 int width = x2-x1 + 1;
60 RivaPtr pRiva = RivaPTR(pScrn);
62 RIVA_FIFO_FREE(pRiva->riva, Clip, 2);
63 pRiva->riva.Clip->TopLeft = (y1 << 16) | (x1 & 0xffff);
64 pRiva->riva.Clip->WidthHeight = (height << 16) | width;
69 RivaDisableClipping(ScrnInfoPtr pScrn)
71 RivaSetClippingRectangle(pScrn, 0, 0, 0x7fff, 0x7fff);
75 * Set pattern. Internal routine. The upper bits of the colors
76 * are the ALPHA bits. 0 == transparency.
79 RivaSetPattern(RivaPtr pRiva, int clr0, int clr1, int pat0, int pat1)
81 RIVA_FIFO_FREE(pRiva->riva, Patt, 4);
82 pRiva->riva.Patt->Color0 = clr0;
83 pRiva->riva.Patt->Color1 = clr1;
84 pRiva->riva.Patt->Monochrome[0] = pat0;
85 pRiva->riva.Patt->Monochrome[1] = pat1;
89 * Set ROP. Translate X rop into ROP3. Internal routine.
92 RivaSetRopSolid(RivaPtr pRiva, int rop)
94 if (pRiva->currentRop != rop) {
95 if (pRiva->currentRop >= 16)
96 RivaSetPattern(pRiva, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
97 pRiva->currentRop = rop;
98 RIVA_FIFO_FREE(pRiva->riva, Rop, 1);
99 pRiva->riva.Rop->Rop3 = XAAGetCopyROP(rop);
104 RivaSetRopPattern(RivaPtr pRiva, int rop)
106 if (pRiva->currentRop != (rop + 16)) {
107 pRiva->currentRop = rop + 16; /* +16 is important */
108 RIVA_FIFO_FREE(pRiva->riva, Rop, 1);
109 pRiva->riva.Rop->Rop3 = XAAGetPatternROP(rop);
114 * Fill solid rectangles.
117 void RivaSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
120 RivaPtr pRiva = RivaPTR(pScrn);
122 RivaSetRopSolid(pRiva, rop);
123 RIVA_FIFO_FREE(pRiva->riva, Bitmap, 1);
124 pRiva->riva.Bitmap->Color1A = color;
128 RivaSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
130 RivaPtr pRiva = RivaPTR(pScrn);
132 RIVA_FIFO_FREE(pRiva->riva, Bitmap, 2);
133 pRiva->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y;
135 pRiva->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
140 * Screen to screen BLTs.
143 RivaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
144 unsigned planemask, int transparency_color)
146 RivaSetRopSolid(RivaPTR(pScrn), rop);
150 RivaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
151 int x2, int y2, int w, int h)
153 RivaPtr pRiva = RivaPTR(pScrn);
155 RIVA_FIFO_FREE(pRiva->riva, Blt, 3);
156 pRiva->riva.Blt->TopLeftSrc = (y1 << 16) | x1;
157 pRiva->riva.Blt->TopLeftDst = (y2 << 16) | x2;
159 pRiva->riva.Blt->WidthHeight = (h << 16) | w;
165 * Fill 8x8 monochrome pattern rectangles. patternx and patterny are
166 * the overloaded pattern bits themselves. The pattern colors don't
167 * support 565, only 555. Hack around it.
170 RivaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
171 int fg, int bg, int rop, unsigned planemask)
173 RivaPtr pRiva = RivaPTR(pScrn);
175 RivaSetRopPattern(pRiva, rop);
176 if (pScrn->depth == 16)
178 fg = ((fg & 0x0000F800) << 8)
179 | ((fg & 0x000007E0) << 5)
180 | ((fg & 0x0000001F) << 3)
183 bg = ((bg & 0x0000F800) << 8)
184 | ((bg & 0x000007E0) << 5)
185 | ((bg & 0x0000001F) << 3)
192 fg |= pRiva->opaqueMonochrome;
193 bg = (bg == -1) ? 0 : bg | pRiva->opaqueMonochrome;
195 RivaSetPattern(pRiva, bg, fg, patternx, patterny);
196 RIVA_FIFO_FREE(pRiva->riva, Bitmap, 1);
197 pRiva->riva.Bitmap->Color1A = fg;
201 RivaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
202 int patternx, int patterny,
203 int x, int y, int w, int h)
205 RivaPtr pRiva = RivaPTR(pScrn);
207 RIVA_FIFO_FREE(pRiva->riva, Bitmap, 2);
208 pRiva->riva.Bitmap->UnclippedRectangle[0].TopLeft = (x << 16) | y;
210 pRiva->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
216 RivaResetGraphics(ScrnInfoPtr pScrn)
218 RivaPtr pRiva = RivaPTR(pScrn);
220 if(pRiva->NoAccel) return;
222 RIVA_FIFO_FREE(pRiva->riva, Patt, 1);
223 pRiva->riva.Patt->Shape = 0;
224 RivaDisableClipping(pScrn);
225 pRiva->currentRop = 16; /* to force RivaSetRopSolid to reset the pattern */
226 RivaSetRopSolid(pRiva, GXcopy);
232 * Synchronise with graphics engine. Make sure it is idle before returning.
233 * Should attempt to yield CPU if busy for awhile.
235 void RivaSync(ScrnInfoPtr pScrn)
237 RivaPtr pRiva = RivaPTR(pScrn);
238 RIVA_BUSY(pRiva->riva);
241 /* Color expansion */
243 RivaSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
244 int fg, int bg, int rop,
245 unsigned int planemask)
247 RivaPtr pRiva = RivaPTR(pScrn);
249 RivaSetRopSolid(pRiva, rop);
253 /* Transparent case */
255 pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData1C;
259 pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData01E;
260 if (pScrn->depth == 16)
262 bg = ((bg & 0x0000F800) << 8)
263 | ((bg & 0x000007E0) << 5)
264 | ((bg & 0x0000001F) << 3)
269 bg |= pRiva->opaqueMonochrome;
277 RivaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
279 RivaPtr pRiva = RivaPTR(pScrn);
281 int t = pRiva->expandWidth;
282 CARD32 *pbits = (CARD32*)pRiva->expandBuffer;
283 CARD32 *d = (CARD32*)pRiva->expandFifo;
287 RIVA_FIFO_FREE(pRiva->riva, Bitmap, 16);
304 t -= 16; pbits += 16;
307 RIVA_FIFO_FREE(pRiva->riva, Bitmap, t);
320 if (!(--pRiva->expandRows)) { /* hardware bug workaround */
321 RIVA_FIFO_FREE(pRiva->riva, Blt, 1);
323 pRiva->riva.Blt->TopLeftSrc = 0;
329 RivaSubsequentColorExpandScanlineFifo(ScrnInfoPtr pScrn, int bufno)
331 RivaPtr pRiva = RivaPTR(pScrn);
333 if ( --pRiva->expandRows ) {
334 RIVA_FIFO_FREE(pRiva->riva, Bitmap, pRiva->expandWidth);
335 } else { /* hardware bug workaround */
336 RIVA_FIFO_FREE(pRiva->riva, Blt, 1);
338 pRiva->riva.Blt->TopLeftSrc = 0;
344 RivaSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
349 RivaPtr pRiva = RivaPTR(pScrn);
352 pRiva->expandWidth = bw >> 5;
354 if ( pRiva->BgColor == 0x80000000 )
356 /* Use faster transparent method */
357 RIVA_FIFO_FREE(pRiva->riva, Bitmap, 5);
358 pRiva->riva.Bitmap->ClipC.TopLeft = (y << 16) | ((x+skipleft)
360 pRiva->riva.Bitmap->ClipC.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
361 pRiva->riva.Bitmap->Color1C = pRiva->FgColor;
362 pRiva->riva.Bitmap->WidthHeightC = (h << 16) | bw;
364 pRiva->riva.Bitmap->PointC = (y << 16) | (x & 0xFFFF);
370 RIVA_FIFO_FREE(pRiva->riva, Bitmap, 7);
371 pRiva->riva.Bitmap->ClipE.TopLeft = (y << 16) | ((x+skipleft)
373 pRiva->riva.Bitmap->ClipE.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
374 pRiva->riva.Bitmap->Color0E = pRiva->BgColor;
375 pRiva->riva.Bitmap->Color1E = pRiva->FgColor;
376 pRiva->riva.Bitmap->WidthHeightInE = (h << 16) | bw;
377 pRiva->riva.Bitmap->WidthHeightOutE = (h << 16) | bw;
379 pRiva->riva.Bitmap->PointE = (y << 16) | (x & 0xFFFF);
383 pRiva->expandRows = h;
385 if(pRiva->expandWidth > (pRiva->riva.FifoEmptyCount >> 2)) {
386 pRiva->AccelInfoRec->ScanlineColorExpandBuffers = &pRiva->expandBuffer;
387 pRiva->AccelInfoRec->SubsequentColorExpandScanline =
388 RivaSubsequentColorExpandScanline;
390 pRiva->AccelInfoRec->ScanlineColorExpandBuffers = &pRiva->expandFifo;
391 pRiva->AccelInfoRec->SubsequentColorExpandScanline =
392 RivaSubsequentColorExpandScanlineFifo;
393 RIVA_FIFO_FREE(pRiva->riva, Bitmap, pRiva->expandWidth);
398 RivaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask)
400 RivaPtr pRiva = RivaPTR(pScrn);
402 RivaSetRopSolid(pRiva, rop);
403 pRiva->FgColor = color;
407 RivaSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir)
409 RivaPtr pRiva = RivaPTR(pScrn);
411 RIVA_FIFO_FREE(pRiva->riva, Line, 3);
412 pRiva->riva.Line->Color = pRiva->FgColor;
413 pRiva->riva.Line->Lin[0].point0 = ((y << 16) | ( x & 0xffff));
415 if ( dir ==DEGREES_0 )
416 pRiva->riva.Line->Lin[0].point1 = ((y << 16) | (( x + len ) & 0xffff));
418 pRiva->riva.Line->Lin[0].point1 = (((y + len) << 16) | ( x & 0xffff));
423 RivaSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1,
424 int x2, int y2, int flags)
426 RivaPtr pRiva = RivaPTR(pScrn);
427 Bool lastPoint = !(flags & OMIT_LAST);
429 RIVA_FIFO_FREE(pRiva->riva, Line, lastPoint ? 5 : 3);
430 pRiva->riva.Line->Color = pRiva->FgColor;
431 pRiva->riva.Line->Lin[0].point0 = ((y1 << 16) | (x1 & 0xffff));
433 pRiva->riva.Line->Lin[0].point1 = ((y2 << 16) | (x2 & 0xffff));
437 pRiva->riva.Line->Lin[1].point0 = ((y2 << 16) | (x2 & 0xffff));
439 pRiva->riva.Line->Lin[1].point1 = (((y2 + 1) << 16) | (x2 & 0xffff));
447 unsigned long changes,
450 if(pGC->planemask != ~0) return;
452 if(!pGC->lineWidth &&
453 ((pGC->alu != GXcopy) || (pGC->lineStyle != LineSolid)))
455 pGC->ops->PolyArc = miZeroPolyArc;
460 RivaValidatePolyPoint(
462 unsigned long changes,
465 pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint;
467 if(pGC->planemask != ~0) return;
469 if(pGC->alu != GXcopy)
470 pGC->ops->PolyPoint = miPolyPoint;
473 /* Initialize XAA acceleration info */
475 RivaAccelInit(ScreenPtr pScreen)
477 XAAInfoRecPtr infoPtr;
478 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
479 RivaPtr pRiva = RivaPTR(pScrn);
481 pRiva->AccelInfoRec = infoPtr = XAACreateInfoRec();
482 if(!infoPtr) return FALSE;
484 /* fill out infoPtr here */
485 infoPtr->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
488 infoPtr->Sync = RivaSync;
491 infoPtr->SolidFillFlags = NO_PLANEMASK;
492 infoPtr->SetupForSolidFill = RivaSetupForSolidFill;
493 infoPtr->SubsequentSolidFillRect = RivaSubsequentSolidFillRect;
495 /* screen to screen copy */
496 infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
497 infoPtr->SetupForScreenToScreenCopy = RivaSetupForScreenToScreenCopy;
498 infoPtr->SubsequentScreenToScreenCopy = RivaSubsequentScreenToScreenCopy;
500 /* 8x8 mono patterns */
502 * Set pattern opaque bits based on pixel format.
504 pRiva->opaqueMonochrome = ~((1 << pScrn->depth) - 1);
506 infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN |
507 HARDWARE_PATTERN_PROGRAMMED_BITS |
509 infoPtr->SetupForMono8x8PatternFill = RivaSetupForMono8x8PatternFill;
510 infoPtr->SubsequentMono8x8PatternFillRect =
511 RivaSubsequentMono8x8PatternFillRect;
513 /* Color expansion */
514 infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
515 BIT_ORDER_IN_BYTE_LSBFIRST |
517 CPU_TRANSFER_PAD_DWORD |
519 LEFT_EDGE_CLIPPING_NEGATIVE_X;
521 infoPtr->NumScanlineColorExpandBuffers = 1;
523 infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
524 RivaSetupForScanlineCPUToScreenColorExpandFill;
525 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
526 RivaSubsequentScanlineCPUToScreenColorExpandFill;
528 pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData01E;
530 /* Allocate buffer for color expansion and also image writes in the
532 pRiva->expandBuffer = xnfalloc(((pScrn->virtualX*pScrn->bitsPerPixel)/8) + 8);
535 infoPtr->ScanlineColorExpandBuffers = &pRiva->expandBuffer;
536 infoPtr->SubsequentColorExpandScanline = RivaSubsequentColorExpandScanline;
538 infoPtr->SolidLineFlags = infoPtr->SolidFillFlags;
539 infoPtr->SetupForSolidLine = RivaSetupForSolidLine;
540 infoPtr->SubsequentSolidHorVertLine =
541 RivaSubsequentSolidHorVertLine;
542 infoPtr->SubsequentSolidTwoPointLine =
543 RivaSubsequentSolidTwoPointLine;
544 infoPtr->SetClippingRectangle = RivaSetClippingRectangle;
545 infoPtr->DisableClipping = RivaDisableClipping;
546 infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE;
547 miSetZeroLineBias(pScreen, OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6);
549 infoPtr->ValidatePolyArc = RivaValidatePolyArc;
550 infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask;
551 infoPtr->ValidatePolyPoint = RivaValidatePolyPoint;
552 infoPtr->PolyPointMask = GCFunction | GCPlaneMask;
554 RivaResetGraphics(pScrn);
556 return(XAAInit(pScreen, infoPtr));