readding XFree86's cvs IDs
[xf86-video-sis/mirage.git] / src / sis310_accel.c
blobf64977a522972ec6b80a772d74ec04528b5f0cb5
1 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis310_accel.c,v 1.37 2004/01/27 11:58:27 twini Exp $ */
2 /*
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
9 * are met:
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
39 #include "xf86.h"
40 #include "xf86_OSproc.h"
41 #include "xf86_ansic.h"
42 #include "xf86PciInfo.h"
43 #include "xf86Pci.h"
44 #include "compiler.h"
45 #include "xaa.h"
46 #include "xaalocal.h"
47 #include "xaarop.h"
49 #include "sis.h"
50 #include "sis310_accel.h"
52 #if 0
53 #define ACCELDEBUG
54 #endif
56 #ifdef SISDUALHEAD
57 #define HEADOFFSET (pSiS->dhmOffset)
58 #endif
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,
84 * see comments below.
87 #define INCL_RENDER /* Use/Don't use RENDER extension acceleration */
89 #ifdef INCL_RENDER
90 #ifdef RENDER
91 #include "mipict.h"
92 #include "dixstruct.h"
93 #endif
94 #endif
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);
109 #ifdef TRAP
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);
113 #endif
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,
130 int patx, int paty,
131 int x, int y, int w, int h);
132 #ifdef TRAP
133 static void SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
134 int patx, int paty,
135 int y, int h,
136 int left, int dxL, int dyL, int eL,
137 int right, int dxR, int dyR, int eR);
138 #endif
139 #ifdef SISVRAMQ
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,
145 int w, int h);
146 #endif
147 #ifdef STSCE
148 static void SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
149 int fg, int bg,
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);
154 #endif
155 #ifdef CTSCE
156 #ifdef CTSCE_DIRECT
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,
162 int skipleft);
163 #else
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,
169 int skipleft);
170 static void SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno);
171 #endif
172 #endif
173 #ifdef INCL_RENDER
174 #ifdef RENDER
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,
188 int dstx, int dsty,
189 int srcx, int srcy,
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 };
196 #endif
197 #endif
199 #ifdef SISDUALHEAD
200 static void SiSRestoreAccelState(ScrnInfoPtr pScrn);
201 #endif
203 static void
204 SiSInitializeAccelerator(ScrnInfoPtr pScrn)
206 SISPtr pSiS = SISPTR(pScrn);
208 pSiS->DoColorExpand = FALSE;
209 pSiS->alphaBlitBusy = FALSE;
210 #ifndef SISVRAMQ
211 if(pSiS->ChipFlags & SiSCF_Integrated) {
212 CmdQueLen = 0;
213 } else {
214 CmdQueLen = ((128 * 1024) / 4) - 64;
216 #endif
219 Bool
220 SiS315AccelInit(ScreenPtr pScreen)
222 XAAInfoRecPtr infoPtr;
223 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
224 SISPtr pSiS = SISPTR(pScrn);
225 int topFB;
226 int reservedFbSize;
227 int UsableFbSize;
228 BoxRec Avail;
229 #ifdef SISDUALHEAD
230 SISEntPtr pSiSEnt = NULL;
231 #endif
232 #ifdef CTSCE
233 unsigned char *AvailBufBase;
234 #ifndef CTSCE_DIRECT
235 int i;
236 #endif
237 #endif
239 pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec();
240 if(!infoPtr) return FALSE;
242 SiSInitializeAccelerator(pScrn);
244 infoPtr->Flags = LINEAR_FRAMEBUFFER |
245 OFFSCREEN_PIXMAPS |
246 PIXMAP_CACHE;
248 /* sync */
249 infoPtr->Sync = SiSSync;
251 if((pScrn->bitsPerPixel != 8) && (pScrn->bitsPerPixel != 16) &&
252 (pScrn->bitsPerPixel != 32))
253 return FALSE;
255 #ifdef SISDUALHEAD
256 pSiSEnt = pSiS->entityPrivate;
257 #endif
259 /* BitBlt */
260 infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy;
261 infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy;
262 infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | TRANSPARENCY_GXCOPY_ONLY;
264 /* solid fills */
265 infoPtr->SetupForSolidFill = SiSSetupForSolidFill;
266 infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect;
267 #ifdef TRAP
268 if((pSiS->Chipset != PCI_CHIP_SIS660) &&
269 (pSiS->Chipset != PCI_CHIP_SIS330)) {
270 infoPtr->SubsequentSolidFillTrap = SiSSubsequentSolidFillTrap;
272 #endif
273 infoPtr->SolidFillFlags = NO_PLANEMASK;
275 /* solid line */
276 infoPtr->SetupForSolidLine = SiSSetupForSolidLine;
277 infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine;
278 infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine;
279 infoPtr->SolidLineFlags = NO_PLANEMASK;
281 /* dashed line */
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;
291 #ifdef TRAP
292 if((pSiS->Chipset != PCI_CHIP_SIS660) &&
293 (pSiS->Chipset != PCI_CHIP_SIS330)) {
294 infoPtr->SubsequentMono8x8PatternFillTrap = SiSSubsequentMonoPatternFillTrap;
296 #endif
297 infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
298 HARDWARE_PATTERN_SCREEN_ORIGIN |
299 HARDWARE_PATTERN_PROGRAMMED_BITS |
300 BIT_ORDER_IN_BYTE_MSBFIRST;
302 #ifdef SISVRAMQ
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 |
308 NO_TRANSPARENCY;
309 #endif
311 #ifdef STSCE
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 ;
323 #endif
325 #ifdef CTSCE
326 #ifdef CTSCE_DIRECT
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
332 * color expand.
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 =
347 NO_PLANEMASK |
348 CPU_TRANSFER_PAD_DWORD |
349 SCANLINE_PAD_DWORD |
350 BIT_ORDER_IN_BYTE_MSBFIRST |
351 LEFT_EDGE_CLIPPING |
352 SYNC_AFTER_COLOR_EXPAND;
353 #else
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.
361 #ifndef SISVRAMQ
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 =
374 NO_PLANEMASK |
375 CPU_TRANSFER_PAD_DWORD |
376 SCANLINE_PAD_DWORD |
377 BIT_ORDER_IN_BYTE_MSBFIRST |
378 LEFT_EDGE_CLIPPING;
379 } else {
380 #endif
381 pSiS->ColorExpandBufferNumber = 0;
382 pSiS->PerColorExpandBufferSize = 0;
383 #ifndef SISVRAMQ
385 #endif
386 #endif
387 #else
388 pSiS->ColorExpandBufferNumber = 0;
389 pSiS->PerColorExpandBufferSize = 0;
390 #endif
392 pSiS->RenderAccelArray = NULL;
394 #ifdef INCL_RENDER
395 #ifdef RENDER
396 /* Render */
397 if(((pScrn->bitsPerPixel == 16) || (pScrn->bitsPerPixel == 32)) && pSiS->doRender) {
398 int i, j;
399 #ifdef SISDUALHEAD
400 if(pSiSEnt) pSiS->RenderAccelArray = pSiSEnt->RenderAccelArray;
401 #endif
402 if(!pSiS->RenderAccelArray) {
403 if((pSiS->RenderAccelArray = xnfcalloc(65536, 1))) {
404 #ifdef SISDUALHEAD
405 if(pSiSEnt) pSiSEnt->RenderAccelArray = pSiS->RenderAccelArray;
406 #endif
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");
429 #endif
430 #endif
432 #ifdef SISDUALHEAD
433 if(pSiS->DualHeadMode) {
434 infoPtr->RestoreAccelState = SiSRestoreAccelState;
436 #endif
438 /* Init Frame Buffer Manager */
440 topFB = pSiS->maxxfbmem;
442 reservedFbSize = (pSiS->ColorExpandBufferNumber
443 * pSiS->PerColorExpandBufferSize);
445 UsableFbSize = topFB - reservedFbSize;
446 /* Layout:
447 * |--------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
448 * UsableFbSize ColorExpandBuffers | DRI-Heap HWCursor CommandQueue
449 * topFB
451 #ifdef CTSCE
452 AvailBufBase = pSiS->FbBase + UsableFbSize;
453 if(pSiS->ColorExpandBufferNumber) {
454 #ifdef CTSCE_DIRECT
455 infoPtr->ColorExpandBase = (unsigned char *)AvailBufBase;
456 pSiS->ColorExpandBase = UsableFbSize;
457 #else
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;
464 #endif
466 #endif
468 Avail.x1 = 0;
469 Avail.y1 = 0;
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;
485 return FALSE;
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));
497 static void
498 SiSSync(ScrnInfoPtr pScrn)
500 SISPtr pSiS = SISPTR(pScrn);
502 PDEBUG(ErrorF("SiSSync()\n"));
504 #ifdef CTSCE
505 #ifdef CTSCE_DIRECT
506 if(pSiS->DoColorExpand) {
507 SiSDoCMD
508 pSiS->ColorExpandBusy = TRUE;
510 #endif
511 #endif
513 pSiS->DoColorExpand = FALSE;
514 pSiS->alphaBlitBusy = FALSE;
516 SiSIdle
519 #ifdef SISDUALHEAD
520 static void
521 SiSRestoreAccelState(ScrnInfoPtr pScrn)
523 SISPtr pSiS = SISPTR(pScrn);
525 pSiS->ColorExpandBusy = FALSE;
526 pSiS->alphaBlitBusy = FALSE;
527 SiSIdle
529 #endif
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));
540 #ifdef SISVRAMQ
541 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
542 SiSCheckQueue(16 * 2);
543 SiSSetupSRCPitchDSTRect(pSiS->scrnOffset, pSiS->scrnOffset, -1)
544 #else
545 SiSSetupDSTColorDepth(pSiS->DstColor);
546 SiSSetupSRCPitch(pSiS->scrnOffset)
547 SiSSetupDSTRect(pSiS->scrnOffset, -1)
548 #endif
550 if(trans_color != -1) {
551 SiSSetupROP(0x0A)
552 SiSSetupSRCTrans(trans_color)
553 SiSSetupCMDFlag(TRANSPARENT_BITBLT)
554 } else {
555 SiSSetupROP(XAACopyROP[rop])
556 /* Set command - not needed, both 0 */
557 /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
560 #ifndef SISVRAMQ
561 SiSSetupCMDFlag(pSiS->SiS310_AccelDepth)
562 #endif
564 #ifdef SISVRAMQ
565 SiSSyncWP
566 #endif
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;
577 int mymin, mymax;
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))
593 if((src_x < 0) ||
594 (dst_x < 0) ||
595 (src_y < 0) ||
596 (dst_y < 0) ||
597 (width <= 0) ||
598 (height <= 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");
608 return;
610 #endif
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
620 * normal check.
622 if((mymax - mymin) < height) {
623 if((src_y >= 2048) || (dst_y >= 2048)) {
624 srcbase = pSiS->scrnOffset * mymin;
625 dstbase = pSiS->scrnOffset * mymin;
626 src_y -= mymin;
627 dst_y -= mymin;
629 } else {
630 if(src_y >= 2048) {
631 srcbase = pSiS->scrnOffset * src_y;
632 src_y = 0;
634 if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) {
635 dstbase = pSiS->scrnOffset * dst_y;
636 dst_y = 0;
639 #ifdef SISDUALHEAD
640 srcbase += HEADOFFSET;
641 dstbase += HEADOFFSET;
642 #endif
644 #ifdef SISVRAMQ
645 SiSCheckQueue(16 * 3);
646 SiSSetupSRCDSTBase(srcbase, dstbase)
647 SiSSetupSRCDSTXY(src_x, src_y, dst_x, dst_y)
648 SiSSetRectDoCMD(width,height)
649 #else
650 SiSSetupSRCBase(srcbase);
651 SiSSetupDSTBase(dstbase);
652 SiSSetupRect(width, height)
653 SiSSetupSRCXY(src_x, src_y)
654 SiSSetupDSTXY(dst_x, dst_y)
655 SiSDoCMD
656 #endif
659 static void
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) {
670 rop = 5; /* NOOP */
674 #ifdef SISVRAMQ
675 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
676 SiSCheckQueue(16 * 1);
677 SiSSetupPATFGDSTRect(color, pSiS->scrnOffset, -1)
678 SiSSetupROP(XAAPatternROP[rop])
679 SiSSetupCMDFlag(PATFG)
680 SiSSyncWP
681 #else
682 SiSSetupPATFG(color)
683 SiSSetupDSTRect(pSiS->scrnOffset, -1)
684 SiSSetupDSTColorDepth(pSiS->DstColor);
685 SiSSetupROP(XAAPatternROP[rop])
686 SiSSetupCMDFlag(PATFG | pSiS->SiS310_AccelDepth)
687 #endif
690 static void
691 SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
692 int x, int y, int w, int h)
694 SISPtr pSiS = SISPTR(pScrn);
695 long dstbase;
697 PDEBUG(ErrorF("Subsequent SolidFillRect(%d, %d, %d, %d)\n",
698 x, y, w, h));
700 dstbase = 0;
701 if(y >= 2048) {
702 dstbase = pSiS->scrnOffset * y;
703 y = 0;
705 #ifdef SISDUALHEAD
706 dstbase += HEADOFFSET;
707 #endif
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 |
712 TRAPAZOID_FILL);
714 /* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */
716 #ifdef SISVRAMQ
717 SiSCheckQueue(16 * 2)
718 SiSSetupDSTXYRect(x,y,w,h)
719 SiSSetupDSTBaseDoCMD(dstbase)
720 #else
721 SiSSetupDSTBase(dstbase)
722 SiSSetupDSTXY(x,y)
723 SiSSetupRect(w,h)
724 SiSDoCMD
725 #endif
728 /* Trapezoid */
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.
734 #ifdef TRAP
735 static void
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);
741 long dstbase;
743 dstbase = 0;
744 if(y >= 2048) {
745 dstbase = pSiS->scrnOffset * y;
746 y = 0;
748 #ifdef SISDUALHEAD
749 dstbase += HEADOFFSET;
750 #endif
752 #ifdef SISVRAMQ /* Not optimized yet */
753 SiSCheckQueue(16 * 10)
754 #else
755 SiSSetupDSTBase(dstbase)
756 #endif
758 #if 1
759 SiSSetupPATFG(0xff0000) /* FOR TESTING */
760 #endif
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 |
766 BITBLT);
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);
789 #ifdef SISVRAMQ
790 SiSSetupYHLR(y, h, left, right)
791 SiSSetupdLdR(dxL, dyL, dxR, dyR)
792 SiSSetupELER(eL, eR)
793 SiSSetupDSTBaseDoCMD(dstbase)
794 #else
795 /* Set up deltas */
796 SiSSetupdL(dxL, dyL)
797 SiSSetupdR(dxR, dyR)
798 /* Set up y, h, left, right */
799 SiSSetupYH(y, h)
800 SiSSetupLR(left, right)
801 /* Set up initial error term */
802 SiSSetupEL(eL)
803 SiSSetupER(eR)
804 SiSDoCMD
805 #endif
807 #endif
809 static void
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));
818 #ifdef SISVRAMQ
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)
825 SiSSyncWP
826 #else
827 SiSSetupLineCount(1)
828 SiSSetupPATFG(color)
829 SiSSetupDSTRect(pSiS->scrnOffset, -1)
830 SiSSetupDSTColorDepth(pSiS->DstColor)
831 SiSSetupROP(XAAPatternROP[rop])
832 SiSSetupCMDFlag(PATFG | LINE | pSiS->SiS310_AccelDepth)
833 #endif
836 static void
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));
846 dstbase = 0;
847 miny = (y1 > y2) ? y2 : y1;
848 maxy = (y1 > y2) ? y1 : y2;
849 if(maxy >= 2048) {
850 dstbase = pSiS->scrnOffset*miny;
851 y1 -= miny;
852 y2 -= miny;
854 #ifdef SISDUALHEAD
855 dstbase += HEADOFFSET;
856 #endif
858 if(flags & OMIT_LAST) {
859 SiSSetupCMDFlag(NO_LAST_PIXEL)
860 } else {
861 pSiS->CommandReg &= ~(NO_LAST_PIXEL);
864 #ifdef SISVRAMQ
865 SiSCheckQueue(16 * 2);
866 SiSSetupX0Y0X1Y1(x1,y1,x2,y2)
867 SiSSetupDSTBaseDoCMD(dstbase)
868 #else
869 SiSSetupDSTBase(dstbase)
870 SiSSetupX0Y0(x1,y1)
871 SiSSetupX1Y1(x2,y2)
872 SiSDoCMD
873 #endif
876 static void
877 SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
878 int x, int y, int len, int dir)
880 SISPtr pSiS = SISPTR(pScrn);
881 long dstbase;
883 PDEBUG(ErrorF("Subsequent SolidHorzVertLine(%d, %d, %d, %d)\n",
884 x, y, len, dir));
886 len--; /* starting point is included! */
887 dstbase = 0;
888 if((y >= 2048) || ((y + len) >= 2048)) {
889 dstbase = pSiS->scrnOffset * y;
890 y = 0;
892 #ifdef SISDUALHEAD
893 dstbase += HEADOFFSET;
894 #endif
896 #ifdef SISVRAMQ
897 SiSCheckQueue(16 * 2);
898 if(dir == DEGREES_0) {
899 SiSSetupX0Y0X1Y1(x, y, (x + len), y)
900 } else {
901 SiSSetupX0Y0X1Y1(x, y, x, (y + len))
903 SiSSetupDSTBaseDoCMD(dstbase)
904 #else
905 SiSSetupDSTBase(dstbase)
906 SiSSetupX0Y0(x,y)
907 if(dir == DEGREES_0) {
908 SiSSetupX1Y1(x + len, y);
909 } else {
910 SiSSetupX1Y1(x, y + len);
912 SiSDoCMD
913 #endif
916 static void
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));
926 #ifdef SISVRAMQ
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)
932 #else
933 SiSSetupLineCount(1)
934 SiSSetupDSTRect(pSiS->scrnOffset, -1)
935 SiSSetupDSTColorDepth(pSiS->DstColor);
936 SiSSetupStyleLow(*pattern)
937 SiSSetupStyleHigh(*(pattern+4))
938 SiSSetupStylePeriod(length-1);
939 SiSSetupPATFG(fg)
940 #endif
942 SiSSetupROP(XAAPatternROP[rop])
944 SiSSetupCMDFlag(LINE | LINE_STYLE)
946 if(bg != -1) {
947 SiSSetupPATBG(bg)
948 } else {
949 SiSSetupCMDFlag(TRANSPARENT)
951 #ifndef SISVRAMQ
952 SiSSetupCMDFlag(pSiS->SiS310_AccelDepth)
953 #endif
955 #ifdef SISVRAMQ
956 SiSSyncWP
957 #endif
960 static void
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));
971 dstbase = 0;
972 miny = (y1 > y2) ? y2 : y1;
973 maxy = (y1 > y2) ? y1 : y2;
974 if(maxy >= 2048) {
975 dstbase = pSiS->scrnOffset * miny;
976 y1 -= miny;
977 y2 -= miny;
979 #ifdef SISDUALHEAD
980 dstbase += HEADOFFSET;
981 #endif
983 if(flags & OMIT_LAST) {
984 SiSSetupCMDFlag(NO_LAST_PIXEL)
985 } else {
986 pSiS->CommandReg &= ~(NO_LAST_PIXEL);
989 #ifdef SISVRAMQ
990 SiSCheckQueue(16 * 2);
991 SiSSetupX0Y0X1Y1(x1,y1,x2,y2)
992 SiSSetupDSTBaseDoCMD(dstbase)
993 #else
994 SiSSetupDSTBase(dstbase)
995 SiSSetupX0Y0(x1,y1)
996 SiSSetupX1Y1(x2,y2)
997 SiSDoCMD
998 #endif
1001 static void
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));
1011 #ifdef SISVRAMQ
1012 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1013 SiSCheckQueue(16 * 3);
1014 SiSSetupPATFGDSTRect(fg, pSiS->scrnOffset, -1)
1015 #else
1016 SiSSetupDSTRect(pSiS->scrnOffset, -1)
1017 SiSSetupDSTColorDepth(pSiS->DstColor);
1018 #endif
1020 SiSSetupMONOPAT(patx,paty)
1022 SiSSetupROP(XAAPatternROP[rop])
1024 #ifdef SISVRAMQ
1025 SiSSetupCMDFlag(PATMONO)
1026 #else
1027 SiSSetupPATFG(fg)
1028 SiSSetupCMDFlag(PATMONO | pSiS->SiS310_AccelDepth)
1029 #endif
1031 if(bg != -1) {
1032 SiSSetupPATBG(bg)
1033 } else {
1034 SiSSetupCMDFlag(TRANSPARENT)
1037 #ifdef SISVRAMQ
1038 SiSSyncWP
1039 #endif
1042 static void
1043 SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn,
1044 int patx, int paty,
1045 int x, int y, int w, int h)
1047 SISPtr pSiS = SISPTR(pScrn);
1048 long dstbase;
1050 PDEBUG(ErrorF("Subsequent MonoPatFill(0x%x,0x%x, %d,%d, %d,%d)\n",
1051 patx, paty, x, y, w, h));
1052 dstbase = 0;
1053 if(y >= 2048) {
1054 dstbase = pSiS->scrnOffset * y;
1055 y = 0;
1057 #ifdef SISDUALHEAD
1058 dstbase += HEADOFFSET;
1059 #endif
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 |
1065 TRAPAZOID_FILL);
1067 #ifdef SISVRAMQ
1068 SiSCheckQueue(16 * 2);
1069 SiSSetupDSTXYRect(x,y,w,h)
1070 SiSSetupDSTBaseDoCMD(dstbase)
1071 #else
1072 SiSSetupDSTBase(dstbase)
1073 SiSSetupDSTXY(x,y)
1074 SiSSetupRect(w,h)
1075 SiSDoCMD
1076 #endif
1079 /* --- Trapezoid --- */
1081 /* Does not work at all on 330 series */
1083 #ifdef TRAP
1084 static void
1085 SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
1086 int patx, int paty,
1087 int y, int h,
1088 int left, int dxL, int dyL, int eL,
1089 int right, int dxR, int dyR, int eR)
1091 SISPtr pSiS = SISPTR(pScrn);
1092 long dstbase;
1094 PDEBUG(ErrorF("Subsequent Mono8x8PatternFillTrap(%d, %d, %d - %d %d/%d %d/%d)\n",
1095 y, h, left, right, dxL, dxR, eL, eR));
1097 dstbase = 0;
1098 if(y >= 2048) {
1099 dstbase=pSiS->scrnOffset*y;
1100 y = 0;
1102 #ifdef SISDUALHEAD
1103 dstbase += HEADOFFSET;
1104 #endif
1106 #ifdef SISVRAMQ
1107 SiSCheckQueue(16 * 4);
1108 #else
1109 SiSSetupDSTBase(dstbase)
1110 #endif
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 |
1116 BITBLT);
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);
1134 #ifdef SISVRAMQ
1135 SiSSetupYHLR(y, h, left, right)
1136 SiSSetupdLdR(dxL, dyL, dxR, dyR)
1137 SiSSetupELER(eL, eR)
1138 SiSSetupDSTBaseDoCMD(dstbase)
1139 #else
1140 SiSSetupYH(y, h)
1141 SiSSetupLR(left, right)
1142 SiSSetupdL(dxL, dyL)
1143 SiSSetupdR(dxR, dyR)
1144 SiSSetupEL(eL)
1145 SiSSetupER(eR)
1146 SiSDoCMD
1147 #endif
1149 #endif
1151 /* Color 8x8 pattern */
1153 #ifdef SISVRAMQ
1154 static void
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) +
1161 (patternx * j));
1163 #ifdef ACCELDEBUG
1164 xf86DrvMsg(0, X_INFO, "Setup Color8x8PatFill(0x%x, 0x%x, 0x%x, 0x%x)\n",
1165 patternx, patterny, rop, planemask);
1166 #endif
1168 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1169 SiSCheckQueue(16 * 3);
1171 SiSSetupDSTRectBurstHeader(pSiS->scrnOffset, -1, PATTERN_REG, (pScrn->bitsPerPixel << 1))
1173 while(j--) {
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)
1185 SiSSyncWP
1188 static void
1189 SiSSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
1190 int patterny, int x, int y, int w, int h)
1192 SISPtr pSiS = SISPTR(pScrn);
1193 long dstbase;
1195 #ifdef ACCELDEBUG
1196 xf86DrvMsg(0, X_INFO, "Subsequent Color8x8FillRect(%d, %d, %d, %d)\n",
1197 x, y, w, h);
1198 #endif
1200 dstbase = 0;
1201 if(y >= 2048) {
1202 dstbase = pSiS->scrnOffset * y;
1203 y = 0;
1205 #ifdef SISDUALHEAD
1206 dstbase += HEADOFFSET;
1207 #endif
1208 /* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */
1210 SiSCheckQueue(16 * 2)
1211 SiSSetupDSTXYRect(x,y,w,h)
1212 SiSSetupDSTBaseDoCMD(dstbase)
1214 #endif
1216 /* ---- CPUToScreen Color Expand --- */
1218 #ifdef CTSCE
1220 #ifdef CTSCE_DIRECT
1222 /* Direct method */
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
1226 * color expansion.
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()
1232 static void
1233 SiSSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
1234 int fg, int bg, int rop, unsigned int planemask)
1236 SISPtr pSiS=SISPTR(pScrn);
1238 #ifdef SISVRAMQ
1239 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1240 SiSSetupROP(XAACopyROP[rop]);
1241 SiSSetupSRCFGDSTRect(fg, pSiS->scrnOffset, -1)
1242 if(bg == -1) {
1243 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO);
1244 } else {
1245 SiSSetupSRCBG(bg);
1246 SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO);
1248 SiSSyncWP
1249 #else
1250 SiSSetupSRCXY(0,0);
1251 SiSSetupROP(XAACopyROP[rop]);
1252 SiSSetupSRCFG(fg);
1253 SiSSetupDSTRect(pSiS->scrnOffset, -1);
1254 SiSSetupDSTColorDepth(pSiS->DstColor);
1255 if(bg == -1) {
1256 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO
1257 | pSiS->SiS310_AccelDepth);
1258 } else {
1259 SiSSetupSRCBG(bg);
1260 SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO | pSiS->SiS310_AccelDepth);
1262 #endif
1265 static void
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;
1276 dstbase = 0;
1277 if(y >= 2048) {
1278 dstbase = pSiS->scrnOffset*y;
1279 y = 0;
1282 #ifdef SISDUALHEAD
1283 srcbase += HEADOFFSET;
1284 dstbase += HEADOFFSET;
1285 #endif
1287 #ifdef SISVRAMQ
1288 SiSSetupSRCDSTBase(srcbase,dstbase);
1289 #else
1290 SiSSetupSRCBase(srcbase);
1291 SiSSetupDSTBase(dstbase)
1292 #endif
1294 if(skipleft > 0) {
1295 _x0 = x + skipleft;
1296 _y0 = y;
1297 _x1 = x + w;
1298 _y1 = y + h;
1299 #ifdef SISVRAMQ
1300 SiSSetupClip(_x0, _y0, _x1, _y1);
1301 #else
1302 SiSSetupClipLT(_x0, _y0);
1303 SiSSetupClipRB(_x1, _y1);
1304 #endif
1305 SiSSetupCMDFlag(CLIPENABLE);
1306 } else {
1307 pSiS->CommandReg &= (~CLIPENABLE);
1310 #ifdef SISVRAMQ
1311 SiSSetupRectSRCPitch(w, h, ((((w + 7) >> 3) + 3) >> 2) << 2);
1312 SiSSetupSRCDSTXY(0, 0, x, y);
1313 #else
1314 SiSSetupRect(w, h);
1315 SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4);
1316 SiSSetupDSTXY(x, y);
1317 #endif
1319 if(pSiS->ColorExpandBusy) {
1320 pSiS->ColorExpandBusy = FALSE;
1321 SiSIdle
1324 pSiS->DoColorExpand = TRUE;
1327 #else
1329 /* Indirect method */
1331 /* This is SLOW, slower than the CPU on most chipsets */
1332 /* Does not work in VRAM queue mode. */
1334 static void
1335 SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
1336 int fg, int bg, int rop, unsigned int planemask)
1338 SISPtr pSiS=SISPTR(pScrn);
1340 #ifdef SISVRAMQ
1341 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1342 #endif
1344 /* !!! DOES NOT WORK IN VRAM QUEUE MODE !!! */
1346 /* (hence this is not optimized for VRAM mode) */
1347 #ifndef SISVRAMQ
1348 SiSIdle
1349 #endif
1350 SiSSetupSRCXY(0,0);
1352 SiSSetupROP(XAACopyROP[rop]);
1353 SiSSetupSRCFG(fg);
1354 SiSSetupDSTRect(pSiS->scrnOffset, -1);
1355 #ifndef SISVRAMQ
1356 SiSSetupDSTColorDepth(pSiS->DstColor);
1357 #endif
1358 if(bg == -1) {
1359 #ifdef SISVRAMQ
1360 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO);
1361 #else
1362 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCCPUBLITBUF
1363 | pSiS->SiS310_AccelDepth);
1364 #endif
1365 } else {
1366 SiSSetupSRCBG(bg);
1367 #ifdef SISVRAMQ
1368 SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF);
1369 #else
1370 SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF | pSiS->SiS310_AccelDepth);
1371 #endif
1376 static void
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;
1383 long dstbase;
1385 dstbase = 0;
1386 if(y >= 2048) {
1387 dstbase = pSiS->scrnOffset*y;
1388 y = 0;
1390 #ifdef SISDUALHEAD
1391 dstbase += HEADOFFSET;
1392 #endif
1394 #ifndef SISVRAMQ
1395 if((MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {
1396 SiSIdle;
1398 #endif
1400 SiSSetupDSTBase(dstbase)
1402 if(skipleft > 0) {
1403 _x0 = x+skipleft;
1404 _y0 = y;
1405 _x1 = x+w;
1406 _y1 = y+h;
1407 #ifdef SISVRAMQ
1408 SiSSetupClip(_x0, _y0, _x1, _y1);
1409 #else
1410 SiSSetupClipLT(_x0, _y0);
1411 SiSSetupClipRB(_x1, _y1);
1412 #endif
1413 SiSSetupCMDFlag(CLIPENABLE);
1414 } else {
1415 pSiS->CommandReg &= (~CLIPENABLE);
1417 SiSSetupRect(w, 1);
1418 SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4);
1419 pSiS->ycurrent = y;
1420 pSiS->xcurrent = x;
1424 static void
1425 SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
1427 SISPtr pSiS = SISPTR(pScrn);
1428 long cbo;
1430 cbo = pSiS->ColorExpandBufferScreenOffset[bufno];
1431 #ifdef SISDUALHEAD
1432 cbo += HEADOFFSET;
1433 #endif
1435 #ifndef SISVRAMQ
1436 if((MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {
1437 SiSIdle;
1439 #endif
1441 SiSSetupSRCBase(cbo);
1443 SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent);
1445 SiSDoCMD
1447 pSiS->ycurrent++;
1448 #ifndef SISVRAMQ
1449 SiSIdle
1450 #endif
1452 #endif
1453 #endif
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.
1466 #ifdef STSCE
1467 static void
1468 SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
1469 int fg, int bg,
1470 int rop, unsigned int planemask)
1472 SISPtr pSiS = SISPTR(pScrn);
1474 #ifdef SISVRAMQ
1475 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1476 #else
1477 SiSSetupDSTColorDepth(pSiS->DstColor)
1478 #endif
1479 SiSSetupDSTRect(pSiS->scrnOffset, -1)
1480 SiSSetupROP(XAACopyROP[rop])
1481 SiSSetupSRCFG(fg)
1482 /* SiSSetupSRCXY(0,0) */
1484 if(bg == -1) {
1485 SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO);
1486 } else {
1487 SiSSetupSRCBG(bg);
1488 SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO);
1491 #ifdef SISVRAMQ
1492 SiSSyncWP
1493 #endif
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
1509 * of scrnOffset).
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
1521 * to 0.
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.
1533 static void
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;
1540 #if 0
1541 int _x0, _y0, _x1, _y1;
1542 #endif
1543 #ifdef pitchdw
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);
1553 #endif
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;
1559 #ifdef pitchdw
1560 if(newsrcy >= 2048) {
1561 srcbase = (pScrn->displayWidth / 8) * newsrcy;
1562 newsrcy = 0;
1564 #endif
1565 #ifdef nopitch
1566 srcbase = (pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8));
1567 #endif
1568 #ifdef npitch
1569 if(srcy >= 2048) {
1570 srcbase = pSiS->scrnOffset * srcy;
1571 srcy = 0;
1573 #endif
1574 if(y >= 2048) {
1575 dstbase = pSiS->scrnOffset * y;
1576 y = 0;
1579 #ifdef SISDUALHEAD
1580 srcbase += HEADOFFSET;
1581 dstbase += HEADOFFSET;
1582 #endif
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!
1593 #ifdef pitchdw
1594 SiSSetupSRCPitch(pScrn->displayWidth/8)
1595 #endif
1596 #ifdef nopitch
1597 SiSSetupSRCPitch(pScrn->displayWidth/8)
1598 /* SiSSetupSRCPitch(1024/8) */ /* For test */
1599 #endif
1600 #ifdef npitch
1601 SiSSetupSRCPitch(pScrn->displayWidth/8)
1602 /* SiSSetupSRCPitch(pSiS->scrnOffset) */
1603 #endif
1605 SiSSetupRect(w,h)
1607 #if 0 /* How do I implement the offset? Not this way, that's for sure.. */
1608 if (skipleft > 0) {
1609 _x0 = x+skipleft;
1610 _y0 = y;
1611 _x1 = x+w;
1612 _y1 = y+h;
1613 SiSSetupClipLT(_x0, _y0);
1614 SiSSetupClipRB(_x1, _y1);
1615 SiSSetupCMDFlag(CLIPENABLE);
1617 #endif
1618 #ifdef pitchdw
1619 SiSSetupSRCXY(newsrcx, newsrcy)
1620 #endif
1621 #ifdef nopitch
1622 SiSSetupSRCXY(0,0)
1623 #endif
1624 #ifdef npitch
1625 SiSSetupSRCXY(srcx, srcy)
1626 #endif
1628 SiSSetupDSTXY(x,y)
1630 SiSDoCMD
1631 #ifdef SISVRAMQ
1632 /* We MUST sync here, there must not be 2 or more color expansion commands in the queue */
1633 SiSIdle
1634 #endif
1636 #endif
1638 /* ---- RENDER ---- */
1640 #ifdef INCL_RENDER
1641 #ifdef RENDER
1642 static void
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
1659 static Bool
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) {
1669 return TRUE;
1670 } else {
1671 if(pSiS->alphaBlitBusy) {
1672 pSiS->alphaBlitBusy = FALSE;
1673 SiSIdle
1675 if(xf86ResizeOffscreenLinear(pSiS->AccelLinearScratch, sizeNeeded)) {
1676 return TRUE;
1678 xf86FreeOffscreenLinear(pSiS->AccelLinearScratch);
1679 pSiS->AccelLinearScratch = NULL;
1683 pSiS->AccelLinearScratch = xf86AllocateOffscreenLinear(
1684 pScrn->pScreen, sizeNeeded, 32,
1685 NULL, NULL, NULL);
1687 return(pSiS->AccelLinearScratch != NULL);
1690 Bool
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;
1700 CARD8 myalpha;
1701 CARD32 *dstPtr;
1702 unsigned char *renderaccelarray;
1704 #ifdef ACCELDEBUG
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);
1707 #endif
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)))
1718 return FALSE;
1720 if(!SiSAllocateLinear(pScrn, sizeNeeded))
1721 return FALSE;
1723 red &= 0xff00;
1724 green &= 0xff00;
1725 blue &= 0xff00;
1727 #ifdef SISVRAMQ
1728 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1729 SiSSetupSRCPitchDSTRect((pitch << 2), pSiS->scrnOffset, -1);
1730 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA)
1731 SiSSyncWP
1732 #else
1733 SiSSetupDSTColorDepth(pSiS->DstColor);
1734 SiSSetupSRCPitch((pitch << 2));
1735 SiSSetupDSTRect(pSiS->scrnOffset, -1)
1736 SiSSetupROP(0)
1737 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA | pSiS->SiS310_AccelDepth)
1738 #endif
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;
1747 SiSIdle
1750 if(alphaType == PICT_a8) {
1752 if(alpha == 0xffff) {
1754 while(height--) {
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] |
1760 myalpha << 24;
1762 dstPtr += pitch;
1763 alphaPtr += alphaPitch;
1766 } else {
1768 alpha &= 0xff00;
1770 while(height--) {
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];
1778 dstPtr += pitch;
1779 alphaPtr += alphaPitch;
1784 } else {
1786 width <<= 2;
1788 if(alpha == 0xffff) {
1790 while(height--) {
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] |
1796 myalpha << 24;
1798 dstPtr += pitch;
1799 alphaPtr += alphaPitch;
1802 } else {
1804 alpha &= 0xff00;
1806 while(height--) {
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];
1814 dstPtr += pitch;
1815 alphaPtr += alphaPitch;
1822 return TRUE;
1825 Bool
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;
1833 CARD8 *dst;
1835 #ifdef ACCELDEBUG
1836 xf86DrvMsg(0, X_INFO, "T: type %d op %d w %d h %d T-pitch %d\n",
1837 texType, op, width, height, texPitch);
1838 #endif
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;
1848 width <<= 2;
1849 pitch <<= 2;
1851 if(!SiSAllocateLinear(pScrn, sizeNeeded))
1852 return FALSE;
1854 #ifdef SISVRAMQ
1855 SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
1856 SiSSetupSRCPitchDSTRect(pitch, pSiS->scrnOffset, -1);
1857 SiSSetupAlpha(0x00)
1858 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA)
1859 SiSSyncWP
1860 #else
1861 SiSSetupDSTColorDepth(pSiS->DstColor);
1862 SiSSetupSRCPitch(pitch);
1863 SiSSetupDSTRect(pSiS->scrnOffset, -1)
1864 SiSSetupAlpha(0x00)
1865 SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA | pSiS->SiS310_AccelDepth)
1866 #endif
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;
1875 SiSIdle
1878 while(height--) {
1879 memcpy(dst, texPtr, width);
1880 texPtr += texPitch;
1881 dst += pitch;
1884 return TRUE;
1887 void
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;
1899 #ifdef ACCELDEBUG
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);
1902 #endif
1904 dstbase = 0;
1905 if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) {
1906 dstbase = pSiS->scrnOffset * dst_y;
1907 dst_y = 0;
1909 #ifdef SISDUALHEAD
1910 srcbase += HEADOFFSET;
1911 dstbase += HEADOFFSET;
1912 #endif
1914 #ifdef SISVRAMQ
1915 SiSCheckQueue(16 * 3)
1916 SiSSetupSRCDSTBase(srcbase,dstbase);
1917 SiSSetupSRCDSTXY(src_x, src_y, dst_x, dst_y)
1918 SiSSetRectDoCMD(width,height)
1919 #else
1920 SiSSetupSRCBase(srcbase);
1921 SiSSetupDSTBase(dstbase);
1922 SiSSetupRect(width, height)
1923 SiSSetupSRCXY(src_x, src_y)
1924 SiSSetupDSTXY(dst_x, dst_y)
1925 SiSDoCMD
1926 #endif
1927 pSiS->alphaBlitBusy = TRUE;
1929 #endif
1930 #endif