1fc5a983dSmrg/*
2fc5a983dSmrg * Copyright (c) 1993-1999 NVIDIA, Corporation
3fc5a983dSmrg *
4fc5a983dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5fc5a983dSmrg * copy of this software and associated documentation files (the
6fc5a983dSmrg * "Software"), to deal in the Software without restriction, including
7fc5a983dSmrg * without limitation the rights to use, copy, modify, merge, publish,
8fc5a983dSmrg * distribute, sublicense, and/or sell copies of the Software, and to
9fc5a983dSmrg * permit persons to whom the Software is furnished to do so, subject to
10fc5a983dSmrg * the following conditions:
11fc5a983dSmrg *
12fc5a983dSmrg * The above copyright notice and this permission notice shall be included
13fc5a983dSmrg * in all copies or substantial portions of the Software.
14fc5a983dSmrg *
15fc5a983dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16fc5a983dSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17fc5a983dSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18fc5a983dSmrg * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19fc5a983dSmrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20fc5a983dSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21fc5a983dSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22fc5a983dSmrg */
23fc5a983dSmrg
24fc5a983dSmrg/* Hacked together from mga driver and 3.3.4 NVIDIA driver by
25fc5a983dSmrg   Jarno Paananen <jpaana@s2.org> */
26fc5a983dSmrg
27fc5a983dSmrg#ifdef HAVE_CONFIG_H
28fc5a983dSmrg#include "config.h"
29fc5a983dSmrg#endif
30fc5a983dSmrg
31fc5a983dSmrg#include "riva_include.h"
32bd304fc0Smrg#ifdef HAVE_XAA_H
33fc5a983dSmrg#include "xaalocal.h"
34bd304fc0Smrg#endif
35fc5a983dSmrg#include "xaarop.h"
36fc5a983dSmrg#include "miline.h"
37fc5a983dSmrg
38fc5a983dSmrgstatic void
39fc5a983dSmrgRivaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2)
40fc5a983dSmrg{
41fc5a983dSmrg    int height = y2-y1 + 1;
42fc5a983dSmrg    int width  = x2-x1 + 1;
43fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
44fc5a983dSmrg
45fc5a983dSmrg    RIVA_FIFO_FREE(pRiva->riva, Clip, 2);
46fc5a983dSmrg    pRiva->riva.Clip->TopLeft     = (y1     << 16) | (x1 & 0xffff);
47fc5a983dSmrg    pRiva->riva.Clip->WidthHeight = (height << 16) | width;
48fc5a983dSmrg}
49fc5a983dSmrg
50fc5a983dSmrg
51fc5a983dSmrgstatic void
52fc5a983dSmrgRivaDisableClipping(ScrnInfoPtr pScrn)
53fc5a983dSmrg{
54fc5a983dSmrg    RivaSetClippingRectangle(pScrn, 0, 0, 0x7fff, 0x7fff);
55fc5a983dSmrg}
56fc5a983dSmrg
57fc5a983dSmrg/*
58fc5a983dSmrg * Set pattern. Internal routine. The upper bits of the colors
59fc5a983dSmrg * are the ALPHA bits.  0 == transparency.
60fc5a983dSmrg */
61fc5a983dSmrgstatic void
62fc5a983dSmrgRivaSetPattern(RivaPtr pRiva, int clr0, int clr1, int pat0, int pat1)
63fc5a983dSmrg{
64fc5a983dSmrg    RIVA_FIFO_FREE(pRiva->riva, Patt, 4);
65fc5a983dSmrg    pRiva->riva.Patt->Color0        = clr0;
66fc5a983dSmrg    pRiva->riva.Patt->Color1        = clr1;
67fc5a983dSmrg    pRiva->riva.Patt->Monochrome[0] = pat0;
68fc5a983dSmrg    pRiva->riva.Patt->Monochrome[1] = pat1;
69fc5a983dSmrg}
70fc5a983dSmrg
71fc5a983dSmrg/*
72fc5a983dSmrg * Set ROP.  Translate X rop into ROP3.  Internal routine.
73fc5a983dSmrg */
74fc5a983dSmrgstatic void
75fc5a983dSmrgRivaSetRopSolid(RivaPtr pRiva, int rop)
76fc5a983dSmrg{
77fc5a983dSmrg    if (pRiva->currentRop != rop) {
78fc5a983dSmrg        if (pRiva->currentRop >= 16)
79fc5a983dSmrg            RivaSetPattern(pRiva, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
80fc5a983dSmrg        pRiva->currentRop = rop;
81fc5a983dSmrg        RIVA_FIFO_FREE(pRiva->riva, Rop, 1);
82bd304fc0Smrg#ifdef HAVE_XAA_H
83fc5a983dSmrg        pRiva->riva.Rop->Rop3 = XAAGetCopyROP(rop);
84bd304fc0Smrg#endif
85fc5a983dSmrg    }
86fc5a983dSmrg}
87fc5a983dSmrg
88a55f3320Smrg#ifdef HAVE_XAA_H
89fc5a983dSmrgstatic void
90fc5a983dSmrgRivaSetRopPattern(RivaPtr pRiva, int rop)
91fc5a983dSmrg{
92fc5a983dSmrg    if (pRiva->currentRop != (rop + 16)) {
93fc5a983dSmrg        pRiva->currentRop = rop + 16; /* +16 is important */
94fc5a983dSmrg        RIVA_FIFO_FREE(pRiva->riva, Rop, 1);
95fc5a983dSmrg        pRiva->riva.Rop->Rop3 = XAAGetPatternROP(rop);
96fc5a983dSmrg    }
97fc5a983dSmrg}
98a55f3320Smrg
99fc5a983dSmrg/*
100fc5a983dSmrg * Fill solid rectangles.
101fc5a983dSmrg */
102fc5a983dSmrgstatic
103fc5a983dSmrgvoid RivaSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
104fc5a983dSmrg                         unsigned planemask)
105fc5a983dSmrg{
106fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
107fc5a983dSmrg
108fc5a983dSmrg    RivaSetRopSolid(pRiva, rop);
109fc5a983dSmrg    RIVA_FIFO_FREE(pRiva->riva, Bitmap, 1);
110fc5a983dSmrg    pRiva->riva.Bitmap->Color1A = color;
111fc5a983dSmrg}
112fc5a983dSmrg
113fc5a983dSmrgstatic void
114fc5a983dSmrgRivaSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
115fc5a983dSmrg{
116fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
117fc5a983dSmrg
118fc5a983dSmrg    RIVA_FIFO_FREE(pRiva->riva, Bitmap, 2);
119fc5a983dSmrg    pRiva->riva.Bitmap->UnclippedRectangle[0].TopLeft     = (x << 16) | y;
120fc5a983dSmrg    write_mem_barrier();
121fc5a983dSmrg    pRiva->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
122fc5a983dSmrg    write_mem_barrier();
123fc5a983dSmrg}
124fc5a983dSmrg
125fc5a983dSmrg/*
126fc5a983dSmrg * Screen to screen BLTs.
127fc5a983dSmrg */
128fc5a983dSmrgstatic void
129fc5a983dSmrgRivaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop,
130fc5a983dSmrg                             unsigned planemask, int transparency_color)
131fc5a983dSmrg{
132fc5a983dSmrg    RivaSetRopSolid(RivaPTR(pScrn), rop);
133fc5a983dSmrg}
134fc5a983dSmrg
135fc5a983dSmrgstatic void
136fc5a983dSmrgRivaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1,
137fc5a983dSmrg                               int x2, int y2, int w, int h)
138fc5a983dSmrg{
139fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
140fc5a983dSmrg
141fc5a983dSmrg    RIVA_FIFO_FREE(pRiva->riva, Blt, 3);
142fc5a983dSmrg    pRiva->riva.Blt->TopLeftSrc  = (y1 << 16) | x1;
143fc5a983dSmrg    pRiva->riva.Blt->TopLeftDst  = (y2 << 16) | x2;
144fc5a983dSmrg    write_mem_barrier();
145fc5a983dSmrg    pRiva->riva.Blt->WidthHeight = (h  << 16) | w;
146fc5a983dSmrg    write_mem_barrier();
147fc5a983dSmrg}
148fc5a983dSmrg
149fc5a983dSmrg
150fc5a983dSmrg/*
151fc5a983dSmrg * Fill 8x8 monochrome pattern rectangles.  patternx and patterny are
152fc5a983dSmrg * the overloaded pattern bits themselves. The pattern colors don't
153fc5a983dSmrg * support 565, only 555. Hack around it.
154fc5a983dSmrg */
155fc5a983dSmrgstatic void
156fc5a983dSmrgRivaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
157fc5a983dSmrg                             int fg, int bg, int rop, unsigned planemask)
158fc5a983dSmrg{
159fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
160fc5a983dSmrg
161fc5a983dSmrg    RivaSetRopPattern(pRiva, rop);
162fc5a983dSmrg    if (pScrn->depth == 16)
163fc5a983dSmrg    {
164fc5a983dSmrg        fg = ((fg & 0x0000F800) << 8)
165fc5a983dSmrg           | ((fg & 0x000007E0) << 5)
166fc5a983dSmrg           | ((fg & 0x0000001F) << 3)
167fc5a983dSmrg           |        0xFF000000;
168fc5a983dSmrg        if (bg != -1)
169fc5a983dSmrg            bg = ((bg & 0x0000F800) << 8)
170fc5a983dSmrg               | ((bg & 0x000007E0) << 5)
171fc5a983dSmrg               | ((bg & 0x0000001F) << 3)
172fc5a983dSmrg               |        0xFF000000;
173fc5a983dSmrg        else
174fc5a983dSmrg            bg = 0;
175fc5a983dSmrg    }
176fc5a983dSmrg    else
177fc5a983dSmrg    {
178fc5a983dSmrg	fg |= pRiva->opaqueMonochrome;
179fc5a983dSmrg	bg  = (bg == -1) ? 0 : bg | pRiva->opaqueMonochrome;
180fc5a983dSmrg    };
181fc5a983dSmrg    RivaSetPattern(pRiva, bg, fg, patternx, patterny);
182fc5a983dSmrg    RIVA_FIFO_FREE(pRiva->riva, Bitmap, 1);
183fc5a983dSmrg    pRiva->riva.Bitmap->Color1A = fg;
184fc5a983dSmrg}
185fc5a983dSmrg
186fc5a983dSmrgstatic void
187fc5a983dSmrgRivaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
188fc5a983dSmrg                                   int patternx, int patterny,
189fc5a983dSmrg                                   int x, int y, int w, int h)
190fc5a983dSmrg{
191fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
192fc5a983dSmrg
193fc5a983dSmrg    RIVA_FIFO_FREE(pRiva->riva, Bitmap, 2);
194fc5a983dSmrg    pRiva->riva.Bitmap->UnclippedRectangle[0].TopLeft     = (x << 16) | y;
195fc5a983dSmrg    write_mem_barrier();
196fc5a983dSmrg    pRiva->riva.Bitmap->UnclippedRectangle[0].WidthHeight = (w << 16) | h;
197fc5a983dSmrg    write_mem_barrier();
198fc5a983dSmrg}
199bd304fc0Smrg#endif
200fc5a983dSmrg
201fc5a983dSmrgvoid
202fc5a983dSmrgRivaResetGraphics(ScrnInfoPtr pScrn)
203fc5a983dSmrg{
204fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
205fc5a983dSmrg
206fc5a983dSmrg    if(pRiva->NoAccel) return;
207fc5a983dSmrg
208fc5a983dSmrg    RIVA_FIFO_FREE(pRiva->riva, Patt, 1);
209fc5a983dSmrg    pRiva->riva.Patt->Shape = 0;
210fc5a983dSmrg    RivaDisableClipping(pScrn);
211fc5a983dSmrg    pRiva->currentRop = 16;  /* to force RivaSetRopSolid to reset the pattern */
212fc5a983dSmrg    RivaSetRopSolid(pRiva, GXcopy);
213fc5a983dSmrg}
214fc5a983dSmrg
215fc5a983dSmrg
216fc5a983dSmrg
217fc5a983dSmrg/*
218fc5a983dSmrg * Synchronise with graphics engine.  Make sure it is idle before returning.
219fc5a983dSmrg * Should attempt to yield CPU if busy for awhile.
220fc5a983dSmrg */
221fc5a983dSmrgvoid RivaSync(ScrnInfoPtr pScrn)
222fc5a983dSmrg{
223fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
224fc5a983dSmrg    RIVA_BUSY(pRiva->riva);
225fc5a983dSmrg}
226fc5a983dSmrg
227bd304fc0Smrg#ifdef HAVE_XAA_H
228fc5a983dSmrg/* Color expansion */
229fc5a983dSmrgstatic void
230fc5a983dSmrgRivaSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
231fc5a983dSmrg                                             int fg, int bg, int rop,
232fc5a983dSmrg                                             unsigned int planemask)
233fc5a983dSmrg{
234fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
235fc5a983dSmrg
236fc5a983dSmrg    RivaSetRopSolid(pRiva, rop);
237fc5a983dSmrg
238fc5a983dSmrg    if ( bg == -1 )
239fc5a983dSmrg    {
240fc5a983dSmrg        /* Transparent case */
241fc5a983dSmrg        bg = 0x80000000;
242fc5a983dSmrg        pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData1C;
243fc5a983dSmrg    }
244fc5a983dSmrg    else
245fc5a983dSmrg    {
246fc5a983dSmrg        pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData01E;
247fc5a983dSmrg        if (pScrn->depth == 16)
248fc5a983dSmrg        {
249fc5a983dSmrg            bg = ((bg & 0x0000F800) << 8)
250fc5a983dSmrg               | ((bg & 0x000007E0) << 5)
251fc5a983dSmrg               | ((bg & 0x0000001F) << 3)
252fc5a983dSmrg               |        0xFF000000;
253fc5a983dSmrg        }
254fc5a983dSmrg        else
255fc5a983dSmrg        {
256fc5a983dSmrg            bg  |= pRiva->opaqueMonochrome;
257fc5a983dSmrg        };
258fc5a983dSmrg    }
259fc5a983dSmrg    pRiva->FgColor = fg;
260fc5a983dSmrg    pRiva->BgColor = bg;
261fc5a983dSmrg}
262fc5a983dSmrg
263fc5a983dSmrgstatic void
264fc5a983dSmrgRivaSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
265fc5a983dSmrg{
266fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
267fc5a983dSmrg
268fc5a983dSmrg    int t = pRiva->expandWidth;
269fc5a983dSmrg    CARD32 *pbits = (CARD32*)pRiva->expandBuffer;
270fc5a983dSmrg    CARD32 *d = (CARD32*)pRiva->expandFifo;
271fc5a983dSmrg
272fc5a983dSmrg    while(t >= 16)
273fc5a983dSmrg    {
274fc5a983dSmrg	RIVA_FIFO_FREE(pRiva->riva, Bitmap, 16);
275fc5a983dSmrg	d[0]  = pbits[0];
276fc5a983dSmrg	d[1]  = pbits[1];
277fc5a983dSmrg	d[2]  = pbits[2];
278fc5a983dSmrg	d[3]  = pbits[3];
279fc5a983dSmrg	d[4]  = pbits[4];
280fc5a983dSmrg	d[5]  = pbits[5];
281fc5a983dSmrg	d[6]  = pbits[6];
282fc5a983dSmrg	d[7]  = pbits[7];
283fc5a983dSmrg	d[8]  = pbits[8];
284fc5a983dSmrg	d[9]  = pbits[9];
285fc5a983dSmrg	d[10] = pbits[10];
286fc5a983dSmrg	d[11] = pbits[11];
287fc5a983dSmrg	d[12] = pbits[12];
288fc5a983dSmrg	d[13] = pbits[13];
289fc5a983dSmrg	d[14] = pbits[14];
290fc5a983dSmrg	d[15] = pbits[15];
291fc5a983dSmrg	t -= 16; pbits += 16;
292fc5a983dSmrg    }
293fc5a983dSmrg    if(t) {
294fc5a983dSmrg	RIVA_FIFO_FREE(pRiva->riva, Bitmap, t);
295fc5a983dSmrg	while(t >= 4)
296fc5a983dSmrg	{
297fc5a983dSmrg	    d[0]  = pbits[0];
298fc5a983dSmrg	    d[1]  = pbits[1];
299fc5a983dSmrg	    d[2]  = pbits[2];
300fc5a983dSmrg	    d[3]  = pbits[3];
301fc5a983dSmrg	    t -= 4; pbits += 4;
302fc5a983dSmrg	}
303fc5a983dSmrg	while(t--)
304fc5a983dSmrg	    *(d++) = *(pbits++);
305fc5a983dSmrg    }
306fc5a983dSmrg
307fc5a983dSmrg    if (!(--pRiva->expandRows)) { /* hardware bug workaround */
308fc5a983dSmrg       RIVA_FIFO_FREE(pRiva->riva, Blt, 1);
309fc5a983dSmrg       write_mem_barrier();
310fc5a983dSmrg       pRiva->riva.Blt->TopLeftSrc = 0;
311fc5a983dSmrg    }
312fc5a983dSmrg    write_mem_barrier();
313fc5a983dSmrg}
314fc5a983dSmrg
315fc5a983dSmrgstatic void
316fc5a983dSmrgRivaSubsequentColorExpandScanlineFifo(ScrnInfoPtr pScrn, int bufno)
317fc5a983dSmrg{
318fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
319fc5a983dSmrg
320fc5a983dSmrg    if ( --pRiva->expandRows ) {
321fc5a983dSmrg       RIVA_FIFO_FREE(pRiva->riva, Bitmap, pRiva->expandWidth);
322fc5a983dSmrg    } else { /* hardware bug workaround */
323fc5a983dSmrg       RIVA_FIFO_FREE(pRiva->riva, Blt, 1);
324fc5a983dSmrg       write_mem_barrier();
325fc5a983dSmrg       pRiva->riva.Blt->TopLeftSrc = 0;
326fc5a983dSmrg    }
327fc5a983dSmrg    write_mem_barrier();
328fc5a983dSmrg}
329fc5a983dSmrg
330fc5a983dSmrgstatic void
331fc5a983dSmrgRivaSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x,
332fc5a983dSmrg                                               int y, int w, int h,
333fc5a983dSmrg                                               int skipleft)
334fc5a983dSmrg{
335fc5a983dSmrg    int bw;
336fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
337fc5a983dSmrg
338fc5a983dSmrg    bw = (w + 31) & ~31;
339fc5a983dSmrg    pRiva->expandWidth = bw >> 5;
340fc5a983dSmrg
341fc5a983dSmrg    if ( pRiva->BgColor == 0x80000000 )
342fc5a983dSmrg    {
343fc5a983dSmrg        /* Use faster transparent method */
344fc5a983dSmrg        RIVA_FIFO_FREE(pRiva->riva, Bitmap, 5);
345fc5a983dSmrg        pRiva->riva.Bitmap->ClipC.TopLeft     = (y << 16) | ((x+skipleft)
346fc5a983dSmrg                                                           & 0xFFFF);
347fc5a983dSmrg        pRiva->riva.Bitmap->ClipC.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
348fc5a983dSmrg        pRiva->riva.Bitmap->Color1C           = pRiva->FgColor;
349fc5a983dSmrg        pRiva->riva.Bitmap->WidthHeightC      = (h << 16) | bw;
350fc5a983dSmrg        write_mem_barrier();
351fc5a983dSmrg        pRiva->riva.Bitmap->PointC            = (y << 16) | (x & 0xFFFF);
352fc5a983dSmrg        write_mem_barrier();
353fc5a983dSmrg    }
354fc5a983dSmrg    else
355fc5a983dSmrg    {
356fc5a983dSmrg        /* Opaque */
357fc5a983dSmrg        RIVA_FIFO_FREE(pRiva->riva, Bitmap, 7);
358fc5a983dSmrg        pRiva->riva.Bitmap->ClipE.TopLeft     = (y << 16) | ((x+skipleft)
359fc5a983dSmrg                                                           & 0xFFFF);
360fc5a983dSmrg        pRiva->riva.Bitmap->ClipE.BottomRight = ((y+h) << 16) | ((x+w)&0xffff);
361fc5a983dSmrg        pRiva->riva.Bitmap->Color0E           = pRiva->BgColor;
362fc5a983dSmrg        pRiva->riva.Bitmap->Color1E           = pRiva->FgColor;
363fc5a983dSmrg        pRiva->riva.Bitmap->WidthHeightInE  = (h << 16) | bw;
364fc5a983dSmrg        pRiva->riva.Bitmap->WidthHeightOutE = (h << 16) | bw;
365fc5a983dSmrg        write_mem_barrier();
366fc5a983dSmrg        pRiva->riva.Bitmap->PointE          = (y << 16) | (x & 0xFFFF);
367fc5a983dSmrg        write_mem_barrier();
368fc5a983dSmrg    }
369fc5a983dSmrg
370fc5a983dSmrg    pRiva->expandRows = h;
371fc5a983dSmrg
372fc5a983dSmrg    if(pRiva->expandWidth > (pRiva->riva.FifoEmptyCount >> 2)) {
373fc5a983dSmrg	pRiva->AccelInfoRec->ScanlineColorExpandBuffers = &pRiva->expandBuffer;
374fc5a983dSmrg	pRiva->AccelInfoRec->SubsequentColorExpandScanline =
375fc5a983dSmrg				RivaSubsequentColorExpandScanline;
376fc5a983dSmrg    } else {
377fc5a983dSmrg	pRiva->AccelInfoRec->ScanlineColorExpandBuffers = &pRiva->expandFifo;
378fc5a983dSmrg	pRiva->AccelInfoRec->SubsequentColorExpandScanline =
379fc5a983dSmrg				RivaSubsequentColorExpandScanlineFifo;
380fc5a983dSmrg	RIVA_FIFO_FREE(pRiva->riva, Bitmap, pRiva->expandWidth);
381fc5a983dSmrg    }
382fc5a983dSmrg}
383fc5a983dSmrg
384fc5a983dSmrgstatic void
385fc5a983dSmrgRivaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask)
386fc5a983dSmrg{
387fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
388fc5a983dSmrg
389fc5a983dSmrg    RivaSetRopSolid(pRiva, rop);
390fc5a983dSmrg    pRiva->FgColor = color;
391fc5a983dSmrg}
392fc5a983dSmrg
393fc5a983dSmrgstatic void
394fc5a983dSmrgRivaSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir)
395fc5a983dSmrg{
396fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
397fc5a983dSmrg
398fc5a983dSmrg    RIVA_FIFO_FREE(pRiva->riva, Line, 3);
399fc5a983dSmrg    pRiva->riva.Line->Color = pRiva->FgColor;
400fc5a983dSmrg    pRiva->riva.Line->Lin[0].point0 = ((y << 16) | ( x & 0xffff));
401fc5a983dSmrg    write_mem_barrier();
402fc5a983dSmrg    if ( dir ==DEGREES_0 )
403fc5a983dSmrg        pRiva->riva.Line->Lin[0].point1 = ((y << 16) | (( x + len ) & 0xffff));
404fc5a983dSmrg    else
405fc5a983dSmrg        pRiva->riva.Line->Lin[0].point1 = (((y + len) << 16) | ( x & 0xffff));
406fc5a983dSmrg    write_mem_barrier();
407fc5a983dSmrg}
408fc5a983dSmrg
409fc5a983dSmrgstatic void
410fc5a983dSmrgRivaSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1,
411fc5a983dSmrg                              int x2, int y2, int flags)
412fc5a983dSmrg{
413fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
414fc5a983dSmrg    Bool  lastPoint = !(flags & OMIT_LAST);
415fc5a983dSmrg
416fc5a983dSmrg    RIVA_FIFO_FREE(pRiva->riva, Line, lastPoint ? 5 : 3);
417fc5a983dSmrg    pRiva->riva.Line->Color = pRiva->FgColor;
418fc5a983dSmrg    pRiva->riva.Line->Lin[0].point0 = ((y1 << 16) | (x1 & 0xffff));
419fc5a983dSmrg    write_mem_barrier();
420fc5a983dSmrg    pRiva->riva.Line->Lin[0].point1 = ((y2 << 16) | (x2 & 0xffff));
421fc5a983dSmrg    write_mem_barrier();
422fc5a983dSmrg    if (lastPoint)
423fc5a983dSmrg    {
424fc5a983dSmrg        pRiva->riva.Line->Lin[1].point0 = ((y2 << 16) | (x2 & 0xffff));
425fc5a983dSmrg        write_mem_barrier();
426fc5a983dSmrg        pRiva->riva.Line->Lin[1].point1 = (((y2 + 1) << 16) | (x2 & 0xffff));
427fc5a983dSmrg        write_mem_barrier();
428fc5a983dSmrg    }
429fc5a983dSmrg}
430fc5a983dSmrg
431fc5a983dSmrgstatic void
432fc5a983dSmrgRivaValidatePolyArc(
433fc5a983dSmrg   GCPtr        pGC,
434fc5a983dSmrg   unsigned long changes,
435fc5a983dSmrg   DrawablePtr pDraw
436fc5a983dSmrg){
437fc5a983dSmrg   if(pGC->planemask != ~0) return;
438fc5a983dSmrg
439fc5a983dSmrg   if(!pGC->lineWidth &&
440fc5a983dSmrg	((pGC->alu != GXcopy) || (pGC->lineStyle != LineSolid)))
441fc5a983dSmrg   {
442fc5a983dSmrg        pGC->ops->PolyArc = miZeroPolyArc;
443fc5a983dSmrg   }
444fc5a983dSmrg}
445fc5a983dSmrg
446fc5a983dSmrgstatic void
447fc5a983dSmrgRivaValidatePolyPoint(
448fc5a983dSmrg   GCPtr        pGC,
449fc5a983dSmrg   unsigned long changes,
450fc5a983dSmrg   DrawablePtr pDraw
451fc5a983dSmrg){
452fc5a983dSmrg   pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint;
453fc5a983dSmrg
454fc5a983dSmrg   if(pGC->planemask != ~0) return;
455fc5a983dSmrg
456fc5a983dSmrg   if(pGC->alu != GXcopy)
457fc5a983dSmrg        pGC->ops->PolyPoint = miPolyPoint;
458fc5a983dSmrg}
459bd304fc0Smrg#endif
460fc5a983dSmrg
461fc5a983dSmrg/* Initialize XAA acceleration info */
462fc5a983dSmrgBool
463fc5a983dSmrgRivaAccelInit(ScreenPtr pScreen)
464fc5a983dSmrg{
465bd304fc0Smrg#ifdef HAVE_XAA_H
466fc5a983dSmrg    XAAInfoRecPtr infoPtr;
467bd304fc0Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
468fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
469fc5a983dSmrg
470fc5a983dSmrg    pRiva->AccelInfoRec = infoPtr = XAACreateInfoRec();
471fc5a983dSmrg    if(!infoPtr) return FALSE;
472fc5a983dSmrg
473fc5a983dSmrg    /* fill out infoPtr here */
474fc5a983dSmrg    infoPtr->Flags = LINEAR_FRAMEBUFFER | PIXMAP_CACHE | OFFSCREEN_PIXMAPS;
475fc5a983dSmrg
476fc5a983dSmrg    /* sync */
477fc5a983dSmrg    infoPtr->Sync = RivaSync;
478fc5a983dSmrg
479fc5a983dSmrg    /* solid fills */
480fc5a983dSmrg    infoPtr->SolidFillFlags = NO_PLANEMASK;
481fc5a983dSmrg    infoPtr->SetupForSolidFill = RivaSetupForSolidFill;
482fc5a983dSmrg    infoPtr->SubsequentSolidFillRect = RivaSubsequentSolidFillRect;
483fc5a983dSmrg
484fc5a983dSmrg    /* screen to screen copy */
485fc5a983dSmrg    infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
486fc5a983dSmrg    infoPtr->SetupForScreenToScreenCopy = RivaSetupForScreenToScreenCopy;
487fc5a983dSmrg    infoPtr->SubsequentScreenToScreenCopy = RivaSubsequentScreenToScreenCopy;
488fc5a983dSmrg
489fc5a983dSmrg    /* 8x8 mono patterns */
490fc5a983dSmrg    /*
491fc5a983dSmrg     * Set pattern opaque bits based on pixel format.
492fc5a983dSmrg     */
493fc5a983dSmrg    pRiva->opaqueMonochrome = ~((1 << pScrn->depth) - 1);
494fc5a983dSmrg
495fc5a983dSmrg    infoPtr->Mono8x8PatternFillFlags = HARDWARE_PATTERN_SCREEN_ORIGIN |
496fc5a983dSmrg				       HARDWARE_PATTERN_PROGRAMMED_BITS |
497fc5a983dSmrg				       NO_PLANEMASK;
498fc5a983dSmrg    infoPtr->SetupForMono8x8PatternFill = RivaSetupForMono8x8PatternFill;
499fc5a983dSmrg    infoPtr->SubsequentMono8x8PatternFillRect =
500fc5a983dSmrg        RivaSubsequentMono8x8PatternFillRect;
501fc5a983dSmrg
502fc5a983dSmrg    /* Color expansion */
503fc5a983dSmrg    infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
504fc5a983dSmrg				BIT_ORDER_IN_BYTE_LSBFIRST |
505fc5a983dSmrg				NO_PLANEMASK |
506fc5a983dSmrg				CPU_TRANSFER_PAD_DWORD |
507fc5a983dSmrg				LEFT_EDGE_CLIPPING |
508fc5a983dSmrg				LEFT_EDGE_CLIPPING_NEGATIVE_X;
509fc5a983dSmrg
510fc5a983dSmrg    infoPtr->NumScanlineColorExpandBuffers = 1;
511fc5a983dSmrg
512fc5a983dSmrg    infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
513fc5a983dSmrg        RivaSetupForScanlineCPUToScreenColorExpandFill;
514fc5a983dSmrg    infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
515fc5a983dSmrg        RivaSubsequentScanlineCPUToScreenColorExpandFill;
516fc5a983dSmrg
517fc5a983dSmrg    pRiva->expandFifo = (unsigned char*)&pRiva->riva.Bitmap->MonochromeData01E;
518fc5a983dSmrg
519fc5a983dSmrg    /* Allocate buffer for color expansion and also image writes in the
520fc5a983dSmrg       future */
521fc5a983dSmrg    pRiva->expandBuffer = xnfalloc(((pScrn->virtualX*pScrn->bitsPerPixel)/8) + 8);
522fc5a983dSmrg
523fc5a983dSmrg
524fc5a983dSmrg    infoPtr->ScanlineColorExpandBuffers = &pRiva->expandBuffer;
525fc5a983dSmrg    infoPtr->SubsequentColorExpandScanline = RivaSubsequentColorExpandScanline;
526fc5a983dSmrg
527fc5a983dSmrg    infoPtr->SolidLineFlags = infoPtr->SolidFillFlags;
528fc5a983dSmrg    infoPtr->SetupForSolidLine = RivaSetupForSolidLine;
529fc5a983dSmrg    infoPtr->SubsequentSolidHorVertLine =
530fc5a983dSmrg		RivaSubsequentSolidHorVertLine;
531fc5a983dSmrg    infoPtr->SubsequentSolidTwoPointLine =
532fc5a983dSmrg		RivaSubsequentSolidTwoPointLine;
533fc5a983dSmrg    infoPtr->SetClippingRectangle = RivaSetClippingRectangle;
534fc5a983dSmrg    infoPtr->DisableClipping = RivaDisableClipping;
535fc5a983dSmrg    infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE;
536fc5a983dSmrg    miSetZeroLineBias(pScreen, OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6);
537fc5a983dSmrg
538fc5a983dSmrg    infoPtr->ValidatePolyArc = RivaValidatePolyArc;
539fc5a983dSmrg    infoPtr->PolyArcMask = GCFunction | GCLineWidth | GCPlaneMask;
540fc5a983dSmrg    infoPtr->ValidatePolyPoint = RivaValidatePolyPoint;
541fc5a983dSmrg    infoPtr->PolyPointMask = GCFunction | GCPlaneMask;
542fc5a983dSmrg
543fc5a983dSmrg    RivaResetGraphics(pScrn);
544fc5a983dSmrg
545fc5a983dSmrg    return(XAAInit(pScreen, infoPtr));
546bd304fc0Smrg#else
547bd304fc0Smrg    return FALSE;
548bd304fc0Smrg#endif
549fc5a983dSmrg}
550