1 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c,v 1.20 2003/09/02 18:28:35 twini Exp $ */
3 * 2D Acceleration for SiS 315 and Xabre series
4 * (315/550/650/740/M650/651/652/M652/330/660/M660/760/M760)
6 * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of the copyright holder not be used in
13 * advertising or publicity pertaining to distribution of the software without
14 * specific, written prior permission. The copyright holder makes no representations
15 * about the suitability of this software for any purpose. It is provided
16 * "as is" without express or implied warranty.
18 * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20 * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
24 * PERFORMANCE OF THIS SOFTWARE.
26 * Based on sis300_accel.c
27 * 2003/08/18: Rewritten for using VRAM command queue (TW)
29 * Author: Thomas Winischhofer <thomas@winischhofer.net>
34 #include "xf86_OSproc.h"
35 #include "xf86_ansic.h"
36 #include "xf86PciInfo.h"
43 #include "sis310_accel.h"
50 #define HEADOFFSET (pSiS->dhmOffset)
53 #undef TRAP /* Use/Don't use Trapezoid Fills
54 * DOES NOT WORK. XAA sometimes provides illegal
55 * trapezoid data (left and right edges cross each
56 * other) which causes drawing errors. Since
57 * checking the trapezoid for such a case is very
58 * time-intensive, it is faster to let it be done
59 * by the generic polygon functions.
60 * Does not work on XABRE at all, hangs the engine.
61 * Even with correct trapezoids, this is slower than
62 * doing it by the CPU.
65 #undef CTSCE /* Use/Don't use CPUToScreenColorExpand. Disabled
66 * because it is slower than doing it by the CPU.
67 * Indirect mode does not work in VRAM queue mode.
68 * Does not work on Xabre (even in MMIO mode).
70 #undef CTSCE_DIRECT /* Use direct method - This works (on both 315 and Xabre at
71 * least in VRAM queue mode) but we don't use this either,
72 * because it's slower than doing it by the CPU. (Using it
73 * would require defining CTSCE)
76 #undef STSCE /* Use/Don't use ScreenToScreenColorExpand - does not work,
80 #define INCL_RENDER /* Use/Don't use RENDER extension acceleration */
85 #include "dixstruct.h"
89 /* Accelerator functions */
90 static void SiSInitializeAccelerator(ScrnInfoPtr pScrn
);
91 static void SiSSync(ScrnInfoPtr pScrn
);
92 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn
,
93 int xdir
, int ydir
, int rop
,
94 unsigned int planemask
, int trans_color
);
95 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn
,
96 int x1
, int y1
, int x2
, int y2
,
97 int width
, int height
);
98 static void SiSSetupForSolidFill(ScrnInfoPtr pScrn
, int color
,
99 int rop
, unsigned int planemask
);
100 static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn
,
101 int x
, int y
, int w
, int h
);
103 static void SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn
, int y
, int h
,
104 int left
, int dxL
, int dyL
, int eL
,
105 int right
, int dxR
, int dyR
, int eR
);
107 static void SiSSetupForSolidLine(ScrnInfoPtr pScrn
, int color
,
108 int rop
, unsigned int planemask
);
109 static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn
, int x1
,
110 int y1
, int x2
, int y2
, int flags
);
111 static void SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn
,
112 int x
, int y
, int len
, int dir
);
113 static void SiSSetupForDashedLine(ScrnInfoPtr pScrn
,
114 int fg
, int bg
, int rop
, unsigned int planemask
,
115 int length
, unsigned char *pattern
);
116 static void SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn
,
117 int x1
, int y1
, int x2
, int y2
,
118 int flags
, int phase
);
119 static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn
,
120 int patx
, int paty
, int fg
, int bg
,
121 int rop
, unsigned int planemask
);
122 static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn
,
124 int x
, int y
, int w
, int h
);
126 static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn
,
129 int left
, int dxL
, int dyL
, int eL
,
130 int right
, int dxR
, int dyR
, int eR
);
133 static void SiSSetupForColor8x8PatternFill(ScrnInfoPtr pScrn
,
134 int patternx
, int patterny
,
135 int rop
, unsigned int planemask
, int trans_col
);
136 static void SiSSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn
,
137 int patternx
, int patterny
, int x
, int y
,
141 static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
143 int rop
, unsigned int planemask
);
144 static void SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
145 int x
, int y
, int w
, int h
,
146 int srcx
, int srcy
, int skipleft
);
150 static void SiSSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
151 int fg
, int bg
, int rop
,
152 unsigned int planemask
);
153 static void SiSSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
154 int x
, int y
, int w
, int h
,
157 static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
158 int fg
, int bg
, int rop
,
159 unsigned int planemask
);
160 static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
161 int x
, int y
, int w
, int h
,
163 static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn
, int bufno
);
168 extern Bool
SiSSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn
,
169 int op
, CARD16 red
, CARD16 green
,
170 CARD16 blue
, CARD16 alpha
,
171 int alphaType
, CARD8
*alphaPtr
,
172 int alphaPitch
, int width
,
173 int height
, int flags
);
175 extern Bool
SiSSetupForCPUToScreenTexture( ScrnInfoPtr pScrn
,
176 int op
, int texType
, CARD8
*texPtr
,
177 int texPitch
, int width
,
178 int height
, int flags
);
180 extern void SiSSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn
,
183 int width
, int height
);
185 extern CARD32 SiSAlphaTextureFormats
[2];
186 extern CARD32 SiSTextureFormats
[2];
187 CARD32 SiSAlphaTextureFormats
[2] = { PICT_a8
, 0 };
188 CARD32 SiSTextureFormats
[2] = { PICT_a8r8g8b8
, 0 };
193 static void SiSRestoreAccelState(ScrnInfoPtr pScrn
);
197 SiSInitializeAccelerator(ScrnInfoPtr pScrn
)
199 SISPtr pSiS
= SISPTR(pScrn
);
201 pSiS
->DoColorExpand
= FALSE
;
202 pSiS
->alphaBlitBusy
= FALSE
;
204 if(pSiS
->ChipFlags
& SiSCF_Integrated
) {
207 CmdQueLen
= ((128 * 1024) / 4) - 64;
213 SiS315AccelInit(ScreenPtr pScreen
)
215 XAAInfoRecPtr infoPtr
;
216 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
217 SISPtr pSiS
= SISPTR(pScrn
);
221 unsigned char *AvailBufBase
;
229 pSiS
->AccelInfoPtr
= infoPtr
= XAACreateInfoRec();
230 if(!infoPtr
) return FALSE
;
232 SiSInitializeAccelerator(pScrn
);
234 infoPtr
->Flags
= LINEAR_FRAMEBUFFER
|
239 infoPtr
->Sync
= SiSSync
;
241 if((pScrn
->bitsPerPixel
!= 8) && (pScrn
->bitsPerPixel
!= 16) &&
242 (pScrn
->bitsPerPixel
!= 32))
246 infoPtr
->SetupForScreenToScreenCopy
= SiSSetupForScreenToScreenCopy
;
247 infoPtr
->SubsequentScreenToScreenCopy
= SiSSubsequentScreenToScreenCopy
;
248 infoPtr
->ScreenToScreenCopyFlags
= NO_PLANEMASK
| TRANSPARENCY_GXCOPY_ONLY
;
251 infoPtr
->SetupForSolidFill
= SiSSetupForSolidFill
;
252 infoPtr
->SubsequentSolidFillRect
= SiSSubsequentSolidFillRect
;
254 if((pSiS
->Chipset
!= PCI_CHIP_SIS660
) &&
255 (pSiS
->Chipset
!= PCI_CHIP_SIS330
)) {
256 infoPtr
->SubsequentSolidFillTrap
= SiSSubsequentSolidFillTrap
;
259 infoPtr
->SolidFillFlags
= NO_PLANEMASK
;
262 infoPtr
->SetupForSolidLine
= SiSSetupForSolidLine
;
263 infoPtr
->SubsequentSolidTwoPointLine
= SiSSubsequentSolidTwoPointLine
;
264 infoPtr
->SubsequentSolidHorVertLine
= SiSSubsequentSolidHorzVertLine
;
265 infoPtr
->SolidLineFlags
= NO_PLANEMASK
;
268 infoPtr
->SetupForDashedLine
= SiSSetupForDashedLine
;
269 infoPtr
->SubsequentDashedTwoPointLine
= SiSSubsequentDashedTwoPointLine
;
270 infoPtr
->DashPatternMaxLength
= 64;
271 infoPtr
->DashedLineFlags
= NO_PLANEMASK
|
272 LINE_PATTERN_MSBFIRST_LSBJUSTIFIED
;
274 /* 8x8 mono pattern fill */
275 infoPtr
->SetupForMono8x8PatternFill
= SiSSetupForMonoPatternFill
;
276 infoPtr
->SubsequentMono8x8PatternFillRect
= SiSSubsequentMonoPatternFill
;
278 if((pSiS
->Chipset
!= PCI_CHIP_SIS660
) &&
279 (pSiS
->Chipset
!= PCI_CHIP_SIS330
)) {
280 infoPtr
->SubsequentMono8x8PatternFillTrap
= SiSSubsequentMonoPatternFillTrap
;
283 infoPtr
->Mono8x8PatternFillFlags
= NO_PLANEMASK
|
284 HARDWARE_PATTERN_SCREEN_ORIGIN
|
285 HARDWARE_PATTERN_PROGRAMMED_BITS
|
286 BIT_ORDER_IN_BYTE_MSBFIRST
;
289 /* 8x8 color pattern fill (MMIO support not implemented) */
290 infoPtr
->SetupForColor8x8PatternFill
= SiSSetupForColor8x8PatternFill
;
291 infoPtr
->SubsequentColor8x8PatternFillRect
= SiSSubsequentColor8x8PatternFillRect
;
292 infoPtr
->Color8x8PatternFillFlags
= NO_PLANEMASK
|
293 HARDWARE_PATTERN_SCREEN_ORIGIN
|
298 /* Screen To Screen Color Expand */
299 /* The hardware does not support this the way we need it, because
300 * the mono-bitmap is not provided with a pitch of (width), but
301 * with a pitch of scrnOffset (= width * bpp / 8).
303 infoPtr
->SetupForScreenToScreenColorExpandFill
=
304 SiSSetupForScreenToScreenColorExpand
;
305 infoPtr
->SubsequentScreenToScreenColorExpandFill
=
306 SiSSubsequentScreenToScreenColorExpand
;
307 infoPtr
->ScreenToScreenColorExpandFillFlags
= NO_PLANEMASK
|
308 BIT_ORDER_IN_BYTE_MSBFIRST
;
313 /* CPU color expansion - direct method
315 * We somewhat fake this function here in the following way:
316 * XAA copies its mono-bitmap data not into an aperture, but
317 * into our video RAM buffer. We then do a ScreenToScreen
319 * Unfortunately, XAA sends the data to the aperture AFTER
320 * the call to Subsequent(), therefore we do not execute the
321 * command in Subsequent, but in the following call to Sync().
322 * (Hence, the SYNC_AFTER_COLOR_EXPAND flag MUST BE SET)
324 * This is slower than doing it by the CPU.
327 pSiS
->ColorExpandBufferNumber
= 48;
328 pSiS
->PerColorExpandBufferSize
= ((pScrn
->virtualX
+ 31)/32) * 4;
329 infoPtr
->SetupForCPUToScreenColorExpandFill
= SiSSetupForCPUToScreenColorExpandFill
;
330 infoPtr
->SubsequentCPUToScreenColorExpandFill
= SiSSubsequentCPUToScreenColorExpandFill
;
331 infoPtr
->ColorExpandRange
= pSiS
->ColorExpandBufferNumber
* pSiS
->PerColorExpandBufferSize
;
332 infoPtr
->CPUToScreenColorExpandFillFlags
=
334 CPU_TRANSFER_PAD_DWORD
|
336 BIT_ORDER_IN_BYTE_MSBFIRST
|
338 SYNC_AFTER_COLOR_EXPAND
;
340 /* CPU color expansion - per-scanline / indirect method
342 * SLOW! SLOWER! SLOWEST!
344 * Does not work on XABRE, hangs the engine (both VRAM and MMIO).
345 * Does not work in VRAM queue mode.
348 if((pSiS
->Chipset
!= PCI_CHIP_SIS650
) &&
349 (pSiS
->Chipset
!= PCI_CHIP_SIS660
) &&
350 (pSiS
->Chipset
!= PCI_CHIP_SIS330
)) {
351 pSiS
->ColorExpandBufferNumber
= 16;
352 pSiS
->ColorExpandBufferCountMask
= 0x0F;
353 pSiS
->PerColorExpandBufferSize
= ((pScrn
->virtualX
+ 31)/32) * 4;
354 infoPtr
->NumScanlineColorExpandBuffers
= pSiS
->ColorExpandBufferNumber
;
355 infoPtr
->ScanlineColorExpandBuffers
= (unsigned char **)&pSiS
->ColorExpandBufferAddr
[0];
356 infoPtr
->SetupForScanlineCPUToScreenColorExpandFill
= SiSSetupForScanlineCPUToScreenColorExpandFill
;
357 infoPtr
->SubsequentScanlineCPUToScreenColorExpandFill
= SiSSubsequentScanlineCPUToScreenColorExpandFill
;
358 infoPtr
->SubsequentColorExpandScanline
= SiSSubsequentColorExpandScanline
;
359 infoPtr
->ScanlineCPUToScreenColorExpandFillFlags
=
361 CPU_TRANSFER_PAD_DWORD
|
363 BIT_ORDER_IN_BYTE_MSBFIRST
|
367 pSiS
->ColorExpandBufferNumber
= 0;
368 pSiS
->PerColorExpandBufferSize
= 0;
374 pSiS
->ColorExpandBufferNumber
= 0;
375 pSiS
->PerColorExpandBufferSize
= 0;
381 if(((pScrn
->bitsPerPixel
== 16) || (pScrn
->bitsPerPixel
== 32)) && pSiS
->doRender
) {
383 if((pSiS
->RenderAccelArray
= xnfcalloc(65536, 1))) {
384 for(i
= 0; i
< 256; i
++) {
385 for(j
= 0; j
< 256; j
++) {
386 pSiS
->RenderAccelArray
[(i
<< 8) + j
] = (i
* j
) / 255;
390 pSiS
->AccelLinearScratch
= NULL
;
392 infoPtr
->SetupForCPUToScreenAlphaTexture
= SiSSetupForCPUToScreenAlphaTexture
;
393 infoPtr
->SubsequentCPUToScreenAlphaTexture
= SiSSubsequentCPUToScreenTexture
;
394 infoPtr
->CPUToScreenAlphaTextureFormats
= SiSAlphaTextureFormats
;
395 infoPtr
->CPUToScreenAlphaTextureFlags
= XAA_RENDER_NO_TILE
|
396 XAA_RENDER_NO_SRC_ALPHA
;
398 infoPtr
->SetupForCPUToScreenTexture
= SiSSetupForCPUToScreenTexture
;
399 infoPtr
->SubsequentCPUToScreenTexture
= SiSSubsequentCPUToScreenTexture
;
400 infoPtr
->CPUToScreenTextureFormats
= SiSTextureFormats
;
401 infoPtr
->CPUToScreenTextureFlags
= XAA_RENDER_NO_TILE
;
402 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "RENDER acceleration enabled\n");
409 if(pSiS
->DualHeadMode
) {
410 infoPtr
->RestoreAccelState
= SiSRestoreAccelState
;
414 /* Init Frame Buffer Manager */
416 topFB
= pSiS
->maxxfbmem
;
418 reservedFbSize
= (pSiS
->ColorExpandBufferNumber
419 * pSiS
->PerColorExpandBufferSize
);
421 UsableFbSize
= topFB
- reservedFbSize
;
423 * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
424 * UsableFbSize ColorExpandBuffers | DRI-Heap HWCursor CommandQueue
427 AvailBufBase
= pSiS
->FbBase
+ UsableFbSize
;
429 if(pSiS
->ColorExpandBufferNumber
) {
431 infoPtr
->ColorExpandBase
= (unsigned char *)AvailBufBase
;
432 pSiS
->ColorExpandBase
= UsableFbSize
;
434 for(i
= 0; i
< pSiS
->ColorExpandBufferNumber
; i
++) {
435 pSiS
->ColorExpandBufferAddr
[i
] = AvailBufBase
+
436 i
* pSiS
->PerColorExpandBufferSize
;
437 pSiS
->ColorExpandBufferScreenOffset
[i
] = UsableFbSize
+
438 i
* pSiS
->PerColorExpandBufferSize
;
446 Avail
.x2
= pScrn
->displayWidth
;
447 Avail
.y2
= (UsableFbSize
/ (pScrn
->displayWidth
* pScrn
->bitsPerPixel
/8)) - 1;
449 if(Avail
.y2
< 0) Avail
.y2
= 32767;
450 if(Avail
.y2
< pScrn
->currentMode
->VDisplay
) {
451 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
452 "Not enough video RAM for accelerator. At least "
453 "%dKB needed, %dKB available\n",
454 ((((pScrn
->displayWidth
* pScrn
->bitsPerPixel
/8) /* +8 for make it sure */
455 * pScrn
->currentMode
->VDisplay
) + reservedFbSize
) / 1024) + 8,
456 pSiS
->maxxfbmem
/1024);
457 pSiS
->NoAccel
= TRUE
;
458 pSiS
->NoXvideo
= TRUE
;
459 XAADestroyInfoRec(pSiS
->AccelInfoPtr
);
460 pSiS
->AccelInfoPtr
= NULL
;
464 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
465 "Frame Buffer From (%d,%d) To (%d,%d)\n",
466 Avail
.x1
, Avail
.y1
, Avail
.x2
, Avail
.y2
);
468 xf86InitFBManager(pScreen
, &Avail
);
470 return(XAAInit(pScreen
, infoPtr
));
474 SiSSync(ScrnInfoPtr pScrn
)
476 SISPtr pSiS
= SISPTR(pScrn
);
478 PDEBUG(ErrorF("SiSSync()\n"));
482 if(pSiS
->DoColorExpand
) {
484 pSiS
->ColorExpandBusy
= TRUE
;
489 pSiS
->DoColorExpand
= FALSE
;
490 pSiS
->alphaBlitBusy
= FALSE
;
497 SiSRestoreAccelState(ScrnInfoPtr pScrn
)
499 SISPtr pSiS
= SISPTR(pScrn
);
501 pSiS
->ColorExpandBusy
= FALSE
;
502 pSiS
->alphaBlitBusy
= FALSE
;
507 static const int sisALUConv
[] =
509 0x00, /* dest = 0; 0, GXclear, 0 */
510 0x88, /* dest &= src; DSa, GXand, 0x1 */
511 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
512 0xCC, /* dest = src; S, GXcopy, 0x3 */
513 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
514 0xAA, /* dest = dest; D, GXnoop, 0x5 */
515 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
516 0xEE, /* dest |= src; DSo, GXor, 0x7 */
517 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
518 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
519 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
520 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
521 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
522 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
523 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
524 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
527 /* same ROP but with Pattern as Source */
528 static const int sisPatALUConv
[] =
530 0x00, /* dest = 0; 0, GXclear, 0 */
531 0xA0, /* dest &= src; DPa, GXand, 0x1 */
532 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
533 0xF0, /* dest = src; P, GXcopy, 0x3 */
534 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
535 0xAA, /* dest = dest; D, GXnoop, 0x5 */
536 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
537 0xFA, /* dest |= src; DPo, GXor, 0x7 */
538 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
539 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
540 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
541 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
542 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
543 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
544 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
545 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
548 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn
,
549 int xdir
, int ydir
, int rop
,
550 unsigned int planemask
, int trans_color
)
552 SISPtr pSiS
= SISPTR(pScrn
);
554 PDEBUG(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
555 xdir
, ydir
, rop
, planemask
, trans_color
));
558 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
559 SiSCheckQueue(16 * 2);
560 SiSSetupSRCPitchDSTRect(pSiS
->scrnOffset
, pSiS
->scrnOffset
, -1)
562 SiSSetupDSTColorDepth(pSiS
->DstColor
);
563 SiSSetupSRCPitch(pSiS
->scrnOffset
)
564 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
567 if(trans_color
!= -1) {
569 SiSSetupSRCTrans(trans_color
)
570 SiSSetupCMDFlag(TRANSPARENT_BITBLT
)
572 SiSSetupROP(sisALUConv
[rop
])
573 /* Set command - not needed, both 0 */
574 /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
578 SiSSetupCMDFlag(pSiS
->SiS310_AccelDepth
)
585 /* The chip is smart enough to know the direction */
588 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn
,
589 int src_x
, int src_y
, int dst_x
, int dst_y
,
590 int width
, int height
)
592 SISPtr pSiS
= SISPTR(pScrn
);
593 long srcbase
, dstbase
;
596 PDEBUG(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
597 src_x
, src_y
, dst_x
, dst_y
, width
, height
));
599 srcbase
= dstbase
= 0;
600 mymin
= min(src_y
, dst_y
);
601 mymax
= max(src_y
, dst_y
);
603 /* Libxaa.a has a bug: The tilecache cannot operate
604 * correctly if there are 512x512 slots, but no 256x256
605 * slots. This leads to catastrophic data fed to us.
606 * Filter this out here and warn the user.
614 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
615 "BitBlit fatal error: Illegal coordinates:\n");
616 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
617 "Source x %d y %d, dest x %d y %d, width %d height %d\n",
618 src_x
, src_y
, dst_x
, dst_y
, width
, height
);
619 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
620 "This is very probably caused by a known bug in libxaa.a.\n");
621 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
622 "Please update libxaa.a to avoid this error.\n");
626 /* Although the chip knows the direction to use
627 * if the source and destination areas overlap,
628 * that logic fails if we fiddle with the bitmap
629 * addresses. Therefore, we check if the source
630 * and destination blitting areas overlap and
631 * adapt the bitmap addresses synchronously
632 * if the coordinates exceed the valid range.
633 * The the areas do not overlap, we do our
636 if((mymax
- mymin
) < height
) {
637 if((src_y
>= 2048) || (dst_y
>= 2048)) {
638 srcbase
= pSiS
->scrnOffset
* mymin
;
639 dstbase
= pSiS
->scrnOffset
* mymin
;
645 srcbase
= pSiS
->scrnOffset
* src_y
;
648 if((dst_y
>= pScrn
->virtualY
) || (dst_y
>= 2048)) {
649 dstbase
= pSiS
->scrnOffset
* dst_y
;
654 srcbase
+= HEADOFFSET
;
655 dstbase
+= HEADOFFSET
;
659 SiSCheckQueue(16 * 3);
660 SiSSetupSRCDSTBase(srcbase
, dstbase
)
661 SiSSetupSRCDSTXY(src_x
, src_y
, dst_x
, dst_y
)
662 SiSSetRectDoCMD(width
,height
)
664 SiSSetupSRCBase(srcbase
);
665 SiSSetupDSTBase(dstbase
);
666 SiSSetupRect(width
, height
)
667 SiSSetupSRCXY(src_x
, src_y
)
668 SiSSetupDSTXY(dst_x
, dst_y
)
674 SiSSetupForSolidFill(ScrnInfoPtr pScrn
, int color
,
675 int rop
, unsigned int planemask
)
677 SISPtr pSiS
= SISPTR(pScrn
);
679 PDEBUG(ErrorF("Setup SolidFill(0x%x, 0x%x, 0x%x)\n",
680 color
, rop
, planemask
));
682 if(pSiS
->disablecolorkeycurrent
) {
683 if((CARD32
)color
== pSiS
->colorKey
) {
689 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
690 SiSCheckQueue(16 * 1);
691 SiSSetupPATFGDSTRect(color
, pSiS
->scrnOffset
, -1)
692 SiSSetupROP(sisPatALUConv
[rop
])
693 SiSSetupCMDFlag(PATFG
)
697 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
698 SiSSetupDSTColorDepth(pSiS
->DstColor
);
699 SiSSetupROP(sisPatALUConv
[rop
])
700 SiSSetupCMDFlag(PATFG
| pSiS
->SiS310_AccelDepth
)
705 SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn
,
706 int x
, int y
, int w
, int h
)
708 SISPtr pSiS
= SISPTR(pScrn
);
711 PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
716 dstbase
= pSiS
->scrnOffset
* y
;
720 dstbase
+= HEADOFFSET
;
723 pSiS
->CommandReg
&= ~(T_XISMAJORL
| T_XISMAJORR
|
724 T_L_X_INC
| T_L_Y_INC
|
725 T_R_X_INC
| T_R_Y_INC
|
728 /* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */
731 SiSCheckQueue(16 * 2)
732 SiSSetupDSTXYRect(x
,y
,w
,h
)
733 SiSSetupDSTBaseDoCMD(dstbase
)
735 SiSSetupDSTBase(dstbase
)
743 /* This would work better if XAA would provide us with valid trapezoids.
744 * In fact, with small trapezoids the left and the right edge often cross
745 * each other which causes drawing errors (filling over whole scanline).
746 * DOES NOT WORK ON XABRE, HANGS THE ENGINE.
750 SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn
, int y
, int h
,
751 int left
, int dxL
, int dyL
, int eL
,
752 int right
, int dxR
, int dyR
, int eR
)
754 SISPtr pSiS
= SISPTR(pScrn
);
759 dstbase
= pSiS
->scrnOffset
* y
;
763 dstbase
+= HEADOFFSET
;
766 #ifdef SISVRAMQ /* Not optimized yet */
767 SiSCheckQueue(16 * 10)
769 SiSSetupDSTBase(dstbase
)
773 SiSSetupPATFG(0xff0000) /* FOR TESTING */
776 /* Clear CommandReg because SetUp can be used for Rect and Trap */
777 pSiS
->CommandReg
&= ~(T_L_X_INC
| T_L_Y_INC
|
778 T_R_X_INC
| T_R_Y_INC
|
779 T_XISMAJORL
| T_XISMAJORR
|
782 xf86DrvMsg(0, X_INFO
, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n",
783 left
, right
, y
, h
, dxL
, dyL
, eL
, dxR
, dyR
, eR
);
785 /* Determine egde angles */
786 if(dxL
< 0) { dxL
= -dxL
; }
787 else { SiSSetupCMDFlag(T_L_X_INC
) }
788 if(dxR
< 0) { dxR
= -dxR
; }
789 else { SiSSetupCMDFlag(T_R_X_INC
) }
791 /* (Y direction always positive - do this anyway) */
792 if(dyL
< 0) { dyL
= -dyL
; }
793 else { SiSSetupCMDFlag(T_L_Y_INC
) }
794 if(dyR
< 0) { dyR
= -dyR
; }
795 else { SiSSetupCMDFlag(T_R_Y_INC
) }
797 /* Determine major axis */
798 if(dxL
>= dyL
) { SiSSetupCMDFlag(T_XISMAJORL
) }
799 if(dxR
>= dyR
) { SiSSetupCMDFlag(T_XISMAJORR
) }
801 SiSSetupCMDFlag(TRAPAZOID_FILL
);
804 SiSSetupYHLR(y
, h
, left
, right
)
805 SiSSetupdLdR(dxL
, dyL
, dxR
, dyR
)
807 SiSSetupDSTBaseDoCMD(dstbase
)
812 /* Set up y, h, left, right */
814 SiSSetupLR(left
, right
)
815 /* Set up initial error term */
824 SiSSetupForSolidLine(ScrnInfoPtr pScrn
, int color
, int rop
,
825 unsigned int planemask
)
827 SISPtr pSiS
= SISPTR(pScrn
);
829 PDEBUG(ErrorF("Setup SolidLine(0x%x, 0x%x, 0x%x)\n",
830 color
, rop
, planemask
));
833 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
834 SiSCheckQueue(16 * 3);
835 SiSSetupLineCountPeriod(1, 1)
836 SiSSetupPATFGDSTRect(color
, pSiS
->scrnOffset
, -1)
837 SiSSetupROP(sisPatALUConv
[rop
])
838 SiSSetupCMDFlag(PATFG
| LINE
)
843 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
844 SiSSetupDSTColorDepth(pSiS
->DstColor
)
845 SiSSetupROP(sisPatALUConv
[rop
])
846 SiSSetupCMDFlag(PATFG
| LINE
| pSiS
->SiS310_AccelDepth
)
851 SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn
,
852 int x1
, int y1
, int x2
, int y2
, int flags
)
854 SISPtr pSiS
= SISPTR(pScrn
);
855 long dstbase
,miny
,maxy
;
857 PDEBUG(ErrorF("Subsequent SolidLine(%d, %d, %d, %d, 0x%x)\n",
858 x1
, y1
, x2
, y2
, flags
));
861 miny
= (y1
> y2
) ? y2
: y1
;
862 maxy
= (y1
> y2
) ? y1
: y2
;
864 dstbase
= pSiS
->scrnOffset
*miny
;
869 dstbase
+= HEADOFFSET
;
872 if(flags
& OMIT_LAST
) {
873 SiSSetupCMDFlag(NO_LAST_PIXEL
)
875 pSiS
->CommandReg
&= ~(NO_LAST_PIXEL
);
879 SiSCheckQueue(16 * 2);
880 SiSSetupX0Y0X1Y1(x1
,y1
,x2
,y2
)
881 SiSSetupDSTBaseDoCMD(dstbase
)
883 SiSSetupDSTBase(dstbase
)
891 SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn
,
892 int x
, int y
, int len
, int dir
)
894 SISPtr pSiS
= SISPTR(pScrn
);
897 PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n",
900 len
--; /* starting point is included! */
902 if((y
>= 2048) || ((y
+ len
) >= 2048)) {
903 dstbase
= pSiS
->scrnOffset
* y
;
907 dstbase
+= HEADOFFSET
;
911 SiSCheckQueue(16 * 2);
912 if(dir
== DEGREES_0
) {
913 SiSSetupX0Y0X1Y1(x
, y
, (x
+ len
), y
)
915 SiSSetupX0Y0X1Y1(x
, y
, x
, (y
+ len
))
917 SiSSetupDSTBaseDoCMD(dstbase
)
919 SiSSetupDSTBase(dstbase
)
921 if(dir
== DEGREES_0
) {
922 SiSSetupX1Y1(x
+ len
, y
);
924 SiSSetupX1Y1(x
, y
+ len
);
931 SiSSetupForDashedLine(ScrnInfoPtr pScrn
,
932 int fg
, int bg
, int rop
, unsigned int planemask
,
933 int length
, unsigned char *pattern
)
935 SISPtr pSiS
= SISPTR(pScrn
);
937 PDEBUG(ErrorF("Setup DashedLine(0x%x, 0x%x, 0x%x, 0x%x, %d, 0x%x:%x)\n",
938 fg
, bg
, rop
, planemask
, length
, *(pattern
+4), *pattern
));
941 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
942 SiSCheckQueue(16 * 3);
943 SiSSetupLineCountPeriod(1, length
-1)
944 SiSSetupStyle(*pattern
,*(pattern
+4))
945 SiSSetupPATFGDSTRect(fg
, pSiS
->scrnOffset
, -1)
948 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
949 SiSSetupDSTColorDepth(pSiS
->DstColor
);
950 SiSSetupStyleLow(*pattern
)
951 SiSSetupStyleHigh(*(pattern
+4))
952 SiSSetupStylePeriod(length
-1);
956 SiSSetupROP(sisPatALUConv
[rop
])
958 SiSSetupCMDFlag(LINE
| LINE_STYLE
)
963 SiSSetupCMDFlag(TRANSPARENT
)
966 SiSSetupCMDFlag(pSiS
->SiS310_AccelDepth
)
975 SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn
,
976 int x1
, int y1
, int x2
, int y2
,
977 int flags
, int phase
)
979 SISPtr pSiS
= SISPTR(pScrn
);
980 long dstbase
,miny
,maxy
;
982 PDEBUG(ErrorF("Subsequent DashedLine(%d,%d, %d,%d, 0x%x,0x%x)\n",
983 x1
, y1
, x2
, y2
, flags
, phase
));
986 miny
= (y1
> y2
) ? y2
: y1
;
987 maxy
= (y1
> y2
) ? y1
: y2
;
989 dstbase
= pSiS
->scrnOffset
* miny
;
994 dstbase
+= HEADOFFSET
;
997 if(flags
& OMIT_LAST
) {
998 SiSSetupCMDFlag(NO_LAST_PIXEL
)
1000 pSiS
->CommandReg
&= ~(NO_LAST_PIXEL
);
1004 SiSCheckQueue(16 * 2);
1005 SiSSetupX0Y0X1Y1(x1
,y1
,x2
,y2
)
1006 SiSSetupDSTBaseDoCMD(dstbase
)
1008 SiSSetupDSTBase(dstbase
)
1016 SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn
,
1017 int patx
, int paty
, int fg
, int bg
,
1018 int rop
, unsigned int planemask
)
1020 SISPtr pSiS
= SISPTR(pScrn
);
1022 PDEBUG(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n",
1023 patx
, paty
, fg
, bg
, rop
, planemask
));
1026 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1027 SiSCheckQueue(16 * 3);
1028 SiSSetupPATFGDSTRect(fg
, pSiS
->scrnOffset
, -1)
1030 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
1031 SiSSetupDSTColorDepth(pSiS
->DstColor
);
1034 SiSSetupMONOPAT(patx
,paty
)
1036 SiSSetupROP(sisPatALUConv
[rop
])
1039 SiSSetupCMDFlag(PATMONO
)
1042 SiSSetupCMDFlag(PATMONO
| pSiS
->SiS310_AccelDepth
)
1048 SiSSetupCMDFlag(TRANSPARENT
)
1057 SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn
,
1059 int x
, int y
, int w
, int h
)
1061 SISPtr pSiS
= SISPTR(pScrn
);
1064 PDEBUG(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
1065 patx
, paty
, x
, y
, w
, h
));
1068 dstbase
= pSiS
->scrnOffset
* y
;
1072 dstbase
+= HEADOFFSET
;
1075 /* Clear commandReg because Setup can be used for Rect and Trap */
1076 pSiS
->CommandReg
&= ~(T_XISMAJORL
| T_XISMAJORR
|
1077 T_L_X_INC
| T_L_Y_INC
|
1078 T_R_X_INC
| T_R_Y_INC
|
1082 SiSCheckQueue(16 * 2);
1083 SiSSetupDSTXYRect(x
,y
,w
,h
)
1084 SiSSetupDSTBaseDoCMD(dstbase
)
1086 SiSSetupDSTBase(dstbase
)
1093 /* --- Trapezoid --- */
1095 /* Does not work at all on Xabre */
1099 SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn
,
1102 int left
, int dxL
, int dyL
, int eL
,
1103 int right
, int dxR
, int dyR
, int eR
)
1105 SISPtr pSiS
= SISPTR(pScrn
);
1108 PDEBUG(ErrorF("Subsequent Mono8x8PatternFillTrap(%d, %d, %d - %d %d/%d %d/%d)\n",
1109 y
, h
, left
, right
, dxL
, dxR
, eL
, eR
));
1113 dstbase
=pSiS
->scrnOffset
*y
;
1117 dstbase
+= HEADOFFSET
;
1121 SiSCheckQueue(16 * 4);
1123 SiSSetupDSTBase(dstbase
)
1126 /* Clear CommandReg because SetUp can be used for Rect and Trap */
1127 pSiS
->CommandReg
&= ~(T_XISMAJORL
| T_XISMAJORR
|
1128 T_L_X_INC
| T_L_Y_INC
|
1129 T_R_X_INC
| T_R_Y_INC
|
1132 if(dxL
< 0) { dxL
= -dxL
; }
1133 else { SiSSetupCMDFlag(T_L_X_INC
) }
1134 if(dxR
< 0) { dxR
= -dxR
; }
1135 else { SiSSetupCMDFlag(T_R_X_INC
) }
1137 if(dyL
< 0) { dyL
= -dyL
; }
1138 else { SiSSetupCMDFlag(T_L_Y_INC
) }
1139 if(dyR
< 0) { dyR
= -dyR
; }
1140 else { SiSSetupCMDFlag(T_R_Y_INC
) }
1142 /* Determine major axis */
1143 if(dxL
>= dyL
) { SiSSetupCMDFlag(T_XISMAJORL
) }
1144 if(dxR
>= dyR
) { SiSSetupCMDFlag(T_XISMAJORR
) }
1146 SiSSetupCMDFlag(TRAPAZOID_FILL
);
1149 SiSSetupYHLR(y
, h
, left
, right
)
1150 SiSSetupdLdR(dxL
, dyL
, dxR
, dyR
)
1151 SiSSetupELER(eL
, eR
)
1152 SiSSetupDSTBaseDoCMD(dstbase
)
1155 SiSSetupLR(left
, right
)
1156 SiSSetupdL(dxL
, dyL
)
1157 SiSSetupdR(dxR
, dyR
)
1165 /* Color 8x8 pattern */
1169 SiSSetupForColor8x8PatternFill(ScrnInfoPtr pScrn
, int patternx
, int patterny
,
1170 int rop
, unsigned int planemask
, int trans_col
)
1172 SISPtr pSiS
= SISPTR(pScrn
);
1173 int j
= pScrn
->bitsPerPixel
>> 3;
1174 CARD32
*patadr
= (CARD32
*)(pSiS
->FbBase
+ (patterny
* pSiS
->scrnOffset
) +
1178 xf86DrvMsg(0, X_INFO
, "Setup Color8x8PatFill(0x%x, 0x%x, 0x%x, 0x%x)\n",
1179 patternx
, patterny
, rop
, planemask
);
1182 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1183 SiSCheckQueue(16 * 3);
1185 SiSSetupDSTRectBurstHeader(pSiS
->scrnOffset
, -1, PATTERN_REG
, (pScrn
->bitsPerPixel
<< 1))
1188 SiSSetupPatternRegBurst(patadr
[0], patadr
[1], patadr
[2], patadr
[3]);
1189 SiSSetupPatternRegBurst(patadr
[4], patadr
[5], patadr
[6], patadr
[7]);
1190 SiSSetupPatternRegBurst(patadr
[8], patadr
[9], patadr
[10], patadr
[11]);
1191 SiSSetupPatternRegBurst(patadr
[12], patadr
[13], patadr
[14], patadr
[15]);
1192 patadr
+= 16; /* = 64 due to (CARD32 *) */
1195 SiSSetupROP(sisPatALUConv
[rop
])
1197 SiSSetupCMDFlag(PATPATREG
)
1203 SiSSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn
, int patternx
,
1204 int patterny
, int x
, int y
, int w
, int h
)
1206 SISPtr pSiS
= SISPTR(pScrn
);
1210 xf86DrvMsg(0, X_INFO
, "Subsequent Color8x8FillRect(%d, %d, %d, %d)\n",
1216 dstbase
= pSiS
->scrnOffset
* y
;
1220 dstbase
+= HEADOFFSET
;
1222 /* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */
1224 SiSCheckQueue(16 * 2)
1225 SiSSetupDSTXYRect(x
,y
,w
,h
)
1226 SiSSetupDSTBaseDoCMD(dstbase
)
1230 /* ---- CPUToScreen Color Expand --- */
1238 /* This is somewhat a fake. We let XAA copy its data not to an
1239 * aperture, but to video RAM, and then do a ScreenToScreen
1241 * Since the data is sent AFTER the call to Subsequent, we
1242 * don't execute the command here, but set a flag and do
1243 * that in the (subsequent) call to Sync()
1247 SiSSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
1248 int fg
, int bg
, int rop
, unsigned int planemask
)
1250 SISPtr pSiS
=SISPTR(pScrn
);
1253 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1254 SiSSetupROP(sisALUConv
[rop
]);
1255 SiSSetupSRCFGDSTRect(fg
, pSiS
->scrnOffset
, -1)
1257 SiSSetupCMDFlag(TRANSPARENT
| ENCOLOREXP
| SRCVIDEO
);
1260 SiSSetupCMDFlag(ENCOLOREXP
| SRCVIDEO
);
1265 SiSSetupROP(sisALUConv
[rop
]);
1267 SiSSetupDSTRect(pSiS
->scrnOffset
, -1);
1268 SiSSetupDSTColorDepth(pSiS
->DstColor
);
1270 SiSSetupCMDFlag(TRANSPARENT
| ENCOLOREXP
| SRCVIDEO
1271 | pSiS
->SiS310_AccelDepth
);
1274 SiSSetupCMDFlag(ENCOLOREXP
| SRCVIDEO
| pSiS
->SiS310_AccelDepth
);
1280 SiSSubsequentCPUToScreenColorExpandFill(
1281 ScrnInfoPtr pScrn
, int x
, int y
, int w
,
1282 int h
, int skipleft
)
1284 SISPtr pSiS
= SISPTR(pScrn
);
1285 int _x0
, _y0
, _x1
, _y1
;
1286 long srcbase
, dstbase
;
1288 srcbase
= pSiS
->ColorExpandBase
;
1292 dstbase
= pSiS
->scrnOffset
*y
;
1297 srcbase
+= HEADOFFSET
;
1298 dstbase
+= HEADOFFSET
;
1302 SiSSetupSRCDSTBase(srcbase
,dstbase
);
1304 SiSSetupSRCBase(srcbase
);
1305 SiSSetupDSTBase(dstbase
)
1314 SiSSetupClip(_x0
, _y0
, _x1
, _y1
);
1316 SiSSetupClipLT(_x0
, _y0
);
1317 SiSSetupClipRB(_x1
, _y1
);
1319 SiSSetupCMDFlag(CLIPENABLE
);
1321 pSiS
->CommandReg
&= (~CLIPENABLE
);
1325 SiSSetupRectSRCPitch(w
, h
, ((((w
+ 7) >> 3) + 3) >> 2) << 2);
1326 SiSSetupSRCDSTXY(0, 0, x
, y
);
1329 SiSSetupSRCPitch(((((w
+7)/8)+3) >> 2) * 4);
1330 SiSSetupDSTXY(x
, y
);
1333 if(pSiS
->ColorExpandBusy
) {
1334 pSiS
->ColorExpandBusy
= FALSE
;
1338 pSiS
->DoColorExpand
= TRUE
;
1343 /* Indirect method */
1345 /* This is SLOW, slower than the CPU on most chipsets */
1346 /* Does not work in VRAM queue mode. */
1349 SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
1350 int fg
, int bg
, int rop
, unsigned int planemask
)
1352 SISPtr pSiS
=SISPTR(pScrn
);
1355 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1358 /* !!! DOES NOT WORK IN VRAM QUEUE MODE !!! */
1360 /* (hence this is not optimized for VRAM mode) */
1366 SiSSetupROP(sisALUConv
[rop
]);
1368 SiSSetupDSTRect(pSiS
->scrnOffset
, -1);
1370 SiSSetupDSTColorDepth(pSiS
->DstColor
);
1374 SiSSetupCMDFlag(TRANSPARENT
| ENCOLOREXP
| SRCVIDEO
);
1376 SiSSetupCMDFlag(TRANSPARENT
| ENCOLOREXP
| SRCCPUBLITBUF
1377 | pSiS
->SiS310_AccelDepth
);
1382 SiSSetupCMDFlag(ENCOLOREXP
| SRCCPUBLITBUF
);
1384 SiSSetupCMDFlag(ENCOLOREXP
| SRCCPUBLITBUF
| pSiS
->SiS310_AccelDepth
);
1391 SiSSubsequentScanlineCPUToScreenColorExpandFill(
1392 ScrnInfoPtr pScrn
, int x
, int y
, int w
,
1393 int h
, int skipleft
)
1395 SISPtr pSiS
= SISPTR(pScrn
);
1396 int _x0
, _y0
, _x1
, _y1
;
1401 dstbase
= pSiS
->scrnOffset
*y
;
1405 dstbase
+= HEADOFFSET
;
1409 if((MMIO_IN16(pSiS
->IOBase
, Q_STATUS
+2) & 0x8000) != 0x8000) {
1414 SiSSetupDSTBase(dstbase
)
1422 SiSSetupClip(_x0
, _y0
, _x1
, _y1
);
1424 SiSSetupClipLT(_x0
, _y0
);
1425 SiSSetupClipRB(_x1
, _y1
);
1427 SiSSetupCMDFlag(CLIPENABLE
);
1429 pSiS
->CommandReg
&= (~CLIPENABLE
);
1432 SiSSetupSRCPitch(((((w
+7)/8)+3) >> 2) * 4);
1439 SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn
, int bufno
)
1441 SISPtr pSiS
= SISPTR(pScrn
);
1444 cbo
= pSiS
->ColorExpandBufferScreenOffset
[bufno
];
1450 if((MMIO_IN16(pSiS
->IOBase
, Q_STATUS
+2) & 0x8000) != 0x8000) {
1455 SiSSetupSRCBase(cbo
);
1457 SiSSetupDSTXY(pSiS
->xcurrent
, pSiS
->ycurrent
);
1469 /* --- Screen To Screen Color Expand --- */
1471 /* This method blits in a single task; this does not work because
1472 * the hardware does not use the source pitch as scanline offset
1473 * but to calculate pattern address from source X and Y and to
1474 * limit the drawing width (similar to width set by SetupRect).
1475 * XAA provides the pattern bitmap with scrnOffset (displayWidth * bpp/8)
1476 * offset, but this is not supported by the hardware.
1477 * DOES NOT WORK ON XABRE, HANGS ENGINE.
1482 SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
1484 int rop
, unsigned int planemask
)
1486 SISPtr pSiS
= SISPTR(pScrn
);
1489 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1491 SiSSetupDSTColorDepth(pSiS
->DstColor
)
1493 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
1494 SiSSetupROP(sisALUConv
[rop
])
1496 /* SiSSetupSRCXY(0,0) */
1499 SiSSetupCMDFlag(TRANSPARENT
| ENCOLOREXP
| SRCVIDEO
);
1502 SiSSetupCMDFlag(ENCOLOREXP
| SRCVIDEO
);
1510 /* For testing, these are the methods: (use only one at a time!) */
1512 #undef npitch /* Normal: Use srcx/y as srcx/y, use scrnOffset as source pitch
1513 * Does not work on 315 series, because the hardware does not
1514 * regard the src x and y. Apart from this problem:
1515 * This would work if the hareware used the source pitch for
1516 * incrementing the source address after each scanline - but
1517 * it doesn't do this! The first line of the area is correctly
1518 * color expanded, but since the source pitch is ignored and
1519 * the source address not incremented correctly, the following
1520 * lines are color expanded with any bit pattern that is left
1521 * in the unused space of the source bitmap (which is organized
1522 * with the depth of the screen framebuffer hence with a pitch
1526 #undef pitchdw /* Use source pitch "displayWidth / 8" instead
1527 * of scrnOffset (=displayWidth * bpp / 8)
1528 * This can't work, because the pitch of the source
1529 * bitmap is scrnoffset!
1532 #define nopitch /* Calculate srcbase with srcx and srcy, set the
1533 * pitch to scrnOffset (which IS the correct pitch
1534 * for the source bitmap) and set srcx and srcy both
1536 * This would work if the hareware used the source pitch for
1537 * incrementing the source address after each scanline - but
1538 * it doesn't do this! Again: The first line of the area is
1539 * correctly color expanded, but since the source pitch is
1540 * ignored for scanline address incremention, the following
1541 * lines are not correctly color expanded.
1542 * This is the only way it works (apart from the problem
1543 * described above). The hardware does not regard the src
1544 * x and y values in any way.
1548 SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
1549 int x
, int y
, int w
, int h
,
1550 int srcx
, int srcy
, int skipleft
)
1552 SISPtr pSiS
= SISPTR(pScrn
);
1553 long srcbase
, dstbase
;
1555 int _x0
, _y0
, _x1
, _y1
;
1558 int newsrcx
, newsrcy
;
1560 /* srcx and srcy are provided based on a scrnOffset pitch ( = displayWidth * bpp / 8 )
1561 * We recalulate srcx and srcy based on pitch = displayWidth / 8
1563 newsrcy
= ((pSiS
->scrnOffset
* srcy
) + (srcx
* ((pScrn
->bitsPerPixel
+7)/8))) /
1564 (pScrn
->displayWidth
/8);
1565 newsrcx
= ((pSiS
->scrnOffset
* srcy
) + (srcx
* ((pScrn
->bitsPerPixel
+7)/8))) %
1566 (pScrn
->displayWidth
/8);
1568 xf86DrvMsg(0, X_INFO
, "Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n",
1569 x
, y
, w
, h
, srcx
, srcy
, skipleft
);
1571 srcbase
= dstbase
= 0;
1574 if(newsrcy
>= 2048) {
1575 srcbase
= (pScrn
->displayWidth
/ 8) * newsrcy
;
1580 srcbase
= (pSiS
->scrnOffset
* srcy
) + (srcx
* ((pScrn
->bitsPerPixel
+7)/8));
1584 srcbase
= pSiS
->scrnOffset
* srcy
;
1589 dstbase
= pSiS
->scrnOffset
* y
;
1594 srcbase
+= HEADOFFSET
;
1595 dstbase
+= HEADOFFSET
;
1598 SiSSetupSRCBase(srcbase
)
1599 SiSSetupDSTBase(dstbase
)
1601 /* 315 series seem to treat the src pitch as
1602 * a "drawing limit", but still (as 300 series)
1603 * does not use it for incrementing the
1604 * address pointer for the next scanline. ARGH!
1608 SiSSetupSRCPitch(pScrn
->displayWidth
/8)
1611 SiSSetupSRCPitch(pScrn
->displayWidth
/8)
1612 /* SiSSetupSRCPitch(1024/8) */ /* For test */
1615 SiSSetupSRCPitch(pScrn
->displayWidth
/8)
1616 /* SiSSetupSRCPitch(pSiS->scrnOffset) */
1621 #if 0 /* How do I implement the offset? Not this way, that's for sure.. */
1627 SiSSetupClipLT(_x0
, _y0
);
1628 SiSSetupClipRB(_x1
, _y1
);
1629 SiSSetupCMDFlag(CLIPENABLE
);
1633 SiSSetupSRCXY(newsrcx
, newsrcy
)
1639 SiSSetupSRCXY(srcx
, srcy
)
1646 /* We MUST sync here, there must not be 2 or more color expansion commands in the queue */
1652 /* ---- RENDER ---- */
1657 SiSRenderCallback(ScrnInfoPtr pScrn
)
1659 SISPtr pSiS
= SISPTR(pScrn
);
1661 if((currentTime
.milliseconds
> pSiS
->RenderTime
) && pSiS
->AccelLinearScratch
) {
1662 xf86FreeOffscreenLinear(pSiS
->AccelLinearScratch
);
1663 pSiS
->AccelLinearScratch
= NULL
;
1666 if(!pSiS
->AccelLinearScratch
) {
1667 pSiS
->RenderCallback
= NULL
;
1671 #define RENDER_DELAY 15000
1674 SiSAllocateLinear(ScrnInfoPtr pScrn
, int sizeNeeded
)
1676 SISPtr pSiS
= SISPTR(pScrn
);
1678 pSiS
->RenderTime
= currentTime
.milliseconds
+ RENDER_DELAY
;
1679 pSiS
->RenderCallback
= SiSRenderCallback
;
1681 if(pSiS
->AccelLinearScratch
) {
1682 if(pSiS
->AccelLinearScratch
->size
>= sizeNeeded
) {
1685 if(pSiS
->alphaBlitBusy
) {
1686 pSiS
->alphaBlitBusy
= FALSE
;
1689 if(xf86ResizeOffscreenLinear(pSiS
->AccelLinearScratch
, sizeNeeded
)) {
1692 xf86FreeOffscreenLinear(pSiS
->AccelLinearScratch
);
1693 pSiS
->AccelLinearScratch
= NULL
;
1697 pSiS
->AccelLinearScratch
= xf86AllocateOffscreenLinear(
1698 pScrn
->pScreen
, sizeNeeded
, 32,
1701 return(pSiS
->AccelLinearScratch
!= NULL
);
1705 SiSSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn
,
1706 int op
, CARD16 red
, CARD16 green
,
1707 CARD16 blue
, CARD16 alpha
,
1708 int alphaType
, CARD8
*alphaPtr
,
1709 int alphaPitch
, int width
,
1710 int height
, int flags
)
1712 SISPtr pSiS
= SISPTR(pScrn
);
1713 int x
, pitch
, sizeNeeded
, offset
;
1716 unsigned char *renderaccelarray
;
1719 xf86DrvMsg(0, X_INFO
, "AT: op %d RGB %x %x %x, w %d h %d A-pitch %d\n",
1720 op
, red
, green
, blue
, width
, height
, alphaPitch
);
1723 if(op
!= PictOpOver
) return FALSE
;
1725 if((width
> 2048) || (height
> 2048)) return FALSE
;
1727 pitch
= (width
+ 31) & ~31;
1728 sizeNeeded
= pitch
* height
;
1729 if(pScrn
->bitsPerPixel
== 16) sizeNeeded
<<= 1;
1734 renderaccelarray
= pSiS
->RenderAccelArray
;
1736 if(!SiSAllocateLinear(pScrn
, sizeNeeded
))
1740 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1741 SiSSetupSRCPitchDSTRect((pitch
<< 2), pSiS
->scrnOffset
, -1);
1742 SiSSetupCMDFlag(ALPHA_BLEND
| SRCVIDEO
| A_PERPIXELALPHA
)
1745 SiSSetupDSTColorDepth(pSiS
->DstColor
);
1746 SiSSetupSRCPitch((pitch
<< 2));
1747 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
1749 SiSSetupCMDFlag(ALPHA_BLEND
| SRCVIDEO
| A_PERPIXELALPHA
| pSiS
->SiS310_AccelDepth
)
1752 offset
= pSiS
->AccelLinearScratch
->offset
<< 1;
1753 if(pScrn
->bitsPerPixel
== 32) offset
<<= 1;
1755 dstPtr
= (CARD32
*)(pSiS
->FbBase
+ offset
);
1757 if(pSiS
->alphaBlitBusy
) {
1758 pSiS
->alphaBlitBusy
= FALSE
;
1763 for(x
= 0; x
< width
; x
++) {
1764 myalpha
= alphaPtr
[x
];
1765 dstPtr
[x
] = (renderaccelarray
[red
+ myalpha
] << 16) |
1766 (renderaccelarray
[green
+ myalpha
] << 8) |
1767 renderaccelarray
[blue
+ myalpha
] |
1771 alphaPtr
+= alphaPitch
;
1778 SiSSetupForCPUToScreenTexture(ScrnInfoPtr pScrn
,
1779 int op
, int texType
, CARD8
*texPtr
,
1780 int texPitch
, int width
,
1781 int height
, int flags
)
1783 SISPtr pSiS
= SISPTR(pScrn
);
1784 int pitch
, sizeNeeded
, offset
;
1788 xf86DrvMsg(0, X_INFO
, "T: type %d op %d w %d h %d T-pitch %d\n",
1789 texType
, op
, width
, height
, texPitch
);
1792 if(op
!= PictOpOver
) return FALSE
;
1794 if((width
> 2048) || (height
> 2048)) return FALSE
;
1796 pitch
= (width
+ 31) & ~31;
1797 sizeNeeded
= pitch
* height
;
1798 if(pScrn
->bitsPerPixel
== 16) sizeNeeded
<<= 1;
1803 if(!SiSAllocateLinear(pScrn
, sizeNeeded
))
1807 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1808 SiSSetupSRCPitchDSTRect(pitch
, pSiS
->scrnOffset
, -1);
1810 SiSSetupCMDFlag(ALPHA_BLEND
| SRCVIDEO
| A_PERPIXELALPHA
)
1813 SiSSetupDSTColorDepth(pSiS
->DstColor
);
1814 SiSSetupSRCPitch(pitch
);
1815 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
1817 SiSSetupCMDFlag(ALPHA_BLEND
| SRCVIDEO
| A_PERPIXELALPHA
| pSiS
->SiS310_AccelDepth
)
1820 offset
= pSiS
->AccelLinearScratch
->offset
<< 1;
1821 if(pScrn
->bitsPerPixel
== 32) offset
<<= 1;
1823 dst
= (CARD8
*)(pSiS
->FbBase
+ offset
);
1825 if(pSiS
->alphaBlitBusy
) {
1826 pSiS
->alphaBlitBusy
= FALSE
;
1831 memcpy(dst
, texPtr
, width
);
1840 SiSSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn
,
1841 int dst_x
, int dst_y
,
1842 int src_x
, int src_y
,
1843 int width
, int height
)
1845 SISPtr pSiS
= SISPTR(pScrn
);
1846 long srcbase
, dstbase
;
1848 srcbase
= pSiS
->AccelLinearScratch
->offset
<< 1;
1849 if(pScrn
->bitsPerPixel
== 32)
1853 xf86DrvMsg(0, X_INFO
, "FIRE: scrbase %x dx %d dy %d w %d h %d\n",
1854 srcbase
, dst_x
, dst_y
, width
, height
);
1858 if((dst_y
>= pScrn
->virtualY
) || (dst_y
>= 2048)) {
1859 dstbase
= pSiS
->scrnOffset
* dst_y
;
1863 srcbase
+= HEADOFFSET
;
1864 dstbase
+= HEADOFFSET
;
1868 SiSCheckQueue(16 * 3)
1869 SiSSetupSRCDSTBase(srcbase
,dstbase
);
1870 SiSSetupSRCDSTXY(src_x
, src_y
, dst_x
, dst_y
)
1871 SiSSetRectDoCMD(width
,height
)
1873 SiSSetupSRCBase(srcbase
);
1874 SiSSetupDSTBase(dstbase
);
1875 SiSSetupRect(width
, height
)
1876 SiSSetupSRCXY(src_x
, src_y
)
1877 SiSSetupDSTXY(dst_x
, dst_y
)
1880 pSiS
->alphaBlitBusy
= TRUE
;