1 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c,v 1.37 2004/01/27 11:58:27 twini Exp $ */
3 * 2D Acceleration for SiS 315 and 330 series
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.
33 * Author: Thomas Winischhofer <thomas@winischhofer.net>
35 * 2003/08/18: Rewritten for using VRAM command queue
40 #include "xf86_OSproc.h"
41 #include "xf86_ansic.h"
42 #include "xf86PciInfo.h"
50 #include "sis310_accel.h"
57 #define HEADOFFSET (pSiS->dhmOffset)
60 #undef TRAP /* Use/Don't use Trapezoid Fills
61 * DOES NOT WORK. XAA sometimes provides illegal
62 * trapezoid data (left and right edges cross each
63 * other) which causes drawing errors. Since
64 * checking the trapezoid for such a case is very
65 * time-intensive, it is faster to let it be done
66 * by the generic polygon functions.
67 * Does not work on 330 series at all, hangs the engine.
68 * Even with correct trapezoids, this is slower than
69 * doing it by the CPU.
72 #undef CTSCE /* Use/Don't use CPUToScreenColorExpand. Disabled
73 * because it is slower than doing it by the CPU.
74 * Indirect mode does not work in VRAM queue mode.
75 * Does not work on 330 series (even in MMIO mode).
77 #undef CTSCE_DIRECT /* Use direct method - This works (on both 315 and 330 at
78 * least in VRAM queue mode) but we don't use this either,
79 * because it's slower than doing it by the CPU. (Using it
80 * would require defining CTSCE)
83 #undef STSCE /* Use/Don't use ScreenToScreenColorExpand - does not work,
87 #define INCL_RENDER /* Use/Don't use RENDER extension acceleration */
92 #include "dixstruct.h"
96 /* Accelerator functions */
97 static void SiSInitializeAccelerator(ScrnInfoPtr pScrn
);
98 static void SiSSync(ScrnInfoPtr pScrn
);
99 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn
,
100 int xdir
, int ydir
, int rop
,
101 unsigned int planemask
, int trans_color
);
102 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn
,
103 int x1
, int y1
, int x2
, int y2
,
104 int width
, int height
);
105 static void SiSSetupForSolidFill(ScrnInfoPtr pScrn
, int color
,
106 int rop
, unsigned int planemask
);
107 static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn
,
108 int x
, int y
, int w
, int h
);
110 static void SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn
, int y
, int h
,
111 int left
, int dxL
, int dyL
, int eL
,
112 int right
, int dxR
, int dyR
, int eR
);
114 static void SiSSetupForSolidLine(ScrnInfoPtr pScrn
, int color
,
115 int rop
, unsigned int planemask
);
116 static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn
, int x1
,
117 int y1
, int x2
, int y2
, int flags
);
118 static void SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn
,
119 int x
, int y
, int len
, int dir
);
120 static void SiSSetupForDashedLine(ScrnInfoPtr pScrn
,
121 int fg
, int bg
, int rop
, unsigned int planemask
,
122 int length
, unsigned char *pattern
);
123 static void SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn
,
124 int x1
, int y1
, int x2
, int y2
,
125 int flags
, int phase
);
126 static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn
,
127 int patx
, int paty
, int fg
, int bg
,
128 int rop
, unsigned int planemask
);
129 static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn
,
131 int x
, int y
, int w
, int h
);
133 static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn
,
136 int left
, int dxL
, int dyL
, int eL
,
137 int right
, int dxR
, int dyR
, int eR
);
140 static void SiSSetupForColor8x8PatternFill(ScrnInfoPtr pScrn
,
141 int patternx
, int patterny
,
142 int rop
, unsigned int planemask
, int trans_col
);
143 static void SiSSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn
,
144 int patternx
, int patterny
, int x
, int y
,
148 static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
150 int rop
, unsigned int planemask
);
151 static void SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
152 int x
, int y
, int w
, int h
,
153 int srcx
, int srcy
, int skipleft
);
157 static void SiSSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
158 int fg
, int bg
, int rop
,
159 unsigned int planemask
);
160 static void SiSSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
161 int x
, int y
, int w
, int h
,
164 static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
165 int fg
, int bg
, int rop
,
166 unsigned int planemask
);
167 static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
168 int x
, int y
, int w
, int h
,
170 static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn
, int bufno
);
175 extern Bool
SiSSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn
,
176 int op
, CARD16 red
, CARD16 green
,
177 CARD16 blue
, CARD16 alpha
,
178 int alphaType
, CARD8
*alphaPtr
,
179 int alphaPitch
, int width
,
180 int height
, int flags
);
182 extern Bool
SiSSetupForCPUToScreenTexture( ScrnInfoPtr pScrn
,
183 int op
, int texType
, CARD8
*texPtr
,
184 int texPitch
, int width
,
185 int height
, int flags
);
187 extern void SiSSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn
,
190 int width
, int height
);
192 extern CARD32 SiSAlphaTextureFormats
[3];
193 extern CARD32 SiSTextureFormats
[2];
194 CARD32 SiSAlphaTextureFormats
[3] = { PICT_a8
, PICT_a8r8g8b8
, 0 };
195 CARD32 SiSTextureFormats
[2] = { PICT_a8r8g8b8
, 0 };
200 static void SiSRestoreAccelState(ScrnInfoPtr pScrn
);
204 SiSInitializeAccelerator(ScrnInfoPtr pScrn
)
206 SISPtr pSiS
= SISPTR(pScrn
);
208 pSiS
->DoColorExpand
= FALSE
;
209 pSiS
->alphaBlitBusy
= FALSE
;
211 if(pSiS
->ChipFlags
& SiSCF_Integrated
) {
214 CmdQueLen
= ((128 * 1024) / 4) - 64;
220 SiS315AccelInit(ScreenPtr pScreen
)
222 XAAInfoRecPtr infoPtr
;
223 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
224 SISPtr pSiS
= SISPTR(pScrn
);
230 SISEntPtr pSiSEnt
= NULL
;
233 unsigned char *AvailBufBase
;
239 pSiS
->AccelInfoPtr
= infoPtr
= XAACreateInfoRec();
240 if(!infoPtr
) return FALSE
;
242 SiSInitializeAccelerator(pScrn
);
244 infoPtr
->Flags
= LINEAR_FRAMEBUFFER
|
249 infoPtr
->Sync
= SiSSync
;
251 if((pScrn
->bitsPerPixel
!= 8) && (pScrn
->bitsPerPixel
!= 16) &&
252 (pScrn
->bitsPerPixel
!= 32))
256 pSiSEnt
= pSiS
->entityPrivate
;
260 infoPtr
->SetupForScreenToScreenCopy
= SiSSetupForScreenToScreenCopy
;
261 infoPtr
->SubsequentScreenToScreenCopy
= SiSSubsequentScreenToScreenCopy
;
262 infoPtr
->ScreenToScreenCopyFlags
= NO_PLANEMASK
| TRANSPARENCY_GXCOPY_ONLY
;
265 infoPtr
->SetupForSolidFill
= SiSSetupForSolidFill
;
266 infoPtr
->SubsequentSolidFillRect
= SiSSubsequentSolidFillRect
;
268 if((pSiS
->Chipset
!= PCI_CHIP_SIS660
) &&
269 (pSiS
->Chipset
!= PCI_CHIP_SIS330
)) {
270 infoPtr
->SubsequentSolidFillTrap
= SiSSubsequentSolidFillTrap
;
273 infoPtr
->SolidFillFlags
= NO_PLANEMASK
;
276 infoPtr
->SetupForSolidLine
= SiSSetupForSolidLine
;
277 infoPtr
->SubsequentSolidTwoPointLine
= SiSSubsequentSolidTwoPointLine
;
278 infoPtr
->SubsequentSolidHorVertLine
= SiSSubsequentSolidHorzVertLine
;
279 infoPtr
->SolidLineFlags
= NO_PLANEMASK
;
282 infoPtr
->SetupForDashedLine
= SiSSetupForDashedLine
;
283 infoPtr
->SubsequentDashedTwoPointLine
= SiSSubsequentDashedTwoPointLine
;
284 infoPtr
->DashPatternMaxLength
= 64;
285 infoPtr
->DashedLineFlags
= NO_PLANEMASK
|
286 LINE_PATTERN_MSBFIRST_LSBJUSTIFIED
;
288 /* 8x8 mono pattern fill */
289 infoPtr
->SetupForMono8x8PatternFill
= SiSSetupForMonoPatternFill
;
290 infoPtr
->SubsequentMono8x8PatternFillRect
= SiSSubsequentMonoPatternFill
;
292 if((pSiS
->Chipset
!= PCI_CHIP_SIS660
) &&
293 (pSiS
->Chipset
!= PCI_CHIP_SIS330
)) {
294 infoPtr
->SubsequentMono8x8PatternFillTrap
= SiSSubsequentMonoPatternFillTrap
;
297 infoPtr
->Mono8x8PatternFillFlags
= NO_PLANEMASK
|
298 HARDWARE_PATTERN_SCREEN_ORIGIN
|
299 HARDWARE_PATTERN_PROGRAMMED_BITS
|
300 BIT_ORDER_IN_BYTE_MSBFIRST
;
303 /* 8x8 color pattern fill (MMIO support not implemented) */
304 infoPtr
->SetupForColor8x8PatternFill
= SiSSetupForColor8x8PatternFill
;
305 infoPtr
->SubsequentColor8x8PatternFillRect
= SiSSubsequentColor8x8PatternFillRect
;
306 infoPtr
->Color8x8PatternFillFlags
= NO_PLANEMASK
|
307 HARDWARE_PATTERN_SCREEN_ORIGIN
|
312 /* Screen To Screen Color Expand */
313 /* The hardware does not support this the way we need it, because
314 * the mono-bitmap is not provided with a pitch of (width), but
315 * with a pitch of scrnOffset (= width * bpp / 8).
317 infoPtr
->SetupForScreenToScreenColorExpandFill
=
318 SiSSetupForScreenToScreenColorExpand
;
319 infoPtr
->SubsequentScreenToScreenColorExpandFill
=
320 SiSSubsequentScreenToScreenColorExpand
;
321 infoPtr
->ScreenToScreenColorExpandFillFlags
= NO_PLANEMASK
|
322 BIT_ORDER_IN_BYTE_MSBFIRST
;
327 /* CPU color expansion - direct method
329 * We somewhat fake this function here in the following way:
330 * XAA copies its mono-bitmap data not into an aperture, but
331 * into our video RAM buffer. We then do a ScreenToScreen
333 * Unfortunately, XAA sends the data to the aperture AFTER
334 * the call to Subsequent(), therefore we do not execute the
335 * command in Subsequent, but in the following call to Sync().
336 * (Hence, the SYNC_AFTER_COLOR_EXPAND flag MUST BE SET)
338 * This is slower than doing it by the CPU.
341 pSiS
->ColorExpandBufferNumber
= 48;
342 pSiS
->PerColorExpandBufferSize
= ((pScrn
->virtualX
+ 31)/32) * 4;
343 infoPtr
->SetupForCPUToScreenColorExpandFill
= SiSSetupForCPUToScreenColorExpandFill
;
344 infoPtr
->SubsequentCPUToScreenColorExpandFill
= SiSSubsequentCPUToScreenColorExpandFill
;
345 infoPtr
->ColorExpandRange
= pSiS
->ColorExpandBufferNumber
* pSiS
->PerColorExpandBufferSize
;
346 infoPtr
->CPUToScreenColorExpandFillFlags
=
348 CPU_TRANSFER_PAD_DWORD
|
350 BIT_ORDER_IN_BYTE_MSBFIRST
|
352 SYNC_AFTER_COLOR_EXPAND
;
354 /* CPU color expansion - per-scanline / indirect method
356 * SLOW! SLOWER! SLOWEST!
358 * Does not work on 330 series, hangs the engine (both VRAM and MMIO).
359 * Does not work in VRAM queue mode.
362 if((pSiS
->Chipset
!= PCI_CHIP_SIS650
) &&
363 (pSiS
->Chipset
!= PCI_CHIP_SIS660
) &&
364 (pSiS
->Chipset
!= PCI_CHIP_SIS330
)) {
365 pSiS
->ColorExpandBufferNumber
= 16;
366 pSiS
->ColorExpandBufferCountMask
= 0x0F;
367 pSiS
->PerColorExpandBufferSize
= ((pScrn
->virtualX
+ 31)/32) * 4;
368 infoPtr
->NumScanlineColorExpandBuffers
= pSiS
->ColorExpandBufferNumber
;
369 infoPtr
->ScanlineColorExpandBuffers
= (unsigned char **)&pSiS
->ColorExpandBufferAddr
[0];
370 infoPtr
->SetupForScanlineCPUToScreenColorExpandFill
= SiSSetupForScanlineCPUToScreenColorExpandFill
;
371 infoPtr
->SubsequentScanlineCPUToScreenColorExpandFill
= SiSSubsequentScanlineCPUToScreenColorExpandFill
;
372 infoPtr
->SubsequentColorExpandScanline
= SiSSubsequentColorExpandScanline
;
373 infoPtr
->ScanlineCPUToScreenColorExpandFillFlags
=
375 CPU_TRANSFER_PAD_DWORD
|
377 BIT_ORDER_IN_BYTE_MSBFIRST
|
381 pSiS
->ColorExpandBufferNumber
= 0;
382 pSiS
->PerColorExpandBufferSize
= 0;
388 pSiS
->ColorExpandBufferNumber
= 0;
389 pSiS
->PerColorExpandBufferSize
= 0;
392 pSiS
->RenderAccelArray
= NULL
;
397 if(((pScrn
->bitsPerPixel
== 16) || (pScrn
->bitsPerPixel
== 32)) && pSiS
->doRender
) {
400 if(pSiSEnt
) pSiS
->RenderAccelArray
= pSiSEnt
->RenderAccelArray
;
402 if(!pSiS
->RenderAccelArray
) {
403 if((pSiS
->RenderAccelArray
= xnfcalloc(65536, 1))) {
405 if(pSiSEnt
) pSiSEnt
->RenderAccelArray
= pSiS
->RenderAccelArray
;
407 for(i
= 0; i
< 256; i
++) {
408 for(j
= 0; j
< 256; j
++) {
409 pSiS
->RenderAccelArray
[(i
<< 8) + j
] = (i
* j
) / 255;
414 if(pSiS
->RenderAccelArray
) {
415 pSiS
->AccelLinearScratch
= NULL
;
417 infoPtr
->SetupForCPUToScreenAlphaTexture
= SiSSetupForCPUToScreenAlphaTexture
;
418 infoPtr
->SubsequentCPUToScreenAlphaTexture
= SiSSubsequentCPUToScreenTexture
;
419 infoPtr
->CPUToScreenAlphaTextureFormats
= SiSAlphaTextureFormats
;
420 infoPtr
->CPUToScreenAlphaTextureFlags
= XAA_RENDER_NO_TILE
;
422 infoPtr
->SetupForCPUToScreenTexture
= SiSSetupForCPUToScreenTexture
;
423 infoPtr
->SubsequentCPUToScreenTexture
= SiSSubsequentCPUToScreenTexture
;
424 infoPtr
->CPUToScreenTextureFormats
= SiSTextureFormats
;
425 infoPtr
->CPUToScreenTextureFlags
= XAA_RENDER_NO_TILE
;
426 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
, "RENDER acceleration enabled\n");
433 if(pSiS
->DualHeadMode
) {
434 infoPtr
->RestoreAccelState
= SiSRestoreAccelState
;
438 /* Init Frame Buffer Manager */
440 topFB
= pSiS
->maxxfbmem
;
442 reservedFbSize
= (pSiS
->ColorExpandBufferNumber
443 * pSiS
->PerColorExpandBufferSize
);
445 UsableFbSize
= topFB
- reservedFbSize
;
447 * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
448 * UsableFbSize ColorExpandBuffers | DRI-Heap HWCursor CommandQueue
452 AvailBufBase
= pSiS
->FbBase
+ UsableFbSize
;
453 if(pSiS
->ColorExpandBufferNumber
) {
455 infoPtr
->ColorExpandBase
= (unsigned char *)AvailBufBase
;
456 pSiS
->ColorExpandBase
= UsableFbSize
;
458 for(i
= 0; i
< pSiS
->ColorExpandBufferNumber
; i
++) {
459 pSiS
->ColorExpandBufferAddr
[i
] = AvailBufBase
+
460 i
* pSiS
->PerColorExpandBufferSize
;
461 pSiS
->ColorExpandBufferScreenOffset
[i
] = UsableFbSize
+
462 i
* pSiS
->PerColorExpandBufferSize
;
470 Avail
.x2
= pScrn
->displayWidth
;
471 Avail
.y2
= (UsableFbSize
/ (pScrn
->displayWidth
* pScrn
->bitsPerPixel
/8)) - 1;
473 if(Avail
.y2
< 0) Avail
.y2
= 32767;
474 if(Avail
.y2
< pScrn
->currentMode
->VDisplay
) {
475 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
476 "Not enough video RAM for accelerator. At least "
477 "%dKB needed, %ldKB available\n",
478 ((((pScrn
->displayWidth
* pScrn
->bitsPerPixel
/8) /* +8 for make it sure */
479 * pScrn
->currentMode
->VDisplay
) + reservedFbSize
) / 1024) + 8,
480 pSiS
->maxxfbmem
/1024);
481 pSiS
->NoAccel
= TRUE
;
482 pSiS
->NoXvideo
= TRUE
;
483 XAADestroyInfoRec(pSiS
->AccelInfoPtr
);
484 pSiS
->AccelInfoPtr
= NULL
;
488 xf86DrvMsg(pScrn
->scrnIndex
, X_INFO
,
489 "Frame Buffer From (%d,%d) To (%d,%d)\n",
490 Avail
.x1
, Avail
.y1
, Avail
.x2
, Avail
.y2
);
492 xf86InitFBManager(pScreen
, &Avail
);
494 return(XAAInit(pScreen
, infoPtr
));
498 SiSSync(ScrnInfoPtr pScrn
)
500 SISPtr pSiS
= SISPTR(pScrn
);
502 PDEBUG(ErrorF("SiSSync()\n"));
506 if(pSiS
->DoColorExpand
) {
508 pSiS
->ColorExpandBusy
= TRUE
;
513 pSiS
->DoColorExpand
= FALSE
;
514 pSiS
->alphaBlitBusy
= FALSE
;
521 SiSRestoreAccelState(ScrnInfoPtr pScrn
)
523 SISPtr pSiS
= SISPTR(pScrn
);
525 pSiS
->ColorExpandBusy
= FALSE
;
526 pSiS
->alphaBlitBusy
= FALSE
;
531 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn
,
532 int xdir
, int ydir
, int rop
,
533 unsigned int planemask
, int trans_color
)
535 SISPtr pSiS
= SISPTR(pScrn
);
537 PDEBUG(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
538 xdir
, ydir
, rop
, planemask
, trans_color
));
541 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
542 SiSCheckQueue(16 * 2);
543 SiSSetupSRCPitchDSTRect(pSiS
->scrnOffset
, pSiS
->scrnOffset
, -1)
545 SiSSetupDSTColorDepth(pSiS
->DstColor
);
546 SiSSetupSRCPitch(pSiS
->scrnOffset
)
547 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
550 if(trans_color
!= -1) {
552 SiSSetupSRCTrans(trans_color
)
553 SiSSetupCMDFlag(TRANSPARENT_BITBLT
)
555 SiSSetupROP(XAACopyROP
[rop
])
556 /* Set command - not needed, both 0 */
557 /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
561 SiSSetupCMDFlag(pSiS
->SiS310_AccelDepth
)
568 /* The chip is smart enough to know the direction */
571 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn
,
572 int src_x
, int src_y
, int dst_x
, int dst_y
,
573 int width
, int height
)
575 SISPtr pSiS
= SISPTR(pScrn
);
576 long srcbase
, dstbase
;
579 PDEBUG(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
580 src_x
, src_y
, dst_x
, dst_y
, width
, height
));
582 srcbase
= dstbase
= 0;
583 mymin
= min(src_y
, dst_y
);
584 mymax
= max(src_y
, dst_y
);
586 /* Libxaa.a has a bug: The tilecache cannot operate
587 * correctly if there are 512x512 slots, but no 256x256
588 * slots. This leads to catastrophic data fed to us.
589 * Filter this out here and warn the user.
590 * Fixed in 4.3.99.10 (?) and Debian's 4.3.0.1
592 #if (XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,10,0)) && (XF86_VERSION_CURRENT != XF86_VERSION_NUMERIC(4,3,0,1,0))
599 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
600 "BitBlit fatal error: Illegal coordinates:\n");
601 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
602 "Source x %d y %d, dest x %d y %d, width %d height %d\n",
603 src_x
, src_y
, dst_x
, dst_y
, width
, height
);
604 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
605 "This is very probably caused by a known bug in libxaa.a.\n");
606 xf86DrvMsg(pScrn
->scrnIndex
, X_ERROR
,
607 "Please update libxaa.a to avoid this error.\n");
612 /* Although the chip knows the direction to use
613 * if the source and destination areas overlap,
614 * that logic fails if we fiddle with the bitmap
615 * addresses. Therefore, we check if the source
616 * and destination blitting areas overlap and
617 * adapt the bitmap addresses synchronously
618 * if the coordinates exceed the valid range.
619 * The the areas do not overlap, we do our
622 if((mymax
- mymin
) < height
) {
623 if((src_y
>= 2048) || (dst_y
>= 2048)) {
624 srcbase
= pSiS
->scrnOffset
* mymin
;
625 dstbase
= pSiS
->scrnOffset
* mymin
;
631 srcbase
= pSiS
->scrnOffset
* src_y
;
634 if((dst_y
>= pScrn
->virtualY
) || (dst_y
>= 2048)) {
635 dstbase
= pSiS
->scrnOffset
* dst_y
;
640 srcbase
+= HEADOFFSET
;
641 dstbase
+= HEADOFFSET
;
645 SiSCheckQueue(16 * 3);
646 SiSSetupSRCDSTBase(srcbase
, dstbase
)
647 SiSSetupSRCDSTXY(src_x
, src_y
, dst_x
, dst_y
)
648 SiSSetRectDoCMD(width
,height
)
650 SiSSetupSRCBase(srcbase
);
651 SiSSetupDSTBase(dstbase
);
652 SiSSetupRect(width
, height
)
653 SiSSetupSRCXY(src_x
, src_y
)
654 SiSSetupDSTXY(dst_x
, dst_y
)
660 SiSSetupForSolidFill(ScrnInfoPtr pScrn
, int color
,
661 int rop
, unsigned int planemask
)
663 SISPtr pSiS
= SISPTR(pScrn
);
665 PDEBUG(ErrorF("Setup SolidFill(0x%x, 0x%x, 0x%x)\n",
666 color
, rop
, planemask
));
668 if(pSiS
->disablecolorkeycurrent
) {
669 if((CARD32
)color
== pSiS
->colorKey
) {
675 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
676 SiSCheckQueue(16 * 1);
677 SiSSetupPATFGDSTRect(color
, pSiS
->scrnOffset
, -1)
678 SiSSetupROP(XAAPatternROP
[rop
])
679 SiSSetupCMDFlag(PATFG
)
683 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
684 SiSSetupDSTColorDepth(pSiS
->DstColor
);
685 SiSSetupROP(XAAPatternROP
[rop
])
686 SiSSetupCMDFlag(PATFG
| pSiS
->SiS310_AccelDepth
)
691 SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn
,
692 int x
, int y
, int w
, int h
)
694 SISPtr pSiS
= SISPTR(pScrn
);
697 PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
702 dstbase
= pSiS
->scrnOffset
* y
;
706 dstbase
+= HEADOFFSET
;
709 pSiS
->CommandReg
&= ~(T_XISMAJORL
| T_XISMAJORR
|
710 T_L_X_INC
| T_L_Y_INC
|
711 T_R_X_INC
| T_R_Y_INC
|
714 /* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */
717 SiSCheckQueue(16 * 2)
718 SiSSetupDSTXYRect(x
,y
,w
,h
)
719 SiSSetupDSTBaseDoCMD(dstbase
)
721 SiSSetupDSTBase(dstbase
)
729 /* This would work better if XAA would provide us with valid trapezoids.
730 * In fact, with small trapezoids the left and the right edge often cross
731 * each other which causes drawing errors (filling over whole scanline).
732 * DOES NOT WORK ON 330 SERIES, HANGS THE ENGINE.
736 SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn
, int y
, int h
,
737 int left
, int dxL
, int dyL
, int eL
,
738 int right
, int dxR
, int dyR
, int eR
)
740 SISPtr pSiS
= SISPTR(pScrn
);
745 dstbase
= pSiS
->scrnOffset
* y
;
749 dstbase
+= HEADOFFSET
;
752 #ifdef SISVRAMQ /* Not optimized yet */
753 SiSCheckQueue(16 * 10)
755 SiSSetupDSTBase(dstbase
)
759 SiSSetupPATFG(0xff0000) /* FOR TESTING */
762 /* Clear CommandReg because SetUp can be used for Rect and Trap */
763 pSiS
->CommandReg
&= ~(T_L_X_INC
| T_L_Y_INC
|
764 T_R_X_INC
| T_R_Y_INC
|
765 T_XISMAJORL
| T_XISMAJORR
|
768 xf86DrvMsg(0, X_INFO
, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n",
769 left
, right
, y
, h
, dxL
, dyL
, eL
, dxR
, dyR
, eR
);
771 /* Determine egde angles */
772 if(dxL
< 0) { dxL
= -dxL
; }
773 else { SiSSetupCMDFlag(T_L_X_INC
) }
774 if(dxR
< 0) { dxR
= -dxR
; }
775 else { SiSSetupCMDFlag(T_R_X_INC
) }
777 /* (Y direction always positive - do this anyway) */
778 if(dyL
< 0) { dyL
= -dyL
; }
779 else { SiSSetupCMDFlag(T_L_Y_INC
) }
780 if(dyR
< 0) { dyR
= -dyR
; }
781 else { SiSSetupCMDFlag(T_R_Y_INC
) }
783 /* Determine major axis */
784 if(dxL
>= dyL
) { SiSSetupCMDFlag(T_XISMAJORL
) }
785 if(dxR
>= dyR
) { SiSSetupCMDFlag(T_XISMAJORR
) }
787 SiSSetupCMDFlag(TRAPAZOID_FILL
);
790 SiSSetupYHLR(y
, h
, left
, right
)
791 SiSSetupdLdR(dxL
, dyL
, dxR
, dyR
)
793 SiSSetupDSTBaseDoCMD(dstbase
)
798 /* Set up y, h, left, right */
800 SiSSetupLR(left
, right
)
801 /* Set up initial error term */
810 SiSSetupForSolidLine(ScrnInfoPtr pScrn
, int color
, int rop
,
811 unsigned int planemask
)
813 SISPtr pSiS
= SISPTR(pScrn
);
815 PDEBUG(ErrorF("Setup SolidLine(0x%x, 0x%x, 0x%x)\n",
816 color
, rop
, planemask
));
819 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
820 SiSCheckQueue(16 * 3);
821 SiSSetupLineCountPeriod(1, 1)
822 SiSSetupPATFGDSTRect(color
, pSiS
->scrnOffset
, -1)
823 SiSSetupROP(XAAPatternROP
[rop
])
824 SiSSetupCMDFlag(PATFG
| LINE
)
829 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
830 SiSSetupDSTColorDepth(pSiS
->DstColor
)
831 SiSSetupROP(XAAPatternROP
[rop
])
832 SiSSetupCMDFlag(PATFG
| LINE
| pSiS
->SiS310_AccelDepth
)
837 SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn
,
838 int x1
, int y1
, int x2
, int y2
, int flags
)
840 SISPtr pSiS
= SISPTR(pScrn
);
841 long dstbase
,miny
,maxy
;
843 PDEBUG(ErrorF("Subsequent SolidLine(%d, %d, %d, %d, 0x%x)\n",
844 x1
, y1
, x2
, y2
, flags
));
847 miny
= (y1
> y2
) ? y2
: y1
;
848 maxy
= (y1
> y2
) ? y1
: y2
;
850 dstbase
= pSiS
->scrnOffset
*miny
;
855 dstbase
+= HEADOFFSET
;
858 if(flags
& OMIT_LAST
) {
859 SiSSetupCMDFlag(NO_LAST_PIXEL
)
861 pSiS
->CommandReg
&= ~(NO_LAST_PIXEL
);
865 SiSCheckQueue(16 * 2);
866 SiSSetupX0Y0X1Y1(x1
,y1
,x2
,y2
)
867 SiSSetupDSTBaseDoCMD(dstbase
)
869 SiSSetupDSTBase(dstbase
)
877 SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn
,
878 int x
, int y
, int len
, int dir
)
880 SISPtr pSiS
= SISPTR(pScrn
);
883 PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n",
886 len
--; /* starting point is included! */
888 if((y
>= 2048) || ((y
+ len
) >= 2048)) {
889 dstbase
= pSiS
->scrnOffset
* y
;
893 dstbase
+= HEADOFFSET
;
897 SiSCheckQueue(16 * 2);
898 if(dir
== DEGREES_0
) {
899 SiSSetupX0Y0X1Y1(x
, y
, (x
+ len
), y
)
901 SiSSetupX0Y0X1Y1(x
, y
, x
, (y
+ len
))
903 SiSSetupDSTBaseDoCMD(dstbase
)
905 SiSSetupDSTBase(dstbase
)
907 if(dir
== DEGREES_0
) {
908 SiSSetupX1Y1(x
+ len
, y
);
910 SiSSetupX1Y1(x
, y
+ len
);
917 SiSSetupForDashedLine(ScrnInfoPtr pScrn
,
918 int fg
, int bg
, int rop
, unsigned int planemask
,
919 int length
, unsigned char *pattern
)
921 SISPtr pSiS
= SISPTR(pScrn
);
923 PDEBUG(ErrorF("Setup DashedLine(0x%x, 0x%x, 0x%x, 0x%x, %d, 0x%x:%x)\n",
924 fg
, bg
, rop
, planemask
, length
, *(pattern
+4), *pattern
));
927 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
928 SiSCheckQueue(16 * 3);
929 SiSSetupLineCountPeriod(1, length
-1)
930 SiSSetupStyle(*pattern
,*(pattern
+4))
931 SiSSetupPATFGDSTRect(fg
, pSiS
->scrnOffset
, -1)
934 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
935 SiSSetupDSTColorDepth(pSiS
->DstColor
);
936 SiSSetupStyleLow(*pattern
)
937 SiSSetupStyleHigh(*(pattern
+4))
938 SiSSetupStylePeriod(length
-1);
942 SiSSetupROP(XAAPatternROP
[rop
])
944 SiSSetupCMDFlag(LINE
| LINE_STYLE
)
949 SiSSetupCMDFlag(TRANSPARENT
)
952 SiSSetupCMDFlag(pSiS
->SiS310_AccelDepth
)
961 SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn
,
962 int x1
, int y1
, int x2
, int y2
,
963 int flags
, int phase
)
965 SISPtr pSiS
= SISPTR(pScrn
);
966 long dstbase
,miny
,maxy
;
968 PDEBUG(ErrorF("Subsequent DashedLine(%d,%d, %d,%d, 0x%x,0x%x)\n",
969 x1
, y1
, x2
, y2
, flags
, phase
));
972 miny
= (y1
> y2
) ? y2
: y1
;
973 maxy
= (y1
> y2
) ? y1
: y2
;
975 dstbase
= pSiS
->scrnOffset
* miny
;
980 dstbase
+= HEADOFFSET
;
983 if(flags
& OMIT_LAST
) {
984 SiSSetupCMDFlag(NO_LAST_PIXEL
)
986 pSiS
->CommandReg
&= ~(NO_LAST_PIXEL
);
990 SiSCheckQueue(16 * 2);
991 SiSSetupX0Y0X1Y1(x1
,y1
,x2
,y2
)
992 SiSSetupDSTBaseDoCMD(dstbase
)
994 SiSSetupDSTBase(dstbase
)
1002 SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn
,
1003 int patx
, int paty
, int fg
, int bg
,
1004 int rop
, unsigned int planemask
)
1006 SISPtr pSiS
= SISPTR(pScrn
);
1008 PDEBUG(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n",
1009 patx
, paty
, fg
, bg
, rop
, planemask
));
1012 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1013 SiSCheckQueue(16 * 3);
1014 SiSSetupPATFGDSTRect(fg
, pSiS
->scrnOffset
, -1)
1016 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
1017 SiSSetupDSTColorDepth(pSiS
->DstColor
);
1020 SiSSetupMONOPAT(patx
,paty
)
1022 SiSSetupROP(XAAPatternROP
[rop
])
1025 SiSSetupCMDFlag(PATMONO
)
1028 SiSSetupCMDFlag(PATMONO
| pSiS
->SiS310_AccelDepth
)
1034 SiSSetupCMDFlag(TRANSPARENT
)
1043 SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn
,
1045 int x
, int y
, int w
, int h
)
1047 SISPtr pSiS
= SISPTR(pScrn
);
1050 PDEBUG(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
1051 patx
, paty
, x
, y
, w
, h
));
1054 dstbase
= pSiS
->scrnOffset
* y
;
1058 dstbase
+= HEADOFFSET
;
1061 /* Clear commandReg because Setup can be used for Rect and Trap */
1062 pSiS
->CommandReg
&= ~(T_XISMAJORL
| T_XISMAJORR
|
1063 T_L_X_INC
| T_L_Y_INC
|
1064 T_R_X_INC
| T_R_Y_INC
|
1068 SiSCheckQueue(16 * 2);
1069 SiSSetupDSTXYRect(x
,y
,w
,h
)
1070 SiSSetupDSTBaseDoCMD(dstbase
)
1072 SiSSetupDSTBase(dstbase
)
1079 /* --- Trapezoid --- */
1081 /* Does not work at all on 330 series */
1085 SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn
,
1088 int left
, int dxL
, int dyL
, int eL
,
1089 int right
, int dxR
, int dyR
, int eR
)
1091 SISPtr pSiS
= SISPTR(pScrn
);
1094 PDEBUG(ErrorF("Subsequent Mono8x8PatternFillTrap(%d, %d, %d - %d %d/%d %d/%d)\n",
1095 y
, h
, left
, right
, dxL
, dxR
, eL
, eR
));
1099 dstbase
=pSiS
->scrnOffset
*y
;
1103 dstbase
+= HEADOFFSET
;
1107 SiSCheckQueue(16 * 4);
1109 SiSSetupDSTBase(dstbase
)
1112 /* Clear CommandReg because SetUp can be used for Rect and Trap */
1113 pSiS
->CommandReg
&= ~(T_XISMAJORL
| T_XISMAJORR
|
1114 T_L_X_INC
| T_L_Y_INC
|
1115 T_R_X_INC
| T_R_Y_INC
|
1118 if(dxL
< 0) { dxL
= -dxL
; }
1119 else { SiSSetupCMDFlag(T_L_X_INC
) }
1120 if(dxR
< 0) { dxR
= -dxR
; }
1121 else { SiSSetupCMDFlag(T_R_X_INC
) }
1123 if(dyL
< 0) { dyL
= -dyL
; }
1124 else { SiSSetupCMDFlag(T_L_Y_INC
) }
1125 if(dyR
< 0) { dyR
= -dyR
; }
1126 else { SiSSetupCMDFlag(T_R_Y_INC
) }
1128 /* Determine major axis */
1129 if(dxL
>= dyL
) { SiSSetupCMDFlag(T_XISMAJORL
) }
1130 if(dxR
>= dyR
) { SiSSetupCMDFlag(T_XISMAJORR
) }
1132 SiSSetupCMDFlag(TRAPAZOID_FILL
);
1135 SiSSetupYHLR(y
, h
, left
, right
)
1136 SiSSetupdLdR(dxL
, dyL
, dxR
, dyR
)
1137 SiSSetupELER(eL
, eR
)
1138 SiSSetupDSTBaseDoCMD(dstbase
)
1141 SiSSetupLR(left
, right
)
1142 SiSSetupdL(dxL
, dyL
)
1143 SiSSetupdR(dxR
, dyR
)
1151 /* Color 8x8 pattern */
1155 SiSSetupForColor8x8PatternFill(ScrnInfoPtr pScrn
, int patternx
, int patterny
,
1156 int rop
, unsigned int planemask
, int trans_col
)
1158 SISPtr pSiS
= SISPTR(pScrn
);
1159 int j
= pScrn
->bitsPerPixel
>> 3;
1160 CARD32
*patadr
= (CARD32
*)(pSiS
->FbBase
+ (patterny
* pSiS
->scrnOffset
) +
1164 xf86DrvMsg(0, X_INFO
, "Setup Color8x8PatFill(0x%x, 0x%x, 0x%x, 0x%x)\n",
1165 patternx
, patterny
, rop
, planemask
);
1168 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1169 SiSCheckQueue(16 * 3);
1171 SiSSetupDSTRectBurstHeader(pSiS
->scrnOffset
, -1, PATTERN_REG
, (pScrn
->bitsPerPixel
<< 1))
1174 SiSSetupPatternRegBurst(patadr
[0], patadr
[1], patadr
[2], patadr
[3]);
1175 SiSSetupPatternRegBurst(patadr
[4], patadr
[5], patadr
[6], patadr
[7]);
1176 SiSSetupPatternRegBurst(patadr
[8], patadr
[9], patadr
[10], patadr
[11]);
1177 SiSSetupPatternRegBurst(patadr
[12], patadr
[13], patadr
[14], patadr
[15]);
1178 patadr
+= 16; /* = 64 due to (CARD32 *) */
1181 SiSSetupROP(XAAPatternROP
[rop
])
1183 SiSSetupCMDFlag(PATPATREG
)
1189 SiSSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn
, int patternx
,
1190 int patterny
, int x
, int y
, int w
, int h
)
1192 SISPtr pSiS
= SISPTR(pScrn
);
1196 xf86DrvMsg(0, X_INFO
, "Subsequent Color8x8FillRect(%d, %d, %d, %d)\n",
1202 dstbase
= pSiS
->scrnOffset
* y
;
1206 dstbase
+= HEADOFFSET
;
1208 /* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */
1210 SiSCheckQueue(16 * 2)
1211 SiSSetupDSTXYRect(x
,y
,w
,h
)
1212 SiSSetupDSTBaseDoCMD(dstbase
)
1216 /* ---- CPUToScreen Color Expand --- */
1224 /* This is somewhat a fake. We let XAA copy its data not to an
1225 * aperture, but to video RAM, and then do a ScreenToScreen
1227 * Since the data is sent AFTER the call to Subsequent, we
1228 * don't execute the command here, but set a flag and do
1229 * that in the (subsequent) call to Sync()
1233 SiSSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
1234 int fg
, int bg
, int rop
, unsigned int planemask
)
1236 SISPtr pSiS
=SISPTR(pScrn
);
1239 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1240 SiSSetupROP(XAACopyROP
[rop
]);
1241 SiSSetupSRCFGDSTRect(fg
, pSiS
->scrnOffset
, -1)
1243 SiSSetupCMDFlag(TRANSPARENT
| ENCOLOREXP
| SRCVIDEO
);
1246 SiSSetupCMDFlag(ENCOLOREXP
| SRCVIDEO
);
1251 SiSSetupROP(XAACopyROP
[rop
]);
1253 SiSSetupDSTRect(pSiS
->scrnOffset
, -1);
1254 SiSSetupDSTColorDepth(pSiS
->DstColor
);
1256 SiSSetupCMDFlag(TRANSPARENT
| ENCOLOREXP
| SRCVIDEO
1257 | pSiS
->SiS310_AccelDepth
);
1260 SiSSetupCMDFlag(ENCOLOREXP
| SRCVIDEO
| pSiS
->SiS310_AccelDepth
);
1266 SiSSubsequentCPUToScreenColorExpandFill(
1267 ScrnInfoPtr pScrn
, int x
, int y
, int w
,
1268 int h
, int skipleft
)
1270 SISPtr pSiS
= SISPTR(pScrn
);
1271 int _x0
, _y0
, _x1
, _y1
;
1272 long srcbase
, dstbase
;
1274 srcbase
= pSiS
->ColorExpandBase
;
1278 dstbase
= pSiS
->scrnOffset
*y
;
1283 srcbase
+= HEADOFFSET
;
1284 dstbase
+= HEADOFFSET
;
1288 SiSSetupSRCDSTBase(srcbase
,dstbase
);
1290 SiSSetupSRCBase(srcbase
);
1291 SiSSetupDSTBase(dstbase
)
1300 SiSSetupClip(_x0
, _y0
, _x1
, _y1
);
1302 SiSSetupClipLT(_x0
, _y0
);
1303 SiSSetupClipRB(_x1
, _y1
);
1305 SiSSetupCMDFlag(CLIPENABLE
);
1307 pSiS
->CommandReg
&= (~CLIPENABLE
);
1311 SiSSetupRectSRCPitch(w
, h
, ((((w
+ 7) >> 3) + 3) >> 2) << 2);
1312 SiSSetupSRCDSTXY(0, 0, x
, y
);
1315 SiSSetupSRCPitch(((((w
+7)/8)+3) >> 2) * 4);
1316 SiSSetupDSTXY(x
, y
);
1319 if(pSiS
->ColorExpandBusy
) {
1320 pSiS
->ColorExpandBusy
= FALSE
;
1324 pSiS
->DoColorExpand
= TRUE
;
1329 /* Indirect method */
1331 /* This is SLOW, slower than the CPU on most chipsets */
1332 /* Does not work in VRAM queue mode. */
1335 SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn
,
1336 int fg
, int bg
, int rop
, unsigned int planemask
)
1338 SISPtr pSiS
=SISPTR(pScrn
);
1341 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1344 /* !!! DOES NOT WORK IN VRAM QUEUE MODE !!! */
1346 /* (hence this is not optimized for VRAM mode) */
1352 SiSSetupROP(XAACopyROP
[rop
]);
1354 SiSSetupDSTRect(pSiS
->scrnOffset
, -1);
1356 SiSSetupDSTColorDepth(pSiS
->DstColor
);
1360 SiSSetupCMDFlag(TRANSPARENT
| ENCOLOREXP
| SRCVIDEO
);
1362 SiSSetupCMDFlag(TRANSPARENT
| ENCOLOREXP
| SRCCPUBLITBUF
1363 | pSiS
->SiS310_AccelDepth
);
1368 SiSSetupCMDFlag(ENCOLOREXP
| SRCCPUBLITBUF
);
1370 SiSSetupCMDFlag(ENCOLOREXP
| SRCCPUBLITBUF
| pSiS
->SiS310_AccelDepth
);
1377 SiSSubsequentScanlineCPUToScreenColorExpandFill(
1378 ScrnInfoPtr pScrn
, int x
, int y
, int w
,
1379 int h
, int skipleft
)
1381 SISPtr pSiS
= SISPTR(pScrn
);
1382 int _x0
, _y0
, _x1
, _y1
;
1387 dstbase
= pSiS
->scrnOffset
*y
;
1391 dstbase
+= HEADOFFSET
;
1395 if((MMIO_IN16(pSiS
->IOBase
, Q_STATUS
+2) & 0x8000) != 0x8000) {
1400 SiSSetupDSTBase(dstbase
)
1408 SiSSetupClip(_x0
, _y0
, _x1
, _y1
);
1410 SiSSetupClipLT(_x0
, _y0
);
1411 SiSSetupClipRB(_x1
, _y1
);
1413 SiSSetupCMDFlag(CLIPENABLE
);
1415 pSiS
->CommandReg
&= (~CLIPENABLE
);
1418 SiSSetupSRCPitch(((((w
+7)/8)+3) >> 2) * 4);
1425 SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn
, int bufno
)
1427 SISPtr pSiS
= SISPTR(pScrn
);
1430 cbo
= pSiS
->ColorExpandBufferScreenOffset
[bufno
];
1436 if((MMIO_IN16(pSiS
->IOBase
, Q_STATUS
+2) & 0x8000) != 0x8000) {
1441 SiSSetupSRCBase(cbo
);
1443 SiSSetupDSTXY(pSiS
->xcurrent
, pSiS
->ycurrent
);
1455 /* --- Screen To Screen Color Expand --- */
1457 /* This method blits in a single task; this does not work because
1458 * the hardware does not use the source pitch as scanline offset
1459 * but to calculate pattern address from source X and Y and to
1460 * limit the drawing width (similar to width set by SetupRect).
1461 * XAA provides the pattern bitmap with scrnOffset (displayWidth * bpp/8)
1462 * offset, but this is not supported by the hardware.
1463 * DOES NOT WORK ON 330 SERIES, HANGS ENGINE.
1468 SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
1470 int rop
, unsigned int planemask
)
1472 SISPtr pSiS
= SISPTR(pScrn
);
1475 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1477 SiSSetupDSTColorDepth(pSiS
->DstColor
)
1479 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
1480 SiSSetupROP(XAACopyROP
[rop
])
1482 /* SiSSetupSRCXY(0,0) */
1485 SiSSetupCMDFlag(TRANSPARENT
| ENCOLOREXP
| SRCVIDEO
);
1488 SiSSetupCMDFlag(ENCOLOREXP
| SRCVIDEO
);
1496 /* For testing, these are the methods: (use only one at a time!) */
1498 #undef npitch /* Normal: Use srcx/y as srcx/y, use scrnOffset as source pitch
1499 * Does not work on 315 series, because the hardware does not
1500 * regard the src x and y. Apart from this problem:
1501 * This would work if the hareware used the source pitch for
1502 * incrementing the source address after each scanline - but
1503 * it doesn't do this! The first line of the area is correctly
1504 * color expanded, but since the source pitch is ignored and
1505 * the source address not incremented correctly, the following
1506 * lines are color expanded with any bit pattern that is left
1507 * in the unused space of the source bitmap (which is organized
1508 * with the depth of the screen framebuffer hence with a pitch
1512 #undef pitchdw /* Use source pitch "displayWidth / 8" instead
1513 * of scrnOffset (=displayWidth * bpp / 8)
1514 * This can't work, because the pitch of the source
1515 * bitmap is scrnoffset!
1518 #define nopitch /* Calculate srcbase with srcx and srcy, set the
1519 * pitch to scrnOffset (which IS the correct pitch
1520 * for the source bitmap) and set srcx and srcy both
1522 * This would work if the hareware used the source pitch for
1523 * incrementing the source address after each scanline - but
1524 * it doesn't do this! Again: The first line of the area is
1525 * correctly color expanded, but since the source pitch is
1526 * ignored for scanline address incremention, the following
1527 * lines are not correctly color expanded.
1528 * This is the only way it works (apart from the problem
1529 * described above). The hardware does not regard the src
1530 * x and y values in any way.
1534 SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn
,
1535 int x
, int y
, int w
, int h
,
1536 int srcx
, int srcy
, int skipleft
)
1538 SISPtr pSiS
= SISPTR(pScrn
);
1539 long srcbase
, dstbase
;
1541 int _x0
, _y0
, _x1
, _y1
;
1544 int newsrcx
, newsrcy
;
1546 /* srcx and srcy are provided based on a scrnOffset pitch ( = displayWidth * bpp / 8 )
1547 * We recalulate srcx and srcy based on pitch = displayWidth / 8
1549 newsrcy
= ((pSiS
->scrnOffset
* srcy
) + (srcx
* ((pScrn
->bitsPerPixel
+7)/8))) /
1550 (pScrn
->displayWidth
/8);
1551 newsrcx
= ((pSiS
->scrnOffset
* srcy
) + (srcx
* ((pScrn
->bitsPerPixel
+7)/8))) %
1552 (pScrn
->displayWidth
/8);
1554 xf86DrvMsg(0, X_INFO
, "Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n",
1555 x
, y
, w
, h
, srcx
, srcy
, skipleft
);
1557 srcbase
= dstbase
= 0;
1560 if(newsrcy
>= 2048) {
1561 srcbase
= (pScrn
->displayWidth
/ 8) * newsrcy
;
1566 srcbase
= (pSiS
->scrnOffset
* srcy
) + (srcx
* ((pScrn
->bitsPerPixel
+7)/8));
1570 srcbase
= pSiS
->scrnOffset
* srcy
;
1575 dstbase
= pSiS
->scrnOffset
* y
;
1580 srcbase
+= HEADOFFSET
;
1581 dstbase
+= HEADOFFSET
;
1584 SiSSetupSRCBase(srcbase
)
1585 SiSSetupDSTBase(dstbase
)
1587 /* 315 series seem to treat the src pitch as
1588 * a "drawing limit", but still (as 300 series)
1589 * does not use it for incrementing the
1590 * address pointer for the next scanline. ARGH!
1594 SiSSetupSRCPitch(pScrn
->displayWidth
/8)
1597 SiSSetupSRCPitch(pScrn
->displayWidth
/8)
1598 /* SiSSetupSRCPitch(1024/8) */ /* For test */
1601 SiSSetupSRCPitch(pScrn
->displayWidth
/8)
1602 /* SiSSetupSRCPitch(pSiS->scrnOffset) */
1607 #if 0 /* How do I implement the offset? Not this way, that's for sure.. */
1613 SiSSetupClipLT(_x0
, _y0
);
1614 SiSSetupClipRB(_x1
, _y1
);
1615 SiSSetupCMDFlag(CLIPENABLE
);
1619 SiSSetupSRCXY(newsrcx
, newsrcy
)
1625 SiSSetupSRCXY(srcx
, srcy
)
1632 /* We MUST sync here, there must not be 2 or more color expansion commands in the queue */
1638 /* ---- RENDER ---- */
1643 SiSRenderCallback(ScrnInfoPtr pScrn
)
1645 SISPtr pSiS
= SISPTR(pScrn
);
1647 if((currentTime
.milliseconds
> pSiS
->RenderTime
) && pSiS
->AccelLinearScratch
) {
1648 xf86FreeOffscreenLinear(pSiS
->AccelLinearScratch
);
1649 pSiS
->AccelLinearScratch
= NULL
;
1652 if(!pSiS
->AccelLinearScratch
) {
1653 pSiS
->RenderCallback
= NULL
;
1657 #define RENDER_DELAY 15000
1660 SiSAllocateLinear(ScrnInfoPtr pScrn
, int sizeNeeded
)
1662 SISPtr pSiS
= SISPTR(pScrn
);
1664 pSiS
->RenderTime
= currentTime
.milliseconds
+ RENDER_DELAY
;
1665 pSiS
->RenderCallback
= SiSRenderCallback
;
1667 if(pSiS
->AccelLinearScratch
) {
1668 if(pSiS
->AccelLinearScratch
->size
>= sizeNeeded
) {
1671 if(pSiS
->alphaBlitBusy
) {
1672 pSiS
->alphaBlitBusy
= FALSE
;
1675 if(xf86ResizeOffscreenLinear(pSiS
->AccelLinearScratch
, sizeNeeded
)) {
1678 xf86FreeOffscreenLinear(pSiS
->AccelLinearScratch
);
1679 pSiS
->AccelLinearScratch
= NULL
;
1683 pSiS
->AccelLinearScratch
= xf86AllocateOffscreenLinear(
1684 pScrn
->pScreen
, sizeNeeded
, 32,
1687 return(pSiS
->AccelLinearScratch
!= NULL
);
1691 SiSSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn
,
1692 int op
, CARD16 red
, CARD16 green
,
1693 CARD16 blue
, CARD16 alpha
,
1694 int alphaType
, CARD8
*alphaPtr
,
1695 int alphaPitch
, int width
,
1696 int height
, int flags
)
1698 SISPtr pSiS
= SISPTR(pScrn
);
1699 int x
, y
, pitch
, sizeNeeded
, offset
;
1702 unsigned char *renderaccelarray
;
1705 xf86DrvMsg(0, X_INFO
, "AT: op %d ARGB %x %x %x %x, w %d h %d A-pitch %d\n",
1706 op
, alpha
, red
, green
, blue
, width
, height
, alphaPitch
);
1709 if(op
!= PictOpOver
) return FALSE
;
1711 if((width
> 2048) || (height
> 2048)) return FALSE
;
1713 pitch
= (width
+ 31) & ~31;
1714 sizeNeeded
= pitch
* height
;
1715 if(pScrn
->bitsPerPixel
== 16) sizeNeeded
<<= 1;
1717 if(!((renderaccelarray
= pSiS
->RenderAccelArray
)))
1720 if(!SiSAllocateLinear(pScrn
, sizeNeeded
))
1728 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1729 SiSSetupSRCPitchDSTRect((pitch
<< 2), pSiS
->scrnOffset
, -1);
1730 SiSSetupCMDFlag(ALPHA_BLEND
| SRCVIDEO
| A_PERPIXELALPHA
)
1733 SiSSetupDSTColorDepth(pSiS
->DstColor
);
1734 SiSSetupSRCPitch((pitch
<< 2));
1735 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
1737 SiSSetupCMDFlag(ALPHA_BLEND
| SRCVIDEO
| A_PERPIXELALPHA
| pSiS
->SiS310_AccelDepth
)
1740 offset
= pSiS
->AccelLinearScratch
->offset
<< 1;
1741 if(pScrn
->bitsPerPixel
== 32) offset
<<= 1;
1743 dstPtr
= (CARD32
*)(pSiS
->FbBase
+ offset
);
1745 if(pSiS
->alphaBlitBusy
) {
1746 pSiS
->alphaBlitBusy
= FALSE
;
1750 if(alphaType
== PICT_a8
) {
1752 if(alpha
== 0xffff) {
1755 for(x
= 0; x
< width
; x
++) {
1756 myalpha
= alphaPtr
[x
];
1757 dstPtr
[x
] = (renderaccelarray
[red
+ myalpha
] << 16) |
1758 (renderaccelarray
[green
+ myalpha
] << 8) |
1759 renderaccelarray
[blue
+ myalpha
] |
1763 alphaPtr
+= alphaPitch
;
1771 for(x
= 0; x
< width
; x
++) {
1772 myalpha
= alphaPtr
[x
];
1773 dstPtr
[x
] = (renderaccelarray
[alpha
+ myalpha
] << 24) |
1774 (renderaccelarray
[red
+ myalpha
] << 16) |
1775 (renderaccelarray
[green
+ myalpha
] << 8) |
1776 renderaccelarray
[blue
+ myalpha
];
1779 alphaPtr
+= alphaPitch
;
1788 if(alpha
== 0xffff) {
1791 for(x
= 0, y
= 0; x
< width
; x
+=4, y
++) {
1792 myalpha
= alphaPtr
[x
];
1793 dstPtr
[y
] = (renderaccelarray
[red
+ myalpha
] << 16) |
1794 (renderaccelarray
[green
+ myalpha
] << 8) |
1795 renderaccelarray
[blue
+ myalpha
] |
1799 alphaPtr
+= alphaPitch
;
1807 for(x
= 0, y
= 0; x
< width
; x
+=4, y
++) {
1808 myalpha
= alphaPtr
[x
];
1809 dstPtr
[y
] = (renderaccelarray
[alpha
+ myalpha
] << 24) |
1810 (renderaccelarray
[red
+ myalpha
] << 16) |
1811 (renderaccelarray
[green
+ myalpha
] << 8) |
1812 renderaccelarray
[blue
+ myalpha
];
1815 alphaPtr
+= alphaPitch
;
1826 SiSSetupForCPUToScreenTexture(ScrnInfoPtr pScrn
,
1827 int op
, int texType
, CARD8
*texPtr
,
1828 int texPitch
, int width
,
1829 int height
, int flags
)
1831 SISPtr pSiS
= SISPTR(pScrn
);
1832 int pitch
, sizeNeeded
, offset
;
1836 xf86DrvMsg(0, X_INFO
, "T: type %d op %d w %d h %d T-pitch %d\n",
1837 texType
, op
, width
, height
, texPitch
);
1840 if(op
!= PictOpOver
) return FALSE
;
1842 if((width
> 2048) || (height
> 2048)) return FALSE
;
1844 pitch
= (width
+ 31) & ~31;
1845 sizeNeeded
= pitch
* height
;
1846 if(pScrn
->bitsPerPixel
== 16) sizeNeeded
<<= 1;
1851 if(!SiSAllocateLinear(pScrn
, sizeNeeded
))
1855 SiSSetupDSTColorDepth(pSiS
->SiS310_AccelDepth
);
1856 SiSSetupSRCPitchDSTRect(pitch
, pSiS
->scrnOffset
, -1);
1858 SiSSetupCMDFlag(ALPHA_BLEND
| SRCVIDEO
| A_PERPIXELALPHA
)
1861 SiSSetupDSTColorDepth(pSiS
->DstColor
);
1862 SiSSetupSRCPitch(pitch
);
1863 SiSSetupDSTRect(pSiS
->scrnOffset
, -1)
1865 SiSSetupCMDFlag(ALPHA_BLEND
| SRCVIDEO
| A_PERPIXELALPHA
| pSiS
->SiS310_AccelDepth
)
1868 offset
= pSiS
->AccelLinearScratch
->offset
<< 1;
1869 if(pScrn
->bitsPerPixel
== 32) offset
<<= 1;
1871 dst
= (CARD8
*)(pSiS
->FbBase
+ offset
);
1873 if(pSiS
->alphaBlitBusy
) {
1874 pSiS
->alphaBlitBusy
= FALSE
;
1879 memcpy(dst
, texPtr
, width
);
1888 SiSSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn
,
1889 int dst_x
, int dst_y
,
1890 int src_x
, int src_y
,
1891 int width
, int height
)
1893 SISPtr pSiS
= SISPTR(pScrn
);
1894 long srcbase
, dstbase
;
1896 srcbase
= pSiS
->AccelLinearScratch
->offset
<< 1;
1897 if(pScrn
->bitsPerPixel
== 32) srcbase
<<= 1;
1900 xf86DrvMsg(0, X_INFO
, "FIRE: scrbase %x dx %d dy %d w %d h %d\n",
1901 srcbase
, dst_x
, dst_y
, width
, height
);
1905 if((dst_y
>= pScrn
->virtualY
) || (dst_y
>= 2048)) {
1906 dstbase
= pSiS
->scrnOffset
* dst_y
;
1910 srcbase
+= HEADOFFSET
;
1911 dstbase
+= HEADOFFSET
;
1915 SiSCheckQueue(16 * 3)
1916 SiSSetupSRCDSTBase(srcbase
,dstbase
);
1917 SiSSetupSRCDSTXY(src_x
, src_y
, dst_x
, dst_y
)
1918 SiSSetRectDoCMD(width
,height
)
1920 SiSSetupSRCBase(srcbase
);
1921 SiSSetupDSTBase(dstbase
);
1922 SiSSetupRect(width
, height
)
1923 SiSSetupSRCXY(src_x
, src_y
)
1924 SiSSetupDSTXY(dst_x
, dst_y
)
1927 pSiS
->alphaBlitBusy
= TRUE
;