3 * 2D Acceleration for SiS 530, 620, 300, 540, 630, 730.
5 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1) Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2) Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3) All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: "This product includes
17 * software developed by Thomas Winischhofer, Vienna, Austria."
18 * 4) The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * Authors: Thomas Winischhofer <thomas@winischhofer.net>
33 * Can-Ru Yeou, SiS Inc.
42 #include "xf86_OSproc.h"
43 #include "xf86_ansic.h"
44 #include "xf86PciInfo.h"
52 #include "sis300_accel.h"
55 /* TW: This is the offset to the memory for each head */
56 #define HEADOFFSET (pSiS->dhmOffset)
59 #undef STSCE /* TW: Use/Don't use ScreenToScreenColorExpand - does not work */
61 #undef TRAP /* TW: Use/Don't use Trapezoid Fills - does not work - XAA provides
62 * illegal trapezoid data (left and right edges cross each other
63 * sometimes) which causes drawing errors. Further, I have not found
64 * out how to draw polygones with a height greater than 127...
67 static void SiSInitializeAccelerator(ScrnInfoPtr pScrn
);
68 static void SiSSync(ScrnInfoPtr pScrn
);
69 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn
,
70 int xdir
, int ydir
, int rop
,
71 unsigned int planemask
, int trans_color
);
72 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn
,
73 int x1
, int y1
, int x2
, int y2
,
74 int width
, int height
);
75 static void SiSSetupForSolidFill(ScrnInfoPtr pScrn
, int color
,
76 int rop
, unsigned int planemask
);
77 static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn
,
78 int x
, int y
, int w
, int h
);
80 static void SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn
, int y
, int h
,
81 int left
, int dxL
, int dyL
, int eL
,
82 int right
, int dxR
, int dyR
, int eR
);
84 static void SiSSetupForSolidLine(ScrnInfoPtr pScrn
, int color
,
85 int rop
, unsigned int planemask
);
86 static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn
, int x1
,
87 int y1
, int x2
, int y2
, int flags
);
88 static void SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn
,
89 int x
, int y
, int len
, int dir
);
90 static void SiSSetupForDashedLine(ScrnInfoPtr pScrn
,
91 int fg
, int bg
, int rop
, unsigned int planemask
,
92 int length
, unsigned char *pattern
);
93 static void SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn
,
94 int x1
, int y1
, int x2
, int y2
,
95 int flags
, int phase
);
96 static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn
,
97 int patx
, int paty
, int fg
, int bg
,
98 int rop
, unsigned int planemask
);
99 static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn
,
101 int x
, int y
, int w
, int h
);
103 static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn
,
106 int left
, int dxL
, int dyL
, int eL
,
107 int right
, int dxR
, int dyR
, int eR
);
110 static void SiSSetupForColorPatternFill(ScrnInfoPtr pScrn
,
111 int patx
, int paty
, int rop
,
112 unsigned int planemask
,
114 static void SiSSubsequentColorPatternFill(ScrnInfoPtr pScrn
,
116 int x
, int y
, int w
, int h
);
119 static void SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn
,
121 int rop
, unsigned int planemask
);
122 static void SiSSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn
,
123 int x
, int y
, int w
, int h
, int skipleft
);
126 static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
128 int rop
, unsigned int planemask
);
129 static void SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
130 int x
, int y
, int w
, int h
,
131 int srcx
, int srcy
, int skipleft
);
133 static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
134 int fg
, int bg
, int rop
,
135 unsigned int planemask
);
136 static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
137 int x
, int y
, int w
, int h
,
139 static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn
, int bufno
);
142 static void SiSRestoreAccelState(ScrnInfoPtr pScrn
);
146 SiSInitializeAccelerator(ScrnInfoPtr pScrn
)
148 SISPtr pSiS
= SISPTR(pScrn
);
150 pSiS
->DoColorExpand
= FALSE
;
154 SiS300AccelInit(ScreenPtr pScreen
)
156 XAAInfoRecPtr infoPtr
;
157 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
158 SISPtr pSiS
= SISPTR(pScrn
);
162 unsigned char *AvailBufBase
;
166 pSiS
->AccelInfoPtr
= infoPtr
= XAACreateInfoRec();
167 if (!infoPtr
) return FALSE
;
169 SiSInitializeAccelerator(pScrn
);
171 infoPtr
->Flags
= LINEAR_FRAMEBUFFER
|
176 infoPtr
->Sync
= SiSSync
;
178 /* Acceleration only supported at 8, 16 and 32 bpp */
179 if((pScrn
->bitsPerPixel
!= 8) && (pScrn
->bitsPerPixel
!= 16) &&
180 (pScrn
->bitsPerPixel
!= 32))
183 /* TW: Although SiS states that the 300 series supports a
184 * virtual framebuffer of 4096x4096, the 2D accelerator
185 * does not seem to know that. If the destination bitmap
186 * pitch is > 8192 (which easily happens in 32bpp mode),
187 * the accelerator engine collapses.
188 * TODO: Find out about the 530 and 620
191 if(pSiS
->scrnOffset
< 8192) {
193 /* screen to screen copy */
194 infoPtr
->SetupForScreenToScreenCopy
= SiSSetupForScreenToScreenCopy
;
195 infoPtr
->SubsequentScreenToScreenCopy
= SiSSubsequentScreenToScreenCopy
;
196 infoPtr
->ScreenToScreenCopyFlags
= NO_PLANEMASK
|
197 TRANSPARENCY_GXCOPY_ONLY
;
200 infoPtr
->SetupForSolidFill
= SiSSetupForSolidFill
;
201 infoPtr
->SubsequentSolidFillRect
= SiSSubsequentSolidFillRect
;
203 infoPtr
->SubsequentSolidFillTrap
= SiSSubsequentSolidFillTrap
;
205 infoPtr
->SolidFillFlags
= NO_PLANEMASK
;
208 infoPtr
->SetupForSolidLine
= SiSSetupForSolidLine
;
209 infoPtr
->SubsequentSolidTwoPointLine
= SiSSubsequentSolidTwoPointLine
;
210 infoPtr
->SubsequentSolidHorVertLine
= SiSSubsequentSolidHorzVertLine
;
211 infoPtr
->SolidLineFlags
= NO_PLANEMASK
;
214 infoPtr
->SetupForDashedLine
= SiSSetupForDashedLine
;
215 infoPtr
->SubsequentDashedTwoPointLine
= SiSSubsequentDashedTwoPointLine
;
216 infoPtr
->DashPatternMaxLength
= 64;
217 infoPtr
->DashedLineFlags
= NO_PLANEMASK
|
218 LINE_PATTERN_MSBFIRST_LSBJUSTIFIED
;
220 /* 8x8 mono pattern fill */
221 infoPtr
->SetupForMono8x8PatternFill
= SiSSetupForMonoPatternFill
;
222 infoPtr
->SubsequentMono8x8PatternFillRect
= SiSSubsequentMonoPatternFill
;
224 infoPtr
->SubsequentMono8x8PatternFillTrap
= SiSSubsequentMonoPatternFillTrap
;
226 infoPtr
->Mono8x8PatternFillFlags
= NO_PLANEMASK
|
227 HARDWARE_PATTERN_SCREEN_ORIGIN
|
228 HARDWARE_PATTERN_PROGRAMMED_BITS
|
229 /* NO_TRANSPARENCY | */
230 BIT_ORDER_IN_BYTE_MSBFIRST
;
233 /* Screen To Screen Color Expand */
234 /* TW: The hardware does support this the way we need it */
235 infoPtr
->SetupForScreenToScreenColorExpandFill
=
236 SiSSetupForScreenToScreenColorExpand
;
237 infoPtr
->SubsequentScreenToScreenColorExpandFill
=
238 SiSSubsequentScreenToScreenColorExpand
;
239 infoPtr
->ScreenToScreenColorExpandFillFlags
= NO_PLANEMASK
|
240 BIT_ORDER_IN_BYTE_MSBFIRST
;
244 /* CPU To Screen Color Expand --- implement another instead of this one! */
245 infoPtr
->SetupForCPUToScreenColorExpandFill
=
246 SiSSetupForCPUToScreenColorExpand
;
247 infoPtr
->SubsequentCPUToScreenColorExpandFill
=
248 SiSSubsequentCPUToScreenColorExpand
;
249 infoPtr
->ColorExpandRange
= PATREGSIZE
;
250 infoPtr
->ColorExpandBase
= pSiS
->IOBase
+PBR(0);
251 infoPtr
->CPUToScreenColorExpandFillFlags
= NO_PLANEMASK
|
252 BIT_ORDER_IN_BYTE_MSBFIRST
|
254 SYNC_AFTER_COLOR_EXPAND
|
255 HARDWARE_PATTERN_SCREEN_ORIGIN
|
256 HARDWARE_PATTERN_PROGRAMMED_BITS
;
259 /* per-scanline color expansion (using indirect method) */
260 if(pSiS
->VGAEngine
== SIS_530_VGA
) {
261 pSiS
->ColorExpandBufferNumber
= 4;
262 pSiS
->ColorExpandBufferCountMask
= 0x03;
264 pSiS
->ColorExpandBufferNumber
= 16;
265 pSiS
->ColorExpandBufferCountMask
= 0x0F;
267 pSiS
->PerColorExpandBufferSize
= ((pScrn
->virtualX
+ 31)/32) * 4;
268 infoPtr
->NumScanlineColorExpandBuffers
= pSiS
->ColorExpandBufferNumber
;
269 infoPtr
->ScanlineColorExpandBuffers
= (unsigned char **)&pSiS
->ColorExpandBufferAddr
[0];
271 infoPtr
->SetupForScanlineCPUToScreenColorExpandFill
=
272 SiSSetupForScanlineCPUToScreenColorExpandFill
;
273 infoPtr
->SubsequentScanlineCPUToScreenColorExpandFill
=
274 SiSSubsequentScanlineCPUToScreenColorExpandFill
;
275 infoPtr
->SubsequentColorExpandScanline
=
276 SiSSubsequentColorExpandScanline
;
277 infoPtr
->ScanlineCPUToScreenColorExpandFillFlags
= NO_PLANEMASK
|
278 CPU_TRANSFER_PAD_DWORD
|
280 BIT_ORDER_IN_BYTE_MSBFIRST
|
283 xf86DrvMsg(pScrn
->scrnIndex
, X_WARNING
,
284 "Virtual screen width too large for accelerator engine\n");
285 xf86DrvMsg(pScrn
->scrnIndex
, X_WARNING
,
286 "2D acceleration and Xv disabled\n");
287 pSiS
->NoXvideo
= TRUE
;
291 if(pSiS
->DualHeadMode
) {
292 infoPtr
->RestoreAccelState
= SiSRestoreAccelState
;
296 /* init Frame Buffer Manager */
297 topFB
= pSiS
->maxxfbmem
;
299 reservedFbSize
= pSiS
->ColorExpandBufferNumber
* pSiS
->PerColorExpandBufferSize
;
301 UsableFbSize
= topFB
- reservedFbSize
;
303 /* Layout: (Sizes do not reflect correct proportions)
304 * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
305 * UsableFbSize ColorExpandBuffers | DRI-Heap | HWCursor TurboQueue 300/310/325 series
306 * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~|
307 * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor 530/620
311 AvailBufBase
= pSiS
->FbBase
+ UsableFbSize
;
312 for(i
= 0; i
< pSiS
->ColorExpandBufferNumber
; i
++) {
313 pSiS
->ColorExpandBufferAddr
[i
] = AvailBufBase
+
314 i
* pSiS
->PerColorExpandBufferSize
;
315 pSiS
->ColorExpandBufferScreenOffset
[i
] = UsableFbSize
+
316 i
* pSiS
->PerColorExpandBufferSize
;
320 Avail
.x2
= pScrn
->displayWidth
;
321 Avail
.y2
= (UsableFbSize
/ (pScrn
->displayWidth
* pScrn
->bitsPerPixel
/8)) - 1;
323 if(Avail
.y2
< 0) Avail
.y2
= 32767;
325 if(Avail
.y2
< pScrn
->currentMode
->VDisplay
) {
326 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
327 "Not enough video RAM for accelerator. At least "
328 "%dKB needed, %ldKB available\n",
329 ((((pScrn
->displayWidth
* pScrn
->bitsPerPixel
/8) /* TW: +8 for make it sure */
330 * pScrn
->currentMode
->VDisplay
) + reservedFbSize
) / 1024) + 8,
331 pSiS
->maxxfbmem
/1024);
332 pSiS
->NoAccel
= TRUE
;
333 pSiS
->NoXvideo
= TRUE
;
334 XAADestroyInfoRec(pSiS
->AccelInfoPtr
);
335 pSiS
->AccelInfoPtr
= NULL
;
339 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
340 "Frame Buffer From (%d,%d) To (%d,%d)\n",
341 Avail
.x1
, Avail
.y1
, Avail
.x2
, Avail
.y2
);
343 xf86InitFBManager(pScreen
, &Avail
);
345 return(XAAInit(pScreen
, infoPtr
));
350 SiSSync(ScrnInfoPtr pScrn
)
352 SISPtr pSiS
= SISPTR(pScrn
);
354 PDEBUG(ErrorF("SiSSync()\n"));
356 pSiS
->DoColorExpand
= FALSE
;
362 SiSRestoreAccelState(ScrnInfoPtr pScrn
)
364 SISPtr pSiS
= SISPTR(pScrn
);
366 /* TW: We don't need to do anything special here; forcing the
367 * other head to re-read the CmdQueLen is not necessary:
368 * After the Sync in RestoreAccelState(), the real queue
369 * length is always larger than (or at least equal to)
370 * the amount stored in CmdQueueLen of the other head,
371 * so the only thing that might happen is one unnecessary
372 * Sync on the other head. I think we can live with that.
374 pSiS
->DoColorExpand
= FALSE
;
379 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn
,
380 int xdir
, int ydir
, int rop
,
381 unsigned int planemask
, int trans_color
)
383 SISPtr pSiS
= SISPTR(pScrn
);
385 PDEBUG(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
386 xdir
, ydir
, rop
, planemask
, trans_color
));
388 SiSSetupDSTColorDepth(pSiS
->DstColor
);
389 SiSSetupSRCPitch(pSiS
->scrnOffset
)
390 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
392 if(trans_color
!= -1) {
394 SiSSetupSRCTrans(trans_color
)
395 SiSSetupCMDFlag(TRANSPARENT_BITBLT
)
397 SiSSetupROP(XAACopyROP
[rop
])
400 SiSSetupCMDFlag(X_INC
)
403 SiSSetupCMDFlag(Y_INC
)
407 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn
,
408 int src_x
, int src_y
, int dst_x
, int dst_y
,
409 int width
, int height
)
411 SISPtr pSiS
= SISPTR(pScrn
);
412 long srcbase
, dstbase
;
414 PDEBUG(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
415 src_x
, src_y
, dst_x
, dst_y
, width
, height
));
417 srcbase
= dstbase
= 0;
419 srcbase
= pSiS
->scrnOffset
* src_y
;
422 if((dst_y
>= pScrn
->virtualY
) || (dst_y
>= 2048)) {
423 dstbase
= pSiS
->scrnOffset
* dst_y
;
427 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
428 srcbase
+= HEADOFFSET
;
429 dstbase
+= HEADOFFSET
;
432 SiSSetupSRCBase(srcbase
);
433 SiSSetupDSTBase(dstbase
);
435 if(!(pSiS
->CommandReg
& X_INC
)) {
439 if(!(pSiS
->CommandReg
& Y_INC
)) {
443 SiSSetupRect(width
, height
)
444 SiSSetupSRCXY(src_x
, src_y
)
445 SiSSetupDSTXY(dst_x
, dst_y
)
451 SiSSetupForSolidFill(ScrnInfoPtr pScrn
,
452 int color
, int rop
, unsigned int planemask
)
454 SISPtr pSiS
= SISPTR(pScrn
);
456 PDEBUG(ErrorF("Setup SolidFill(0x%x, 0x%x, 0x%x)\n",
457 color
, rop
, planemask
));
459 if(pSiS
->disablecolorkeycurrent
) {
460 if((CARD32
)color
== pSiS
->colorKey
) {
465 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
466 SiSSetupDSTColorDepth(pSiS
->DstColor
);
467 SiSSetupROP(XAAPatternROP
[rop
])
468 /* SiSSetupCMDFlag(PATFG) - is zero */
472 SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn
,
473 int x
, int y
, int w
, int h
)
475 SISPtr pSiS
= SISPTR(pScrn
);
478 PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
483 dstbase
= pSiS
->scrnOffset
* y
;
487 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
488 dstbase
+= HEADOFFSET
;
491 SiSSetupDSTBase(dstbase
)
494 /* Clear commandReg because Setup can be used for Rect and Trap */
495 pSiS
->CommandReg
&= ~(T_XISMAJORL
| T_XISMAJORR
|
496 T_L_X_INC
| T_L_Y_INC
|
497 T_R_X_INC
| T_R_Y_INC
|
499 SiSSetupCMDFlag(X_INC
| Y_INC
| BITBLT
)
505 /* This would work better if XAA would provide us with valid trapezoids.
506 * In fact, with small trapezoids the left and the right edge often cross
507 * each other or result in a line length of 0 which causes drawing errors
508 * (filling over whole scanline).
509 * Furthermore, I have not found out how to draw trapezoids with a height
514 SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn
, int y
, int h
,
515 int left
, int dxL
, int dyL
, int eL
,
516 int right
, int dxR
, int dyR
, int eR
)
518 SISPtr pSiS
= SISPTR(pScrn
);
526 dstbase
=pSiS
->scrnOffset
*y
;
530 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
531 dstbase
+= HEADOFFSET
;
534 SiSSetupDSTBase(dstbase
)
535 /* SiSSetupRect(w,h) */
538 SiSSetupPATFG(0xff0000) /* FOR TESTING */
541 /* Clear CommandReg because SetUp can be used for Rect and Trap */
542 pSiS
->CommandReg
&= ~(T_L_X_INC
| T_L_Y_INC
|
543 T_R_X_INC
| T_R_Y_INC
|
544 T_XISMAJORL
| T_XISMAJORR
|
547 xf86DrvMsg(0, X_INFO
, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n",
548 left
, right
, y
, h
, dxL
, dyL
, eL
, dxR
, dyR
, eR
);
550 /* Unfortunately, we must check if the right and the left edge
551 * cross each other... INCOMPLETE (line equation wrong)
554 if (dxL
== 0) kL
= 0;
555 else kL
= (float)dyL
/ (float)dxL
;
556 if (dxR
== 0) kR
= 0;
557 else kR
= (float)dyR
/ (float)dxR
;
558 xf86DrvMsg(0, X_INFO
, "kL %f kR %f!\n", kL
, kR
);
560 (!(kR
== 0 && kL
== 0)) &&
561 (!(kR
< 0 && kL
> 0)) ) {
562 xf86DrvMsg(0, X_INFO
, "Inside if (%f - %d)\n", ( kL
* ( ( ((float)right
- (float)left
) / (kL
- kR
) ) - left
) + y
), h
+y
);
563 if ( ( ( kL
* ( ( ((float)right
- (float)left
) / (kL
- kR
) ) - (float)left
) + (float)y
) < (h
+ y
) ) ) {
564 xf86DrvMsg(0, X_INFO
, "Cross detected!\n");
569 /* Determine egde angles */
570 if(dxL
< 0) { dxL
= -dxL
; }
571 else { SiSSetupCMDFlag(T_L_X_INC
) }
572 if(dxR
< 0) { dxR
= -dxR
; }
573 else { SiSSetupCMDFlag(T_R_X_INC
) }
575 /* (Y direction always positive - do this anyway) */
576 if(dyL
< 0) { dyL
= -dyL
; }
577 else { SiSSetupCMDFlag(T_L_Y_INC
) }
578 if(dyR
< 0) { dyR
= -dyR
; }
579 else { SiSSetupCMDFlag(T_R_Y_INC
) }
581 /* Determine major axis */
582 if(dxL
>= dyL
) { /* X is major axis */
583 SiSSetupCMDFlag(T_XISMAJORL
)
585 if(dxR
>= dyR
) { /* X is major axis */
586 SiSSetupCMDFlag(T_XISMAJORR
)
593 #if 0 /* Could it be that this crappy engine can only draw trapezoids up to 127 pixels high? */
598 /* Set up y, h, left, right */
600 SiSSetupLR(left
,right
)
602 /* Set up initial error term */
606 SiSSetupCMDFlag(TRAPAZOID_FILL
);
613 SiSSetupForSolidLine(ScrnInfoPtr pScrn
,
614 int color
, int rop
, unsigned int planemask
)
616 SISPtr pSiS
= SISPTR(pScrn
);
618 PDEBUG(ErrorF("Setup SolidLine(0x%x, 0x%x, 0x%x)\n",
619 color
, rop
, planemask
));
623 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
624 SiSSetupDSTColorDepth(pSiS
->DstColor
);
625 SiSSetupROP(XAAPatternROP
[rop
])
626 SiSSetupCMDFlag(PATFG
| LINE
)
630 SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn
,
631 int x1
, int y1
, int x2
, int y2
, int flags
)
633 SISPtr pSiS
= SISPTR(pScrn
);
634 long dstbase
,miny
,maxy
;
636 PDEBUG(ErrorF("Subsequent SolidLine(%d, %d, %d, %d, 0x%x)\n",
637 x1
, y1
, x2
, y2
, flags
));
640 miny
= (y1
> y2
) ? y2
: y1
;
641 maxy
= (y1
> y2
) ? y1
: y2
;
643 dstbase
= pSiS
->scrnOffset
* miny
;
648 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
649 dstbase
+= HEADOFFSET
;
652 SiSSetupDSTBase(dstbase
)
656 if(flags
& OMIT_LAST
) {
657 SiSSetupCMDFlag(NO_LAST_PIXEL
)
659 pSiS
->CommandReg
&= ~(NO_LAST_PIXEL
);
666 SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn
,
667 int x
, int y
, int len
, int dir
)
669 SISPtr pSiS
= SISPTR(pScrn
);
672 PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n",
674 len
--; /* starting point is included! */
677 if((y
>= 2048) || ((dir
!= DEGREES_0
) && ((y
+ len
) >= 2048))) {
678 dstbase
= pSiS
->scrnOffset
* y
;
682 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
683 dstbase
+= HEADOFFSET
;
686 SiSSetupDSTBase(dstbase
)
689 if(dir
== DEGREES_0
) {
690 SiSSetupX1Y1(x
+ len
, y
);
692 SiSSetupX1Y1(x
, y
+ len
);
699 SiSSetupForDashedLine(ScrnInfoPtr pScrn
,
700 int fg
, int bg
, int rop
, unsigned int planemask
,
701 int length
, unsigned char *pattern
)
703 SISPtr pSiS
= SISPTR(pScrn
);
705 PDEBUG(ErrorF("Setup DashedLine(0x%x, 0x%x, 0x%x, 0x%x, %d, 0x%x:%x)\n",
706 fg
, bg
, rop
, planemask
, length
, *(pattern
+4), *pattern
));
709 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
710 SiSSetupDSTColorDepth(pSiS
->DstColor
);
711 SiSSetupStyleLow(*pattern
)
712 SiSSetupStyleHigh(*(pattern
+4))
713 SiSSetupStylePeriod(length
-1);
714 SiSSetupROP(XAAPatternROP
[rop
])
716 SiSSetupCMDFlag(LINE
| LINE_STYLE
)
720 SiSSetupCMDFlag(TRANSPARENT
);
725 SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn
,
726 int x1
, int y1
, int x2
, int y2
,
727 int flags
, int phase
)
729 SISPtr pSiS
= SISPTR(pScrn
);
730 long dstbase
,miny
,maxy
;
732 PDEBUG(ErrorF("Subsequent DashedLine(%d,%d, %d,%d, 0x%x,0x%x)\n",
733 x1
, y1
, x2
, y2
, flags
, phase
));
736 miny
= (y1
> y2
) ? y2
: y1
;
737 maxy
= (y1
> y2
) ? y1
: y2
;
739 dstbase
= pSiS
->scrnOffset
* miny
;
744 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
745 dstbase
+= HEADOFFSET
;
748 SiSSetupDSTBase(dstbase
)
752 if(flags
& OMIT_LAST
) {
753 SiSSetupCMDFlag(NO_LAST_PIXEL
)
755 pSiS
->CommandReg
&= ~(NO_LAST_PIXEL
);
762 SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn
,
763 int patx
, int paty
, int fg
, int bg
,
764 int rop
, unsigned int planemask
)
766 SISPtr pSiS
= SISPTR(pScrn
);
768 PDEBUG(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n",
769 patx
, paty
, fg
, bg
, rop
, planemask
));
770 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
771 SiSSetupDSTColorDepth(pSiS
->DstColor
);
772 SiSSetupMONOPAT(patx
,paty
)
774 SiSSetupROP(XAAPatternROP
[rop
])
775 SiSSetupCMDFlag(PATMONO
)
779 SiSSetupCMDFlag(TRANSPARENT
)
784 SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn
,
786 int x
, int y
, int w
, int h
)
788 SISPtr pSiS
= SISPTR(pScrn
);
791 PDEBUG(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
792 patx
, paty
, x
, y
, w
, h
));
796 dstbase
= pSiS
->scrnOffset
* y
;
800 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
801 dstbase
+= HEADOFFSET
;
804 SiSSetupDSTBase(dstbase
)
807 /* Clear commandReg because Setup can be used for Rect and Trap */
808 pSiS
->CommandReg
&= ~(T_XISMAJORL
| T_XISMAJORR
|
809 T_L_X_INC
| T_L_Y_INC
|
810 T_R_X_INC
| T_R_Y_INC
|
812 SiSSetupCMDFlag(X_INC
| Y_INC
)
820 SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn
,
823 int left
, int dxL
, int dyL
, int eL
,
824 int right
, int dxR
, int dyR
, int eR
)
826 SISPtr pSiS
= SISPTR(pScrn
);
829 PDEBUG(ErrorF("Subsequent Mono8x8PatternFillTrap(%d, %d, %d - %d %d/%d %d/%d)\n",
830 y
, h
, left
, right
, dxL
, dxR
, eL
, eR
));
834 dstbase
= pSiS
->scrnOffset
* y
;
838 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
839 dstbase
+= HEADOFFSET
;
842 SiSSetupDSTBase(dstbase
)
844 /* Clear CommandReg because SetUp can be used for Rect and Trap */
845 pSiS
->CommandReg
&= ~(T_XISMAJORL
| T_XISMAJORR
|
846 T_L_X_INC
| T_L_Y_INC
|
847 T_R_X_INC
| T_R_Y_INC
|
850 if(dxL
< 0) { dxL
= -dxL
; }
851 else { SiSSetupCMDFlag(T_L_X_INC
) }
852 if(dxR
< 0) { dxR
= -dxR
; }
853 else { SiSSetupCMDFlag(T_R_X_INC
) }
855 if(dyL
< 0) { dyL
= -dyL
; }
856 else { SiSSetupCMDFlag(T_L_Y_INC
) }
857 if(dyR
< 0) { dyR
= -dyR
; }
858 else { SiSSetupCMDFlag(T_R_Y_INC
) }
860 /* Determine major axis */
861 if(dxL
>= dyL
) { /* X is major axis */
862 SiSSetupCMDFlag(T_XISMAJORL
)
864 if(dxR
>= dyR
) { /* X is major axis */
865 SiSSetupCMDFlag(T_XISMAJORR
)
869 SiSSetupLR(left
,right
)
877 SiSSetupCMDFlag(TRAPAZOID_FILL
);
886 /* TW: The following (already commented) functions have NOT been adapted for dual-head mode */
888 /* ----- CPU To Screen Color Expand (single task) ------------------------- */
890 /* This does not work. Assumingly for the same
891 * reason why STSColorExpand does not work either.
894 SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn
,
896 int rop
, unsigned int planemask
)
898 SISPtr pSiS
= SISPTR(pScrn
);
900 PDEBUG(ErrorF("Setup CPUToScreen ColorExpand(0x%x,0x%x, 0x%x,0x%x)\n",
901 fg
, bg
, rop
, planemask
));
903 /* SiSSetupDSTRect(pSiS->scrnOffset, pScrn->virtualY)*/
904 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
905 SiSSetupDSTColorDepth(pSiS
->DstColor
);
908 SiSSetupROP(XAAPatternROP
[rop
])
909 SiSSetupCMDFlag(X_INC
| Y_INC
| COLOREXP
)
911 SiSSetupCMDFlag(TRANSPARENT
)
918 SiSSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn
,
919 int x
, int y
, int w
, int h
, int skipleft
)
921 SISPtr pSiS
= SISPTR(pScrn
);
924 PDEBUG(ErrorF("Subsequent CPUToScreen ColorExpand(%d,%d, %d,%d, %d)\n",
925 x
, y
, w
, h
, skipleft
));
929 dstbase
= pSiS
->scrnOffset
* y
;
932 SiSSetupDSTBase(dstbase
)
934 /* SiSSetupSRCPitch(((w+31)&0xFFE0)/8)*/
935 SiSSetupSRCPitch((w
+7)/8)
939 pSiS
->DoColorExpand
= TRUE
;
943 /* ------ Screen To Screen Color Expand ------------------------------- */
945 /* TW: The hareware does not seem to support this the way we need it */
949 SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
951 int rop
, unsigned int planemask
)
953 SISPtr pSiS
= SISPTR(pScrn
);
955 PDEBUG(ErrorF("Setup ScreenToScreen ColorExp(0x%x,0x%x, 0x%x)\n",
958 SiSSetupDSTColorDepth(pSiS
->DstColor
)
959 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
960 SiSSetupROP(XAACopyROP
[rop
])
962 /* SiSSetupSRCXY(0,0) */
965 SiSSetupCMDFlag(TRANSPARENT
| ENCOLOREXP
| X_INC
|
969 SiSSetupCMDFlag(ENCOLOREXP
| X_INC
| Y_INC
|
975 /* TW. This method blits in a single task; this does not seem to work
976 * because the hardware does not use the source pitch as scanline
977 * offset but only to calculate pattern address from source X and Y.
978 * XAA provides the pattern bitmap with scrnOffset (displayWidth * bpp/8)
979 * offset, but this does not seem to be supported by the hardware.
983 /* For testing, these are the methods: (use only one at a time!) */
985 #undef npitch /* Normal: Use srcx/y as srcx/y, use scrnOffset as source pitch
986 * This would work if the hareware used the source pitch for
987 * incrementing the source address after each scanline - but
988 * it doesn't do this! The first line of the area is correctly
989 * color expanded, but since the source pitch is ignored and
990 * the source address not incremented correctly, the following
991 * lines are color expanded with any bit pattern that is left
992 * in the unused space of the source bitmap (which is organized
993 * with the depth of the screen framebuffer hence with a pitch
997 #undef pitchdw /* Use source pitch "displayWidth / 8" instead
998 * of scrnOffset (=displayWidth * bpp / 8)
999 * This can't work, because the pitch of the source
1000 * bitmap is scrnoffset!
1003 #define nopitch /* Calculate srcbase with srcx and srcy, set the
1004 * pitch to scrnOffset (which IS the correct pitch
1005 * for the source bitmap) and set srcx and srcy both
1007 * This would work if the hareware used the source pitch for
1008 * incrementing the source address after each scanline - but
1009 * it doesn't do this! Again: The first line of the area is
1010 * correctly color expanded, but since the source pitch is
1011 * ignored for scanline address incremention, the following
1012 * lines are not correctly color expanded.
1013 * WHATEVER I write to source pitch is ignored!
1017 SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
1018 int x
, int y
, int w
, int h
,
1019 int srcx
, int srcy
, int skipleft
)
1021 SISPtr pSiS
= SISPTR(pScrn
);
1022 long srcbase
, dstbase
;
1024 int _x0
, _y0
, _x1
, _y1
;
1027 int newsrcx
, newsrcy
;
1029 /* srcx and srcy are provided based on a scrnOffset pitch ( = displayWidth * bpp / 8 )
1030 * We recalulate srcx and srcy based on pitch = displayWidth / 8
1032 newsrcy
= ((pSiS
->scrnOffset
* srcy
) + (srcx
* ((pScrn
->bitsPerPixel
+7)/8))) /
1033 (pScrn
->displayWidth
/8);
1034 newsrcx
= ((pSiS
->scrnOffset
* srcy
) + (srcx
* ((pScrn
->bitsPerPixel
+7)/8))) %
1035 (pScrn
->displayWidth
/8);
1037 xf86DrvMsg(0, X_INFO
, "Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n",
1038 x
, y
, w
, h
, srcx
, srcy
, skipleft
);
1040 srcbase
= dstbase
= 0;
1043 if(newsrcy
>= 2048) {
1044 srcbase
= (pScrn
->displayWidth
/ 8) * newsrcy
;
1049 srcbase
= (pSiS
->scrnOffset
* srcy
) + (srcx
* ((pScrn
->bitsPerPixel
+7)/8));
1053 srcbase
= pSiS
->scrnOffset
* srcy
;
1058 dstbase
= pSiS
->scrnOffset
* y
;
1062 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
1063 srcbase
+= HEADOFFSET
;
1064 dstbase
+= HEADOFFSET
;
1067 SiSSetupSRCBase(srcbase
)
1068 SiSSetupDSTBase(dstbase
)
1071 SiSSetupSRCPitch(pScrn
->displayWidth
/8)
1074 SiSSetupSRCPitch(pSiS
->scrnOffset
)
1075 /* SiSSetupSRCPitch(100) */ /* For test - has NO effect WHATSOEVER */
1078 SiSSetupSRCPitch(pSiS
->scrnOffset
)
1083 #if 0 /* How do I implement the offset? Not this way, that's for sure.. */
1089 SiSSetupClipLT(_x0
, _y0
);
1090 SiSSetupClipRB(_x1
, _y1
);
1091 SiSSetupCMDFlag(CLIPENABLE
);
1095 SiSSetupSRCXY(newsrcx
, newsrcy
)
1101 SiSSetupSRCXY(srcx
, srcy
)
1110 /* ----- CPU To Screen Color Expand (scanline-wise) ----------------- */
1112 /* We do it using the indirect method */
1115 SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
1116 int fg
, int bg
, int rop
, unsigned int planemask
)
1118 SISPtr pSiS
=SISPTR(pScrn
);
1120 /* TW: Make sure that current CPU-driven BitBlt buffer stage is 0
1121 * This is required!!! (Otherwise -> drawing errors)
1123 while((MMIO_IN16(pSiS
->IOBase
, 0x8242) & 0x1F00) != 0) {} /* WDR: == 0x10 */
1126 SiSSetupROP(XAACopyROP
[rop
]);
1128 SiSSetupDSTRect(pSiS
->scrnOffset
, -1);
1129 SiSSetupDSTColorDepth(pSiS
->DstColor
);
1131 SiSSetupCMDFlag(TRANSPARENT
|
1137 SiSSetupCMDFlag(ENCOLOREXP
|
1145 SiSSubsequentScanlineCPUToScreenColorExpandFill(
1146 ScrnInfoPtr pScrn
, int x
, int y
, int w
,
1147 int h
, int skipleft
)
1149 SISPtr pSiS
= SISPTR(pScrn
);
1150 int _x0
, _y0
, _x1
, _y1
;
1154 if((y
>= 2048) || ((y
+ h
) >= 2048)) {
1155 dstbase
= pSiS
->scrnOffset
* y
;
1159 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
1160 dstbase
+= HEADOFFSET
;
1164 /* TW: Wait until there is no color expansion command in queue
1165 * (This solves the OpenOffice.org window-move bug)
1166 * Added Idle-check - bit 23 is set sometimes, although
1167 * engine is actually idle!
1168 * Update: Bit 23 is not reliable. After heavy 3D engine
1169 * action, this bit never gets cleared again. So do
1172 if((MMIO_IN16(pSiS
->IOBase
, 0x8242) & 0xe000) != 0xe000) {
1173 /* while ((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x0080) != 0) {} */
1177 SiSSetupDSTBase(dstbase
)
1184 SiSSetupClipLT(_x0
, _y0
);
1185 SiSSetupClipRB(_x1
, _y1
);
1186 SiSSetupCMDFlag(CLIPENABLE
);
1188 pSiS
->CommandReg
&= (~CLIPENABLE
);
1192 SiSSetupSRCPitch(((((w
+7)/8)+3) >> 2) * 4);
1198 SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn
, int bufno
)
1200 SISPtr pSiS
=SISPTR(pScrn
);
1202 int newhead
,bltbufstage
,newtail
;
1206 cbo
= pSiS
->ColorExpandBufferScreenOffset
[bufno
];
1208 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
1213 /* TW: Wait until there is no color expansion command in queue
1214 * (This solves the GTK-big-font bug)
1215 * Added Idle-check - bit 23 is set sometimes, although
1216 * engine is actually idle!
1217 * Update: Bit 23 is not reliable. After heavy 3D engine
1218 * action, this bit never gets cleared again. So do
1221 if((MMIO_IN16(pSiS
->IOBase
, 0x8242) & 0xe000) != 0xe000) {
1222 /* while ((MMIO_IN16(pSiS->IOBase, 0x8242) & 0x0080) != 0) {} */
1226 SiSSetupSRCBase(cbo
);
1228 SiSSetupDSTXY(pSiS
->xcurrent
, pSiS
->ycurrent
);
1234 if(pSiS
->VGAEngine
== SIS_530_VGA
) {
1235 while(MMIO_IN8(pSiS
->IOBase
, 0x8242) & 0x80) {}