SiS_DDC2Delay: initialize variable before adding to it
[xf86-video-sis.git] / src / sis_accel.c
blobdc45f2b8b132284843e0f78f0d39d1c8dd74486c
1 /*
2 * 2D acceleration for SiS5597/5598 and 6326
4 * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
5 * Parts Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
7 * Licensed under the following terms:
9 * Permission to use, copy, modify, distribute, and sell this software and its
10 * documentation for any purpose is hereby granted without fee, provided that
11 * the above copyright notice appears in all copies and that both that copyright
12 * notice and this permission notice appear in supporting documentation, and
13 * and that the name of the copyright holder not be used in advertising
14 * or publicity pertaining to distribution of the software without specific,
15 * written prior permission. The copyright holder makes no representations
16 * about the suitability of this software for any purpose. It is provided
17 * "as is" without expressed or implied warranty.
19 * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
20 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
21 * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
22 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
23 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
24 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
25 * PERFORMANCE OF THIS SOFTWARE.
27 * Authors: Alan Hourihane <alanh@fairlite.demon.co.uk>,
28 * Mike Chapman <mike@paranoia.com>,
29 * Juanjo Santamarta <santamarta@ctv.es>,
30 * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
31 * David Thomas <davtom@dream.org.uk>,
32 * Thomas Winischhofer <thomas@winischhofer.net>.
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
39 #include "sis.h"
40 #include "sis_regs.h"
41 #ifdef SIS_USE_XAA
42 #include "xaarop.h"
43 #endif
44 #include "sis_accel.h"
46 #ifdef SIS_USE_XAA
48 #if 0
49 #define CTSCE /* Include enhanced color expansion code */
50 #endif /* This produces drawing errors sometimes */
52 #endif /* XAA */
54 #ifdef SIS_USE_EXA
55 extern void SiSScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area);
56 extern Bool SiSUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst);
57 #endif /* EXA */
59 extern UChar SiSGetCopyROP(int rop);
60 extern UChar SiSGetPatternROP(int rop);
62 static void
63 SiSInitializeAccelerator(ScrnInfoPtr pScrn)
65 /* Nothing here yet */
68 /* sync */
69 static void
70 SiSSync(ScrnInfoPtr pScrn)
72 SISPtr pSiS = SISPTR(pScrn);
74 sisBLTSync;
77 static void
78 SiSSyncAccel(ScrnInfoPtr pScrn)
80 SISPtr pSiS = SISPTR(pScrn);
82 if(!pSiS->NoAccel) SiSSync(pScrn);
85 /* Screen to screen copy */
86 static void
87 SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
88 int rop, unsigned int planemask,
89 int transparency_color)
91 SISPtr pSiS = SISPTR(pScrn);
93 sisBLTSync;
94 sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset);
96 sisSETROP(SiSGetCopyROP(rop));
97 pSiS->Xdirection = xdir;
98 pSiS->Ydirection = ydir;
101 static void
102 SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
103 int y2, int w, int h)
105 SISPtr pSiS = SISPTR(pScrn);
106 int srcaddr, destaddr, op;
108 op = sisCMDBLT | sisSRCVIDEO;
110 if(pSiS->Ydirection == -1) {
111 op |= sisBOTTOM2TOP;
112 srcaddr = (y1 + h - 1) * pSiS->CurrentLayout.displayWidth;
113 destaddr = (y2 + h - 1) * pSiS->CurrentLayout.displayWidth;
114 } else {
115 op |= sisTOP2BOTTOM;
116 srcaddr = y1 * pSiS->CurrentLayout.displayWidth;
117 destaddr = y2 * pSiS->CurrentLayout.displayWidth;
120 if(pSiS->Xdirection == -1) {
121 op |= sisRIGHT2LEFT;
122 srcaddr += x1 + w - 1;
123 destaddr += x2 + w - 1;
124 } else {
125 op |= sisLEFT2RIGHT;
126 srcaddr += x1;
127 destaddr += x2;
130 if(pSiS->ClipEnabled)
131 op |= sisCLIPINTRN | sisCLIPENABL;
133 srcaddr *= (pSiS->CurrentLayout.bitsPerPixel/8);
134 destaddr *= (pSiS->CurrentLayout.bitsPerPixel/8);
135 if(((pSiS->CurrentLayout.bitsPerPixel / 8) > 1) && (pSiS->Xdirection == -1)) {
136 srcaddr += (pSiS->CurrentLayout.bitsPerPixel/8)-1;
137 destaddr += (pSiS->CurrentLayout.bitsPerPixel/8)-1;
140 sisBLTSync;
141 sisSETSRCADDR(srcaddr);
142 sisSETDSTADDR(destaddr);
143 sisSETHEIGHTWIDTH(h-1, w * (pSiS->CurrentLayout.bitsPerPixel/8)-1);
144 sisSETCMD(op);
147 /* solid fill */
148 static void
149 SiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
150 unsigned int planemask)
152 SISPtr pSiS = SISPTR(pScrn);
154 sisBLTSync;
155 sisSETBGROPCOL(SiSGetCopyROP(rop), color);
156 sisSETFGROPCOL(SiSGetCopyROP(rop), color);
157 sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset);
160 static void
161 SiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
163 SISPtr pSiS = SISPTR(pScrn);
164 int destaddr, op;
166 destaddr = y * pSiS->CurrentLayout.displayWidth + x;
168 op = sisCMDBLT | sisSRCBG | sisTOP2BOTTOM | sisLEFT2RIGHT;
170 if(pSiS->ClipEnabled)
171 op |= sisCLIPINTRN | sisCLIPENABL;
173 destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8);
175 sisBLTSync;
176 sisSETHEIGHTWIDTH(h-1, w * (pSiS->CurrentLayout.bitsPerPixel/8)-1);
177 sisSETDSTADDR(destaddr);
178 sisSETCMD(op);
181 #ifdef SIS_USE_XAA /* ---------------------------- XAA -------------------------- */
183 /* Clipping */
184 static void
185 SiSSetClippingRectangle(ScrnInfoPtr pScrn,
186 int left, int top, int right, int bottom)
188 SISPtr pSiS = SISPTR(pScrn);
190 sisBLTSync;
191 sisSETCLIPTOP(left,top);
192 sisSETCLIPBOTTOM(right,bottom);
193 pSiS->ClipEnabled = TRUE;
196 static void
197 SiSDisableClipping(ScrnInfoPtr pScrn)
199 SISPtr pSiS = SISPTR(pScrn);
200 pSiS->ClipEnabled = FALSE;
203 /* 8x8 mono */
204 static void
205 SiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
206 int fg, int bg, int rop, unsigned int planemask)
208 SISPtr pSiS = SISPTR(pScrn);
209 unsigned int *patternRegPtr;
210 int i;
212 (void)XAAHelpPatternROP(pScrn, &fg, &bg, planemask, &rop);
214 sisBLTSync;
215 if(bg != -1) {
216 sisSETBGROPCOL(0xcc, bg); /* copy */
217 } else {
218 sisSETBGROPCOL(0xAA, bg); /* noop */
220 sisSETFGROPCOL(rop, fg);
221 sisSETPITCH(0, pSiS->scrnOffset);
222 sisSETSRCADDR(0);
223 patternRegPtr = (unsigned int *)sisSETPATREG();
224 pSiS->sisPatternReg[0] = pSiS->sisPatternReg[2] = patternx ;
225 pSiS->sisPatternReg[1] = pSiS->sisPatternReg[3] = patterny ;
226 for(i = 0 ; i < 16 /* sisPatternHeight */ ; ) {
227 patternRegPtr[i++] = patternx ;
228 patternRegPtr[i++] = patterny ;
232 static void
233 SiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
234 int patterny, int x, int y, int w, int h)
236 SISPtr pSiS = SISPTR(pScrn);
237 register UChar *patternRegPtr;
238 register UChar *srcPatternRegPtr;
239 register unsigned int *patternRegPtrL;
240 UShort tmp;
241 int dstaddr, i, k, shift;
242 int op = sisCMDCOLEXP |
243 sisTOP2BOTTOM |
244 sisLEFT2RIGHT |
245 sisPATFG |
246 sisSRCBG;
248 if(pSiS->ClipEnabled)
249 op |= sisCLIPINTRN | sisCLIPENABL;
251 dstaddr = ( y * pSiS->CurrentLayout.displayWidth + x ) *
252 pSiS->CurrentLayout.bitsPerPixel / 8;
254 sisBLTSync;
256 patternRegPtr = sisSETPATREG();
257 srcPatternRegPtr = (UChar *)pSiS->sisPatternReg ;
258 shift = 8 - patternx ;
259 for(i = 0, k = patterny ; i < 8 ; i++, k++ ) {
260 tmp = srcPatternRegPtr[k]<<8 | srcPatternRegPtr[k] ;
261 tmp >>= shift ;
262 patternRegPtr[i] = tmp & 0xff;
264 patternRegPtrL = (unsigned int *)sisSETPATREG();
265 for(i = 2 ; i < 16 /* sisPatternHeight */; ) {
266 patternRegPtrL[i++] = patternRegPtrL[0];
267 patternRegPtrL[i++] = patternRegPtrL[1];
270 sisSETDSTADDR(dstaddr);
271 sisSETHEIGHTWIDTH(h-1, w*(pSiS->CurrentLayout.bitsPerPixel/8)-1);
272 sisSETCMD(op);
275 /* Line */
276 static void
277 SiSSetupForSolidLine(ScrnInfoPtr pScrn,
278 int color, int rop, unsigned int planemask)
280 SISPtr pSiS = SISPTR(pScrn);
282 sisBLTSync;
283 sisSETBGROPCOL(SiSGetCopyROP(rop), 0);
284 sisSETFGROPCOL(SiSGetCopyROP(rop), color);
287 static void
288 SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
289 int x1, int y1, int x2, int y2, int flags)
292 SISPtr pSiS = SISPTR(pScrn);
293 int op, major, minor, err, K1, K2, tmp;
295 op = sisCMDLINE | sisSRCFG;
297 if((flags & OMIT_LAST))
298 op |= sisLASTPIX;
300 if(pSiS->ClipEnabled)
301 op |= sisCLIPINTRN | sisCLIPENABL;
303 if((major = x2 - x1) <= 0)
304 major = -major;
305 else
306 op |= sisXINCREASE;
308 if((minor = y2 - y1) <= 0)
309 minor = -minor;
310 else
311 op |= sisYINCREASE;
313 if(minor >= major) {
314 tmp = minor;
315 minor = major;
316 major = tmp;
317 } else
318 op |= sisXMAJOR;
320 K1 = (minor - major) << 1;
321 K2 = minor << 1;
322 err = (minor << 1) - major;
324 sisBLTSync;
325 sisSETXStart(x1);
326 sisSETYStart(y1);
327 sisSETLineSteps((short)K1,(short)K2);
328 sisSETLineErrorTerm((short)err);
329 sisSETLineMajorCount((short)major);
330 sisSETCMD(op);
333 static void
334 SiSSubsequentSolidHorVertLine(ScrnInfoPtr pScrn,
335 int x, int y, int len, int dir)
337 SISPtr pSiS = SISPTR(pScrn);
338 int destaddr, op;
340 destaddr = y * pSiS->CurrentLayout.displayWidth + x;
342 op = sisCMDBLT | sisSRCFG | sisTOP2BOTTOM | sisLEFT2RIGHT;
344 if(pSiS->ClipEnabled)
345 op |= sisCLIPINTRN | sisCLIPENABL;
347 destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8);
349 sisBLTSync;
351 sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset);
353 if(dir == DEGREES_0) {
354 sisSETHEIGHTWIDTH(0, len * (pSiS->CurrentLayout.bitsPerPixel >> 3) - 1);
355 } else {
356 sisSETHEIGHTWIDTH(len - 1, (pSiS->CurrentLayout.bitsPerPixel >> 3) - 1);
359 sisSETDSTADDR(destaddr);
360 sisSETCMD(op);
363 #ifdef CTSCE
364 /* ----- CPU To Screen Color Expand (scanline-wise) ------ */
365 static void
366 SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
367 int fg, int bg, int rop, unsigned int planemask)
369 SISPtr pSiS=SISPTR(pScrn);
371 pSiS->CommandReg = 0;
373 pSiS->CommandReg |= (sisCMDECOLEXP |
374 sisLEFT2RIGHT |
375 sisTOP2BOTTOM);
377 sisBLTSync;
379 /* The combination of flags in the following
380 * is not understandable. However, this is the
381 * only combination that seems to work.
383 if(bg == -1) {
384 sisSETROPBG(0xAA); /* dst = dst (=noop) */
385 pSiS->CommandReg |= sisSRCFG;
386 } else {
387 sisSETBGROPCOL(SiSGetPatternROP(rop), bg);
388 pSiS->CommandReg |= sisSRCFG | sisPATBG;
391 sisSETFGROPCOL(SiSGetCopyROP(rop), fg);
393 sisSETDSTPITCH(pSiS->scrnOffset);
397 static void
398 SiSSubsequentScanlineCPUToScreenColorExpandFill(
399 ScrnInfoPtr pScrn, int x, int y, int w,
400 int h, int skipleft)
402 SISPtr pSiS = SISPTR(pScrn);
403 int _x0, _y0, _x1, _y1;
404 int op = pSiS->CommandReg;
406 if(skipleft > 0) {
407 _x0 = x + skipleft;
408 _y0 = y;
409 _x1 = x + w;
410 _y1 = y + h;
411 sisSETCLIPTOP(_x0, _y0);
412 sisSETCLIPBOTTOM(_x1, _y1);
413 op |= sisCLIPENABL;
414 } else {
415 op &= (~(sisCLIPINTRN | sisCLIPENABL));
418 sisSETSRCPITCH(((((w + 7) / 8) + 3) >> 2) * 4);
420 sisSETHEIGHTWIDTH(1-1, (w * (pSiS->CurrentLayout.bitsPerPixel/8)) - 1);
422 pSiS->xcurrent = x;
423 pSiS->ycurrent = y;
425 pSiS->CommandReg = op;
428 static void
429 SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
431 SISPtr pSiS = SISPTR(pScrn);
432 unsigned long cbo = pSiS->ColorExpandBufferScreenOffset[bufno];
433 int op = pSiS->CommandReg;
434 int destaddr;
436 destaddr = (pSiS->ycurrent * pSiS->CurrentLayout.displayWidth) + pSiS->xcurrent;
437 destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8);
439 /* Wait until there is no color expansion command in queue */
440 /* sisBLTSync; */
442 sisSETSRCADDR(cbo);
444 sisSETDSTADDR(destaddr);
446 sisSETCMD(op);
448 pSiS->ycurrent++;
450 /* Wait for eventual color expand commands to finish */
451 /* (needs to be done, otherwise the data in the buffer may
452 * be overwritten while accessed by the hardware)
454 while((SIS_MMIO_IN32(pSiS->IOBase, 0x8284) & 0x80000000)) {}
456 sisBLTSync;
458 #endif /* CTSCE */
460 #endif /* XAA */
462 #ifdef SIS_USE_EXA /* ---------------------------- EXA -------------------------- */
464 static void
465 SiSEXASync(ScreenPtr pScreen, int marker)
467 SISPtr pSiS = SISPTR(xf86ScreenToScrn(pScreen));
469 sisBLTSync;
472 static Bool
473 SiSPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
475 ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen);
476 SISPtr pSiS = SISPTR(pScrn);
478 /* Planemask not supported */
479 if((planemask & ((1 << pPixmap->drawable.depth) - 1)) !=
480 (1 << pPixmap->drawable.depth) - 1) {
481 return FALSE;
484 /* Since these old engines have no "dest color depth" register, I assume
485 * the 2D engine takes the bpp from the DAC... FIXME ? */
486 if(pPixmap->drawable.bitsPerPixel != pSiS->CurrentLayout.bitsPerPixel)
487 return FALSE;
489 /* Check that the pitch matches the hardware's requirements. Should
490 * never be a problem due to pixmapPitchAlign and fbScreenInit.
492 if(exaGetPixmapPitch(pPixmap) & 7)
493 return FALSE;
495 pSiS->fillPitch = exaGetPixmapPitch(pPixmap);
496 pSiS->fillBpp = pPixmap->drawable.bitsPerPixel >> 3;
497 pSiS->fillDstBase = (CARD32)exaGetPixmapOffset(pPixmap);
499 sisBLTSync;
500 sisSETBGROPCOL(SiSGetCopyROP(alu), fg);
501 sisSETFGROPCOL(SiSGetCopyROP(alu), fg);
502 sisSETPITCH(pSiS->fillPitch, pSiS->fillPitch);
504 return TRUE;
507 static void
508 SiSSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
510 ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen);
511 SISPtr pSiS = SISPTR(pScrn);
513 sisBLTSync;
514 sisSETHEIGHTWIDTH((y2 - y1) - 1, (x2 - x1) * pSiS->fillBpp - 1);
515 sisSETDSTADDR((pSiS->fillDstBase + ((y1 * (pSiS->fillPitch / pSiS->fillBpp) + x1) * pSiS->fillBpp)));
516 sisSETCMD((sisCMDBLT | sisSRCBG | sisTOP2BOTTOM | sisLEFT2RIGHT));
519 static void
520 SiSDoneSolid(PixmapPtr pPixmap)
524 static Bool
525 SiSPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir,
526 int alu, Pixel planemask)
528 ScrnInfoPtr pScrn = xf86ScreenToScrn(pSrcPixmap->drawable.pScreen);
529 SISPtr pSiS = SISPTR(pScrn);
531 /* Planemask not supported */
532 if((planemask & ((1 << pSrcPixmap->drawable.depth) - 1)) !=
533 (1 << pSrcPixmap->drawable.depth) - 1) {
534 return FALSE;
537 /* Since these old engines have no "dest color depth" register, I assume
538 * the 2D engine takes the bpp from the DAC... FIXME ? */
539 if(pDstPixmap->drawable.bitsPerPixel != pSiS->CurrentLayout.bitsPerPixel)
540 return FALSE;
542 /* Check that the pitch matches the hardware's requirements. Should
543 * never be a problem due to pixmapPitchAlign and fbScreenInit.
545 if(exaGetPixmapPitch(pSrcPixmap) & 3)
546 return FALSE;
547 if(exaGetPixmapPitch(pDstPixmap) & 7)
548 return FALSE;
550 pSiS->copyXdir = xdir;
551 pSiS->copyYdir = ydir;
552 pSiS->copyBpp = pSrcPixmap->drawable.bitsPerPixel >> 3;
553 pSiS->copySPitch = exaGetPixmapPitch(pSrcPixmap);
554 pSiS->copyDPitch = exaGetPixmapPitch(pDstPixmap);
555 pSiS->copySrcBase = (CARD32)exaGetPixmapOffset(pSrcPixmap);
556 pSiS->copyDstBase = (CARD32)exaGetPixmapOffset(pDstPixmap);
558 sisBLTSync;
559 sisSETPITCH(pSiS->copySPitch, pSiS->copyDPitch);
560 sisSETROP(SiSGetCopyROP(alu));
562 return TRUE;
565 static void
566 SiSCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height)
568 ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
569 SISPtr pSiS = SISPTR(pScrn);
570 CARD32 srcbase, dstbase, cmd;
571 int bpp = pSiS->copyBpp;
572 int srcPixelPitch = pSiS->copySPitch / bpp;
573 int dstPixelPitch = pSiS->copyDPitch / bpp;
575 cmd = sisCMDBLT | sisSRCVIDEO;
577 if(pSiS->copyYdir < 0) {
578 cmd |= sisBOTTOM2TOP;
579 srcbase = (srcY + height - 1) * srcPixelPitch;
580 dstbase = (dstY + height - 1) * dstPixelPitch;
581 } else {
582 cmd |= sisTOP2BOTTOM;
583 srcbase = srcY * srcPixelPitch;
584 dstbase = dstY * dstPixelPitch;
587 if(pSiS->copyXdir < 0) {
588 cmd |= sisRIGHT2LEFT;
589 srcbase += srcX + width - 1;
590 dstbase += dstX + width - 1;
591 } else {
592 cmd |= sisLEFT2RIGHT;
593 srcbase += srcX;
594 dstbase += dstX;
597 srcbase *= bpp;
598 dstbase *= bpp;
599 if(pSiS->copyXdir < 0) {
600 srcbase += bpp - 1;
601 dstbase += bpp - 1;
604 srcbase += pSiS->copySrcBase;
605 dstbase += pSiS->copyDstBase;
607 sisBLTSync;
608 sisSETSRCADDR(srcbase);
609 sisSETDSTADDR(dstbase);
610 sisSETHEIGHTWIDTH(height - 1, width * bpp - 1);
611 sisSETCMD(cmd);
614 static void
615 SiSDoneCopy(PixmapPtr pDstPixmap)
619 #endif /* EXA */
621 /* For DGA usage */
623 static void
624 SiSDGAFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, int color)
626 SiSSetupForFillRectSolid(pScrn, color, GXcopy, ~0);
627 SiSSubsequentFillRectSolid(pScrn, x, y, w, h);
630 static void
631 SiSDGABlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int dstx, int dsty, int w, int h, int color)
633 int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
634 int ydir = (srcy < dsty) ? -1 : 1;
636 SiSSetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, (CARD32)~0, color);
637 SiSSubsequentScreenToScreenCopy(pScrn, srcx, srcy, dstx, dsty, w, h);
640 /* Initialisation */
642 Bool
643 SiSAccelInit(ScreenPtr pScreen)
645 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
646 SISPtr pSiS = SISPTR(pScrn);
647 #ifdef SIS_USE_XAA
648 XAAInfoRecPtr infoPtr = NULL;
649 int topFB, reservedFbSize, usableFbSize, i;
650 UChar *AvailBufBase;
651 BoxRec Avail;
652 #endif
654 pSiS->ColorExpandBufferNumber = 0;
655 pSiS->PerColorExpandBufferSize = 0;
656 pSiS->RenderAccelArray = NULL;
657 #ifdef SIS_USE_XAA
658 pSiS->AccelInfoPtr = NULL;
659 #endif
660 #ifdef SIS_USE_EXA
661 pSiS->EXADriverPtr = NULL;
662 pSiS->exa_scratch = NULL;
663 #endif
665 if(!pSiS->NoAccel) {
666 #ifdef SIS_USE_XAA
667 if(!pSiS->useEXA) {
668 pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec();
669 if(!infoPtr) pSiS->NoAccel = TRUE;
671 #endif
672 #ifdef SIS_USE_EXA
673 if(pSiS->useEXA) {
674 if(!(pSiS->EXADriverPtr = exaDriverAlloc())) {
675 pSiS->NoAccel = TRUE;
676 pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */
679 #endif
682 if(!pSiS->NoAccel) {
684 SiSInitializeAccelerator(pScrn);
686 pSiS->InitAccel = SiSInitializeAccelerator;
687 pSiS->SyncAccel = SiSSyncAccel;
688 pSiS->FillRect = SiSDGAFillRect;
689 pSiS->BlitRect = SiSDGABlitRect;
691 #ifdef SIS_USE_XAA /* ----------------------- XAA ----------------------- */
692 if(!pSiS->useEXA) {
694 infoPtr->Flags = LINEAR_FRAMEBUFFER |
695 OFFSCREEN_PIXMAPS |
696 PIXMAP_CACHE;
698 /* Sync */
699 infoPtr->Sync = SiSSync;
701 /* Screen To Screen copy */
702 infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy;
703 infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy;
704 infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
706 /* Solid fill */
707 infoPtr->SetupForSolidFill = SiSSetupForFillRectSolid;
708 infoPtr->SubsequentSolidFillRect = SiSSubsequentFillRectSolid;
709 infoPtr->SolidFillFlags = NO_PLANEMASK;
711 /* On 5597/5598 and 6326, clipping and lines only work
712 for 1024, 2048, 4096 logical width */
713 if(pSiS->ValidWidth) {
714 /* Clipping */
715 infoPtr->SetClippingRectangle = SiSSetClippingRectangle;
716 infoPtr->DisableClipping = SiSDisableClipping;
717 infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE |
718 HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
719 HARDWARE_CLIP_MONO_8x8_FILL |
720 HARDWARE_CLIP_SOLID_FILL ;
722 /* Solid Lines */
723 infoPtr->SetupForSolidLine = SiSSetupForSolidLine;
724 infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine;
725 infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorVertLine;
726 infoPtr->SolidLineFlags = NO_PLANEMASK;
729 if(pScrn->bitsPerPixel != 24) {
730 /* 8x8 mono pattern */
731 infoPtr->SetupForMono8x8PatternFill = SiSSetupForMono8x8PatternFill;
732 infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMono8x8PatternFillRect;
733 infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
734 HARDWARE_PATTERN_PROGRAMMED_BITS |
735 HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
736 BIT_ORDER_IN_BYTE_MSBFIRST;
739 #ifdef CTSCE
740 if(pScrn->bitsPerPixel != 24) {
741 /* per-scanline color expansion (using indirect method) */
742 pSiS->ColorExpandBufferNumber = 4;
743 pSiS->ColorExpandBufferCountMask = 0x03;
744 pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31) / 32) * 4;
746 infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber;
747 infoPtr->ScanlineColorExpandBuffers = (UChar **)&pSiS->ColorExpandBufferAddr[0];
749 infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
750 SiSSetupForScanlineCPUToScreenColorExpandFill;
751 infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
752 SiSSubsequentScanlineCPUToScreenColorExpandFill;
753 infoPtr->SubsequentColorExpandScanline =
754 SiSSubsequentColorExpandScanline;
755 infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
756 CPU_TRANSFER_PAD_DWORD |
757 SCANLINE_PAD_DWORD |
758 BIT_ORDER_IN_BYTE_MSBFIRST |
759 LEFT_EDGE_CLIPPING;
761 #endif
762 } /* !exa */
763 #endif /* XAA */
765 #ifdef SIS_USE_EXA /* ----------------------- EXA ----------------------- */
766 if(pSiS->useEXA) {
767 pSiS->EXADriverPtr->exa_major = 2;
768 pSiS->EXADriverPtr->exa_minor = 0;
770 /* data */
771 pSiS->EXADriverPtr->memoryBase = pSiS->FbBase;
772 pSiS->EXADriverPtr->memorySize = pSiS->maxxfbmem;
773 pSiS->EXADriverPtr->offScreenBase = pScrn->virtualX * pScrn->virtualY
774 * (pScrn->bitsPerPixel >> 3);
775 if(pSiS->EXADriverPtr->memorySize > pSiS->EXADriverPtr->offScreenBase) {
776 pSiS->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
777 } else {
778 pSiS->NoXvideo = TRUE;
779 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
780 "Not enough video RAM for offscreen memory manager. Xv disabled\n");
782 pSiS->EXADriverPtr->pixmapOffsetAlign = 8; /* src/dst: double quad word boundary */
783 pSiS->EXADriverPtr->pixmapPitchAlign = 8; /* could possibly be 1, but who knows for sure */
784 pSiS->EXADriverPtr->maxX = 2047;
785 pSiS->EXADriverPtr->maxY = 2047;
787 /* Sync */
788 pSiS->EXADriverPtr->WaitMarker = SiSEXASync;
790 /* Solid fill */
791 pSiS->EXADriverPtr->PrepareSolid = SiSPrepareSolid;
792 pSiS->EXADriverPtr->Solid = SiSSolid;
793 pSiS->EXADriverPtr->DoneSolid = SiSDoneSolid;
795 /* Copy */
796 pSiS->EXADriverPtr->PrepareCopy = SiSPrepareCopy;
797 pSiS->EXADriverPtr->Copy = SiSCopy;
798 pSiS->EXADriverPtr->DoneCopy = SiSDoneCopy;
800 /* Composite not supported */
803 #endif /* EXA */
805 } /* NoAccel */
807 /* Offscreen memory manager
809 * Layout: (Sizes here do not reflect correct proportions)
810 * |--------------++++++++++++++++++++| ====================~~~~~~~~~~~~|
811 * UsableFbSize ColorExpandBuffers | TurboQueue HWCursor
812 * topFB
815 #ifdef SIS_USE_XAA
816 if(!pSiS->useEXA) {
818 topFB = pSiS->maxxfbmem;
820 reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize;
822 usableFbSize = topFB - reservedFbSize;
824 if(pSiS->ColorExpandBufferNumber) {
825 AvailBufBase = pSiS->FbBase + usableFbSize;
826 for(i = 0; i < pSiS->ColorExpandBufferNumber; i++) {
827 pSiS->ColorExpandBufferAddr[i] = AvailBufBase +
828 i * pSiS->PerColorExpandBufferSize;
829 pSiS->ColorExpandBufferScreenOffset[i] = usableFbSize +
830 i * pSiS->PerColorExpandBufferSize;
834 Avail.x1 = 0;
835 Avail.y1 = 0;
836 Avail.x2 = pScrn->displayWidth;
837 Avail.y2 = usableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel / 8) - 1;
839 if(Avail.y2 < 0) Avail.y2 = 32767;
841 if(Avail.y2 < pScrn->currentMode->VDisplay) {
842 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
843 "Not enough video RAM for accelerator: %dKB needed, %dKB available\n",
844 ((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* +8 for make it sure */
845 * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8,
846 pSiS->maxxfbmem/1024);
847 pSiS->NoAccel = TRUE;
848 pSiS->NoXvideo = TRUE;
849 XAADestroyInfoRec(pSiS->AccelInfoPtr);
850 pSiS->AccelInfoPtr = NULL;
851 return FALSE;
854 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
855 "Framebuffer from (%d,%d) to (%d,%d)\n",
856 Avail.x1, Avail.y1, Avail.x2 - 1, Avail.y2 - 1);
858 xf86InitFBManager(pScreen, &Avail);
860 if(!pSiS->NoAccel) {
861 return XAAInit(pScreen, infoPtr);
863 } /* !exa */
864 #endif
866 #ifdef SIS_USE_EXA
867 if(pSiS->useEXA) {
869 if(!pSiS->NoAccel) {
871 if(!exaDriverInit(pScreen, pSiS->EXADriverPtr)) {
872 pSiS->NoAccel = TRUE;
873 pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */
874 return FALSE;
877 /* Reserve locked offscreen scratch area of 64K for glyph data */
878 pSiS->exa_scratch = exaOffscreenAlloc(pScreen, 64 * 1024, 16, TRUE,
879 SiSScratchSave, pSiS);
880 if(pSiS->exa_scratch) {
881 pSiS->exa_scratch_next = pSiS->exa_scratch->offset;
882 pSiS->EXADriverPtr->UploadToScratch = SiSUploadToScratch;
885 } else {
887 pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */
892 #endif /* EXA */
894 return TRUE;