1 /*
2  * The accel file for the Savage driver.
3  *
4  * Created 20/03/97 by Sebastien Marineau for 3.3.6
5  * Modified 17-Nov-2000 by Tim Roberts for 4.0.1
6  * Modified Feb-2004 by Alex Deucher - integrating DRI support
7  * Modified 2005-2006 by Alex Deucher - adding exa support
8  * Revision:
9  *
10  */
11 
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
15 
16 #include <X11/Xarch.h>
17 #include "savage_driver.h"
18 #ifdef HAVE_XAA_H
19 #include "xaalocal.h"
20 #include "xaarop.h"
21 
22 #include "miline.h"
23 
24 #include "savage_bci.h"
25 
26 extern int gSavageEntityIndex;
27 
28 static void SavageSetupForScreenToScreenCopy(
29     ScrnInfoPtr pScrn,
30     int xdir,
31     int ydir,
32     int rop,
33     unsigned planemask,
34     int transparency_color);
35 
36 static void SavageSubsequentScreenToScreenCopy(
37     ScrnInfoPtr pScrn,
38     int x1,
39     int y1,
40     int x2,
41     int y2,
42     int w,
43     int h);
44 
45 static void SavageSetupForSolidFill(
46     ScrnInfoPtr pScrn,
47     int color,
48     int rop,
49     unsigned int planemask);
50 
51 static void SavageSubsequentSolidFillRect(
52     ScrnInfoPtr pScrn,
53     int x,
54     int y,
55     int w,
56     int h);
57 
58 static void SavageSubsequentSolidBresenhamLine(
59     ScrnInfoPtr pScrn,
60     int x1,
61     int y1,
62     int e1,
63     int e2,
64     int err,
65     int length,
66     int octant);
67 
68 static void SavageSetupForCPUToScreenColorExpandFill(
69     ScrnInfoPtr pScrn,
70     int fg,
71     int bg,
72     int rop,
73     unsigned int planemask);
74 
75 static void SavageSubsequentScanlineCPUToScreenColorExpandFill(
76     ScrnInfoPtr pScrn,
77     int x,
78     int y,
79     int w,
80     int h,
81     int skipleft);
82 
83 static void SavageSubsequentColorExpandScanline(
84     ScrnInfoPtr pScrn,
85     int buffer_no);
86 
87 static void SavageSetupForMono8x8PatternFill(
88     ScrnInfoPtr pScrn,
89     int patternx,
90     int patterny,
91     int fg,
92     int bg,
93     int rop,
94     unsigned int planemask);
95 
96 static void SavageSubsequentMono8x8PatternFillRect(
97     ScrnInfoPtr pScrn,
98     int pattern0,
99     int pattern1,
100     int x,
101     int y,
102     int w,
103     int h);
104 
105 static void SavageSetClippingRectangle(
106     ScrnInfoPtr pScrn,
107     int x1,
108     int y1,
109     int x2,
110     int y2);
111 
112 static void SavageDisableClipping( ScrnInfoPtr );
113 
114 /* from savage_image.c: */
115 
116 void SavageSetupForImageWrite(
117     ScrnInfoPtr pScrn,
118     int rop,
119     unsigned int planemask,
120     int transparency_color,
121     int bpp,
122     int depth);
123 
124 void SavageSubsequentImageWriteRect(
125     ScrnInfoPtr pScrn,
126     int x,
127     int y,
128     int w,
129     int h,
130     int skipleft);
131 
132 void SavageWriteBitmapCPUToScreenColorExpand (
133     ScrnInfoPtr pScrn,
134     int x, int y, int w, int h,
135     unsigned char * src,
136     int srcwidth,
137     int skipleft,
138     int fg, int bg,
139     int rop,
140     unsigned int planemask
141 );
142 
143 static
SavageRestoreAccelState(ScrnInfoPtr pScrn)144 void SavageRestoreAccelState(ScrnInfoPtr pScrn)
145 {
146     SavagePtr psav = SAVPTR(pScrn);
147 
148     psav->WaitIdleEmpty(psav);
149 
150     return;
151 }
152 #endif
153 
154 Bool
SavageXAAInit(ScreenPtr pScreen)155 SavageXAAInit(ScreenPtr pScreen)
156 {
157 #ifdef HAVE_XAA_H
158     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
159     SavagePtr psav = SAVPTR(pScrn);
160     XAAInfoRecPtr xaaptr;
161     BoxRec AvailFBArea;
162     int tmp;
163 
164     /* Set-up our GE command primitive */
165 
166     if (pScrn->depth == 8) {
167 	psav->PlaneMask = 0xFF;
168     }
169     else if (pScrn->depth == 15) {
170 	psav->PlaneMask = 0x7FFF;
171     }
172     else if (pScrn->depth == 16) {
173 	psav->PlaneMask = 0xFFFF;
174     }
175     else if (pScrn->depth == 24) {
176 	psav->PlaneMask = 0xFFFFFF;
177     }
178 
179     /* General acceleration flags */
180 
181     if (!(xaaptr = psav->AccelInfoRec = XAACreateInfoRec())) {
182 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
183 		"Failed to allocate XAAInfoRec.\n");
184 	return FALSE;
185     }
186 
187     xaaptr->Flags = 0
188     	| PIXMAP_CACHE
189 	| OFFSCREEN_PIXMAPS
190 	| LINEAR_FRAMEBUFFER
191 	;
192 
193 
194     if(xf86IsEntityShared(pScrn->entityList[0]))
195     {
196         DevUnion* pPriv;
197         SavageEntPtr pEnt;
198         pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
199                 gSavageEntityIndex);
200         pEnt = pPriv->ptr;
201 
202         /*if there are more than one devices sharing this entity, we
203           have to assign this call back, otherwise the XAA will be
204           disabled */
205         if(pEnt->HasSecondary)
206            xaaptr->RestoreAccelState           = SavageRestoreAccelState;
207     }
208 
209     /* Clipping */
210 
211     xaaptr->SetClippingRectangle = SavageSetClippingRectangle;
212     xaaptr->DisableClipping = SavageDisableClipping;
213     xaaptr->ClippingFlags = 0
214 #if 0
215 	| HARDWARE_CLIP_SOLID_FILL
216 	| HARDWARE_CLIP_SOLID_LINE
217 	| HARDWARE_CLIP_DASHED_LINE
218 #endif
219 	| HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY
220 	| HARDWARE_CLIP_MONO_8x8_FILL
221 	| HARDWARE_CLIP_COLOR_8x8_FILL
222 	;
223 
224     xaaptr->Sync = SavageAccelSync;
225 
226     /* ScreenToScreen copies */
227 
228 #if 1
229 
230     xaaptr->SetupForScreenToScreenCopy = SavageSetupForScreenToScreenCopy;
231     xaaptr->SubsequentScreenToScreenCopy = SavageSubsequentScreenToScreenCopy;
232     xaaptr->ScreenToScreenCopyFlags = 0
233 	| NO_TRANSPARENCY
234 	| NO_PLANEMASK
235 	| ROP_NEEDS_SOURCE;
236 
237 #endif
238 
239 
240     /* Solid filled rectangles */
241 
242 #if 1
243     xaaptr->SetupForSolidFill = SavageSetupForSolidFill;
244     xaaptr->SubsequentSolidFillRect = SavageSubsequentSolidFillRect;
245     xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
246 #endif
247 
248     /* Mono 8x8 pattern fills */
249 
250 #if 1
251     xaaptr->SetupForMono8x8PatternFill = SavageSetupForMono8x8PatternFill;
252     xaaptr->SubsequentMono8x8PatternFillRect
253     	= SavageSubsequentMono8x8PatternFillRect;
254     xaaptr->Mono8x8PatternFillFlags = 0
255 	| HARDWARE_PATTERN_PROGRAMMED_BITS
256 	| HARDWARE_PATTERN_SCREEN_ORIGIN
257 	| BIT_ORDER_IN_BYTE_MSBFIRST
258 	| ROP_NEEDS_SOURCE
259 	;
260     if( psav->Chipset == S3_SAVAGE4 )
261 	xaaptr->Mono8x8PatternFillFlags |= NO_TRANSPARENCY;
262 #endif
263 
264     /* Solid lines */
265 
266 #if 1
267     xaaptr->SolidLineFlags = NO_PLANEMASK;
268     xaaptr->SetupForSolidLine = SavageSetupForSolidFill;
269     xaaptr->SubsequentSolidBresenhamLine = SavageSubsequentSolidBresenhamLine;
270 #if 0
271     xaaptr->SubsequentSolidFillTrap = SavageSubsequentSolidFillTrap;
272 #endif
273 
274     xaaptr->SolidBresenhamLineErrorTermBits = 13;
275 #endif
276 
277     /* ImageWrite */
278 
279     xaaptr->ImageWriteFlags = 0
280 	| NO_PLANEMASK
281 	| CPU_TRANSFER_PAD_DWORD
282 	| SCANLINE_PAD_DWORD
283 	| BIT_ORDER_IN_BYTE_MSBFIRST
284 	| LEFT_EDGE_CLIPPING
285 	;
286     xaaptr->SetupForImageWrite = SavageSetupForImageWrite;
287     xaaptr->SubsequentImageWriteRect = SavageSubsequentImageWriteRect;
288     xaaptr->NumScanlineImageWriteBuffers = 1;
289     xaaptr->ImageWriteBase = psav->BciMem;
290     xaaptr->ImageWriteRange = 120 * 1024;
291 
292 
293     /* CPU to Screen color expansion */
294 
295     xaaptr->ScanlineCPUToScreenColorExpandFillFlags = 0
296 	| NO_PLANEMASK
297 	| CPU_TRANSFER_PAD_DWORD
298 	| SCANLINE_PAD_DWORD
299 	| BIT_ORDER_IN_BYTE_MSBFIRST
300 	| LEFT_EDGE_CLIPPING
301 	| ROP_NEEDS_SOURCE
302 	;
303 
304     xaaptr->SetupForScanlineCPUToScreenColorExpandFill =
305             SavageSetupForCPUToScreenColorExpandFill;
306     xaaptr->SubsequentScanlineCPUToScreenColorExpandFill =
307             SavageSubsequentScanlineCPUToScreenColorExpandFill;
308     xaaptr->SubsequentColorExpandScanline =
309 	    SavageSubsequentColorExpandScanline;
310     xaaptr->ColorExpandBase = psav->BciMem;
311     xaaptr->ScanlineColorExpandBuffers = &xaaptr->ColorExpandBase;
312     xaaptr->NumScanlineColorExpandBuffers = 1;
313 
314     /* Set up screen parameters. */
315 
316     psav->Bpp = pScrn->bitsPerPixel / 8;
317     psav->Bpl = pScrn->displayWidth * psav->Bpp;
318     psav->ScissB = (psav->CursorKByte << 10) / psav->Bpl;
319     if (psav->ScissB > 2047)
320         psav->ScissB = 2047;
321 
322     /*
323      * Finally, we set up the video memory space available to the pixmap
324      * cache. In this case, all memory from the end of the virtual screen
325      * to the end of the command overflow buffer can be used. If you haven't
326      * enabled the PIXMAP_CACHE flag, then these lines can be omitted.
327      */
328 
329     AvailFBArea.x1 = 0;
330     AvailFBArea.y1 = 0;
331     AvailFBArea.x2 = psav->cxMemory;
332     AvailFBArea.y2 = psav->cyMemory;
333     xf86InitFBManager(pScreen, &AvailFBArea);
334     /*
335      * because the alignment requirement,the on-screen need more memory
336      * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract
337      * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so
338      * here,we should reserver some memory for on-screen
339      */
340     tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY)
341                + psav->cxMemory -1) / (psav->cxMemory);
342     if (tmp)
343         xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL);
344 
345     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
346                    "Using %d lines for offscreen memory.\n",
347                    psav->cyMemory - pScrn->virtualY );
348 
349 
350     return XAAInit(pScreen, xaaptr);
351 #else
352     return FALSE;
353 #endif
354 }
355 
356 /* The sync function for the GE */
357 void
SavageAccelSync(ScrnInfoPtr pScrn)358 SavageAccelSync(ScrnInfoPtr pScrn)
359 {
360     SavagePtr psav = SAVPTR(pScrn);
361     psav->WaitIdleEmpty(psav);
362 }
363 
364 #ifdef HAVE_XAA_H
365 /*
366  * The XAA ROP helper routines all assume that a solid color is a
367  * "pattern".  The Savage chips, however, apply a non-stippled solid
368  * color as "source".  Thus, we use a slightly customized version.
369  */
370 
371 static int
SavageHelpPatternROP(ScrnInfoPtr pScrn,int * fg,int * bg,unsigned int pm,int * rop)372 SavageHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, unsigned int pm, int *rop)
373 {
374     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
375     int ret = 0;
376 
377     pm &= infoRec->FullPlanemask;
378 
379     if(pm == infoRec->FullPlanemask) {
380 	if(!NO_SRC_ROP(*rop))
381 	   ret |= ROP_PAT;
382 	*rop = XAAGetCopyROP(*rop);
383     } else {
384 	switch(*rop) {
385 	case GXnoop:
386 	    break;
387 	case GXset:
388 	case GXclear:
389 	case GXinvert:
390 	    ret |= ROP_PAT;
391 	    *fg = pm;
392 	    if(*bg != -1)
393 		*bg = pm;
394 	    break;
395 	default:
396 	    ret |= ROP_PAT | ROP_SRC;
397 	    break;
398 	}
399 	*rop = XAAGetCopyROP_PM(*rop);
400     }
401 
402     return ret;
403 }
404 
405 
406 static int
SavageHelpSolidROP(ScrnInfoPtr pScrn,int * fg,unsigned int pm,int * rop)407 SavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg, unsigned int pm, int *rop)
408 {
409     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
410     int ret = 0;
411 
412     pm &= infoRec->FullPlanemask;
413 
414     if(pm == infoRec->FullPlanemask) {
415 	if(!NO_SRC_ROP(*rop))
416 	   ret |= ROP_PAT;
417 	*rop = XAAGetCopyROP(*rop);
418     } else {
419 	switch(*rop) {
420 	case GXnoop:
421 	    break;
422 	case GXset:
423 	case GXclear:
424 	case GXinvert:
425 	    ret |= ROP_PAT;
426 	    *fg = pm;
427 	    break;
428 	default:
429 	    ret |= ROP_PAT | ROP_SRC;
430 	    break;
431 	}
432 	*rop = XAAGetCopyROP_PM(*rop);
433     }
434 
435     return ret;
436 }
437 
438 
439 
440 /* These are the ScreenToScreen bitblt functions. We support all ROPs, all
441  * directions, and a planemask by adjusting the ROP and using the mono pattern
442  * registers.
443  *
444  * (That's a lie; we don't really support planemask.)
445  */
446 
447 static void
SavageSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,int xdir,int ydir,int rop,unsigned planemask,int transparency_color)448 SavageSetupForScreenToScreenCopy(
449     ScrnInfoPtr pScrn,
450     int xdir,
451     int ydir,
452     int rop,
453     unsigned planemask,
454     int transparency_color)
455 {
456     SavagePtr psav = SAVPTR(pScrn);
457     int cmd;
458 
459     cmd = BCI_CMD_RECT | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SBD_COLOR_NEW;
460 
461     BCI_CMD_SET_ROP( cmd, XAAGetCopyROP(rop) );
462     if (transparency_color != -1)
463         cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_SRC_TRANSPARENT;
464 
465     if (xdir == 1 ) cmd |= BCI_CMD_RECT_XP;
466     if (ydir == 1 ) cmd |= BCI_CMD_RECT_YP;
467 
468     psav->SavedBciCmd = cmd;
469     psav->SavedBgColor = transparency_color;
470 }
471 
472 static void
SavageSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,int x1,int y1,int x2,int y2,int w,int h)473 SavageSubsequentScreenToScreenCopy(
474     ScrnInfoPtr pScrn,
475     int x1,
476     int y1,
477     int x2,
478     int y2,
479     int w,
480     int h)
481 {
482     SavagePtr psav = SAVPTR(pScrn);
483 
484     BCI_GET_PTR;
485 
486     if (!w || !h) return;
487 
488     if (!(psav->SavedBciCmd & BCI_CMD_RECT_XP)) {
489         w --;
490         x1 += w;
491         x2 += w;
492         w ++;
493     }
494     if (!(psav->SavedBciCmd & BCI_CMD_RECT_YP)) {
495         h --;
496         y1 += h;
497         y2 += h;
498         h ++;
499     }
500 
501     psav->WaitQueue(psav,9);
502 
503 
504     BCI_SEND(psav->SavedBciCmd);
505 
506     BCI_SEND(psav->GlobalBD.bd2.LoPart);
507     BCI_SEND(psav->GlobalBD.bd2.HiPart);
508 
509     BCI_SEND(psav->GlobalBD.bd2.LoPart);
510     BCI_SEND(psav->GlobalBD.bd2.HiPart);
511 
512     if (psav->SavedBgColor != 0xffffffff)
513 	BCI_SEND(psav->SavedBgColor);
514     BCI_SEND(BCI_X_Y(x1, y1));
515     BCI_SEND(BCI_X_Y(x2, y2));
516     BCI_SEND(BCI_W_H(w, h));
517 }
518 
519 
520 /*
521  * SetupForSolidFill is also called to set up for lines.
522  */
523 
524 static void
SavageSetupForSolidFill(ScrnInfoPtr pScrn,int color,int rop,unsigned int planemask)525 SavageSetupForSolidFill(
526     ScrnInfoPtr pScrn,
527     int color,
528     int rop,
529     unsigned int planemask)
530 {
531     SavagePtr psav = SAVPTR(pScrn);
532     XAAInfoRecPtr xaaptr = GET_XAAINFORECPTR_FROM_SCRNINFOPTR( pScrn );
533     int cmd;
534     int mix;
535 
536     cmd = BCI_CMD_RECT
537         | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
538         | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_SOLID;
539 
540     /* Don't send a color if we don't have to. */
541 
542     if( rop == GXcopy )
543     {
544 	if( color == 0 )
545 	    rop = GXclear;
546 	else if( (unsigned int)color == xaaptr->FullPlanemask )
547 	    rop = GXset;
548     }
549 
550     mix = SavageHelpSolidROP( pScrn, &color, planemask, &rop );
551 
552     if( mix & ROP_PAT )
553 	cmd |= BCI_CMD_SEND_COLOR;
554 
555     BCI_CMD_SET_ROP( cmd, rop );
556 
557     psav->SavedBciCmd = cmd;
558     psav->SavedFgColor = color;
559 }
560 
561 
562 static void
SavageSubsequentSolidFillRect(ScrnInfoPtr pScrn,int x,int y,int w,int h)563 SavageSubsequentSolidFillRect(
564     ScrnInfoPtr pScrn,
565     int x,
566     int y,
567     int w,
568     int h)
569 {
570     SavagePtr psav = SAVPTR(pScrn);
571     BCI_GET_PTR;
572 
573     if( !w || !h )
574 	return;
575 
576     psav->WaitQueue(psav,7);
577 
578     BCI_SEND(psav->SavedBciCmd);
579 
580     BCI_SEND(psav->GlobalBD.bd2.LoPart);
581     BCI_SEND(psav->GlobalBD.bd2.HiPart);
582 
583     if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR )
584 	BCI_SEND(psav->SavedFgColor);
585     BCI_SEND(BCI_X_Y(x, y));
586     BCI_SEND(BCI_W_H(w, h));
587 }
588 
589 static void
SavageSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,int fg,int bg,int rop,unsigned int planemask)590 SavageSetupForCPUToScreenColorExpandFill(
591     ScrnInfoPtr pScrn,
592     int fg,
593     int bg,
594     int rop,
595     unsigned int planemask)
596 {
597     SavagePtr psav = SAVPTR(pScrn);
598     int cmd;
599     int mix;
600 
601     cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
602 	| BCI_CMD_CLIP_LR
603         | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_MONO;
604 
605     mix = SavageHelpPatternROP( pScrn, &fg, &bg, planemask, &rop );
606 
607     if( mix & ROP_PAT )
608         cmd |= BCI_CMD_SEND_COLOR;
609 
610     BCI_CMD_SET_ROP( cmd, rop );
611 
612     if (bg != -1)
613         cmd |= BCI_CMD_SEND_COLOR;
614     else
615 	cmd |= BCI_CMD_SRC_TRANSPARENT;
616 
617     psav->SavedBciCmd = cmd;
618     psav->SavedFgColor = fg;
619     psav->SavedBgColor = bg;
620 }
621 
622 
623 static void
SavageSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,int x,int y,int w,int h,int skipleft)624 SavageSubsequentScanlineCPUToScreenColorExpandFill(
625     ScrnInfoPtr pScrn,
626     int x,
627     int y,
628     int w,
629     int h,
630     int skipleft)
631 {
632     SavagePtr psav = SAVPTR(pScrn);
633     BCI_GET_PTR;
634 
635     /* XAA will be sending bitmap data next.  */
636     /* We should probably wait for empty/idle here. */
637 
638     psav->WaitQueue(psav,22);
639 
640     BCI_SEND(psav->SavedBciCmd);
641 
642     BCI_SEND(psav->GlobalBD.bd2.LoPart);
643     BCI_SEND(psav->GlobalBD.bd2.HiPart);
644 
645     BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1));
646     w = (w + 31) & ~31;
647     if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR )
648 	BCI_SEND(psav->SavedFgColor);
649     if( psav->SavedBgColor != 0xffffffff )
650 	BCI_SEND(psav->SavedBgColor);
651     BCI_SEND(BCI_X_Y(x, y));
652     BCI_SEND(BCI_W_H(w, 1));
653 
654     psav->Rect.x = x;
655     psav->Rect.y = y + 1;
656     psav->Rect.width = w;
657     psav->Rect.height = h - 1;
658 }
659 
660 static void
SavageSubsequentColorExpandScanline(ScrnInfoPtr pScrn,int buffer_no)661 SavageSubsequentColorExpandScanline(
662     ScrnInfoPtr pScrn,
663     int buffer_no)
664 {
665     /* This gets call after each scanline's image data has been sent. */
666     SavagePtr psav = SAVPTR(pScrn);
667     xRectangle xr = psav->Rect;
668     BCI_GET_PTR;
669 
670     if( xr.height )
671     {
672 	psav->WaitQueue(psav,20);
673 	BCI_SEND(BCI_X_Y( xr.x, xr.y));
674 	BCI_SEND(BCI_W_H( xr.width, 1 ));
675         psav->Rect.height--;
676 	psav->Rect.y++;
677     }
678 }
679 
680 
681 /*
682  * The meaning of the two pattern paremeters to Setup & Subsequent for
683  * Mono8x8Patterns varies depending on the flag bits.  We specify
684  * HW_PROGRAMMED_BITS, which means our hardware can handle 8x8 patterns
685  * without caching in the frame buffer.  Thus, Setup gets the pattern bits.
686  * There is no way with BCI to rotate an 8x8 pattern, so we do NOT specify
687  * HW_PROGRAMMED_ORIGIN.  XAA wil rotate it for us and pass the rotated
688  * pattern to both Setup and Subsequent.  If we DID specify PROGRAMMED_ORIGIN,
689  * then Setup would get the unrotated pattern, and Subsequent gets the
690  * origin values.
691  */
692 
693 static void
SavageSetupForMono8x8PatternFill(ScrnInfoPtr pScrn,int patternx,int patterny,int fg,int bg,int rop,unsigned int planemask)694 SavageSetupForMono8x8PatternFill(
695     ScrnInfoPtr pScrn,
696     int patternx,
697     int patterny,
698     int fg,
699     int bg,
700     int rop,
701     unsigned int planemask)
702 {
703     SavagePtr psav = SAVPTR(pScrn);
704     int cmd;
705     int mix;
706 
707     mix = XAAHelpPatternROP( pScrn, &fg, &bg, planemask, &rop );
708 
709     cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
710         | BCI_CMD_DEST_PBD_NEW;
711 
712     if( mix & ROP_PAT )
713 	cmd |= BCI_CMD_SEND_COLOR | BCI_CMD_PAT_MONO;
714 
715     if (bg == -1)
716 	cmd |= BCI_CMD_PAT_TRANSPARENT;
717 
718     BCI_CMD_SET_ROP(cmd, rop);
719 
720     psav->SavedBciCmd = cmd;
721     psav->SavedFgColor = fg;
722     psav->SavedBgColor = bg;
723 }
724 
725 
726 static void
SavageSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn,int pattern0,int pattern1,int x,int y,int w,int h)727 SavageSubsequentMono8x8PatternFillRect(
728     ScrnInfoPtr pScrn,
729     int pattern0,
730     int pattern1,
731     int x,
732     int y,
733     int w,
734     int h)
735 {
736     SavagePtr psav = SAVPTR(pScrn);
737     BCI_GET_PTR;
738 
739     /*
740      * I didn't think it was my job to do trivial rejection, but
741      * miFillGeneralPolygon definitely generates null spans, and XAA
742      * just passes them through.
743      */
744 
745     if( !w || !h )
746 	return;
747 
748     psav->WaitQueue(psav,9);
749     BCI_SEND(psav->SavedBciCmd);
750 
751     BCI_SEND(psav->GlobalBD.bd2.LoPart);
752     BCI_SEND(psav->GlobalBD.bd2.HiPart);
753 
754     if( psav->SavedBciCmd & BCI_CMD_SEND_COLOR )
755 	BCI_SEND(psav->SavedFgColor);
756     if( psav->SavedBgColor != 0xffffffff )
757 	BCI_SEND(psav->SavedBgColor);
758     BCI_SEND(BCI_X_Y(x, y));
759     BCI_SEND(BCI_W_H(w, h));
760     if( psav->SavedBciCmd & BCI_CMD_PAT_MONO )
761     {
762 	BCI_SEND(pattern0);
763 	BCI_SEND(pattern1);
764     }
765 }
766 
767 
768 #if 0
769 static void
770 SavageSetupForColor8x8PatternFill(
771     ScrnInfoPtr pScrn,
772     int patternx,
773     int patterny,
774     int rop,
775     unsigned planemask,
776     int trans_col)
777 {
778     SavagePtr psav = SAVPTR(pScrn);
779 
780     int cmd;
781     unsigned int bd;
782     int pat_offset;
783 
784     /* ViRGEs and Savages do not support transparent color patterns. */
785     /* We set the NO_TRANSPARENCY bit, so we should never receive one. */
786 
787     pat_offset = (int) (patternx * psav->Bpp + patterny * psav->Bpl);
788 
789     cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
790         | BCI_CMD_DEST_GBD | BCI_CMD_PAT_PBD_COLOR_NEW;
791 
792     (void) XAAHelpSolidROP( pScrn, &trans_col, planemask, &rop );
793 
794     BCI_CMD_SET_ROP(cmd, rop);
795     bd = BCI_BD_BW_DISABLE;
796     BCI_BD_SET_BPP(bd, pScrn->bitsPerPixel);
797     BCI_BD_SET_STRIDE(bd, 8);
798 
799     psav->SavedBciCmd = cmd;
800     psav->SavedSbdOffset = pat_offset;
801     psav->SavedSbd = bd;
802     psav->SavedBgColor = trans_col;
803 }
804 
805 
806 static void
807 SavageSubsequentColor8x8PatternFillRect(
808     ScrnInfoPtr pScrn,
809     int patternx,
810     int patterny,
811     int x,
812     int y,
813     int w,
814     int h)
815 {
816     SavagePtr psav = SAVPTR(pScrn);
817     BCI_GET_PTR;
818 
819     if( !w || !h )
820 	return;
821 
822     psav->WaitQueue(psav,6);
823     BCI_SEND(psav->SavedBciCmd);
824     BCI_SEND(psav->SavedSbdOffset);
825     BCI_SEND(psav->SavedSbd);
826     BCI_SEND(BCI_X_Y(patternx,patterny));
827     BCI_SEND(BCI_X_Y(x, y));
828     BCI_SEND(BCI_W_H(w, h));
829 }
830 #endif
831 
832 static void
SavageSubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,int x1,int y1,int e1,int e2,int err,int length,int octant)833 SavageSubsequentSolidBresenhamLine(
834     ScrnInfoPtr pScrn,
835     int x1,
836     int y1,
837     int e1,
838     int e2,
839     int err,
840     int length,
841     int octant)
842 {
843     SavagePtr psav = SAVPTR(pScrn);
844     BCI_GET_PTR;
845     int cmd;
846 
847     cmd = (psav->SavedBciCmd & 0x00ffffff);
848     cmd |= BCI_CMD_LINE_LAST_PIXEL;
849 
850 #ifdef DEBUG_EXTRA
851     ErrorF("BresenhamLine, (%4d,%4d), len %4d, oct %d, err %4d,%4d,%4d clr %08x\n",
852         x1, y1, length, octant, e1, e2, err, psav->SavedFgColor );
853 #endif
854 
855     psav->WaitQueue(psav, 7 );
856     BCI_SEND(cmd);
857 
858     BCI_SEND(psav->GlobalBD.bd2.LoPart);
859     BCI_SEND(psav->GlobalBD.bd2.HiPart);
860 
861     if( cmd & BCI_CMD_SEND_COLOR )
862 	BCI_SEND( psav->SavedFgColor );
863     BCI_SEND(BCI_LINE_X_Y(x1, y1));
864     BCI_SEND(BCI_LINE_STEPS(e2-e1, e2));
865     BCI_SEND(BCI_LINE_MISC(length,
866     			   (octant & YMAJOR),
867 			   !(octant & XDECREASING),
868 			   !(octant & YDECREASING),
869 			   e2+err));
870 }
871 
872 static void
SavageSetClippingRectangle(ScrnInfoPtr pScrn,int x1,int y1,int x2,int y2)873 SavageSetClippingRectangle(
874     ScrnInfoPtr pScrn,
875     int x1,
876     int y1,
877     int x2,
878     int y2)
879 {
880     SavagePtr psav = SAVPTR(pScrn);
881     BCI_GET_PTR;
882     int cmd;
883 
884 #ifdef DEBUG_EXTRA
885     ErrorF("ClipRect, (%4d,%4d)-(%4d,%4d) \n", x1, y1, x2, y2 );
886 #endif
887 
888     cmd = BCI_CMD_NOP | BCI_CMD_CLIP_NEW;
889     psav->WaitQueue(psav,3);
890     BCI_SEND(cmd);
891     BCI_SEND(BCI_CLIP_TL(y1, x1));
892     BCI_SEND(BCI_CLIP_BR(y2, x2));
893     psav->SavedBciCmd |= BCI_CMD_CLIP_CURRENT;
894 }
895 
896 
SavageDisableClipping(ScrnInfoPtr pScrn)897 static void SavageDisableClipping( ScrnInfoPtr pScrn )
898 {
899     SavagePtr psav = SAVPTR(pScrn);
900 #ifdef DEBUG_EXTRA
901     ErrorF("Kill ClipRect\n");
902 #endif
903     psav->SavedBciCmd &= ~BCI_CMD_CLIP_CURRENT;
904 }
905 
906 void
SavageWriteBitmapCPUToScreenColorExpand(ScrnInfoPtr pScrn,int x,int y,int w,int h,unsigned char * src,int srcwidth,int skipleft,int fg,int bg,int rop,unsigned int planemask)907 SavageWriteBitmapCPUToScreenColorExpand (
908     ScrnInfoPtr pScrn,
909     int x, int y, int w, int h,
910     unsigned char * src,
911     int srcwidth,
912     int skipleft,
913     int fg, int bg,
914     int rop,
915     unsigned int planemask
916 )
917 {
918     SavagePtr psav = SAVPTR(pScrn);
919     BCI_GET_PTR;
920     int i, j, count, reset;
921     unsigned int cmd;
922     CARD32 * srcp;
923 
924 /* We aren't using planemask at all here... */
925 
926     if( !srcwidth )
927 	return;
928 
929     cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
930         | BCI_CMD_SEND_COLOR | BCI_CMD_CLIP_LR
931         | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_MONO;
932     cmd |= XAAGetCopyROP(rop) << 16;
933 
934     if( bg == -1 )
935         cmd |= BCI_CMD_SRC_TRANSPARENT;
936 
937     BCI_SEND(cmd);
938 
939     BCI_SEND(psav->GlobalBD.bd2.LoPart);
940     BCI_SEND(psav->GlobalBD.bd2.HiPart);
941 
942     BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1));
943     BCI_SEND(fg);
944     if( bg != -1 )
945 	BCI_SEND(bg);
946 
947     /* Bitmaps come in in units of DWORDS, LSBFirst.  This is exactly */
948     /* reversed of what we expect.  */
949 
950     count = (w + 31) / 32;
951 /*    src += ((srcx & ~31) / 8); */
952 
953     /* The BCI region is 128k bytes.  A screen-sized mono bitmap can */
954     /* exceed that. */
955 
956     reset = 65536 / count;
957 
958     for (j = 0; j < h; j ++) {
959         BCI_SEND(BCI_X_Y(x, y+j));
960         BCI_SEND(BCI_W_H(w, 1));
961         srcp = (CARD32 *) src;
962         for (i = count; i > 0; srcp ++, i --) {
963             /* We have to invert the bits in each byte. */
964             CARD32 u = *srcp;
965             u = ((u & 0x0f0f0f0f) << 4) | ((u & 0xf0f0f0f0) >> 4);
966             u = ((u & 0x33333333) << 2) | ((u & 0xcccccccc) >> 2);
967             u = ((u & 0x55555555) << 1) | ((u & 0xaaaaaaaa) >> 1);
968             BCI_SEND(u);
969         }
970         src += srcwidth;
971         if( !--reset ) {
972 	    BCI_RESET;
973             reset = 65536 / count;
974         }
975     }
976 }
977 
978 void
SavageSetupForImageWrite(ScrnInfoPtr pScrn,int rop,unsigned planemask,int transparency_color,int bpp,int depth)979 SavageSetupForImageWrite(
980     ScrnInfoPtr pScrn,
981     int rop,
982     unsigned planemask,
983     int transparency_color,
984     int bpp,
985     int depth)
986 {
987     SavagePtr psav = SAVPTR(pScrn);
988     int cmd;
989 
990     cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP
991         | BCI_CMD_CLIP_LR
992         | BCI_CMD_DEST_PBD_NEW | BCI_CMD_SRC_COLOR;
993 
994     cmd |= XAAGetCopyROP(rop) << 16;
995 
996     if( transparency_color != -1 )
997         cmd |= BCI_CMD_SRC_TRANSPARENT;
998 
999     psav->SavedBciCmd = cmd;
1000     psav->SavedBgColor = transparency_color;
1001 }
1002 
1003 
SavageSubsequentImageWriteRect(ScrnInfoPtr pScrn,int x,int y,int w,int h,int skipleft)1004 void SavageSubsequentImageWriteRect
1005 (
1006     ScrnInfoPtr pScrn,
1007     int x,
1008     int y,
1009     int w,
1010     int h,
1011     int skipleft)
1012 {
1013     SavagePtr psav = SAVPTR(pScrn);
1014     BCI_GET_PTR;
1015 
1016     psav->WaitQueue( psav, 8 );
1017     BCI_SEND(psav->SavedBciCmd);
1018 
1019     BCI_SEND(psav->GlobalBD.bd2.LoPart);
1020     BCI_SEND(psav->GlobalBD.bd2.HiPart);
1021 
1022     BCI_SEND(BCI_CLIP_LR(x+skipleft, x+w-1));
1023     if( psav->SavedBgColor != 0xffffffff )
1024         BCI_SEND(psav->SavedBgColor);
1025     BCI_SEND(BCI_X_Y(x, y));
1026     BCI_SEND(BCI_W_H(w, h));
1027 }
1028 
1029 #endif
1030