newport_accel.c revision ba0eab60
1/*
2 * Accelerated Driver for the SGI Indy's Newport graphics card
3 *
4 * (c) 2004 Dominik Behr <dominikbehr@yahoo.com>
5 * this code is released under xfree 4.3.0 and xorg 6.8.0 license
6 *
7 */
8
9#ifdef HAVE_CONFIG_H
10#include "config.h"
11#endif
12
13#include "newport.h"
14#include <limits.h>
15
16#ifdef NEWPORT_ACCEL
17
18#include "mi.h"
19#include "mizerarc.h"
20
21#define BARF(a) xf86DrvMsg(0, X_INFO, (a))
22#define BARF1(a,b) xf86DrvMsg(0, X_INFO, (a), (b))
23#define BARF2(a,b,c) xf86DrvMsg(0, X_INFO, (a), (b), (c))
24#define BARF3(a,b,c,d) xf86DrvMsg(0, X_INFO, (a), (b), (c), (d))
25#define BARF4(a,b,c,d,e) xf86DrvMsg(0, X_INFO, (a), (b), (c), (d), (e))
26#define BARF5(a,b,c,d,e,f) xf86DrvMsg(0, X_INFO, (a), (b), (c), (d), (e), (f))
27#define BARF6(a,b,c,d,e,f,g) xf86DrvMsg(0, X_INFO, (a), (b), (c), (d), (e), (f), (g))
28
29/* XAA Functions */
30
31#define NEWPORT_PREROTATE
32/*
33    there is a bug in XAA which causes it to reference NULL pointer to pattern cache when
34    using HARDWARE_PROGRAMMED_PATTERN only (try x11perf -strap1)
35    thus we have to also set HARDWARE_PROGRAMMED_ORIGIN and prerotate the pattern
36    in the setup function
37*/
38
39#define NEWPORT_GFIFO_ENTRIES 30
40/*
41 I dont know how many entries are in the gfx FIFO, judging by 6 bits in the GFIFO
42 level status register it can be at most 63. it must be at least 32 because
43 otherwise they would use less bits for status
44
45 for now 16 seems to be safe value
46*/
47#define NEWPORT_DELAY 128
48
49/*******************************************************************************
50
51*******************************************************************************/
52static void
53NewportWaitIdle(NewportPtr pNewport, unsigned int uEntries)
54{
55    NewportRegsPtr pNewportRegs;
56    pNewportRegs = pNewport->pNewportRegs;
57    /* wait for the GFIFO to drain */
58    while ((pNewportRegs->cset.stat & NPORT_STAT_GLMSK))
59    {
60	int i;
61	volatile int x;
62	for (x = 0, i = 0; i < NEWPORT_DELAY; i++)
63	{
64	    x += i;
65	}
66    }
67    /* and then wait for the graphic to be idle */
68    while (pNewportRegs->cset.stat & NPORT_STAT_GBUSY)
69    {
70	int i;
71	volatile int x;
72	for (x = 0, i = 0; i < NEWPORT_DELAY; i++)
73	{
74	    x += i;
75	}
76    }
77    pNewport->fifoleft = NEWPORT_GFIFO_ENTRIES-uEntries;
78}
79
80
81#if 0
82/*******************************************************************************
83
84*******************************************************************************/
85static void
86NewportWaitGFIFO(NewportPtr pNewport, unsigned int uEntries)
87{
88    unsigned int uWaitLevel;
89
90/*    NewportWaitIdle(pNewport, NEWPORT_GFIFO_ENTRIES);
91    return;*/
92
93    if (uEntries >= NEWPORT_GFIFO_ENTRIES)
94    {
95	uWaitLevel = 0;
96    }
97    else
98    {
99	uWaitLevel = NEWPORT_GFIFO_ENTRIES-uEntries;
100    }
101    /* HACK */
102    /*uWaitLevel = 0;*/
103    while (((pNewport->pNewportRegs->cset.stat & NPORT_STAT_GLMSK) >> 7) > uWaitLevel)
104    {
105	int i;
106	volatile int x;
107	for (x = 0, i = 0; i < NEWPORT_DELAY; i++)
108	{
109	    x += i;
110	}
111    }
112}
113#endif
114#if 1
115/*******************************************************************************
116
117*******************************************************************************/
118static void
119NewportWaitGFIFO(NewportPtr pNewport, unsigned int uEntries)
120{
121    if (uEntries > NEWPORT_GFIFO_ENTRIES)
122    {
123	uEntries = NEWPORT_GFIFO_ENTRIES;
124    }
125
126    if (uEntries <= pNewport->fifoleft)
127    {
128	pNewport->fifoleft -= uEntries;
129	return;
130    }
131
132    while (1)
133    {
134	unsigned int fifolevel;
135	int i;
136	volatile int x;
137
138	fifolevel = (pNewport->pNewportRegs->cset.stat & NPORT_STAT_GLMSK) >> 7;
139	if (fifolevel < NEWPORT_GFIFO_ENTRIES)
140	{
141	    pNewport->fifoleft = NEWPORT_GFIFO_ENTRIES - fifolevel;
142	}
143	else
144	{
145	    pNewport->fifoleft = 0;
146	}
147	if (uEntries <= pNewport->fifoleft)
148	{
149	    pNewport->fifoleft -= uEntries;
150	    return;
151        }
152
153	for (x = 0, i = 0; i < NEWPORT_DELAY; i++)
154	{
155	    x += i;
156	}
157    }
158}
159#endif
160
161
162/*******************************************************************************
163
164*******************************************************************************/
165static void
166NewportXAASync(ScrnInfoPtr pScrn)
167{
168    NewportPtr pNewport;
169    pNewport = NEWPORTPTR(pScrn);
170
171    NewportWaitIdle(pNewport, 0);
172}
173
174
175/*******************************************************************************
176
177*******************************************************************************/
178static unsigned int
179Rop2LogicOp(int rop)
180{
181    return (unsigned int)rop << 28;
182}
183
184/*******************************************************************************
185
186*******************************************************************************/
187static void
188NewportUpdateClipping(NewportPtr pNewport)
189{
190    unsigned int smask0x, smask0y;
191
192    if (pNewport->skipleft > pNewport->clipsx)
193    {
194        smask0x = ((pNewport->skipleft & 0xFFFF) << 16) | (pNewport->clipex & 0xFFFF);
195    }
196    else
197    {
198	smask0x = ((pNewport->clipsx & 0xFFFF) << 16) | (pNewport->clipex & 0xFFFF);
199    }
200
201    if (smask0x != pNewport->shadow_smask0x)
202    {
203	NewportWaitGFIFO(pNewport, 1);
204	pNewport->shadow_smask0x = smask0x;
205	pNewport->pNewportRegs->set.smask0x = smask0x;
206    }
207
208    smask0y = ((pNewport->clipsy & 0xFFFF) << 16) | (pNewport->clipey & 0xFFFF);
209    if (smask0y != pNewport->shadow_smask0y)
210    {
211	NewportWaitGFIFO(pNewport, 1);
212	pNewport->shadow_smask0y = smask0y;
213	pNewport->pNewportRegs->set.smask0y = smask0y;
214    }
215}
216
217/*******************************************************************************
218
219*******************************************************************************/
220static unsigned int
221NewportColor2HOSTRW(unsigned int color)
222{
223 /*
224  default XAA color is 0,R,G,B
225 */
226#if 0
227 return  ((color & 0x0000FF) << 16)
228       | ((color & 0xFF0000) >> 16)
229       | ((color & 0x00FF00))
230       ;
231#endif
232/* but we changed masks to match the native format */
233 return color;
234}
235
236/*******************************************************************************
237
238*******************************************************************************/
239static unsigned int
240NewportColor2Planes24(unsigned int color)
241{
242    unsigned int res;
243    unsigned int i;
244    unsigned int mr, mg, mb;
245    unsigned int sr, sg, sb;
246
247 /*
248  XAA color is 0,R,G,B
249 */
250
251    res = 0;
252#if 0
253    mr = 0x800000;
254    mg = 0x008000;
255    mb = 0x000080;
256#endif
257    mr = 0x000080;
258    mg = 0x008000;
259    mb = 0x800000;
260    sr = 2;
261    sg = 1;
262    sb = 4;
263
264    for (i = 0; i < 8; i++)
265    {
266	res |= (color & mr)?sr:0;
267	res |= (color & mg)?sg:0;
268	res |= (color & mb)?sb:0;
269
270	sr <<= 3;
271	sg <<= 3;
272	sb <<= 3;
273	mr >>= 1;
274	mg >>= 1;
275	mb >>= 1;
276    }
277
278    return  res;
279}
280
281/*******************************************************************************
282
283*******************************************************************************/
284static unsigned int
285NewportColor2Planes8(unsigned int color)
286{
287    return color;
288}
289
290/*******************************************************************************
291
292*******************************************************************************/
293static void
294NewportUpdateCOLORI(NewportPtr pNewport, unsigned long colori)
295{
296    if (colori != pNewport->shadow_colori)
297    {
298	NewportWaitGFIFO(pNewport, 1);
299	pNewport->shadow_colori = colori;
300	pNewport->pNewportRegs->set.colori = colori;
301    }
302}
303
304
305/*******************************************************************************
306
307*******************************************************************************/
308static void
309NewportUpdateDRAWMODE0(NewportPtr pNewport, unsigned long drawmode0)
310{
311    if (drawmode0 != pNewport->shadow_drawmode0)
312    {
313	NewportWaitGFIFO(pNewport, 1);
314	pNewport->shadow_drawmode0 = drawmode0;
315	pNewport->pNewportRegs->set.drawmode0 = drawmode0;
316    }
317}
318
319
320/*******************************************************************************
321
322*******************************************************************************/
323static void
324NewportUpdateDRAWMODE1(NewportPtr pNewport, unsigned long drawmode1)
325{
326    if (drawmode1 != pNewport->shadow_drawmode1)
327    {
328	NewportWaitIdle(pNewport, 1);
329	pNewport->shadow_drawmode1 = drawmode1;
330	pNewport->pNewportRegs->set.drawmode1 = drawmode1;
331    }
332}
333
334/*******************************************************************************
335
336*******************************************************************************/
337static void
338NewportUpdateCOLORVRAM(NewportPtr pNewport, unsigned long colorvram)
339{
340    if (colorvram != pNewport->shadow_colorvram)
341    {
342	NewportWaitIdle(pNewport, 1);
343	pNewport->shadow_colorvram = colorvram;
344	pNewport->pNewportRegs->set.colorvram = colorvram;
345    }
346}
347
348/*******************************************************************************
349
350*******************************************************************************/
351static void
352NewportUpdateCOLORBACK(NewportPtr pNewport, unsigned long colorback)
353{
354    if (colorback != pNewport->shadow_colorback)
355    {
356	NewportWaitIdle(pNewport, 1);
357	pNewport->shadow_colorback = colorback;
358	pNewport->pNewportRegs->set.colorback = colorback;
359    }
360}
361
362/*******************************************************************************
363
364*******************************************************************************/
365static void
366NewportUpdateWRMASK(NewportPtr pNewport, unsigned long wrmask)
367{
368    if (wrmask != pNewport->shadow_wrmask)
369    {
370	NewportWaitIdle(pNewport, 1);
371	pNewport->shadow_wrmask = wrmask;
372	pNewport->pNewportRegs->set.wrmask = wrmask;
373    }
374}
375
376/*******************************************************************************
377
378*******************************************************************************/
379static void
380NewportUpdateXYMOVE(NewportPtr pNewport, unsigned long xymove)
381{
382    if (xymove != pNewport->shadow_xymove)
383    {
384	NewportWaitIdle(pNewport, 1);
385	pNewport->shadow_xymove = xymove;
386	pNewport->pNewportRegs->set.xymove = xymove;
387    }
388}
389
390
391/*******************************************************************************
392
393*******************************************************************************/
394static void
395NewportXAASetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
396                                     int xdir,
397				     int ydir,
398				     int rop,
399				     unsigned int planemask,
400				     int trans_color)
401{
402    NewportRegsPtr pNewportRegs;
403    NewportPtr pNewport;
404    pNewport = NEWPORTPTR(pScrn);
405    pNewportRegs = NEWPORTREGSPTR(pScrn);
406
407    NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop));
408    NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask));
409    pNewport->skipleft = 0;
410    NewportUpdateClipping(pNewport);
411    NewportUpdateDRAWMODE0(pNewport,
412                           0
413                           | NPORT_DMODE0_S2S
414                           | NPORT_DMODE0_BLOCK
415		           | NPORT_DMODE0_DOSETUP
416		           | NPORT_DMODE0_STOPX
417			   | NPORT_DMODE0_STOPY
418			  );
419
420
421}
422
423/*******************************************************************************
424
425*******************************************************************************/
426static void
427NewportXAASubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
428                                       int x1, int y1,
429				       int x2, int y2,
430				       int width, int height)
431{
432    int dx, dy;
433    unsigned int sx, sy, ex, ey;
434    NewportRegsPtr pNewportRegs;
435    NewportPtr pNewport;
436    pNewport = NEWPORTPTR(pScrn);
437    pNewportRegs = NEWPORTREGSPTR(pScrn);
438
439    dx = x2 - x1;
440    dy = y2 - y1;
441    if (!dx && !dy)
442	return;
443
444    if (width)
445	x2 = x1 + width - 1;
446    else
447	x2 = x1;
448
449    if (height)
450	y2 = y1 + height - 1;
451    else
452	y2 = y1;
453
454    if (dx < 0)
455    {
456	sx = x1 & 0xFFFF;
457	ex = x2 & 0xFFFF;
458    }
459    else
460    {
461	sx = x2 & 0xFFFF;
462	ex = x1 & 0xFFFF;
463    }
464
465    if (dy < 0)
466    {
467	sy = y1 & 0xFFFF;
468	ey = y2 & 0xFFFF;
469    }
470    else
471    {
472	sy = y2 & 0xFFFF;
473	ey = y1 & 0xFFFF;
474    }
475
476    dx &= 0xFFFF;
477    dy &= 0xFFFF;
478
479    NewportUpdateXYMOVE(pNewport, (dx << 16) | dy); /* this is bad because it stalls the pipeline but nothing can be done about it */
480    NewportWaitGFIFO(pNewport, 2);
481    pNewportRegs->set.xystarti = (sx << 16) | sy;
482    pNewportRegs->go.xyendi = (ex << 16) | ey;
483}
484
485/*******************************************************************************
486
487*******************************************************************************/
488static void
489NewportXAASetupForSolidFill(ScrnInfoPtr pScrn,
490                            int Color,
491			    int rop,
492			    unsigned int planemask)
493{
494    NewportRegsPtr pNewportRegs;
495    NewportPtr pNewport;
496    pNewport = NEWPORTPTR(pScrn);
497    pNewportRegs = NEWPORTREGSPTR(pScrn);
498
499    if (rop == GXcopy
500        || rop == GXclear
501	|| rop == GXset)
502    {
503	/* if possible try to set up a fast clear which is 4x faster */
504	NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | NPORT_DMODE1_FCLR | Rop2LogicOp(GXcopy));
505	if (rop == GXclear)
506	    NewportUpdateCOLORVRAM(pNewport, 0);
507	else
508	if (rop == GXset)
509	    NewportUpdateCOLORVRAM(pNewport, 0xFFFFFF);
510	else
511            NewportUpdateCOLORVRAM(pNewport, pNewport->Color2Planes((unsigned int)Color));
512    }
513    else
514    {
515	NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop));
516	NewportUpdateCOLORI(pNewport, NewportColor2HOSTRW(Color));
517    }
518
519    NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask));
520    pNewport->skipleft = 0;
521    NewportUpdateClipping(pNewport);
522    NewportUpdateDRAWMODE0(pNewport,
523                           0
524                           | NPORT_DMODE0_DRAW
525                           | NPORT_DMODE0_BLOCK
526			   | NPORT_DMODE0_DOSETUP
527			   | NPORT_DMODE0_STOPX
528			   | NPORT_DMODE0_STOPY
529			  );
530}
531
532/*******************************************************************************
533
534*******************************************************************************/
535static void
536NewportXAASubsequentSolidFillRect(ScrnInfoPtr pScrn,
537                                  int x,
538				  int y,
539				  int w,
540				  int h)
541{
542    int ex, ey;
543    NewportRegsPtr pNewportRegs;
544    NewportPtr pNewport;
545    pNewport = NEWPORTPTR(pScrn);
546    pNewportRegs = NEWPORTREGSPTR(pScrn);
547
548    if (w == 0) w = 1;
549    if (h == 0) h = 1;
550    ex = x + w - 1;
551    ey = y + h - 1;
552
553    NewportWaitGFIFO(pNewport, 2);
554    pNewportRegs->set.xystarti = ((x & 0xFFFF) << 16) | (y & 0xFFFF);
555    pNewportRegs->go.xyendi = ((ex & 0xFFFF) << 16) | (ey & 0xFFFF);
556}
557
558/*******************************************************************************
559
560*******************************************************************************/
561static void
562NewportXAASetupForSolidLine(ScrnInfoPtr pScrn,
563                            int Color,
564			    int rop,
565			    unsigned int planemask)
566{
567    NewportRegsPtr pNewportRegs;
568    NewportPtr pNewport;
569    pNewport = NEWPORTPTR(pScrn);
570    pNewportRegs = NEWPORTREGSPTR(pScrn);
571
572    NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop));
573    NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask));
574    NewportUpdateCOLORI(pNewport, NewportColor2HOSTRW(Color));
575
576    pNewport->skipleft = 0;
577    NewportUpdateClipping(pNewport);
578    pNewport->setup_drawmode0 = (0
579                                | NPORT_DMODE0_DRAW
580                                | NPORT_DMODE0_ILINE
581				| NPORT_DMODE0_DOSETUP
582				| NPORT_DMODE0_STOPX
583				| NPORT_DMODE0_STOPY
584				);
585}
586
587/*******************************************************************************
588
589*******************************************************************************/
590static void
591NewportXAASubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
592                                      int x1,
593				      int y1,
594				      int x2,
595				      int y2,
596				      int flags)
597{
598    NewportRegsPtr pNewportRegs;
599    NewportPtr pNewport;
600    pNewport = NEWPORTPTR(pScrn);
601    pNewportRegs = NEWPORTREGSPTR(pScrn);
602
603    NewportUpdateDRAWMODE0(pNewport,
604                           pNewport->setup_drawmode0
605			   | ((flags & OMIT_LAST) ? NPORT_DMODE0_SKLST : 0)
606			  );
607    NewportWaitGFIFO(pNewport, 2);
608    pNewportRegs->set.xystarti = ((x1 & 0xFFFF) << 16) | (y1 & 0xFFFF);
609    pNewportRegs->go.xyendi = ((x2 & 0xFFFF) << 16) | (y2 & 0xFFFF);
610}
611
612
613/*******************************************************************************
614
615*******************************************************************************/
616static void
617NewportXAASetupForDashedLine(ScrnInfoPtr pScrn,
618                             int fg,
619			     int bg,
620			     int rop,
621			     unsigned int planemask,
622			     int length,
623			     unsigned char *pattern)
624{
625    NewportRegsPtr pNewportRegs;
626    NewportPtr pNewport;
627    int i;
628
629    pNewport = NEWPORTPTR(pScrn);
630    pNewportRegs = NEWPORTREGSPTR(pScrn);
631
632    pNewport->dashline_patlen = length;
633    for (i = 0; i < (length+7)>>3; i++)
634	pNewport->dashline_pat[i] = pattern[i];
635
636    NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop));
637    NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask));
638    if (bg != -1)
639	NewportUpdateCOLORBACK(pNewport, NewportColor2HOSTRW(bg));
640    NewportUpdateCOLORI(pNewport, NewportColor2HOSTRW(fg));
641    pNewport->skipleft = 0;
642    NewportUpdateClipping(pNewport);
643    pNewport->setup_drawmode0 = (0
644                                | NPORT_DMODE0_DRAW
645                                | NPORT_DMODE0_ILINE
646				| NPORT_DMODE0_DOSETUP
647				| NPORT_DMODE0_STOPX
648				| NPORT_DMODE0_STOPY
649				| NPORT_DMODE0_L32
650				| NPORT_DMODE0_ZPENAB
651				| ((bg == -1) ? 0 : NPORT_DMODE0_ZOPQ)
652				);
653}
654
655/*******************************************************************************
656
657*******************************************************************************/
658static void
659NewportXAASubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
660                                       int x1,
661			 	       int y1,
662			 	       int x2,
663			 	       int y2,
664			 	       int flags,
665				       int phase)
666{
667    NewportRegsPtr pNewportRegs;
668    NewportPtr pNewport;
669    int dx, dy;
670    unsigned int linelen;
671    unsigned int dwords;
672
673    pNewport = NEWPORTPTR(pScrn);
674    pNewportRegs = NEWPORTREGSPTR(pScrn);
675
676    dx = x2 - x1; if (dx < 0) dx = -dx; dx++;
677    dy = y2 - y1; if (dy < 0) dy = -dy; dy++;
678    if (dx > dy)
679	linelen = dx;
680    else
681	linelen = dy;
682    dwords = (linelen + 31) >> 5;
683
684    NewportUpdateDRAWMODE0(pNewport,
685                           pNewport->setup_drawmode0
686			   | ((flags & OMIT_LAST) ? NPORT_DMODE0_SKLST : 0)
687			  );
688
689    NewportWaitGFIFO(pNewport, 3);
690    pNewportRegs->set.xystarti = ((x1 & 0xFFFF) << 16) | (y1 & 0xFFFF);
691    pNewportRegs->set.xyendi = ((x2 & 0xFFFF) << 16) | (y2 & 0xFFFF);
692    pNewportRegs->set._setup = 1;
693
694    phase %= pNewport->dashline_patlen;
695    while (dwords--) {
696	unsigned int bit;
697	unsigned int pat;
698	unsigned int mask;
699	pat = 0;
700	mask = 0x80000000;
701	for (bit = 0; bit < 32; bit++)
702	{
703	    if (pNewport->dashline_pat[phase >> 3] & (0x80 >> (phase & 7)))
704		pat |= mask;
705	    phase = (phase + 1) % pNewport->dashline_patlen;
706	    mask >>= 1;
707	}
708	NewportWaitGFIFO(pNewport, 1);
709	pNewportRegs->go.zpattern = pat;
710    }
711
712}
713
714/*******************************************************************************
715
716*******************************************************************************/
717static void
718NewportXAASetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
719                                             int fg,
720					     int bg,
721					     int rop,
722					     unsigned int planemask)
723{
724    NewportRegsPtr pNewportRegs;
725    NewportPtr pNewport;
726    pNewport = NEWPORTPTR(pScrn);
727    pNewportRegs = NEWPORTREGSPTR(pScrn);
728
729    NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop));
730    NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask));
731    if (bg != -1)
732	NewportUpdateCOLORBACK(pNewport, NewportColor2HOSTRW(bg));
733    NewportUpdateCOLORI(pNewport, NewportColor2HOSTRW(fg));
734    NewportUpdateDRAWMODE0(pNewport,
735                           0
736                           | NPORT_DMODE0_DRAW
737                           | NPORT_DMODE0_BLOCK
738			   | NPORT_DMODE0_DOSETUP
739			   | NPORT_DMODE0_STOPX
740			   | NPORT_DMODE0_ZPENAB
741			   | ((bg == -1) ? 0 : NPORT_DMODE0_ZOPQ)
742			   | NPORT_DMODE0_L32
743			  );
744}
745
746/*******************************************************************************
747
748*******************************************************************************/
749static void
750NewportXAASubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
751					       int x,
752					       int y,
753					       int w,
754					       int h,
755					       int skipleft)
756{
757    int ex, ey;
758    NewportRegsPtr pNewportRegs;
759    NewportPtr pNewport;
760    pNewport = NEWPORTPTR(pScrn);
761    pNewportRegs = NEWPORTREGSPTR(pScrn);
762
763    if (w == 0) w = 1;
764    if (h == 0) h = 1;
765    ex = x + w - 1;
766    ey = y + h - 1;
767
768    if (skipleft)
769    {
770	pNewport->skipleft = x + skipleft;
771    }
772    else
773    {
774	pNewport->skipleft = 0;
775    }
776    NewportUpdateClipping(pNewport);
777
778    NewportWaitGFIFO(pNewport, 3);
779    pNewportRegs->set.xystarti = ((x & 0xFFFF) << 16) | (y & 0xFFFF);
780    pNewportRegs->set.xyendi = ((ex & 0xFFFF) << 16) | (ey & 0xFFFF);
781    pNewportRegs->set._setup = 1;
782
783    /* after return XAA will start blasting the pattern to go.zpattern register */
784    /* we have to wait here for idle because if there is something in the pipeline that will take
785     long time to complete and if following cpu transfers will overflow the FIFO causing GIO bus
786     stall it will end up in bus error */
787    NewportWaitIdle(pNewport, NEWPORT_GFIFO_ENTRIES);
788
789}
790
791/*******************************************************************************
792
793*******************************************************************************/
794static void
795NewportXAASetupForImageWrite(ScrnInfoPtr pScrn,
796                             int rop,
797			     unsigned int planemask,
798			     int trans_color,
799			     int bpp,
800			     int depth)
801{
802    NewportRegsPtr pNewportRegs;
803    NewportPtr pNewport;
804    pNewport = NEWPORTPTR(pScrn);
805    pNewportRegs = NEWPORTREGSPTR(pScrn);
806
807    NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop));
808    NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask));
809    NewportUpdateDRAWMODE0(pNewport,
810                           0
811                           | NPORT_DMODE0_DRAW
812                           | NPORT_DMODE0_BLOCK
813			   | NPORT_DMODE0_CHOST
814			   | NPORT_DMODE0_DOSETUP
815			  );
816
817}
818
819/*******************************************************************************
820
821*******************************************************************************/
822static void
823NewportXAASubsequentImageWriteRect(ScrnInfoPtr pScrn,
824                                   int x,
825				   int y,
826				   int w,
827				   int h,
828				   int skipleft)
829{
830    int ex, ey;
831    NewportRegsPtr pNewportRegs;
832    NewportPtr pNewport;
833    pNewport = NEWPORTPTR(pScrn);
834    pNewportRegs = NEWPORTREGSPTR(pScrn);
835
836    if (w == 0) w = 1;
837    if (h == 0) h = 1;
838
839    ex = x + w - 1;
840    ey = y + h - 1;
841
842    if (skipleft)
843    {
844	pNewport->skipleft = x + skipleft;
845    }
846    else
847    {
848	pNewport->skipleft = 0;
849    }
850    NewportUpdateClipping(pNewport);
851
852    NewportWaitGFIFO(pNewport, 3);
853    pNewportRegs->set.xystarti = ((x & 0xFFFF) << 16) | (y & 0xFFFF);
854    pNewportRegs->set.xyendi = ((ex & 0xFFFF) << 16) | (ey & 0xFFFF);
855    pNewportRegs->set._setup = 1;
856
857    /* after return XAA will start blasting the image to go.hostrw0 register */
858    /* we have to wait here for idle because if there is something in the pipeline that will take
859     long time to complete and if following cpu transfers will overflow the FIFO causing GIO bus
860     stall it will end up in bus error */
861    NewportWaitIdle(pNewport, NEWPORT_GFIFO_ENTRIES);
862}
863
864static unsigned int
865repbyte(unsigned int b)
866{
867    b &= 0xFF;
868    return b | (b << 8) | (b << 16) | (b << 24);
869}
870
871static void
872prerotatebyte(unsigned int b, unsigned int *p)
873{
874    int i;
875
876    b &= 0xFF;
877
878    for (i = 0; i < 8; i++)
879    {
880	p[i] = repbyte(b);
881	if (b & 1)
882	    b = (b >> 1) | 0x80;
883	else
884	    b = b >> 1;
885    }
886}
887
888/*******************************************************************************
889
890*******************************************************************************/
891static void
892NewportXAASetupForMono8x8PatternFill(ScrnInfoPtr pScrn,
893                                     int patx,
894				     int paty,
895				     int fg,
896				     int bg,
897				     int rop,
898				     unsigned int planemask)
899{
900    NewportRegsPtr pNewportRegs;
901    NewportPtr pNewport;
902    pNewport = NEWPORTPTR(pScrn);
903    pNewportRegs = NEWPORTREGSPTR(pScrn);
904
905#ifdef NEWPORT_PREROTATE
906    /* prerotate the pattern */
907    prerotatebyte((unsigned int)patx >> 24, pNewport->pat8x8[0]);
908    prerotatebyte((unsigned int)patx >> 16, pNewport->pat8x8[1]);
909    prerotatebyte((unsigned int)patx >> 8, pNewport->pat8x8[2]);
910    prerotatebyte((unsigned int)patx, pNewport->pat8x8[3]);
911    prerotatebyte((unsigned int)paty >> 24, pNewport->pat8x8[4]);
912    prerotatebyte((unsigned int)paty >> 16, pNewport->pat8x8[5]);
913    prerotatebyte((unsigned int)paty >> 8, pNewport->pat8x8[6]);
914    prerotatebyte((unsigned int)paty, pNewport->pat8x8[7]);
915#endif
916    NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop));
917    NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(planemask));
918    if (bg != -1)
919	NewportUpdateCOLORBACK(pNewport, NewportColor2HOSTRW(bg));
920    NewportUpdateCOLORI(pNewport, NewportColor2HOSTRW(fg));
921    pNewport->skipleft = 0;
922    NewportUpdateClipping(pNewport);
923    NewportUpdateDRAWMODE0(pNewport,
924                           0
925                           | NPORT_DMODE0_DRAW
926                           | NPORT_DMODE0_BLOCK
927		           | NPORT_DMODE0_DOSETUP
928		           | NPORT_DMODE0_STOPX
929			   | NPORT_DMODE0_ZPENAB
930			   | ((bg == -1) ? 0 : NPORT_DMODE0_ZOPQ)
931			   | NPORT_DMODE0_L32
932			  );
933}
934
935
936
937/*******************************************************************************
938
939*******************************************************************************/
940static void
941NewportXAASubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,
942                                           int patx,
943					   int paty,
944					   int x,
945					   int y,
946					   int w,
947					   int h)
948{
949    int ex, ey;
950    unsigned int d;
951#ifndef NEWPORT_PREROTATE
952    unsigned int p;
953    unsigned int epat[8];
954#endif
955
956    NewportRegsPtr pNewportRegs;
957    NewportPtr pNewport;
958    pNewport = NEWPORTPTR(pScrn);
959    pNewportRegs = NEWPORTREGSPTR(pScrn);
960
961    if (w == 0) w = 1;
962    if (h == 0) h = 1;
963    ex = x + w - 1;
964    ey = y + h - 1;
965
966    NewportWaitGFIFO(pNewport, 3);
967    pNewportRegs->set.xystarti = ((x & 0xFFFF) << 16) | (y & 0xFFFF);
968    pNewportRegs->set.xyendi = ((ex & 0xFFFF) << 16) | (ey & 0xFFFF);
969    pNewportRegs->set._setup = 1;
970
971#ifdef NEWPORT_PREROTATE
972    patx &= 7;
973    paty &= 7;
974    while (h--)
975    {
976	for (d = (w + 31) >> 5; d; d--)
977	{
978	    NewportWaitGFIFO(pNewport, 1);
979	    pNewportRegs->go.zpattern = pNewport->pat8x8[paty][patx];
980	}
981	paty = (paty + 1) & 7;
982    }
983#else
984    epat[0] = repbyte(patx >> 24);
985    epat[1] = repbyte(patx >> 16);
986    epat[2] = repbyte(patx >> 8);
987    epat[3] = repbyte(patx);
988    epat[4] = repbyte(paty >> 24);
989    epat[5] = repbyte(paty >> 16);
990    epat[6] = repbyte(paty >> 8);
991    epat[7] = repbyte(paty);
992
993    p = 0;
994    while (h--)
995    {
996	for (d = (w + 31) >> 5; d; d--)
997	{
998	    NewportWaitGFIFO(pNewport, 1);
999	    pNewportRegs->go.zpattern = epat[p];
1000	}
1001	p = (p + 1) ^ 7;
1002    }
1003#endif
1004}
1005
1006/*******************************************************************************
1007
1008*******************************************************************************/
1009static void
1010NewportXAAReadPixmap(ScrnInfoPtr pScrn,
1011                     int x,
1012		     int y,
1013		     int w,
1014		     int h,
1015		     unsigned char *dst,
1016		     int dstwidth,
1017		     int bpp,
1018		     int depth)
1019{
1020    int ex, ey;
1021    NewportRegsPtr pNewportRegs;
1022    NewportPtr pNewport;
1023    pNewport = NEWPORTPTR(pScrn);
1024    pNewportRegs = NEWPORTREGSPTR(pScrn);
1025
1026    if (w == 0) w = 1;
1027    if (h == 0) h = 1;
1028    ex = x + w - 1;
1029    ey = y + h - 1;
1030
1031    NewportWaitIdle(pNewport, 0);
1032    NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(GXcopy) | NPORT_DMODE1_PFENAB);
1033    NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(0xFFFFFFFF));
1034    NewportUpdateDRAWMODE0(pNewport,
1035                           0
1036                           | NPORT_DMODE0_RD
1037                           | NPORT_DMODE0_BLOCK
1038			   | NPORT_DMODE0_CHOST
1039			   | NPORT_DMODE0_DOSETUP
1040			  );
1041
1042    NewportWaitGFIFO(pNewport, 3);
1043    pNewportRegs->set.xystarti = ((x & 0xFFFF) << 16) | (y & 0xFFFF);
1044    pNewportRegs->set.xyendi = ((ex & 0xFFFF) << 16) | (ey & 0xFFFF);
1045    /* with prefetch enabled go has to be issued before we start reading */
1046    pNewportRegs->go._setup = 1;
1047
1048
1049    if (pScrn->bitsPerPixel == 8)
1050    {
1051	unsigned int d;
1052	while (h--)
1053	{
1054	    unsigned char *p;
1055	    p = (unsigned char *)dst;
1056    	    for (x = 0; x < w; x += 4)
1057	    {
1058		if (!h && x+4 >= w)
1059		{ /* the last dword does not need go */
1060		    d = pNewportRegs->set.hostrw0;
1061		}
1062		else
1063		{
1064		    d = pNewportRegs->go.hostrw0;
1065		}
1066
1067		*p++ = (d & 0xFF000000) >> 24;
1068		if (x+1 < w)
1069		{
1070		    *p++ = (d & 0x00FF0000) >> 16;
1071		}
1072		if (x+2 < w)
1073		{
1074		    *p++ = (d & 0x0000FF00) >> 8;
1075		}
1076		if (x+3 < w)
1077		{
1078		    *p++ = d & 0x000000FF;
1079		}
1080	    }
1081	    dst += dstwidth;
1082	}
1083    }
1084    else
1085    {
1086	while (h--)
1087	{
1088	    unsigned int *p;
1089	    p = (unsigned int *)dst;
1090    	    for (x = 0; x < w; x++)
1091	    {
1092		if (!h && x+1 == w)
1093		{ /* the last dword does not need go */
1094		    *p++ = pNewportRegs->set.hostrw0;
1095		}
1096		else
1097		{
1098		    *p++ = pNewportRegs->go.hostrw0;
1099		}
1100	    }
1101	    dst += dstwidth;
1102	}
1103    }
1104}
1105
1106/*******************************************************************************
1107
1108*******************************************************************************/
1109static void
1110NewportXAASetClippingRectangle(ScrnInfoPtr pScrn,
1111                               int left,
1112			       int top,
1113			       int right,
1114			       int bottom)
1115{
1116    NewportPtr pNewport;
1117    pNewport = NEWPORTPTR(pScrn);
1118
1119    if (left < 0) left = 0;
1120    if (right > pScrn->virtualX-1) right = pScrn->virtualX-1;
1121
1122    if (top < 0) top = 0;
1123    if (bottom > pScrn->virtualY-1) bottom = pScrn->virtualY-1;
1124
1125    pNewport->clipsx = left;
1126    pNewport->clipex = right;
1127    pNewport->clipsy = top;
1128    pNewport->clipey = bottom;
1129
1130    NewportUpdateClipping(pNewport);
1131}
1132
1133/*******************************************************************************
1134
1135*******************************************************************************/
1136static void
1137NewportXAADisableClipping(ScrnInfoPtr pScrn)
1138{
1139    NewportPtr pNewport;
1140    pNewport = NEWPORTPTR(pScrn);
1141
1142    pNewport->clipsx = 0;
1143    pNewport->clipex = pScrn->virtualX-1;
1144    pNewport->clipsy = 0;
1145    pNewport->clipey = pScrn->virtualY-1;
1146    NewportUpdateClipping(pNewport);
1147}
1148
1149/*******************************************************************************
1150
1151*******************************************************************************/
1152static void
1153NewportPolyPoint(DrawablePtr pDraw,
1154                 GCPtr pGC,
1155                 int mode,
1156                 int npt,
1157                 xPoint *ppt)
1158{
1159    ScrnInfoPtr pScrn;
1160    int numRects = REGION_NUM_RECTS(pGC->pCompositeClip);
1161    int rect;
1162    XAAInfoRecPtr infoRec;
1163    BoxPtr pbox;
1164    int x, y;
1165    int rop;
1166
1167    NewportRegsPtr pNewportRegs;
1168    NewportPtr pNewport;
1169
1170    infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
1171    pScrn = infoRec->pScrn;
1172
1173    if (!numRects)
1174	return;
1175
1176    pNewport = NEWPORTPTR(pScrn);
1177    pNewportRegs = NEWPORTREGSPTR(pScrn);
1178
1179    x = pDraw->x;
1180    y = pDraw->y;
1181
1182    rop = pGC->alu;
1183
1184    NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(pGC->planemask));
1185    if (rop == GXcopy
1186        || rop == GXclear
1187	|| rop == GXset)
1188    {
1189	/* if possible try to set up a fast clear which is 4x faster */
1190	NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | NPORT_DMODE1_FCLR | Rop2LogicOp(GXcopy));
1191	if (rop == GXclear)
1192	    NewportUpdateCOLORVRAM(pNewport, 0);
1193	else
1194	if (rop == GXset)
1195	    NewportUpdateCOLORVRAM(pNewport, 0xFFFFFF);
1196	else
1197            NewportUpdateCOLORVRAM(pNewport, pNewport->Color2Planes((unsigned int)(pGC->fgPixel)));
1198    }
1199    else
1200    {
1201	NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(rop));
1202	NewportUpdateCOLORI(pNewport, NewportColor2HOSTRW(pGC->fgPixel));
1203    }
1204
1205    pNewport->skipleft = 0;
1206    NewportUpdateClipping(pNewport);
1207    NewportUpdateDRAWMODE0(pNewport,
1208                           0
1209                           | NPORT_DMODE0_DRAW
1210			   | NPORT_DMODE0_BLOCK
1211		           | NPORT_DMODE0_DOSETUP
1212			  );
1213
1214    pbox = REGION_RECTS(pGC->pCompositeClip);
1215
1216    while (npt--) {
1217	if (mode == CoordModePrevious)
1218	{
1219	    x += ppt->x;
1220	    y += ppt->y;
1221	}
1222	else
1223	{
1224	    x = pDraw->x + ppt->x;
1225	    y = pDraw->y + ppt->y;
1226	}
1227	for (rect = 0; rect < numRects; rect++)
1228	    if (x >= pbox[rect].x1 && x < pbox[rect].x2
1229	        && y >= pbox[rect].y1 && y < pbox[rect].y2)
1230	       { /* draw point */
1231	    	    unsigned int xy;
1232		    xy = ((x & 0xFFFF) << 16) | (y & 0xFFFF);
1233	    	    NewportWaitGFIFO(pNewport, 2);
1234		    pNewportRegs->set.xystarti = xy;
1235		    pNewportRegs->go.xyendi = xy;
1236		    break;
1237	       }
1238	ppt++;
1239    }
1240}
1241
1242/*******************************************************************************
1243
1244*******************************************************************************/
1245static void
1246NewportValidatePolyPoint(GCPtr pGC,
1247                         unsigned long changes,
1248                         DrawablePtr pDraw)
1249{
1250
1251    if (pDraw->type == DRAWABLE_WINDOW)
1252    {
1253	pGC->ops->PolyPoint = NewportPolyPoint;
1254    }
1255    else
1256    {
1257	pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint;
1258    }
1259}
1260
1261#if 1
1262/*******************************************************************************
1263
1264*******************************************************************************/
1265static void
1266NewportPolyArc(DrawablePtr pDraw,
1267               GCPtr pGC,
1268               int narcs,
1269               xArc *parcs)
1270{
1271    xArc *arc;
1272    BoxRec box;
1273    int i, x2, y2;
1274    RegionPtr cclip;
1275
1276    cclip = pGC->pCompositeClip;
1277
1278    if(!REGION_NUM_RECTS(cclip))
1279	return;
1280
1281    for (arc = parcs, i = narcs; --i >= 0; arc++) {
1282	if (miCanZeroArc(arc)) {
1283	    box.x1 = arc->x + pDraw->x;
1284	    box.y1 = arc->y + pDraw->y;
1285 	    x2 = box.x1 + (int)arc->width + 1;
1286 	    box.x2 = x2;
1287 	    y2 = box.y1 + (int)arc->height + 1;
1288 	    box.y2 = y2;
1289 	    if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
1290 		    (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
1291		miZeroPolyArc(pDraw, pGC, 1, arc);
1292	}
1293	else
1294	    miPolyArc(pDraw, pGC, 1, arc);
1295    }
1296}
1297#endif
1298
1299/*******************************************************************************
1300
1301*******************************************************************************/
1302static void
1303NewportValidatePolyArc(GCPtr pGC,
1304                       unsigned long changes,
1305                       DrawablePtr pDraw)
1306{
1307    if (pDraw->type == DRAWABLE_WINDOW)
1308    {
1309	pGC->ops->PolyPoint = NewportPolyPoint;
1310	/*pGC->ops->PolyArc = miPolyArc;*/
1311	pGC->ops->PolyArc = NewportPolyArc;
1312
1313    }
1314    else
1315    {
1316	pGC->ops->PolyPoint = XAAGetFallbackOps()->PolyPoint;
1317	pGC->ops->PolyArc = XAAGetFallbackOps()->PolyArc;
1318    }
1319}
1320
1321
1322#ifdef RENDER
1323/*******************************************************************************
1324
1325*******************************************************************************/
1326static Bool
1327NewportXAASetupForCPUToScreenAlphaTexture(
1328	ScrnInfoPtr	pScrn,
1329	int		op,
1330	CARD16		red,
1331	CARD16		green,
1332	CARD16		blue,
1333	CARD16		alpha,
1334	CARD32          maskFormat,
1335	CARD32          dstFormat,
1336	CARD8		*alphaPtr,
1337	int		alphaPitch,
1338	int		width,
1339	int		height,
1340	int		flags)
1341{
1342    unsigned int col, a;
1343    unsigned char *pSrc;
1344    unsigned int *pDst;
1345    unsigned int w;
1346    NewportRegsPtr pNewportRegs;
1347    NewportPtr pNewport;
1348    pNewport = NEWPORTPTR(pScrn);
1349    pNewportRegs = NEWPORTREGSPTR(pScrn);
1350
1351    if (width * height * sizeof(unsigned int) > pNewport->uTextureSize)
1352    {
1353	free(pNewport->pTexture);
1354	pNewport->pTexture = xnfalloc(pNewport->uTextureSize = width * height * sizeof(unsigned int));
1355    }
1356    col = (((unsigned int)red & 0xFF00) << 8)
1357        | ((unsigned int)green & 0xFF00)
1358	| ((unsigned int)blue >> 8);
1359
1360    pNewport->uTextureWidth = width;
1361    pNewport->uTextureHeight = height;
1362    pNewport->uTextureFlags = flags;
1363
1364    /* copy texture */
1365    pDst = pNewport->pTexture;
1366    while (height--) {
1367	pSrc = (unsigned char *)alphaPtr;
1368
1369	for (w = width; w; w--)
1370	{
1371	    /* premultiply alpha */
1372	    a = *pSrc++;
1373	    a *= alpha;
1374	    a /= 0xFFFF;
1375	    a <<= 24;
1376	    *pDst++ = col | a;
1377	}
1378	alphaPtr += alphaPitch;
1379    }
1380#define SFACTOR (4 << 19)
1381#define DFACTOR (5 << 22)
1382    NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(GXcopy) | NPORT_DMODE1_BENAB | SFACTOR | DFACTOR );
1383#undef SFACTOR
1384#undef DFACTOR
1385    NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(0xFFFFFFFF));
1386
1387    pNewport->skipleft = 0;
1388    NewportUpdateClipping(pNewport);
1389    NewportUpdateDRAWMODE0(pNewport,
1390                           0
1391                           | NPORT_DMODE0_DRAW
1392                           | NPORT_DMODE0_BLOCK
1393			   | NPORT_DMODE0_CHOST
1394			   | NPORT_DMODE0_AHOST
1395			   | NPORT_DMODE0_DOSETUP
1396			  );
1397    return TRUE;
1398}
1399
1400/*******************************************************************************
1401
1402*******************************************************************************/
1403static Bool
1404NewportXAASetupForCPUToScreenTexture(
1405	ScrnInfoPtr	pScrn,
1406	int		op,
1407	CARD32          srcFormat,
1408	CARD32          dstFormat,
1409	CARD8		*texPtr,
1410	int		texPitch,
1411	int		width,
1412	int		height,
1413	int		flags)
1414{
1415    unsigned int *pSrc, *pDst;
1416    unsigned int w;
1417    NewportRegsPtr pNewportRegs;
1418    NewportPtr pNewport;
1419    pNewport = NEWPORTPTR(pScrn);
1420    pNewportRegs = NEWPORTREGSPTR(pScrn);
1421
1422    if (width * height * sizeof(unsigned int) > pNewport->uTextureSize)
1423    {
1424	free(pNewport->pTexture);
1425	pNewport->pTexture = xnfalloc(pNewport->uTextureSize = width * height * sizeof(unsigned int));
1426    }
1427
1428    pNewport->uTextureWidth = width;
1429    pNewport->uTextureHeight = height;
1430    pNewport->uTextureFlags = flags;
1431
1432    /* copy texture */
1433    pDst = pNewport->pTexture;
1434
1435    if (srcFormat == PICT_a8r8g8b8)
1436    {
1437	while (height--) {
1438	    pSrc = (unsigned int *)texPtr;
1439
1440	    for (w = width; w; w--)
1441	    {
1442		unsigned int v;
1443		v = *pSrc++;
1444		*pDst++ = (v & 0xFF00FF00) | ((v & 0x00FF0000) >> 16) | ((v & 0x000000FF) << 16);
1445	    }
1446	    texPtr += texPitch;
1447	}
1448    }
1449    else
1450    if (srcFormat == PICT_a8b8g8r8)
1451    {
1452	while (height--) {
1453	    pSrc = (unsigned int *)texPtr;
1454
1455	    for (w = width; w; w--)
1456		*pDst++ = *pSrc++;
1457	    texPtr += texPitch;
1458	}
1459    }
1460    else
1461    {
1462	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unknown texture format\n");
1463    }
1464
1465#define SFACTOR (4 << 19)
1466#define DFACTOR (5 << 22)
1467    NewportUpdateDRAWMODE1(pNewport, pNewport->setup_drawmode1 | Rop2LogicOp(GXcopy) | NPORT_DMODE1_BENAB | SFACTOR | DFACTOR );
1468#undef SFACTOR
1469#undef DFACTOR
1470    NewportUpdateWRMASK(pNewport, pNewport->Color2Planes(0xFFFFFFFF));
1471
1472    pNewport->skipleft = 0;
1473    NewportUpdateClipping(pNewport);
1474    NewportUpdateDRAWMODE0(pNewport,
1475                           0
1476                           | NPORT_DMODE0_DRAW
1477                           | NPORT_DMODE0_BLOCK
1478			   | NPORT_DMODE0_CHOST
1479			   | NPORT_DMODE0_AHOST
1480			   | NPORT_DMODE0_DOSETUP
1481			  );
1482
1483    return TRUE;
1484}
1485
1486/*******************************************************************************
1487
1488*******************************************************************************/
1489static void
1490NewportRenderTexture1to1(NewportPtr pNewport, int srcx, int srcy, int w, int h)
1491{
1492    unsigned int *p;
1493    unsigned int add, d;
1494    NewportRegsPtr pNewportRegs;
1495    pNewportRegs = pNewport->pNewportRegs;
1496
1497    p = pNewport->pTexture + srcx + (srcy * pNewport->uTextureWidth);
1498    add = pNewport->uTextureWidth - w + srcx;
1499    while (h--)
1500    {
1501	for (d = w; d; d--)
1502	{
1503	    /*NewportWaitGFIFO(pNewport, 1);*/
1504	    /* hopefully we cannot write faster than XL24 can blend */
1505	    pNewportRegs->go.hostrw0 = *p++;
1506	}
1507	p += add;
1508    }
1509}
1510
1511/*******************************************************************************
1512
1513*******************************************************************************/
1514static void
1515NewportRenderTextureScale(NewportPtr pNewport, int srcx, int srcy, int w, int h)
1516{
1517    int d;
1518    int dx, dy;
1519    int curx, cury;
1520    unsigned int *pLine;
1521    int l, p;
1522    NewportRegsPtr pNewportRegs;
1523    pNewportRegs = pNewport->pNewportRegs;
1524
1525    dx = ((pNewport->uTextureWidth - srcx) << 16) / w;
1526    dy = ((pNewport->uTextureHeight - srcy) << 16) / h;
1527
1528    cury = srcy << 16;
1529    while (h--)
1530    {
1531	l = (cury + 0x7FFF) >> 16;
1532	if (l >= pNewport->uTextureHeight)
1533	    l = pNewport->uTextureHeight-1;
1534	pLine = pNewport->pTexture + l * pNewport->uTextureWidth;
1535
1536	curx = srcx << 16;
1537	for (d = w; d; d--)
1538	{
1539	    p = (curx + 0x7FFF) >> 16;
1540	    if (p >= pNewport->uTextureWidth)
1541		p = pNewport->uTextureWidth-1;
1542	    pNewportRegs->go.hostrw0 = pLine[p];
1543	    curx += dx;
1544	}
1545        cury += dy;
1546    }
1547}
1548
1549/*******************************************************************************
1550
1551*******************************************************************************/
1552static void
1553NewportRenderTextureRepeat(NewportPtr pNewport, int srcx, int srcy, int w, int h)
1554{
1555    int d;
1556    unsigned int *pLine;
1557    NewportRegsPtr pNewportRegs;
1558    pNewportRegs = pNewport->pNewportRegs;
1559
1560    srcx %= pNewport->uTextureWidth;
1561    srcy %= pNewport->uTextureHeight;
1562
1563    while (h--)
1564    {
1565	pLine = pNewport->pTexture + pNewport->uTextureWidth * srcy;
1566	for (d = w; d; d--)
1567	{
1568	    pNewportRegs->go.hostrw0 = pLine[srcx];
1569	    srcx++;
1570	    if (srcx >= pNewport->uTextureWidth)
1571		srcx = 0;
1572	}
1573        srcy++;
1574	if (srcy >= pNewport->uTextureHeight)
1575	    srcy = 0;
1576    }
1577
1578}
1579
1580
1581/*******************************************************************************
1582
1583*******************************************************************************/
1584static void
1585NewportXAASubsequentCPUToScreenTexture(
1586	ScrnInfoPtr	pScrn,
1587	int		x,
1588	int		y,
1589	int		srcx,
1590	int		srcy,
1591	int		w,
1592	int		h)
1593{
1594    int ex, ey;
1595    NewportRegsPtr pNewportRegs;
1596    NewportPtr pNewport;
1597    pNewport = NEWPORTPTR(pScrn);
1598    pNewportRegs = NEWPORTREGSPTR(pScrn);
1599
1600    if (w == 0) w = 1;
1601    if (h == 0) h = 1;
1602    ex = x + w - 1;
1603    ey = y + h - 1;
1604
1605    NewportWaitGFIFO(pNewport, 3);
1606    pNewportRegs->set.xystarti = ((x & 0xFFFF) << 16) | (y & 0xFFFF);
1607    pNewportRegs->set.xyendi = ((ex & 0xFFFF) << 16) | (ey & 0xFFFF);
1608    pNewportRegs->set._setup = 1;
1609
1610    NewportWaitIdle(pNewport, NEWPORT_GFIFO_ENTRIES);
1611
1612    if (srcx + w == pNewport->uTextureWidth
1613        && srcy + h == pNewport->uTextureHeight)
1614	NewportRenderTexture1to1(pNewport, srcx, srcy, w, h);
1615    else
1616    if (pNewport->uTextureFlags & XAA_RENDER_REPEAT)
1617	NewportRenderTextureRepeat(pNewport,  srcx, srcy, w, h);
1618    else
1619	NewportRenderTextureScale(pNewport, srcx, srcy, w, h);
1620
1621    NewportWaitIdle(pNewport, NEWPORT_GFIFO_ENTRIES);
1622
1623}
1624
1625CARD32 NewportAlphaTextureFormats[2] = {PICT_a8, 0};
1626CARD32 NewportTextureFormats[3] = {PICT_a8r8g8b8, PICT_a8b8g8r8, 0};
1627/*CARD32 NewportTextureFormats[2] = {PICT_a8r8g8b8, 0};*/
1628CARD32 NewportDstFormats[7] = {PICT_a8r8g8b8, PICT_a8b8g8r8, PICT_x8r8g8b8, PICT_x8b8g8r8, PICT_r8g8b8, PICT_b8g8r8, 0};
1629
1630#endif
1631
1632/*******************************************************************************
1633
1634*******************************************************************************/
1635Bool
1636NewportXAAScreenInit(ScreenPtr pScreen)
1637{
1638	ScrnInfoPtr pScrn;
1639	NewportPtr pNewport;
1640	NewportRegsPtr pNewportRegs;
1641	XAAInfoRecPtr pXAAInfoRec;
1642
1643	/* First get a pointer to our private info */
1644	pScrn = xf86Screens[pScreen->myNum];
1645	pNewport = NEWPORTPTR(pScrn);
1646	pNewportRegs = NEWPORTREGSPTR(pScrn);
1647
1648	pXAAInfoRec =
1649	pNewport->pXAAInfoRec = XAACreateInfoRec();
1650	/* initialize accelerated functions */
1651	pXAAInfoRec->Sync = NewportXAASync;
1652
1653	pXAAInfoRec->Flags = 0
1654	                     /*| LINEAR_FRAMEBUFFER*/
1655	                     ;
1656	/* screen to screen copy */
1657	pXAAInfoRec->ScreenToScreenCopyFlags = 0
1658					     | NO_TRANSPARENCY
1659					     ;
1660	pXAAInfoRec->SetupForScreenToScreenCopy = NewportXAASetupForScreenToScreenCopy;
1661	pXAAInfoRec->SubsequentScreenToScreenCopy = NewportXAASubsequentScreenToScreenCopy;
1662
1663	/* solid fills */
1664	pXAAInfoRec->SolidFillFlags = 0
1665				      ;
1666	pXAAInfoRec->SetupForSolidFill = NewportXAASetupForSolidFill;
1667	pXAAInfoRec->SubsequentSolidFillRect = NewportXAASubsequentSolidFillRect;
1668
1669	/* solid lines */
1670	pXAAInfoRec->SolidLineFlags = 0
1671	                              ;
1672	pXAAInfoRec->SetupForSolidLine = NewportXAASetupForSolidLine;
1673	pXAAInfoRec->SubsequentSolidTwoPointLine = NewportXAASubsequentSolidTwoPointLine;
1674
1675	/* dashed lines */
1676	pXAAInfoRec->DashedLineFlags = 0
1677	                             | LINE_PATTERN_MSBFIRST_MSBJUSTIFIED
1678	                             ;
1679	pXAAInfoRec->DashPatternMaxLength = 2048;
1680	pXAAInfoRec->SetupForDashedLine = NewportXAASetupForDashedLine;
1681	pXAAInfoRec->SubsequentDashedTwoPointLine = NewportXAASubsequentDashedTwoPointLine;
1682
1683	/* cpu to screen expand color fill */
1684	pXAAInfoRec->CPUToScreenColorExpandFillFlags = 0
1685						     | BIT_ORDER_IN_BYTE_LSBFIRST
1686						     | SCANLINE_PAD_DWORD
1687						     | CPU_TRANSFER_PAD_DWORD
1688						     | CPU_TRANSFER_BASE_FIXED
1689				                     | LEFT_EDGE_CLIPPING
1690				                     | LEFT_EDGE_CLIPPING_NEGATIVE_X
1691						     /*| SYNC_AFTER_COLOR_EXPAND*/
1692						     ;
1693
1694	pXAAInfoRec->SetupForCPUToScreenColorExpandFill	= NewportXAASetupForCPUToScreenColorExpandFill;
1695	pXAAInfoRec->SubsequentCPUToScreenColorExpandFill = NewportXAASubsequentCPUToScreenColorExpandFill;
1696	pXAAInfoRec->ColorExpandRange = 4;
1697	pXAAInfoRec->ColorExpandBase = (unsigned char *)&(pNewportRegs->go.zpattern);
1698
1699
1700	/* mono 8x8 pattern fill */
1701	pXAAInfoRec->Mono8x8PatternFillFlags = 0
1702	                                       | BIT_ORDER_IN_BYTE_LSBFIRST
1703					       | HARDWARE_PATTERN_PROGRAMMED_BITS
1704#ifdef NEWPORT_PREROTATE
1705                                               | HARDWARE_PATTERN_PROGRAMMED_ORIGIN
1706#endif
1707                                               ;
1708
1709	pXAAInfoRec->SetupForMono8x8PatternFill	= NewportXAASetupForMono8x8PatternFill;
1710	pXAAInfoRec->SubsequentMono8x8PatternFillRect = NewportXAASubsequentMono8x8PatternFillRect;
1711
1712	/* Image write */
1713	pXAAInfoRec->ImageWriteFlags = 0
1714				     | NO_TRANSPARENCY
1715				     | CPU_TRANSFER_BASE_FIXED
1716				     | CPU_TRANSFER_PAD_DWORD
1717				     | SCANLINE_PAD_DWORD
1718				     | LEFT_EDGE_CLIPPING
1719				     | LEFT_EDGE_CLIPPING_NEGATIVE_X
1720				     /*| SYNC_AFTER_IMAGE_WRITE*/
1721				     ;
1722	pXAAInfoRec->SetupForImageWrite = NewportXAASetupForImageWrite;
1723	pXAAInfoRec->SubsequentImageWriteRect = NewportXAASubsequentImageWriteRect;
1724	pXAAInfoRec->ImageWriteRange = 4;
1725	pXAAInfoRec->ImageWriteBase =  (unsigned char *)&(pNewportRegs->go.hostrw0);
1726
1727	/* read pixmap */
1728	pXAAInfoRec->ReadPixmapFlags = 0
1729	                             | CPU_TRANSFER_PAD_DWORD
1730				     ;
1731	pXAAInfoRec->ReadPixmap = NewportXAAReadPixmap;
1732
1733	/* clipping */
1734	pXAAInfoRec->ClippingFlags = 0
1735	                             /*| HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND*/
1736				     | HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY
1737				     | HARDWARE_CLIP_MONO_8x8_FILL
1738				     /*| HARDWARE_CLIP_COLOR_8x8_FILL*/
1739				     | HARDWARE_CLIP_SOLID_FILL
1740				     | HARDWARE_CLIP_DASHED_LINE
1741				     | HARDWARE_CLIP_SOLID_LINE
1742	                             ;
1743	pXAAInfoRec->SetClippingRectangle = NewportXAASetClippingRectangle;
1744	pXAAInfoRec->DisableClipping = NewportXAADisableClipping;
1745
1746	/* make it draw points using our function */
1747	pXAAInfoRec->ValidatePolyPoint = NewportValidatePolyPoint;
1748	pXAAInfoRec->PolyPointMask = GCFunction | GCPlaneMask;
1749	/*pXAAInfoRec->PolyPointMask = 0xFFFFFFFF;*/
1750
1751	pXAAInfoRec->ValidatePolyArc = NewportValidatePolyArc;
1752	pXAAInfoRec->PolyArcMask = GCFunction | GCLineWidth;
1753#ifdef RENDER
1754	if (pScrn->bitsPerPixel > 8)
1755	{
1756	    pXAAInfoRec->CPUToScreenTextureFlags = 0
1757		                                   ;
1758	    pXAAInfoRec->CPUToScreenTextureFormats = NewportTextureFormats;
1759	    pXAAInfoRec->CPUToScreenTextureDstFormats = NewportDstFormats;
1760	    pXAAInfoRec->SetupForCPUToScreenTexture2 = NewportXAASetupForCPUToScreenTexture;
1761	    pXAAInfoRec->SubsequentCPUToScreenTexture = NewportXAASubsequentCPUToScreenTexture;
1762
1763	    pXAAInfoRec->CPUToScreenAlphaTextureFlags = 0
1764	                                                ;
1765	    pXAAInfoRec->CPUToScreenAlphaTextureFormats = NewportAlphaTextureFormats;
1766	    pXAAInfoRec->CPUToScreenAlphaTextureDstFormats = NewportDstFormats;
1767	    pXAAInfoRec->SetupForCPUToScreenAlphaTexture2 = NewportXAASetupForCPUToScreenAlphaTexture;
1768	    pXAAInfoRec->SubsequentCPUToScreenAlphaTexture = NewportXAASubsequentCPUToScreenTexture; /* this is the same for both */
1769	    pNewport->pTexture = (unsigned int *)xnfalloc(pNewport->uTextureSize = 16*16*sizeof(unsigned int));
1770	}
1771#endif
1772
1773	pNewport->Color2Planes = NewportColor2Planes24;
1774	if (pScrn->bitsPerPixel == 8)
1775	{
1776	    pNewport->Color2Planes = NewportColor2Planes8;
1777	}
1778
1779	if (!XAAInit(pScreen, pXAAInfoRec))
1780	{
1781	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "XAAInit Failed!\n");
1782	    return FALSE;
1783	}
1784
1785	pNewport->fifoleft = 0;
1786	/* init bunch of registers */
1787
1788	pNewport->shadow_drawmode0 = pNewportRegs->set.drawmode0;
1789	pNewport->shadow_colori = pNewportRegs->set.colori;
1790	pNewport->shadow_smask0x = pNewportRegs->set.smask0x;
1791	pNewport->shadow_smask0y = pNewportRegs->set.smask0y;
1792
1793	pNewport->shadow_drawmode1 = pNewport->drawmode1;
1794	pNewportRegs->set.drawmode1 = pNewport->drawmode1;
1795	pNewport->setup_drawmode1 = pNewport->drawmode1 & ~NPORT_DMODE1_LOMASK;
1796
1797	pNewport->shadow_xymove = 0;
1798	pNewportRegs->set.xymove = 0;
1799
1800	pNewport->shadow_wrmask = 0xFFFFFF;
1801	pNewportRegs->set.wrmask = 0xFFFFFF;
1802
1803	pNewport->shadow_colorvram = 0;
1804	pNewportRegs->set.colorvram = 0;
1805
1806	pNewport->shadow_colorback = 0;
1807	pNewportRegs->set.colorback = 0;
1808
1809	pNewport->clipsx = 0;
1810	pNewport->clipex = pScrn->virtualX-1;
1811	pNewport->clipsy = 0;
1812	pNewport->clipey = pScrn->virtualY-1;
1813	pNewport->skipleft = 0;
1814
1815	BARF1("CLIPMODE %08X\n", pNewportRegs->cset.clipmode);
1816	BARF1("XYWIN %08X\n", pNewportRegs->cset.xywin);
1817	BARF1("CONFIG %08X\n", pNewportRegs->cset.config);
1818	BARF1("SMASK0X %08X\n", pNewportRegs->set.smask0x);
1819	BARF1("SMASK0Y %08X\n", pNewportRegs->set.smask0y);
1820
1821/*
1822  set GIO bus timeout to highest possible value 4.32us
1823  this will allow for longer bus stalls without bus error
1824*/
1825	{
1826	    unsigned int conf;
1827	    conf = pNewportRegs->cset.config;
1828	    conf &= ~NPORT_CFG_TOMSK;
1829	    conf |= NPORT_CFG_TOMSK;
1830
1831	    conf &= ~NPORT_CFG_GDMSK;
1832	    conf |= NPORT_CFG_GDMSK;
1833
1834	    pNewportRegs->cset.config = conf;
1835	}
1836
1837	BARF1("CONFIG %08X\n", pNewportRegs->cset.config);
1838
1839	pNewport->shadow_clipmode = pNewportRegs->cset.clipmode;
1840	pNewportRegs->cset.clipmode |= 1; /* enable clipping mask 0 */
1841	NewportUpdateClipping(pNewport);
1842
1843	return TRUE;
1844}
1845
1846#endif
1847/* NEWPORT_ACCEL */
1848