DRI XFree86-4_3_99_12-merge import
[xf86-video-sis/mirage.git] / src / sis310_accel.c
blobe47da9e5b7500ad3ad3357bca18cf545e920bbff
1 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c,v 1.20 2003/09/02 18:28:35 twini Exp $ */
2 /*
3 * 2D Acceleration for SiS 315 and Xabre series
4 * (315/550/650/740/M650/651/652/M652/330/660/M660/760/M760)
6 * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of the copyright holder not be used in
13 * advertising or publicity pertaining to distribution of the software without
14 * specific, written prior permission. The copyright holder makes no representations
15 * about the suitability of this software for any purpose. It is provided
16 * "as is" without express or implied warranty.
18 * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20 * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
24 * PERFORMANCE OF THIS SOFTWARE.
26 * Based on sis300_accel.c
27 * 2003/08/18: Rewritten for using VRAM command queue (TW)
29 * Author: Thomas Winischhofer <thomas@winischhofer.net>
33 #include "xf86.h"
34 #include "xf86_OSproc.h"
35 #include "xf86_ansic.h"
36 #include "xf86PciInfo.h"
37 #include "xf86Pci.h"
38 #include "compiler.h"
39 #include "xaa.h"
40 #include "xaalocal.h"
42 #include "sis.h"
43 #include "sis310_accel.h"
45 #if 0
46 #define ACCELDEBUG
47 #endif
49 #ifdef SISDUALHEAD
50 #define HEADOFFSET (pSiS->dhmOffset)
51 #endif
53 #undef TRAP /* Use/Don't use Trapezoid Fills
54 * DOES NOT WORK. XAA sometimes provides illegal
55 * trapezoid data (left and right edges cross each
56 * other) which causes drawing errors. Since
57 * checking the trapezoid for such a case is very
58 * time-intensive, it is faster to let it be done
59 * by the generic polygon functions.
60 * Does not work on XABRE at all, hangs the engine.
61 * Even with correct trapezoids, this is slower than
62 * doing it by the CPU.
65 #undef CTSCE /* Use/Don't use CPUToScreenColorExpand. Disabled
66 * because it is slower than doing it by the CPU.
67 * Indirect mode does not work in VRAM queue mode.
68 * Does not work on Xabre (even in MMIO mode).
70 #undef CTSCE_DIRECT /* Use direct method - This works (on both 315 and Xabre at
71 * least in VRAM queue mode) but we don't use this either,
72 * because it's slower than doing it by the CPU. (Using it
73 * would require defining CTSCE)
76 #undef STSCE /* Use/Don't use ScreenToScreenColorExpand - does not work,
77 * see comments below.
80 #define INCL_RENDER /* Use/Don't use RENDER extension acceleration */
82 #ifdef INCL_RENDER
83 #ifdef RENDER
84 #include "mipict.h"
85 #include "dixstruct.h"
86 #endif
87 #endif
89 /* Accelerator functions */
90 static void SiSInitializeAccelerator(ScrnInfoPtr pScrn);
91 static void SiSSync(ScrnInfoPtr pScrn);
92 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
93 int xdir, int ydir, int rop,
94 unsigned int planemask, int trans_color);
95 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
96 int x1, int y1, int x2, int y2,
97 int width, int height);
98 static void SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color,
99 int rop, unsigned int planemask);
100 static void SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
101 int x, int y, int w, int h);
102 #ifdef TRAP
103 static void SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
104 int left, int dxL, int dyL, int eL,
105 int right, int dxR, int dyR, int eR);
106 #endif
107 static void SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color,
108 int rop, unsigned int planemask);
109 static void SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1,
110 int y1, int x2, int y2, int flags);
111 static void SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
112 int x, int y, int len, int dir);
113 static void SiSSetupForDashedLine(ScrnInfoPtr pScrn,
114 int fg, int bg, int rop, unsigned int planemask,
115 int length, unsigned char *pattern);
116 static void SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
117 int x1, int y1, int x2, int y2,
118 int flags, int phase);
119 static void SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn,
120 int patx, int paty, int fg, int bg,
121 int rop, unsigned int planemask);
122 static void SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn,
123 int patx, int paty,
124 int x, int y, int w, int h);
125 #ifdef TRAP
126 static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
127 int patx, int paty,
128 int y, int h,
129 int left, int dxL, int dyL, int eL,
130 int right, int dxR, int dyR, int eR);
131 #endif
132 #ifdef SISVRAMQ
133 static void SiSSetupForColor8x8PatternFill(ScrnInfoPtr pScrn,
134 int patternx, int patterny,
135 int rop, unsigned int planemask, int trans_col);
136 static void SiSSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn,
137 int patternx, int patterny, int x, int y,
138 int w, int h);
139 #endif
140 #ifdef STSCE
141 static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
142 int fg, int bg,
143 int rop, unsigned int planemask);
144 static void SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
145 int x, int y, int w, int h,
146 int srcx, int srcy, int skipleft);
147 #endif
148 #ifdef CTSCE
149 #ifdef CTSCE_DIRECT
150 static void SiSSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
151 int fg, int bg, int rop,
152 unsigned int planemask);
153 static void SiSSubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
154 int x, int y, int w, int h,
155 int skipleft);
156 #else
157 static void SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
158 int fg, int bg, int rop,
159 unsigned int planemask);
160 static void SiSSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
161 int x, int y, int w, int h,
162 int skipleft);
163 static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
164 #endif
165 #endif
166 #ifdef INCL_RENDER
167 #ifdef RENDER
168 extern Bool SiSSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn,
169 int op, CARD16 red, CARD16 green,
170 CARD16 blue, CARD16 alpha,
171 int alphaType, CARD8 *alphaPtr,
172 int alphaPitch, int width,
173 int height, int flags);
175 extern Bool SiSSetupForCPUToScreenTexture( ScrnInfoPtr pScrn,
176 int op, int texType, CARD8 *texPtr,
177 int texPitch, int width,
178 int height, int flags);
180 extern void SiSSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn,
181 int dstx, int dsty,
182 int srcx, int srcy,
183 int width, int height);
185 extern CARD32 SiSAlphaTextureFormats[2];
186 extern CARD32 SiSTextureFormats[2];
187 CARD32 SiSAlphaTextureFormats[2] = { PICT_a8, 0 };
188 CARD32 SiSTextureFormats[2] = { PICT_a8r8g8b8, 0 };
189 #endif
190 #endif
192 #ifdef SISDUALHEAD
193 static void SiSRestoreAccelState(ScrnInfoPtr pScrn);
194 #endif
196 static void
197 SiSInitializeAccelerator(ScrnInfoPtr pScrn)
199 SISPtr pSiS = SISPTR(pScrn);
201 pSiS->DoColorExpand = FALSE;
202 pSiS->alphaBlitBusy = FALSE;
203 #ifndef SISVRAMQ
204 if(pSiS->ChipFlags & SiSCF_Integrated) {
205 CmdQueLen = 0;
206 } else {
207 CmdQueLen = ((128 * 1024) / 4) - 64;
209 #endif
212 Bool
213 SiS315AccelInit(ScreenPtr pScreen)
215 XAAInfoRecPtr infoPtr;
216 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
217 SISPtr pSiS = SISPTR(pScrn);
218 int topFB;
219 int reservedFbSize;
220 int UsableFbSize;
221 unsigned char *AvailBufBase;
222 BoxRec Avail;
223 #ifdef CTSCE
224 #ifndef CTSCE_DIRECT
225 int i;
226 #endif
227 #endif
229 pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec();
230 if(!infoPtr) return FALSE;
232 SiSInitializeAccelerator(pScrn);
234 infoPtr->Flags = LINEAR_FRAMEBUFFER |
235 OFFSCREEN_PIXMAPS |
236 PIXMAP_CACHE;
238 /* sync */
239 infoPtr->Sync = SiSSync;
241 if((pScrn->bitsPerPixel != 8) && (pScrn->bitsPerPixel != 16) &&
242 (pScrn->bitsPerPixel != 32))
243 return FALSE;
245 /* BitBlt */
246 infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy;
247 infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy;
248 infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | TRANSPARENCY_GXCOPY_ONLY;
250 /* solid fills */
251 infoPtr->SetupForSolidFill = SiSSetupForSolidFill;
252 infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect;
253 #ifdef TRAP
254 if((pSiS->Chipset != PCI_CHIP_SIS660) &&
255 (pSiS->Chipset != PCI_CHIP_SIS330)) {
256 infoPtr->SubsequentSolidFillTrap = SiSSubsequentSolidFillTrap;
258 #endif
259 infoPtr->SolidFillFlags = NO_PLANEMASK;
261 /* solid line */
262 infoPtr->SetupForSolidLine = SiSSetupForSolidLine;
263 infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine;
264 infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine;
265 infoPtr->SolidLineFlags = NO_PLANEMASK;
267 /* dashed line */
268 infoPtr->SetupForDashedLine = SiSSetupForDashedLine;
269 infoPtr->SubsequentDashedTwoPointLine = SiSSubsequentDashedTwoPointLine;
270 infoPtr->DashPatternMaxLength = 64;
271 infoPtr->DashedLineFlags = NO_PLANEMASK |
272 LINE_PATTERN_MSBFIRST_LSBJUSTIFIED;
274 /* 8x8 mono pattern fill */
275 infoPtr->SetupForMono8x8PatternFill = SiSSetupForMonoPatternFill;
276 infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMonoPatternFill;
277 #ifdef TRAP
278 if((pSiS->Chipset != PCI_CHIP_SIS660) &&
279 (pSiS->Chipset != PCI_CHIP_SIS330)) {
280 infoPtr->SubsequentMono8x8PatternFillTrap = SiSSubsequentMonoPatternFillTrap;
282 #endif
283 infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
284 HARDWARE_PATTERN_SCREEN_ORIGIN |
285 HARDWARE_PATTERN_PROGRAMMED_BITS |
286 BIT_ORDER_IN_BYTE_MSBFIRST ;
288 #ifdef SISVRAMQ
289 /* 8x8 color pattern fill (MMIO support not implemented) */
290 infoPtr->SetupForColor8x8PatternFill = SiSSetupForColor8x8PatternFill;
291 infoPtr->SubsequentColor8x8PatternFillRect = SiSSubsequentColor8x8PatternFillRect;
292 infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
293 HARDWARE_PATTERN_SCREEN_ORIGIN |
294 NO_TRANSPARENCY;
295 #endif
297 #ifdef STSCE
298 /* Screen To Screen Color Expand */
299 /* The hardware does not support this the way we need it, because
300 * the mono-bitmap is not provided with a pitch of (width), but
301 * with a pitch of scrnOffset (= width * bpp / 8).
303 infoPtr->SetupForScreenToScreenColorExpandFill =
304 SiSSetupForScreenToScreenColorExpand;
305 infoPtr->SubsequentScreenToScreenColorExpandFill =
306 SiSSubsequentScreenToScreenColorExpand;
307 infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK |
308 BIT_ORDER_IN_BYTE_MSBFIRST ;
309 #endif
311 #ifdef CTSCE
312 #ifdef CTSCE_DIRECT
313 /* CPU color expansion - direct method
315 * We somewhat fake this function here in the following way:
316 * XAA copies its mono-bitmap data not into an aperture, but
317 * into our video RAM buffer. We then do a ScreenToScreen
318 * color expand.
319 * Unfortunately, XAA sends the data to the aperture AFTER
320 * the call to Subsequent(), therefore we do not execute the
321 * command in Subsequent, but in the following call to Sync().
322 * (Hence, the SYNC_AFTER_COLOR_EXPAND flag MUST BE SET)
324 * This is slower than doing it by the CPU.
327 pSiS->ColorExpandBufferNumber = 48;
328 pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4;
329 infoPtr->SetupForCPUToScreenColorExpandFill = SiSSetupForCPUToScreenColorExpandFill;
330 infoPtr->SubsequentCPUToScreenColorExpandFill = SiSSubsequentCPUToScreenColorExpandFill;
331 infoPtr->ColorExpandRange = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize;
332 infoPtr->CPUToScreenColorExpandFillFlags =
333 NO_PLANEMASK |
334 CPU_TRANSFER_PAD_DWORD |
335 SCANLINE_PAD_DWORD |
336 BIT_ORDER_IN_BYTE_MSBFIRST |
337 LEFT_EDGE_CLIPPING |
338 SYNC_AFTER_COLOR_EXPAND;
339 #else
340 /* CPU color expansion - per-scanline / indirect method
342 * SLOW! SLOWER! SLOWEST!
344 * Does not work on XABRE, hangs the engine (both VRAM and MMIO).
345 * Does not work in VRAM queue mode.
347 #ifndef SISVRAMQ
348 if((pSiS->Chipset != PCI_CHIP_SIS650) &&
349 (pSiS->Chipset != PCI_CHIP_SIS660) &&
350 (pSiS->Chipset != PCI_CHIP_SIS330)) {
351 pSiS->ColorExpandBufferNumber = 16;
352 pSiS->ColorExpandBufferCountMask = 0x0F;
353 pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4;
354 infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber;
355 infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0];
356 infoPtr->SetupForScanlineCPUToScreenColorExpandFill = SiSSetupForScanlineCPUToScreenColorExpandFill;
357 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = SiSSubsequentScanlineCPUToScreenColorExpandFill;
358 infoPtr->SubsequentColorExpandScanline = SiSSubsequentColorExpandScanline;
359 infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
360 NO_PLANEMASK |
361 CPU_TRANSFER_PAD_DWORD |
362 SCANLINE_PAD_DWORD |
363 BIT_ORDER_IN_BYTE_MSBFIRST |
364 LEFT_EDGE_CLIPPING;
365 } else {
366 #endif
367 pSiS->ColorExpandBufferNumber = 0;
368 pSiS->PerColorExpandBufferSize = 0;
369 #ifndef SISVRAMQ
371 #endif
372 #endif
373 #else
374 pSiS->ColorExpandBufferNumber = 0;
375 pSiS->PerColorExpandBufferSize = 0;
376 #endif
378 #ifdef INCL_RENDER
379 #ifdef RENDER
380 /* Render */
381 if(((pScrn->bitsPerPixel == 16) || (pScrn->bitsPerPixel == 32)) && pSiS->doRender) {
382 int i, j;
383 if((pSiS->RenderAccelArray = xnfcalloc(65536, 1))) {
384 for(i = 0; i < 256; i++) {
385 for(j = 0; j < 256; j++) {
386 pSiS->RenderAccelArray[(i << 8) + j] = (i * j) / 255;
390 pSiS->AccelLinearScratch = NULL;
392 infoPtr->SetupForCPUToScreenAlphaTexture = SiSSetupForCPUToScreenAlphaTexture;
393 infoPtr->SubsequentCPUToScreenAlphaTexture = SiSSubsequentCPUToScreenTexture;
394 infoPtr->CPUToScreenAlphaTextureFormats = SiSAlphaTextureFormats;
395 infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE |
396 XAA_RENDER_NO_SRC_ALPHA;
398 infoPtr->SetupForCPUToScreenTexture = SiSSetupForCPUToScreenTexture;
399 infoPtr->SubsequentCPUToScreenTexture = SiSSubsequentCPUToScreenTexture;
400 infoPtr->CPUToScreenTextureFormats = SiSTextureFormats;
401 infoPtr->CPUToScreenTextureFlags = XAA_RENDER_NO_TILE;
402 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RENDER acceleration enabled\n");
405 #endif
406 #endif
408 #ifdef SISDUALHEAD
409 if(pSiS->DualHeadMode) {
410 infoPtr->RestoreAccelState = SiSRestoreAccelState;
412 #endif
414 /* Init Frame Buffer Manager */
416 topFB = pSiS->maxxfbmem;
418 reservedFbSize = (pSiS->ColorExpandBufferNumber
419 * pSiS->PerColorExpandBufferSize);
421 UsableFbSize = topFB - reservedFbSize;
422 /* Layout:
423 * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
424 * UsableFbSize ColorExpandBuffers | DRI-Heap HWCursor CommandQueue
425 * topFB
427 AvailBufBase = pSiS->FbBase + UsableFbSize;
428 #ifdef CTSCE
429 if(pSiS->ColorExpandBufferNumber) {
430 #ifdef CTSCE_DIRECT
431 infoPtr->ColorExpandBase = (unsigned char *)AvailBufBase;
432 pSiS->ColorExpandBase = UsableFbSize;
433 #else
434 for(i = 0; i < pSiS->ColorExpandBufferNumber; i++) {
435 pSiS->ColorExpandBufferAddr[i] = AvailBufBase +
436 i * pSiS->PerColorExpandBufferSize;
437 pSiS->ColorExpandBufferScreenOffset[i] = UsableFbSize +
438 i * pSiS->PerColorExpandBufferSize;
440 #endif
442 #endif
444 Avail.x1 = 0;
445 Avail.y1 = 0;
446 Avail.x2 = pScrn->displayWidth;
447 Avail.y2 = (UsableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel/8)) - 1;
449 if(Avail.y2 < 0) Avail.y2 = 32767;
450 if(Avail.y2 < pScrn->currentMode->VDisplay) {
451 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
452 "Not enough video RAM for accelerator. At least "
453 "%dKB needed, %dKB available\n",
454 ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* +8 for make it sure */
455 * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8,
456 pSiS->maxxfbmem/1024);
457 pSiS->NoAccel = TRUE;
458 pSiS->NoXvideo = TRUE;
459 XAADestroyInfoRec(pSiS->AccelInfoPtr);
460 pSiS->AccelInfoPtr = NULL;
461 return FALSE;
464 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
465 "Frame Buffer From (%d,%d) To (%d,%d)\n",
466 Avail.x1, Avail.y1, Avail.x2, Avail.y2);
468 xf86InitFBManager(pScreen, &Avail);
470 return(XAAInit(pScreen, infoPtr));
473 static void
474 SiSSync(ScrnInfoPtr pScrn)
476 SISPtr pSiS = SISPTR(pScrn);
478 PDEBUG(ErrorF("SiSSync()\n"));
480 #ifdef CTSCE
481 #ifdef CTSCE_DIRECT
482 if(pSiS->DoColorExpand) {
483 SiSDoCMD
484 pSiS->ColorExpandBusy = TRUE;
486 #endif
487 #endif
489 pSiS->DoColorExpand = FALSE;
490 pSiS->alphaBlitBusy = FALSE;
492 SiSIdle
495 #ifdef SISDUALHEAD
496 static void
497 SiSRestoreAccelState(ScrnInfoPtr pScrn)
499 SISPtr pSiS = SISPTR(pScrn);
501 pSiS->ColorExpandBusy = FALSE;
502 pSiS->alphaBlitBusy = FALSE;
503 SiSIdle
505 #endif
507 static const int sisALUConv[] =
509 0x00, /* dest = 0; 0, GXclear, 0 */
510 0x88, /* dest &= src; DSa, GXand, 0x1 */
511 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */
512 0xCC, /* dest = src; S, GXcopy, 0x3 */
513 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */
514 0xAA, /* dest = dest; D, GXnoop, 0x5 */
515 0x66, /* dest = ^src; DSx, GXxor, 0x6 */
516 0xEE, /* dest |= src; DSo, GXor, 0x7 */
517 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */
518 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */
519 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
520 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */
521 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */
522 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */
523 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */
524 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
527 /* same ROP but with Pattern as Source */
528 static const int sisPatALUConv[] =
530 0x00, /* dest = 0; 0, GXclear, 0 */
531 0xA0, /* dest &= src; DPa, GXand, 0x1 */
532 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */
533 0xF0, /* dest = src; P, GXcopy, 0x3 */
534 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */
535 0xAA, /* dest = dest; D, GXnoop, 0x5 */
536 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */
537 0xFA, /* dest |= src; DPo, GXor, 0x7 */
538 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */
539 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */
540 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */
541 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */
542 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */
543 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */
544 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */
545 0xFF, /* dest = 0xFF; 1, GXset, 0xF */
548 static void SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
549 int xdir, int ydir, int rop,
550 unsigned int planemask, int trans_color)
552 SISPtr pSiS = SISPTR(pScrn);
554 PDEBUG(ErrorF("Setup ScreenCopy(%d, %d, 0x%x, 0x%x, 0x%x)\n",
555 xdir, ydir, rop, planemask, trans_color));
557 #ifdef SISVRAMQ
558 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
559 SiSCheckQueue(16 * 2);
560 SiSSetupSRCPitchDSTRect(pSiS->scrnOffset, pSiS->scrnOffset, -1)
561 #else
562 SiSSetupDSTColorDepth(pSiS->DstColor);
563 SiSSetupSRCPitch(pSiS->scrnOffset)
564 SiSSetupDSTRect(pSiS->scrnOffset, -1)
565 #endif
567 if(trans_color != -1) {
568 SiSSetupROP(0x0A)
569 SiSSetupSRCTrans(trans_color)
570 SiSSetupCMDFlag(TRANSPARENT_BITBLT)
571 } else {
572 SiSSetupROP(sisALUConv[rop])
573 /* Set command - not needed, both 0 */
574 /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
577 #ifndef SISVRAMQ
578 SiSSetupCMDFlag(pSiS->SiS310_AccelDepth)
579 #endif
581 #ifdef SISVRAMQ
582 SiSSyncWP
583 #endif
585 /* The chip is smart enough to know the direction */
588 static void SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
589 int src_x, int src_y, int dst_x, int dst_y,
590 int width, int height)
592 SISPtr pSiS = SISPTR(pScrn);
593 long srcbase, dstbase;
594 int mymin, mymax;
596 PDEBUG(ErrorF("Subsequent ScreenCopy(%d,%d, %d,%d, %d,%d)\n",
597 src_x, src_y, dst_x, dst_y, width, height));
599 srcbase = dstbase = 0;
600 mymin = min(src_y, dst_y);
601 mymax = max(src_y, dst_y);
603 /* Libxaa.a has a bug: The tilecache cannot operate
604 * correctly if there are 512x512 slots, but no 256x256
605 * slots. This leads to catastrophic data fed to us.
606 * Filter this out here and warn the user.
608 if((src_x < 0) ||
609 (dst_x < 0) ||
610 (src_y < 0) ||
611 (dst_y < 0) ||
612 (width <= 0) ||
613 (height <= 0)) {
614 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
615 "BitBlit fatal error: Illegal coordinates:\n");
616 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
617 "Source x %d y %d, dest x %d y %d, width %d height %d\n",
618 src_x, src_y, dst_x, dst_y, width, height);
619 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
620 "This is very probably caused by a known bug in libxaa.a.\n");
621 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
622 "Please update libxaa.a to avoid this error.\n");
623 return;
626 /* Although the chip knows the direction to use
627 * if the source and destination areas overlap,
628 * that logic fails if we fiddle with the bitmap
629 * addresses. Therefore, we check if the source
630 * and destination blitting areas overlap and
631 * adapt the bitmap addresses synchronously
632 * if the coordinates exceed the valid range.
633 * The the areas do not overlap, we do our
634 * normal check.
636 if((mymax - mymin) < height) {
637 if((src_y >= 2048) || (dst_y >= 2048)) {
638 srcbase = pSiS->scrnOffset * mymin;
639 dstbase = pSiS->scrnOffset * mymin;
640 src_y -= mymin;
641 dst_y -= mymin;
643 } else {
644 if(src_y >= 2048) {
645 srcbase = pSiS->scrnOffset * src_y;
646 src_y = 0;
648 if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) {
649 dstbase = pSiS->scrnOffset * dst_y;
650 dst_y = 0;
653 #ifdef SISDUALHEAD
654 srcbase += HEADOFFSET;
655 dstbase += HEADOFFSET;
656 #endif
658 #ifdef SISVRAMQ
659 SiSCheckQueue(16 * 3);
660 SiSSetupSRCDSTBase(srcbase, dstbase)
661 SiSSetupSRCDSTXY(src_x, src_y, dst_x, dst_y)
662 SiSSetRectDoCMD(width,height)
663 #else
664 SiSSetupSRCBase(srcbase);
665 SiSSetupDSTBase(dstbase);
666 SiSSetupRect(width, height)
667 SiSSetupSRCXY(src_x, src_y)
668 SiSSetupDSTXY(dst_x, dst_y)
669 SiSDoCMD
670 #endif
673 static void
674 SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color,
675 int rop, unsigned int planemask)
677 SISPtr pSiS = SISPTR(pScrn);
679 PDEBUG(ErrorF("Setup SolidFill(0x%x, 0x%x, 0x%x)\n",
680 color, rop, planemask));
682 if(pSiS->disablecolorkeycurrent) {
683 if((CARD32)color == pSiS->colorKey) {
684 rop = 5; /* NOOP */
688 #ifdef SISVRAMQ
689 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
690 SiSCheckQueue(16 * 1);
691 SiSSetupPATFGDSTRect(color, pSiS->scrnOffset, -1)
692 SiSSetupROP(sisPatALUConv[rop])
693 SiSSetupCMDFlag(PATFG)
694 SiSSyncWP
695 #else
696 SiSSetupPATFG(color)
697 SiSSetupDSTRect(pSiS->scrnOffset, -1)
698 SiSSetupDSTColorDepth(pSiS->DstColor);
699 SiSSetupROP(sisPatALUConv[rop])
700 SiSSetupCMDFlag(PATFG | pSiS->SiS310_AccelDepth)
701 #endif
704 static void
705 SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
706 int x, int y, int w, int h)
708 SISPtr pSiS = SISPTR(pScrn);
709 long dstbase;
711 PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
712 x, y, w, h));
714 dstbase = 0;
715 if(y >= 2048) {
716 dstbase = pSiS->scrnOffset * y;
717 y = 0;
719 #ifdef SISDUALHEAD
720 dstbase += HEADOFFSET;
721 #endif
723 pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
724 T_L_X_INC | T_L_Y_INC |
725 T_R_X_INC | T_R_Y_INC |
726 TRAPAZOID_FILL);
728 /* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */
730 #ifdef SISVRAMQ
731 SiSCheckQueue(16 * 2)
732 SiSSetupDSTXYRect(x,y,w,h)
733 SiSSetupDSTBaseDoCMD(dstbase)
734 #else
735 SiSSetupDSTBase(dstbase)
736 SiSSetupDSTXY(x,y)
737 SiSSetupRect(w,h)
738 SiSDoCMD
739 #endif
742 /* Trapezoid */
743 /* This would work better if XAA would provide us with valid trapezoids.
744 * In fact, with small trapezoids the left and the right edge often cross
745 * each other which causes drawing errors (filling over whole scanline).
746 * DOES NOT WORK ON XABRE, HANGS THE ENGINE.
748 #ifdef TRAP
749 static void
750 SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
751 int left, int dxL, int dyL, int eL,
752 int right, int dxR, int dyR, int eR )
754 SISPtr pSiS = SISPTR(pScrn);
755 long dstbase;
757 dstbase = 0;
758 if(y >= 2048) {
759 dstbase = pSiS->scrnOffset * y;
760 y = 0;
762 #ifdef SISDUALHEAD
763 dstbase += HEADOFFSET;
764 #endif
766 #ifdef SISVRAMQ /* Not optimized yet */
767 SiSCheckQueue(16 * 10)
768 #else
769 SiSSetupDSTBase(dstbase)
770 #endif
772 #if 1
773 SiSSetupPATFG(0xff0000) /* FOR TESTING */
774 #endif
776 /* Clear CommandReg because SetUp can be used for Rect and Trap */
777 pSiS->CommandReg &= ~(T_L_X_INC | T_L_Y_INC |
778 T_R_X_INC | T_R_Y_INC |
779 T_XISMAJORL | T_XISMAJORR |
780 BITBLT);
782 xf86DrvMsg(0, X_INFO, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n",
783 left, right, y, h, dxL, dyL, eL, dxR, dyR, eR);
785 /* Determine egde angles */
786 if(dxL < 0) { dxL = -dxL; }
787 else { SiSSetupCMDFlag(T_L_X_INC) }
788 if(dxR < 0) { dxR = -dxR; }
789 else { SiSSetupCMDFlag(T_R_X_INC) }
791 /* (Y direction always positive - do this anyway) */
792 if(dyL < 0) { dyL = -dyL; }
793 else { SiSSetupCMDFlag(T_L_Y_INC) }
794 if(dyR < 0) { dyR = -dyR; }
795 else { SiSSetupCMDFlag(T_R_Y_INC) }
797 /* Determine major axis */
798 if(dxL >= dyL) { SiSSetupCMDFlag(T_XISMAJORL) }
799 if(dxR >= dyR) { SiSSetupCMDFlag(T_XISMAJORR) }
801 SiSSetupCMDFlag(TRAPAZOID_FILL);
803 #ifdef SISVRAMQ
804 SiSSetupYHLR(y, h, left, right)
805 SiSSetupdLdR(dxL, dyL, dxR, dyR)
806 SiSSetupELER(eL, eR)
807 SiSSetupDSTBaseDoCMD(dstbase)
808 #else
809 /* Set up deltas */
810 SiSSetupdL(dxL, dyL)
811 SiSSetupdR(dxR, dyR)
812 /* Set up y, h, left, right */
813 SiSSetupYH(y, h)
814 SiSSetupLR(left, right)
815 /* Set up initial error term */
816 SiSSetupEL(eL)
817 SiSSetupER(eR)
818 SiSDoCMD
819 #endif
821 #endif
823 static void
824 SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
825 unsigned int planemask)
827 SISPtr pSiS = SISPTR(pScrn);
829 PDEBUG(ErrorF("Setup SolidLine(0x%x, 0x%x, 0x%x)\n",
830 color, rop, planemask));
832 #ifdef SISVRAMQ
833 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
834 SiSCheckQueue(16 * 3);
835 SiSSetupLineCountPeriod(1, 1)
836 SiSSetupPATFGDSTRect(color, pSiS->scrnOffset, -1)
837 SiSSetupROP(sisPatALUConv[rop])
838 SiSSetupCMDFlag(PATFG | LINE)
839 SiSSyncWP
840 #else
841 SiSSetupLineCount(1)
842 SiSSetupPATFG(color)
843 SiSSetupDSTRect(pSiS->scrnOffset, -1)
844 SiSSetupDSTColorDepth(pSiS->DstColor)
845 SiSSetupROP(sisPatALUConv[rop])
846 SiSSetupCMDFlag(PATFG | LINE | pSiS->SiS310_AccelDepth)
847 #endif
850 static void
851 SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
852 int x1, int y1, int x2, int y2, int flags)
854 SISPtr pSiS = SISPTR(pScrn);
855 long dstbase,miny,maxy;
857 PDEBUG(ErrorF("Subsequent SolidLine(%d, %d, %d, %d, 0x%x)\n",
858 x1, y1, x2, y2, flags));
860 dstbase = 0;
861 miny = (y1 > y2) ? y2 : y1;
862 maxy = (y1 > y2) ? y1 : y2;
863 if(maxy >= 2048) {
864 dstbase = pSiS->scrnOffset*miny;
865 y1 -= miny;
866 y2 -= miny;
868 #ifdef SISDUALHEAD
869 dstbase += HEADOFFSET;
870 #endif
872 if(flags & OMIT_LAST) {
873 SiSSetupCMDFlag(NO_LAST_PIXEL)
874 } else {
875 pSiS->CommandReg &= ~(NO_LAST_PIXEL);
878 #ifdef SISVRAMQ
879 SiSCheckQueue(16 * 2);
880 SiSSetupX0Y0X1Y1(x1,y1,x2,y2)
881 SiSSetupDSTBaseDoCMD(dstbase)
882 #else
883 SiSSetupDSTBase(dstbase)
884 SiSSetupX0Y0(x1,y1)
885 SiSSetupX1Y1(x2,y2)
886 SiSDoCMD
887 #endif
890 static void
891 SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
892 int x, int y, int len, int dir)
894 SISPtr pSiS = SISPTR(pScrn);
895 long dstbase;
897 PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n",
898 x, y, len, dir));
900 len--; /* starting point is included! */
901 dstbase = 0;
902 if((y >= 2048) || ((y + len) >= 2048)) {
903 dstbase = pSiS->scrnOffset * y;
904 y = 0;
906 #ifdef SISDUALHEAD
907 dstbase += HEADOFFSET;
908 #endif
910 #ifdef SISVRAMQ
911 SiSCheckQueue(16 * 2);
912 if(dir == DEGREES_0) {
913 SiSSetupX0Y0X1Y1(x, y, (x + len), y)
914 } else {
915 SiSSetupX0Y0X1Y1(x, y, x, (y + len))
917 SiSSetupDSTBaseDoCMD(dstbase)
918 #else
919 SiSSetupDSTBase(dstbase)
920 SiSSetupX0Y0(x,y)
921 if(dir == DEGREES_0) {
922 SiSSetupX1Y1(x + len, y);
923 } else {
924 SiSSetupX1Y1(x, y + len);
926 SiSDoCMD
927 #endif
930 static void
931 SiSSetupForDashedLine(ScrnInfoPtr pScrn,
932 int fg, int bg, int rop, unsigned int planemask,
933 int length, unsigned char *pattern)
935 SISPtr pSiS = SISPTR(pScrn);
937 PDEBUG(ErrorF("Setup DashedLine(0x%x, 0x%x, 0x%x, 0x%x, %d, 0x%x:%x)\n",
938 fg, bg, rop, planemask, length, *(pattern+4), *pattern));
940 #ifdef SISVRAMQ
941 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
942 SiSCheckQueue(16 * 3);
943 SiSSetupLineCountPeriod(1, length-1)
944 SiSSetupStyle(*pattern,*(pattern+4))
945 SiSSetupPATFGDSTRect(fg, pSiS->scrnOffset, -1)
946 #else
947 SiSSetupLineCount(1)
948 SiSSetupDSTRect(pSiS->scrnOffset, -1)
949 SiSSetupDSTColorDepth(pSiS->DstColor);
950 SiSSetupStyleLow(*pattern)
951 SiSSetupStyleHigh(*(pattern+4))
952 SiSSetupStylePeriod(length-1);
953 SiSSetupPATFG(fg)
954 #endif
956 SiSSetupROP(sisPatALUConv[rop])
958 SiSSetupCMDFlag(LINE | LINE_STYLE)
960 if(bg != -1) {
961 SiSSetupPATBG(bg)
962 } else {
963 SiSSetupCMDFlag(TRANSPARENT)
965 #ifndef SISVRAMQ
966 SiSSetupCMDFlag(pSiS->SiS310_AccelDepth)
967 #endif
969 #ifdef SISVRAMQ
970 SiSSyncWP
971 #endif
974 static void
975 SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
976 int x1, int y1, int x2, int y2,
977 int flags, int phase)
979 SISPtr pSiS = SISPTR(pScrn);
980 long dstbase,miny,maxy;
982 PDEBUG(ErrorF("Subsequent DashedLine(%d,%d, %d,%d, 0x%x,0x%x)\n",
983 x1, y1, x2, y2, flags, phase));
985 dstbase = 0;
986 miny = (y1 > y2) ? y2 : y1;
987 maxy = (y1 > y2) ? y1 : y2;
988 if(maxy >= 2048) {
989 dstbase = pSiS->scrnOffset * miny;
990 y1 -= miny;
991 y2 -= miny;
993 #ifdef SISDUALHEAD
994 dstbase += HEADOFFSET;
995 #endif
997 if(flags & OMIT_LAST) {
998 SiSSetupCMDFlag(NO_LAST_PIXEL)
999 } else {
1000 pSiS->CommandReg &= ~(NO_LAST_PIXEL);
1003 #ifdef SISVRAMQ
1004 SiSCheckQueue(16 * 2);
1005 SiSSetupX0Y0X1Y1(x1,y1,x2,y2)
1006 SiSSetupDSTBaseDoCMD(dstbase)
1007 #else
1008 SiSSetupDSTBase(dstbase)
1009 SiSSetupX0Y0(x1,y1)
1010 SiSSetupX1Y1(x2,y2)
1011 SiSDoCMD
1012 #endif
1015 static void
1016 SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn,
1017 int patx, int paty, int fg, int bg,
1018 int rop, unsigned int planemask)
1020 SISPtr pSiS = SISPTR(pScrn);
1022 PDEBUG(ErrorF("Setup MonoPatFill(0x%x,0x%x, 0x%x,0x%x, 0x%x, 0x%x)\n",
1023 patx, paty, fg, bg, rop, planemask));
1025 #ifdef SISVRAMQ
1026 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1027 SiSCheckQueue(16 * 3);
1028 SiSSetupPATFGDSTRect(fg, pSiS->scrnOffset, -1)
1029 #else
1030 SiSSetupDSTRect(pSiS->scrnOffset, -1)
1031 SiSSetupDSTColorDepth(pSiS->DstColor);
1032 #endif
1034 SiSSetupMONOPAT(patx,paty)
1036 SiSSetupROP(sisPatALUConv[rop])
1038 #ifdef SISVRAMQ
1039 SiSSetupCMDFlag(PATMONO)
1040 #else
1041 SiSSetupPATFG(fg)
1042 SiSSetupCMDFlag(PATMONO | pSiS->SiS310_AccelDepth)
1043 #endif
1045 if(bg != -1) {
1046 SiSSetupPATBG(bg)
1047 } else {
1048 SiSSetupCMDFlag(TRANSPARENT)
1051 #ifdef SISVRAMQ
1052 SiSSyncWP
1053 #endif
1056 static void
1057 SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn,
1058 int patx, int paty,
1059 int x, int y, int w, int h)
1061 SISPtr pSiS = SISPTR(pScrn);
1062 long dstbase;
1064 PDEBUG(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
1065 patx, paty, x, y, w, h));
1066 dstbase = 0;
1067 if(y >= 2048) {
1068 dstbase = pSiS->scrnOffset * y;
1069 y = 0;
1071 #ifdef SISDUALHEAD
1072 dstbase += HEADOFFSET;
1073 #endif
1075 /* Clear commandReg because Setup can be used for Rect and Trap */
1076 pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
1077 T_L_X_INC | T_L_Y_INC |
1078 T_R_X_INC | T_R_Y_INC |
1079 TRAPAZOID_FILL);
1081 #ifdef SISVRAMQ
1082 SiSCheckQueue(16 * 2);
1083 SiSSetupDSTXYRect(x,y,w,h)
1084 SiSSetupDSTBaseDoCMD(dstbase)
1085 #else
1086 SiSSetupDSTBase(dstbase)
1087 SiSSetupDSTXY(x,y)
1088 SiSSetupRect(w,h)
1089 SiSDoCMD
1090 #endif
1093 /* --- Trapezoid --- */
1095 /* Does not work at all on Xabre */
1097 #ifdef TRAP
1098 static void
1099 SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
1100 int patx, int paty,
1101 int y, int h,
1102 int left, int dxL, int dyL, int eL,
1103 int right, int dxR, int dyR, int eR)
1105 SISPtr pSiS = SISPTR(pScrn);
1106 long dstbase;
1108 PDEBUG(ErrorF("Subsequent Mono8x8PatternFillTrap(%d, %d, %d - %d %d/%d %d/%d)\n",
1109 y, h, left, right, dxL, dxR, eL, eR));
1111 dstbase = 0;
1112 if(y >= 2048) {
1113 dstbase=pSiS->scrnOffset*y;
1114 y = 0;
1116 #ifdef SISDUALHEAD
1117 dstbase += HEADOFFSET;
1118 #endif
1120 #ifdef SISVRAMQ
1121 SiSCheckQueue(16 * 4);
1122 #else
1123 SiSSetupDSTBase(dstbase)
1124 #endif
1126 /* Clear CommandReg because SetUp can be used for Rect and Trap */
1127 pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
1128 T_L_X_INC | T_L_Y_INC |
1129 T_R_X_INC | T_R_Y_INC |
1130 BITBLT);
1132 if(dxL < 0) { dxL = -dxL; }
1133 else { SiSSetupCMDFlag(T_L_X_INC) }
1134 if(dxR < 0) { dxR = -dxR; }
1135 else { SiSSetupCMDFlag(T_R_X_INC) }
1137 if(dyL < 0) { dyL = -dyL; }
1138 else { SiSSetupCMDFlag(T_L_Y_INC) }
1139 if(dyR < 0) { dyR = -dyR; }
1140 else { SiSSetupCMDFlag(T_R_Y_INC) }
1142 /* Determine major axis */
1143 if(dxL >= dyL) { SiSSetupCMDFlag(T_XISMAJORL) }
1144 if(dxR >= dyR) { SiSSetupCMDFlag(T_XISMAJORR) }
1146 SiSSetupCMDFlag(TRAPAZOID_FILL);
1148 #ifdef SISVRAMQ
1149 SiSSetupYHLR(y, h, left, right)
1150 SiSSetupdLdR(dxL, dyL, dxR, dyR)
1151 SiSSetupELER(eL, eR)
1152 SiSSetupDSTBaseDoCMD(dstbase)
1153 #else
1154 SiSSetupYH(y, h)
1155 SiSSetupLR(left, right)
1156 SiSSetupdL(dxL, dyL)
1157 SiSSetupdR(dxR, dyR)
1158 SiSSetupEL(eL)
1159 SiSSetupER(eR)
1160 SiSDoCMD
1161 #endif
1163 #endif
1165 /* Color 8x8 pattern */
1167 #ifdef SISVRAMQ
1168 static void
1169 SiSSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
1170 int rop, unsigned int planemask, int trans_col)
1172 SISPtr pSiS = SISPTR(pScrn);
1173 int j = pScrn->bitsPerPixel >> 3;
1174 CARD32 *patadr = (CARD32 *)(pSiS->FbBase + (patterny * pSiS->scrnOffset) +
1175 (patternx * j));
1177 #ifdef ACCELDEBUG
1178 xf86DrvMsg(0, X_INFO, "Setup Color8x8PatFill(0x%x, 0x%x, 0x%x, 0x%x)\n",
1179 patternx, patterny, rop, planemask);
1180 #endif
1182 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1183 SiSCheckQueue(16 * 3);
1185 SiSSetupDSTRectBurstHeader(pSiS->scrnOffset, -1, PATTERN_REG, (pScrn->bitsPerPixel << 1))
1187 while(j--) {
1188 SiSSetupPatternRegBurst(patadr[0], patadr[1], patadr[2], patadr[3]);
1189 SiSSetupPatternRegBurst(patadr[4], patadr[5], patadr[6], patadr[7]);
1190 SiSSetupPatternRegBurst(patadr[8], patadr[9], patadr[10], patadr[11]);
1191 SiSSetupPatternRegBurst(patadr[12], patadr[13], patadr[14], patadr[15]);
1192 patadr += 16; /* = 64 due to (CARD32 *) */
1195 SiSSetupROP(sisPatALUConv[rop])
1197 SiSSetupCMDFlag(PATPATREG)
1199 SiSSyncWP
1202 static void
1203 SiSSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
1204 int patterny, int x, int y, int w, int h)
1206 SISPtr pSiS = SISPTR(pScrn);
1207 long dstbase;
1209 #ifdef ACCELDEBUG
1210 xf86DrvMsg(0, X_INFO, "Subsequent Color8x8FillRect(%d, %d, %d, %d)\n",
1211 x, y, w, h);
1212 #endif
1214 dstbase = 0;
1215 if(y >= 2048) {
1216 dstbase = pSiS->scrnOffset * y;
1217 y = 0;
1219 #ifdef SISDUALHEAD
1220 dstbase += HEADOFFSET;
1221 #endif
1222 /* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */
1224 SiSCheckQueue(16 * 2)
1225 SiSSetupDSTXYRect(x,y,w,h)
1226 SiSSetupDSTBaseDoCMD(dstbase)
1228 #endif
1230 /* ---- CPUToScreen Color Expand --- */
1232 #ifdef CTSCE
1234 #ifdef CTSCE_DIRECT
1236 /* Direct method */
1238 /* This is somewhat a fake. We let XAA copy its data not to an
1239 * aperture, but to video RAM, and then do a ScreenToScreen
1240 * color expansion.
1241 * Since the data is sent AFTER the call to Subsequent, we
1242 * don't execute the command here, but set a flag and do
1243 * that in the (subsequent) call to Sync()
1246 static void
1247 SiSSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
1248 int fg, int bg, int rop, unsigned int planemask)
1250 SISPtr pSiS=SISPTR(pScrn);
1252 #ifdef SISVRAMQ
1253 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1254 SiSSetupROP(sisALUConv[rop]);
1255 SiSSetupSRCFGDSTRect(fg, pSiS->scrnOffset, -1)
1256 if(bg == -1) {
1257 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO);
1258 } else {
1259 SiSSetupSRCBG(bg);
1260 SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO);
1262 SiSSyncWP
1263 #else
1264 SiSSetupSRCXY(0,0);
1265 SiSSetupROP(sisALUConv[rop]);
1266 SiSSetupSRCFG(fg);
1267 SiSSetupDSTRect(pSiS->scrnOffset, -1);
1268 SiSSetupDSTColorDepth(pSiS->DstColor);
1269 if(bg == -1) {
1270 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO
1271 | pSiS->SiS310_AccelDepth);
1272 } else {
1273 SiSSetupSRCBG(bg);
1274 SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO | pSiS->SiS310_AccelDepth);
1276 #endif
1279 static void
1280 SiSSubsequentCPUToScreenColorExpandFill(
1281 ScrnInfoPtr pScrn, int x, int y, int w,
1282 int h, int skipleft)
1284 SISPtr pSiS = SISPTR(pScrn);
1285 int _x0, _y0, _x1, _y1;
1286 long srcbase, dstbase;
1288 srcbase = pSiS->ColorExpandBase;
1290 dstbase = 0;
1291 if(y >= 2048) {
1292 dstbase = pSiS->scrnOffset*y;
1293 y = 0;
1296 #ifdef SISDUALHEAD
1297 srcbase += HEADOFFSET;
1298 dstbase += HEADOFFSET;
1299 #endif
1301 #ifdef SISVRAMQ
1302 SiSSetupSRCDSTBase(srcbase,dstbase);
1303 #else
1304 SiSSetupSRCBase(srcbase);
1305 SiSSetupDSTBase(dstbase)
1306 #endif
1308 if(skipleft > 0) {
1309 _x0 = x + skipleft;
1310 _y0 = y;
1311 _x1 = x + w;
1312 _y1 = y + h;
1313 #ifdef SISVRAMQ
1314 SiSSetupClip(_x0, _y0, _x1, _y1);
1315 #else
1316 SiSSetupClipLT(_x0, _y0);
1317 SiSSetupClipRB(_x1, _y1);
1318 #endif
1319 SiSSetupCMDFlag(CLIPENABLE);
1320 } else {
1321 pSiS->CommandReg &= (~CLIPENABLE);
1324 #ifdef SISVRAMQ
1325 SiSSetupRectSRCPitch(w, h, ((((w + 7) >> 3) + 3) >> 2) << 2);
1326 SiSSetupSRCDSTXY(0, 0, x, y);
1327 #else
1328 SiSSetupRect(w, h);
1329 SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4);
1330 SiSSetupDSTXY(x, y);
1331 #endif
1333 if(pSiS->ColorExpandBusy) {
1334 pSiS->ColorExpandBusy = FALSE;
1335 SiSIdle
1338 pSiS->DoColorExpand = TRUE;
1341 #else
1343 /* Indirect method */
1345 /* This is SLOW, slower than the CPU on most chipsets */
1346 /* Does not work in VRAM queue mode. */
1348 static void
1349 SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
1350 int fg, int bg, int rop, unsigned int planemask)
1352 SISPtr pSiS=SISPTR(pScrn);
1354 #ifdef SISVRAMQ
1355 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1356 #endif
1358 /* !!! DOES NOT WORK IN VRAM QUEUE MODE !!! */
1360 /* (hence this is not optimized for VRAM mode) */
1361 #ifndef SISVRAMQ
1362 SiSIdle
1363 #endif
1364 SiSSetupSRCXY(0,0);
1366 SiSSetupROP(sisALUConv[rop]);
1367 SiSSetupSRCFG(fg);
1368 SiSSetupDSTRect(pSiS->scrnOffset, -1);
1369 #ifndef SISVRAMQ
1370 SiSSetupDSTColorDepth(pSiS->DstColor);
1371 #endif
1372 if(bg == -1) {
1373 #ifdef SISVRAMQ
1374 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO);
1375 #else
1376 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCCPUBLITBUF
1377 | pSiS->SiS310_AccelDepth);
1378 #endif
1379 } else {
1380 SiSSetupSRCBG(bg);
1381 #ifdef SISVRAMQ
1382 SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF);
1383 #else
1384 SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF | pSiS->SiS310_AccelDepth);
1385 #endif
1390 static void
1391 SiSSubsequentScanlineCPUToScreenColorExpandFill(
1392 ScrnInfoPtr pScrn, int x, int y, int w,
1393 int h, int skipleft)
1395 SISPtr pSiS = SISPTR(pScrn);
1396 int _x0, _y0, _x1, _y1;
1397 long dstbase;
1399 dstbase = 0;
1400 if(y >= 2048) {
1401 dstbase = pSiS->scrnOffset*y;
1402 y = 0;
1404 #ifdef SISDUALHEAD
1405 dstbase += HEADOFFSET;
1406 #endif
1408 #ifndef SISVRAMQ
1409 if((MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {
1410 SiSIdle;
1412 #endif
1414 SiSSetupDSTBase(dstbase)
1416 if(skipleft > 0) {
1417 _x0 = x+skipleft;
1418 _y0 = y;
1419 _x1 = x+w;
1420 _y1 = y+h;
1421 #ifdef SISVRAMQ
1422 SiSSetupClip(_x0, _y0, _x1, _y1);
1423 #else
1424 SiSSetupClipLT(_x0, _y0);
1425 SiSSetupClipRB(_x1, _y1);
1426 #endif
1427 SiSSetupCMDFlag(CLIPENABLE);
1428 } else {
1429 pSiS->CommandReg &= (~CLIPENABLE);
1431 SiSSetupRect(w, 1);
1432 SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4);
1433 pSiS->ycurrent = y;
1434 pSiS->xcurrent = x;
1438 static void
1439 SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
1441 SISPtr pSiS = SISPTR(pScrn);
1442 long cbo;
1444 cbo = pSiS->ColorExpandBufferScreenOffset[bufno];
1445 #ifdef SISDUALHEAD
1446 cbo += HEADOFFSET;
1447 #endif
1449 #ifndef SISVRAMQ
1450 if((MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {
1451 SiSIdle;
1453 #endif
1455 SiSSetupSRCBase(cbo);
1457 SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent);
1459 SiSDoCMD
1461 pSiS->ycurrent++;
1462 #ifndef SISVRAMQ
1463 SiSIdle
1464 #endif
1466 #endif
1467 #endif
1469 /* --- Screen To Screen Color Expand --- */
1471 /* This method blits in a single task; this does not work because
1472 * the hardware does not use the source pitch as scanline offset
1473 * but to calculate pattern address from source X and Y and to
1474 * limit the drawing width (similar to width set by SetupRect).
1475 * XAA provides the pattern bitmap with scrnOffset (displayWidth * bpp/8)
1476 * offset, but this is not supported by the hardware.
1477 * DOES NOT WORK ON XABRE, HANGS ENGINE.
1480 #ifdef STSCE
1481 static void
1482 SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
1483 int fg, int bg,
1484 int rop, unsigned int planemask)
1486 SISPtr pSiS = SISPTR(pScrn);
1488 #ifdef SISVRAMQ
1489 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1490 #else
1491 SiSSetupDSTColorDepth(pSiS->DstColor)
1492 #endif
1493 SiSSetupDSTRect(pSiS->scrnOffset, -1)
1494 SiSSetupROP(sisALUConv[rop])
1495 SiSSetupSRCFG(fg)
1496 /* SiSSetupSRCXY(0,0) */
1498 if(bg == -1) {
1499 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO);
1500 } else {
1501 SiSSetupSRCBG(bg);
1502 SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO);
1505 #ifdef SISVRAMQ
1506 SiSSyncWP
1507 #endif
1510 /* For testing, these are the methods: (use only one at a time!) */
1512 #undef npitch /* Normal: Use srcx/y as srcx/y, use scrnOffset as source pitch
1513 * Does not work on 315 series, because the hardware does not
1514 * regard the src x and y. Apart from this problem:
1515 * This would work if the hareware used the source pitch for
1516 * incrementing the source address after each scanline - but
1517 * it doesn't do this! The first line of the area is correctly
1518 * color expanded, but since the source pitch is ignored and
1519 * the source address not incremented correctly, the following
1520 * lines are color expanded with any bit pattern that is left
1521 * in the unused space of the source bitmap (which is organized
1522 * with the depth of the screen framebuffer hence with a pitch
1523 * of scrnOffset).
1526 #undef pitchdw /* Use source pitch "displayWidth / 8" instead
1527 * of scrnOffset (=displayWidth * bpp / 8)
1528 * This can't work, because the pitch of the source
1529 * bitmap is scrnoffset!
1532 #define nopitch /* Calculate srcbase with srcx and srcy, set the
1533 * pitch to scrnOffset (which IS the correct pitch
1534 * for the source bitmap) and set srcx and srcy both
1535 * to 0.
1536 * This would work if the hareware used the source pitch for
1537 * incrementing the source address after each scanline - but
1538 * it doesn't do this! Again: The first line of the area is
1539 * correctly color expanded, but since the source pitch is
1540 * ignored for scanline address incremention, the following
1541 * lines are not correctly color expanded.
1542 * This is the only way it works (apart from the problem
1543 * described above). The hardware does not regard the src
1544 * x and y values in any way.
1547 static void
1548 SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
1549 int x, int y, int w, int h,
1550 int srcx, int srcy, int skipleft)
1552 SISPtr pSiS = SISPTR(pScrn);
1553 long srcbase, dstbase;
1554 #if 0
1555 int _x0, _y0, _x1, _y1;
1556 #endif
1557 #ifdef pitchdw
1558 int newsrcx, newsrcy;
1560 /* srcx and srcy are provided based on a scrnOffset pitch ( = displayWidth * bpp / 8 )
1561 * We recalulate srcx and srcy based on pitch = displayWidth / 8
1563 newsrcy = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) /
1564 (pScrn->displayWidth/8);
1565 newsrcx = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) %
1566 (pScrn->displayWidth/8);
1567 #endif
1568 xf86DrvMsg(0, X_INFO, "Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n",
1569 x, y, w, h, srcx, srcy, skipleft);
1571 srcbase = dstbase = 0;
1573 #ifdef pitchdw
1574 if(newsrcy >= 2048) {
1575 srcbase = (pScrn->displayWidth / 8) * newsrcy;
1576 newsrcy = 0;
1578 #endif
1579 #ifdef nopitch
1580 srcbase = (pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8));
1581 #endif
1582 #ifdef npitch
1583 if(srcy >= 2048) {
1584 srcbase = pSiS->scrnOffset * srcy;
1585 srcy = 0;
1587 #endif
1588 if(y >= 2048) {
1589 dstbase = pSiS->scrnOffset * y;
1590 y = 0;
1593 #ifdef SISDUALHEAD
1594 srcbase += HEADOFFSET;
1595 dstbase += HEADOFFSET;
1596 #endif
1598 SiSSetupSRCBase(srcbase)
1599 SiSSetupDSTBase(dstbase)
1601 /* 315 series seem to treat the src pitch as
1602 * a "drawing limit", but still (as 300 series)
1603 * does not use it for incrementing the
1604 * address pointer for the next scanline. ARGH!
1607 #ifdef pitchdw
1608 SiSSetupSRCPitch(pScrn->displayWidth/8)
1609 #endif
1610 #ifdef nopitch
1611 SiSSetupSRCPitch(pScrn->displayWidth/8)
1612 /* SiSSetupSRCPitch(1024/8) */ /* For test */
1613 #endif
1614 #ifdef npitch
1615 SiSSetupSRCPitch(pScrn->displayWidth/8)
1616 /* SiSSetupSRCPitch(pSiS->scrnOffset) */
1617 #endif
1619 SiSSetupRect(w,h)
1621 #if 0 /* How do I implement the offset? Not this way, that's for sure.. */
1622 if (skipleft > 0) {
1623 _x0 = x+skipleft;
1624 _y0 = y;
1625 _x1 = x+w;
1626 _y1 = y+h;
1627 SiSSetupClipLT(_x0, _y0);
1628 SiSSetupClipRB(_x1, _y1);
1629 SiSSetupCMDFlag(CLIPENABLE);
1631 #endif
1632 #ifdef pitchdw
1633 SiSSetupSRCXY(newsrcx, newsrcy)
1634 #endif
1635 #ifdef nopitch
1636 SiSSetupSRCXY(0,0)
1637 #endif
1638 #ifdef npitch
1639 SiSSetupSRCXY(srcx, srcy)
1640 #endif
1642 SiSSetupDSTXY(x,y)
1644 SiSDoCMD
1645 #ifdef SISVRAMQ
1646 /* We MUST sync here, there must not be 2 or more color expansion commands in the queue */
1647 SiSIdle
1648 #endif
1650 #endif
1652 /* ---- RENDER ---- */
1654 #ifdef INCL_RENDER
1655 #ifdef RENDER
1656 static void
1657 SiSRenderCallback(ScrnInfoPtr pScrn)
1659 SISPtr pSiS = SISPTR(pScrn);
1661 if((currentTime.milliseconds > pSiS->RenderTime) && pSiS->AccelLinearScratch) {
1662 xf86FreeOffscreenLinear(pSiS->AccelLinearScratch);
1663 pSiS->AccelLinearScratch = NULL;
1666 if(!pSiS->AccelLinearScratch) {
1667 pSiS->RenderCallback = NULL;
1671 #define RENDER_DELAY 15000
1673 static Bool
1674 SiSAllocateLinear(ScrnInfoPtr pScrn, int sizeNeeded)
1676 SISPtr pSiS = SISPTR(pScrn);
1678 pSiS->RenderTime = currentTime.milliseconds + RENDER_DELAY;
1679 pSiS->RenderCallback = SiSRenderCallback;
1681 if(pSiS->AccelLinearScratch) {
1682 if(pSiS->AccelLinearScratch->size >= sizeNeeded) {
1683 return TRUE;
1684 } else {
1685 if(pSiS->alphaBlitBusy) {
1686 pSiS->alphaBlitBusy = FALSE;
1687 SiSIdle
1689 if(xf86ResizeOffscreenLinear(pSiS->AccelLinearScratch, sizeNeeded)) {
1690 return TRUE;
1692 xf86FreeOffscreenLinear(pSiS->AccelLinearScratch);
1693 pSiS->AccelLinearScratch = NULL;
1697 pSiS->AccelLinearScratch = xf86AllocateOffscreenLinear(
1698 pScrn->pScreen, sizeNeeded, 32,
1699 NULL, NULL, NULL);
1701 return(pSiS->AccelLinearScratch != NULL);
1704 Bool
1705 SiSSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn,
1706 int op, CARD16 red, CARD16 green,
1707 CARD16 blue, CARD16 alpha,
1708 int alphaType, CARD8 *alphaPtr,
1709 int alphaPitch, int width,
1710 int height, int flags)
1712 SISPtr pSiS = SISPTR(pScrn);
1713 int x, pitch, sizeNeeded, offset;
1714 CARD8 myalpha;
1715 CARD32 *dstPtr;
1716 unsigned char *renderaccelarray;
1718 #ifdef ACCELDEBUG
1719 xf86DrvMsg(0, X_INFO, "AT: op %d RGB %x %x %x, w %d h %d A-pitch %d\n",
1720 op, red, green, blue, width, height, alphaPitch);
1721 #endif
1723 if(op != PictOpOver) return FALSE;
1725 if((width > 2048) || (height > 2048)) return FALSE;
1727 pitch = (width + 31) & ~31;
1728 sizeNeeded = pitch * height;
1729 if(pScrn->bitsPerPixel == 16) sizeNeeded <<= 1;
1731 red &= 0xff00;
1732 green &= 0xff00;
1733 blue &= 0xff00;
1734 renderaccelarray = pSiS->RenderAccelArray;
1736 if(!SiSAllocateLinear(pScrn, sizeNeeded))
1737 return FALSE;
1739 #ifdef SISVRAMQ
1740 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1741 SiSSetupSRCPitchDSTRect((pitch << 2), pSiS->scrnOffset, -1);
1742 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA)
1743 SiSSyncWP
1744 #else
1745 SiSSetupDSTColorDepth(pSiS->DstColor);
1746 SiSSetupSRCPitch((pitch << 2));
1747 SiSSetupDSTRect(pSiS->scrnOffset, -1)
1748 SiSSetupROP(0)
1749 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA | pSiS->SiS310_AccelDepth)
1750 #endif
1752 offset = pSiS->AccelLinearScratch->offset << 1;
1753 if(pScrn->bitsPerPixel == 32) offset <<= 1;
1755 dstPtr = (CARD32*)(pSiS->FbBase + offset);
1757 if(pSiS->alphaBlitBusy) {
1758 pSiS->alphaBlitBusy = FALSE;
1759 SiSIdle
1762 while(height--) {
1763 for(x = 0; x < width; x++) {
1764 myalpha = alphaPtr[x];
1765 dstPtr[x] = (renderaccelarray[red + myalpha] << 16) |
1766 (renderaccelarray[green + myalpha] << 8) |
1767 renderaccelarray[blue + myalpha] |
1768 myalpha << 24;
1770 dstPtr += pitch;
1771 alphaPtr += alphaPitch;
1774 return TRUE;
1777 Bool
1778 SiSSetupForCPUToScreenTexture(ScrnInfoPtr pScrn,
1779 int op, int texType, CARD8 *texPtr,
1780 int texPitch, int width,
1781 int height, int flags)
1783 SISPtr pSiS = SISPTR(pScrn);
1784 int pitch, sizeNeeded, offset;
1785 CARD8 *dst;
1787 #ifdef ACCELDEBUG
1788 xf86DrvMsg(0, X_INFO, "T: type %d op %d w %d h %d T-pitch %d\n",
1789 texType, op, width, height, texPitch);
1790 #endif
1792 if(op != PictOpOver) return FALSE;
1794 if((width > 2048) || (height > 2048)) return FALSE;
1796 pitch = (width + 31) & ~31;
1797 sizeNeeded = pitch * height;
1798 if(pScrn->bitsPerPixel == 16) sizeNeeded <<= 1;
1800 width <<= 2;
1801 pitch <<= 2;
1803 if(!SiSAllocateLinear(pScrn, sizeNeeded))
1804 return FALSE;
1806 #ifdef SISVRAMQ
1807 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1808 SiSSetupSRCPitchDSTRect(pitch, pSiS->scrnOffset, -1);
1809 SiSSetupAlpha(0x00)
1810 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA)
1811 SiSSyncWP
1812 #else
1813 SiSSetupDSTColorDepth(pSiS->DstColor);
1814 SiSSetupSRCPitch(pitch);
1815 SiSSetupDSTRect(pSiS->scrnOffset, -1)
1816 SiSSetupAlpha(0x00)
1817 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA | pSiS->SiS310_AccelDepth)
1818 #endif
1820 offset = pSiS->AccelLinearScratch->offset << 1;
1821 if(pScrn->bitsPerPixel == 32) offset <<= 1;
1823 dst = (CARD8*)(pSiS->FbBase + offset);
1825 if(pSiS->alphaBlitBusy) {
1826 pSiS->alphaBlitBusy = FALSE;
1827 SiSIdle
1830 while(height--) {
1831 memcpy(dst, texPtr, width);
1832 texPtr += texPitch;
1833 dst += pitch;
1836 return TRUE;
1839 void
1840 SiSSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn,
1841 int dst_x, int dst_y,
1842 int src_x, int src_y,
1843 int width, int height)
1845 SISPtr pSiS = SISPTR(pScrn);
1846 long srcbase, dstbase;
1848 srcbase = pSiS->AccelLinearScratch->offset << 1;
1849 if(pScrn->bitsPerPixel == 32)
1850 srcbase <<= 1;
1852 #ifdef ACCELDEBUG
1853 xf86DrvMsg(0, X_INFO, "FIRE: scrbase %x dx %d dy %d w %d h %d\n",
1854 srcbase, dst_x, dst_y, width, height);
1855 #endif
1857 dstbase = 0;
1858 if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) {
1859 dstbase = pSiS->scrnOffset * dst_y;
1860 dst_y = 0;
1862 #ifdef SISDUALHEAD
1863 srcbase += HEADOFFSET;
1864 dstbase += HEADOFFSET;
1865 #endif
1867 #ifdef SISVRAMQ
1868 SiSCheckQueue(16 * 3)
1869 SiSSetupSRCDSTBase(srcbase,dstbase);
1870 SiSSetupSRCDSTXY(src_x, src_y, dst_x, dst_y)
1871 SiSSetRectDoCMD(width,height)
1872 #else
1873 SiSSetupSRCBase(srcbase);
1874 SiSSetupDSTBase(dstbase);
1875 SiSSetupRect(width, height)
1876 SiSSetupSRCXY(src_x, src_y)
1877 SiSSetupDSTXY(dst_x, dst_y)
1878 SiSDoCMD
1879 #endif
1880 pSiS->alphaBlitBusy = TRUE;
1882 #endif
1883 #endif