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