2 /* $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/sis/sis300_accel.c,v 1.6 2004/08/04 15:46:33 twini Exp $ */
4 * 2D Acceleration for SiS 530, 620, 300, 540, 630, 730.
6 * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1) Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2) Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3) The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * Authors: Thomas Winischhofer <thomas@winischhofer.net>
31 * Can-Ru Yeou, SiS Inc.
40 #include "xf86_OSproc.h"
41 #include "xf86_ansic.h"
42 #include "xf86PciInfo.h"
49 #include "sis300_accel.h"
52 /* TW: This is the offset to the memory for each head */
53 #define HEADOFFSET (pSiS->dhmOffset)
56 #undef STSCE /* Use/Don't use ScreenToScreenColorExpand - does not work */
58 #undef TRAP /* Use/Don't use Trapezoid Fills - does not work - XAA provides
59 * illegal trapezoid data (left and right edges cross each other
60 * sometimes) which causes drawing errors. Further, I have not found
61 * out how to draw polygones with a height greater than 127...
64 static void SiSInitializeAccelerator(ScrnInfoPtr pScrn
);
65 static void SiSSync(ScrnInfoPtr pScrn
);
66 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn
,
67 int xdir
, int ydir
, int rop
,
68 unsigned int planemask
, int trans_color
);
69 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn
,
70 int x1
, int y1
, int x2
, int y2
,
71 int width
, int height
);
72 static void SiSSetupForSolidFill(ScrnInfoPtr pScrn
, int color
,
73 int rop
, unsigned int planemask
);
74 static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn
,
75 int x
, int y
, int w
, int h
);
77 static void SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn
, int y
, int h
,
78 int left
, int dxL
, int dyL
, int eL
,
79 int right
, int dxR
, int dyR
, int eR
);
81 static void SiSSetupForSolidLine(ScrnInfoPtr pScrn
, int color
,
82 int rop
, unsigned int planemask
);
83 static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn
, int x1
,
84 int y1
, int x2
, int y2
, int flags
);
85 static void SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn
,
86 int x
, int y
, int len
, int dir
);
87 static void SiSSetupForDashedLine(ScrnInfoPtr pScrn
,
88 int fg
, int bg
, int rop
, unsigned int planemask
,
89 int length
, unsigned char *pattern
);
90 static void SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn
,
91 int x1
, int y1
, int x2
, int y2
,
92 int flags
, int phase
);
93 static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn
,
94 int patx
, int paty
, int fg
, int bg
,
95 int rop
, unsigned int planemask
);
96 static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn
,
98 int x
, int y
, int w
, int h
);
100 static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn
,
103 int left
, int dxL
, int dyL
, int eL
,
104 int right
, int dxR
, int dyR
, int eR
);
107 static void SiSSetupForColorPatternFill(ScrnInfoPtr pScrn
,
108 int patx
, int paty
, int rop
,
109 unsigned int planemask
,
111 static void SiSSubsequentColorPatternFill(ScrnInfoPtr pScrn
,
113 int x
, int y
, int w
, int h
);
116 static void SiSSetupForCPUToScreenColorExpand(ScrnInfoPtr pScrn
,
118 int rop
, unsigned int planemask
);
119 static void SiSSubsequentCPUToScreenColorExpand(ScrnInfoPtr pScrn
,
120 int x
, int y
, int w
, int h
, int skipleft
);
123 static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
125 int rop
, unsigned int planemask
);
126 static void SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
127 int x
, int y
, int w
, int h
,
128 int srcx
, int srcy
, int skipleft
);
130 static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
131 int fg
, int bg
, int rop
,
132 unsigned int planemask
);
133 static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
134 int x
, int y
, int w
, int h
,
136 static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn
, int bufno
);
139 static void SiSRestoreAccelState(ScrnInfoPtr pScrn
);
142 extern unsigned char SiSGetCopyROP(int rop
);
143 extern unsigned char SiSGetPatternROP(int rop
);
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 /* 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 /* 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
;
257 /* per-scanline color expansion (using indirect method) */
258 if(pSiS
->VGAEngine
== SIS_530_VGA
) {
259 pSiS
->ColorExpandBufferNumber
= 4;
260 pSiS
->ColorExpandBufferCountMask
= 0x03;
262 pSiS
->ColorExpandBufferNumber
= 16;
263 pSiS
->ColorExpandBufferCountMask
= 0x0F;
265 pSiS
->PerColorExpandBufferSize
= ((pScrn
->virtualX
+ 31)/32) * 4;
266 infoPtr
->NumScanlineColorExpandBuffers
= pSiS
->ColorExpandBufferNumber
;
267 infoPtr
->ScanlineColorExpandBuffers
= (unsigned char **)&pSiS
->ColorExpandBufferAddr
[0];
269 infoPtr
->SetupForScanlineCPUToScreenColorExpandFill
=
270 SiSSetupForScanlineCPUToScreenColorExpandFill
;
271 infoPtr
->SubsequentScanlineCPUToScreenColorExpandFill
=
272 SiSSubsequentScanlineCPUToScreenColorExpandFill
;
273 infoPtr
->SubsequentColorExpandScanline
=
274 SiSSubsequentColorExpandScanline
;
275 infoPtr
->ScanlineCPUToScreenColorExpandFillFlags
= NO_PLANEMASK
|
276 CPU_TRANSFER_PAD_DWORD
|
278 BIT_ORDER_IN_BYTE_MSBFIRST
|
281 xf86DrvMsg(pScrn
->scrnIndex
, X_WARNING
,
282 "Virtual screen width too large for accelerator engine\n");
283 xf86DrvMsg(pScrn
->scrnIndex
, X_WARNING
,
284 "2D acceleration and Xv disabled\n");
285 pSiS
->NoXvideo
= TRUE
;
289 if(pSiS
->DualHeadMode
) {
290 infoPtr
->RestoreAccelState
= SiSRestoreAccelState
;
294 /* init Frame Buffer Manager */
295 topFB
= pSiS
->maxxfbmem
;
297 reservedFbSize
= pSiS
->ColorExpandBufferNumber
* pSiS
->PerColorExpandBufferSize
;
299 UsableFbSize
= topFB
- reservedFbSize
;
301 /* Layout: (Sizes do not reflect correct proportions)
302 * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
303 * UsableFbSize ColorExpandBuffers | DRI-Heap | HWCursor TurboQueue 300/310/325 series
304 * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~|
305 * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor 530/620
309 AvailBufBase
= pSiS
->FbBase
+ UsableFbSize
;
310 for(i
= 0; i
< pSiS
->ColorExpandBufferNumber
; i
++) {
311 pSiS
->ColorExpandBufferAddr
[i
] = AvailBufBase
+
312 i
* pSiS
->PerColorExpandBufferSize
;
313 pSiS
->ColorExpandBufferScreenOffset
[i
] = UsableFbSize
+
314 i
* pSiS
->PerColorExpandBufferSize
;
318 Avail
.x2
= pScrn
->displayWidth
;
319 Avail
.y2
= (UsableFbSize
/ (pScrn
->displayWidth
* pScrn
->bitsPerPixel
/8)) - 1;
321 if(Avail
.y2
< 0) Avail
.y2
= 32767;
323 if(Avail
.y2
< pScrn
->currentMode
->VDisplay
) {
324 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
325 "Not enough video RAM for accelerator. At least "
326 "%dKB needed, %ldKB available\n",
327 ((((pScrn
->displayWidth
* pScrn
->bitsPerPixel
/8) /* TW: +8 for make it sure */
328 * pScrn
->currentMode
->VDisplay
) + reservedFbSize
) / 1024) + 8,
329 pSiS
->maxxfbmem
/1024);
330 pSiS
->NoAccel
= TRUE
;
331 pSiS
->NoXvideo
= TRUE
;
332 XAADestroyInfoRec(pSiS
->AccelInfoPtr
);
333 pSiS
->AccelInfoPtr
= NULL
;
337 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
338 "Frame Buffer From (%d,%d) To (%d,%d)\n",
339 Avail
.x1
, Avail
.y1
, Avail
.x2
, Avail
.y2
);
341 xf86InitFBManager(pScreen
, &Avail
);
343 return(XAAInit(pScreen
, infoPtr
));
348 SiSSync(ScrnInfoPtr pScrn
)
350 SISPtr pSiS
= SISPTR(pScrn
);
352 PDEBUG(ErrorF("SiSSync()\n"));
354 pSiS
->DoColorExpand
= FALSE
;
360 SiSRestoreAccelState(ScrnInfoPtr pScrn
)
362 SISPtr pSiS
= SISPTR(pScrn
);
364 /* We don't need to do anything special here; forcing the
365 * other head to re-read the CmdQueLen is not necessary:
366 * After the Sync in RestoreAccelState(), the real queue
367 * length is always larger than (or at least equal to)
368 * the amount stored in CmdQueueLen of the other head,
369 * so the only thing that might happen is one unnecessary
370 * Sync on the other head. I think we can live with that.
372 pSiS
->DoColorExpand
= FALSE
;
377 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn
,
378 int xdir
, int ydir
, int rop
,
379 unsigned int planemask
, int trans_color
)
381 SISPtr pSiS
= SISPTR(pScrn
);
383 PDEBUG(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
384 xdir
, ydir
, rop
, planemask
, trans_color
));
386 SiSSetupDSTColorDepth(pSiS
->DstColor
);
387 SiSSetupSRCPitch(pSiS
->scrnOffset
)
388 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
390 if(trans_color
!= -1) {
392 SiSSetupSRCTrans(trans_color
)
393 SiSSetupCMDFlag(TRANSPARENT_BITBLT
)
395 SiSSetupROP(SiSGetCopyROP(rop
))
398 SiSSetupCMDFlag(X_INC
)
401 SiSSetupCMDFlag(Y_INC
)
405 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn
,
406 int src_x
, int src_y
, int dst_x
, int dst_y
,
407 int width
, int height
)
409 SISPtr pSiS
= SISPTR(pScrn
);
410 CARD32 srcbase
, dstbase
;
412 PDEBUG(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
413 src_x
, src_y
, dst_x
, dst_y
, width
, height
));
415 srcbase
= dstbase
= 0;
417 srcbase
= pSiS
->scrnOffset
* src_y
;
420 if((dst_y
>= pScrn
->virtualY
) || (dst_y
>= 2048)) {
421 dstbase
= pSiS
->scrnOffset
* dst_y
;
425 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
426 srcbase
+= HEADOFFSET
;
427 dstbase
+= HEADOFFSET
;
430 SiSSetupSRCBase(srcbase
);
431 SiSSetupDSTBase(dstbase
);
433 if(!(pSiS
->CommandReg
& X_INC
)) {
437 if(!(pSiS
->CommandReg
& Y_INC
)) {
441 SiSSetupRect(width
, height
)
442 SiSSetupSRCXY(src_x
, src_y
)
443 SiSSetupDSTXY(dst_x
, dst_y
)
449 SiSSetupForSolidFill(ScrnInfoPtr pScrn
,
450 int color
, int rop
, unsigned int planemask
)
452 SISPtr pSiS
= SISPTR(pScrn
);
454 PDEBUG(ErrorF("Setup SolidFill(0x%x, 0x%x, 0x%x)\n",
455 color
, rop
, planemask
));
457 if(pSiS
->disablecolorkeycurrent
) {
458 if((CARD32
)color
== pSiS
->colorKey
) {
463 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
464 SiSSetupDSTColorDepth(pSiS
->DstColor
);
465 SiSSetupROP(SiSGetPatternROP(rop
))
466 /* SiSSetupCMDFlag(PATFG) - is zero */
470 SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn
,
471 int x
, int y
, int w
, int h
)
473 SISPtr pSiS
= SISPTR(pScrn
);
476 PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
481 dstbase
= pSiS
->scrnOffset
* y
;
485 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
486 dstbase
+= HEADOFFSET
;
489 SiSSetupDSTBase(dstbase
)
492 /* Clear commandReg because Setup can be used for Rect and Trap */
493 pSiS
->CommandReg
&= ~(T_XISMAJORL
| T_XISMAJORR
|
494 T_L_X_INC
| T_L_Y_INC
|
495 T_R_X_INC
| T_R_Y_INC
|
497 SiSSetupCMDFlag(X_INC
| Y_INC
| BITBLT
)
503 /* This would work better if XAA would provide us with valid trapezoids.
504 * In fact, with small trapezoids the left and the right edge often cross
505 * each other or result in a line length of 0 which causes drawing errors
506 * (filling over whole scanline).
507 * Furthermore, I have not found out how to draw trapezoids with a height
512 SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn
, int y
, int h
,
513 int left
, int dxL
, int dyL
, int eL
,
514 int right
, int dxR
, int dyR
, int eR
)
516 SISPtr pSiS
= SISPTR(pScrn
);
524 dstbase
=pSiS
->scrnOffset
*y
;
528 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
529 dstbase
+= HEADOFFSET
;
532 SiSSetupDSTBase(dstbase
)
533 /* SiSSetupRect(w,h) */
536 SiSSetupPATFG(0xff0000) /* FOR TESTING */
539 /* Clear CommandReg because SetUp can be used for Rect and Trap */
540 pSiS
->CommandReg
&= ~(T_L_X_INC
| T_L_Y_INC
|
541 T_R_X_INC
| T_R_Y_INC
|
542 T_XISMAJORL
| T_XISMAJORR
|
545 xf86DrvMsg(0, X_INFO
, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n",
546 left
, right
, y
, h
, dxL
, dyL
, eL
, dxR
, dyR
, eR
);
548 /* Unfortunately, we must check if the right and the left edge
549 * cross each other... INCOMPLETE (line equation wrong)
552 if (dxL
== 0) kL
= 0;
553 else kL
= (float)dyL
/ (float)dxL
;
554 if (dxR
== 0) kR
= 0;
555 else kR
= (float)dyR
/ (float)dxR
;
556 xf86DrvMsg(0, X_INFO
, "kL %f kR %f!\n", kL
, kR
);
558 (!(kR
== 0 && kL
== 0)) &&
559 (!(kR
< 0 && kL
> 0)) ) {
560 xf86DrvMsg(0, X_INFO
, "Inside if (%f - %d)\n", ( kL
* ( ( ((float)right
- (float)left
) / (kL
- kR
) ) - left
) + y
), h
+y
);
561 if ( ( ( kL
* ( ( ((float)right
- (float)left
) / (kL
- kR
) ) - (float)left
) + (float)y
) < (h
+ y
) ) ) {
562 xf86DrvMsg(0, X_INFO
, "Cross detected!\n");
567 /* Determine egde angles */
568 if(dxL
< 0) { dxL
= -dxL
; }
569 else { SiSSetupCMDFlag(T_L_X_INC
) }
570 if(dxR
< 0) { dxR
= -dxR
; }
571 else { SiSSetupCMDFlag(T_R_X_INC
) }
573 /* (Y direction always positive - do this anyway) */
574 if(dyL
< 0) { dyL
= -dyL
; }
575 else { SiSSetupCMDFlag(T_L_Y_INC
) }
576 if(dyR
< 0) { dyR
= -dyR
; }
577 else { SiSSetupCMDFlag(T_R_Y_INC
) }
579 /* Determine major axis */
580 if(dxL
>= dyL
) { /* X is major axis */
581 SiSSetupCMDFlag(T_XISMAJORL
)
583 if(dxR
>= dyR
) { /* X is major axis */
584 SiSSetupCMDFlag(T_XISMAJORR
)
591 #if 0 /* Could it be that this crappy engine can only draw trapezoids up to 127 pixels high? */
596 /* Set up y, h, left, right */
598 SiSSetupLR(left
,right
)
600 /* Set up initial error term */
604 SiSSetupCMDFlag(TRAPAZOID_FILL
);
611 SiSSetupForSolidLine(ScrnInfoPtr pScrn
,
612 int color
, int rop
, unsigned int planemask
)
614 SISPtr pSiS
= SISPTR(pScrn
);
616 PDEBUG(ErrorF("Setup SolidLine(0x%x, 0x%x, 0x%x)\n",
617 color
, rop
, planemask
));
621 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
622 SiSSetupDSTColorDepth(pSiS
->DstColor
);
623 SiSSetupROP(SiSGetPatternROP(rop
))
624 SiSSetupCMDFlag(PATFG
| LINE
)
628 SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn
,
629 int x1
, int y1
, int x2
, int y2
, int flags
)
631 SISPtr pSiS
= SISPTR(pScrn
);
635 PDEBUG(ErrorF("Subsequent SolidLine(%d, %d, %d, %d, 0x%x)\n",
636 x1
, y1
, x2
, y2
, flags
));
639 miny
= (y1
> y2
) ? y2
: y1
;
640 maxy
= (y1
> y2
) ? y1
: y2
;
642 dstbase
= pSiS
->scrnOffset
* miny
;
647 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
648 dstbase
+= HEADOFFSET
;
651 SiSSetupDSTBase(dstbase
)
655 if(flags
& OMIT_LAST
) {
656 SiSSetupCMDFlag(NO_LAST_PIXEL
)
658 pSiS
->CommandReg
&= ~(NO_LAST_PIXEL
);
665 SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn
,
666 int x
, int y
, int len
, int dir
)
668 SISPtr pSiS
= SISPTR(pScrn
);
671 PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n",
673 len
--; /* starting point is included! */
676 if((y
>= 2048) || ((dir
!= DEGREES_0
) && ((y
+ len
) >= 2048))) {
677 dstbase
= pSiS
->scrnOffset
* y
;
681 if(pSiS
->VGAEngine
!= SIS_530_VGA
) {
682 dstbase
+= HEADOFFSET
;
685 SiSSetupDSTBase(dstbase
)
688 if(dir
== DEGREES_0
) {
689 SiSSetupX1Y1(x
+ len
, y
);
691 SiSSetupX1Y1(x
, y
+ len
);
698 SiSSetupForDashedLine(ScrnInfoPtr pScrn
,
699 int fg
, int bg
, int rop
, unsigned int planemask
,
700 int length
, unsigned char *pattern
)
702 SISPtr pSiS
= SISPTR(pScrn
);
704 PDEBUG(ErrorF("Setup DashedLine(0x%x, 0x%x, 0x%x, 0x%x, %d, 0x%x:%x)\n",
705 fg
, bg
, rop
, planemask
, length
, *(pattern
+4), *pattern
));
708 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
709 SiSSetupDSTColorDepth(pSiS
->DstColor
);
710 SiSSetupStyleLow(*pattern
)
711 SiSSetupStyleHigh(*(pattern
+4))
712 SiSSetupStylePeriod(length
-1);
713 SiSSetupROP(SiSGetPatternROP(rop
))
715 SiSSetupCMDFlag(LINE
| LINE_STYLE
)
719 SiSSetupCMDFlag(TRANSPARENT
);
724 SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn
,
725 int x1
, int y1
, int x2
, int y2
,
726 int flags
, int phase
)
728 SISPtr pSiS
= SISPTR(pScrn
);
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(SiSGetPatternROP(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 /* 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(SiSGetPatternROP(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 /* 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(SiSGetCopyROP(rop
))
962 /* SiSSetupSRCXY(0,0) */
965 SiSSetupCMDFlag(TRANSPARENT
| ENCOLOREXP
| X_INC
|
969 SiSSetupCMDFlag(ENCOLOREXP
| X_INC
| Y_INC
|
975 /* 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 CARD32 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(SiSGetCopyROP(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 /* 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 /* 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) {}