172b676d7Smrg/*
272b676d7Smrg * 2D acceleration for SiS5597/5598 and 6326
372b676d7Smrg *
472b676d7Smrg * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
572b676d7Smrg * Parts Copyright (C) 2001-2005 Thomas Winischhofer, Vienna, Austria.
672b676d7Smrg *
772b676d7Smrg * Licensed under the following terms:
872b676d7Smrg *
972b676d7Smrg * Permission to use, copy, modify, distribute, and sell this software and its
1072b676d7Smrg * documentation for any purpose is hereby granted without fee, provided that
1172b676d7Smrg * the above copyright notice appears in all copies and that both that copyright
1272b676d7Smrg * notice and this permission notice appear in supporting documentation, and
1372b676d7Smrg * and that the name of the copyright holder not be used in advertising
1472b676d7Smrg * or publicity pertaining to distribution of the software without specific,
1572b676d7Smrg * written prior permission. The copyright holder makes no representations
1672b676d7Smrg * about the suitability of this software for any purpose.  It is provided
1772b676d7Smrg * "as is" without expressed or implied warranty.
1872b676d7Smrg *
1972b676d7Smrg * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
2072b676d7Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
2172b676d7Smrg * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
2272b676d7Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
2372b676d7Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
2472b676d7Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2572b676d7Smrg * PERFORMANCE OF THIS SOFTWARE.
2672b676d7Smrg *
2772b676d7Smrg * Authors:  Alan Hourihane <alanh@fairlite.demon.co.uk>,
2872b676d7Smrg *           Mike Chapman <mike@paranoia.com>,
2972b676d7Smrg *           Juanjo Santamarta <santamarta@ctv.es>,
3072b676d7Smrg *           Mitani Hiroshi <hmitani@drl.mei.co.jp>,
3172b676d7Smrg *           David Thomas <davtom@dream.org.uk>,
3272b676d7Smrg *	     Thomas Winischhofer <thomas@winischhofer.net>.
3372b676d7Smrg */
3472b676d7Smrg
3572b676d7Smrg#ifdef HAVE_CONFIG_H
3672b676d7Smrg#include "config.h"
3772b676d7Smrg#endif
3872b676d7Smrg
3972b676d7Smrg#include "sis.h"
4072b676d7Smrg#include "sis_regs.h"
4172b676d7Smrg#ifdef SIS_USE_XAA
4272b676d7Smrg#include "xaarop.h"
4372b676d7Smrg#endif
4472b676d7Smrg#include "sis_accel.h"
4572b676d7Smrg
4672b676d7Smrg#ifdef SIS_USE_XAA
4772b676d7Smrg
4872b676d7Smrg#if 0
4972b676d7Smrg#define CTSCE		/* Include enhanced color expansion code */
5072b676d7Smrg#endif			/* This produces drawing errors sometimes */
5172b676d7Smrg
5272b676d7Smrg#endif /* XAA */
5372b676d7Smrg
5472b676d7Smrg#ifdef SIS_USE_EXA
5572b676d7Smrgextern void SiSScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area);
5672b676d7Smrgextern Bool SiSUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst);
5772b676d7Smrg#endif /* EXA */
5872b676d7Smrg
5972b676d7Smrgextern UChar SiSGetCopyROP(int rop);
6072b676d7Smrgextern UChar SiSGetPatternROP(int rop);
6172b676d7Smrg
6272b676d7Smrgstatic void
6372b676d7SmrgSiSInitializeAccelerator(ScrnInfoPtr pScrn)
6472b676d7Smrg{
6572b676d7Smrg    /* Nothing here yet */
6672b676d7Smrg}
6772b676d7Smrg
6872b676d7Smrg/* sync */
6972b676d7Smrgstatic void
7072b676d7SmrgSiSSync(ScrnInfoPtr pScrn)
7172b676d7Smrg{
7272b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
7372b676d7Smrg
7472b676d7Smrg    sisBLTSync;
7572b676d7Smrg}
7672b676d7Smrg
7772b676d7Smrgstatic void
7872b676d7SmrgSiSSyncAccel(ScrnInfoPtr pScrn)
7972b676d7Smrg{
8072b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
8172b676d7Smrg
8272b676d7Smrg    if(!pSiS->NoAccel) SiSSync(pScrn);
8372b676d7Smrg}
8472b676d7Smrg
8572b676d7Smrg/* Screen to screen copy */
8672b676d7Smrgstatic void
8772b676d7SmrgSiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
8872b676d7Smrg			int rop, unsigned int planemask,
8972b676d7Smrg			int transparency_color)
9072b676d7Smrg{
9172b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
9272b676d7Smrg
9372b676d7Smrg    sisBLTSync;
9472b676d7Smrg    sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset);
9572b676d7Smrg
9672b676d7Smrg    sisSETROP(SiSGetCopyROP(rop));
9772b676d7Smrg    pSiS->Xdirection = xdir;
9872b676d7Smrg    pSiS->Ydirection = ydir;
9972b676d7Smrg}
10072b676d7Smrg
10172b676d7Smrgstatic void
10272b676d7SmrgSiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2,
10372b676d7Smrg			int y2, int w, int h)
10472b676d7Smrg{
10572b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
10672b676d7Smrg    int srcaddr, destaddr, op;
10772b676d7Smrg
10872b676d7Smrg    op = sisCMDBLT | sisSRCVIDEO;
10972b676d7Smrg
11072b676d7Smrg    if(pSiS->Ydirection == -1) {
11172b676d7Smrg       op |= sisBOTTOM2TOP;
11272b676d7Smrg       srcaddr = (y1 + h - 1) * pSiS->CurrentLayout.displayWidth;
11372b676d7Smrg       destaddr = (y2 + h - 1) * pSiS->CurrentLayout.displayWidth;
11472b676d7Smrg    } else {
11572b676d7Smrg       op |= sisTOP2BOTTOM;
11672b676d7Smrg       srcaddr = y1 * pSiS->CurrentLayout.displayWidth;
11772b676d7Smrg       destaddr = y2 * pSiS->CurrentLayout.displayWidth;
11872b676d7Smrg    }
11972b676d7Smrg
12072b676d7Smrg    if(pSiS->Xdirection == -1) {
12172b676d7Smrg       op |= sisRIGHT2LEFT;
12272b676d7Smrg       srcaddr += x1 + w - 1;
12372b676d7Smrg       destaddr += x2 + w - 1;
12472b676d7Smrg    } else {
12572b676d7Smrg       op |= sisLEFT2RIGHT;
12672b676d7Smrg       srcaddr += x1;
12772b676d7Smrg       destaddr += x2;
12872b676d7Smrg    }
12972b676d7Smrg
13072b676d7Smrg    if(pSiS->ClipEnabled)
13172b676d7Smrg       op |= sisCLIPINTRN | sisCLIPENABL;
13272b676d7Smrg
13372b676d7Smrg    srcaddr *= (pSiS->CurrentLayout.bitsPerPixel/8);
13472b676d7Smrg    destaddr *= (pSiS->CurrentLayout.bitsPerPixel/8);
13572b676d7Smrg    if(((pSiS->CurrentLayout.bitsPerPixel / 8) > 1) && (pSiS->Xdirection == -1)) {
13672b676d7Smrg       srcaddr += (pSiS->CurrentLayout.bitsPerPixel/8)-1;
13772b676d7Smrg       destaddr += (pSiS->CurrentLayout.bitsPerPixel/8)-1;
13872b676d7Smrg    }
13972b676d7Smrg
14072b676d7Smrg    sisBLTSync;
14172b676d7Smrg    sisSETSRCADDR(srcaddr);
14272b676d7Smrg    sisSETDSTADDR(destaddr);
14372b676d7Smrg    sisSETHEIGHTWIDTH(h-1, w * (pSiS->CurrentLayout.bitsPerPixel/8)-1);
14472b676d7Smrg    sisSETCMD(op);
14572b676d7Smrg}
14672b676d7Smrg
14772b676d7Smrg/* solid fill */
14872b676d7Smrgstatic void
14972b676d7SmrgSiSSetupForFillRectSolid(ScrnInfoPtr pScrn, int color, int rop,
15072b676d7Smrg			unsigned int planemask)
15172b676d7Smrg{
15272b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
15372b676d7Smrg
15472b676d7Smrg    sisBLTSync;
15572b676d7Smrg    sisSETBGROPCOL(SiSGetCopyROP(rop), color);
15672b676d7Smrg    sisSETFGROPCOL(SiSGetCopyROP(rop), color);
15772b676d7Smrg    sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset);
15872b676d7Smrg}
15972b676d7Smrg
16072b676d7Smrgstatic void
16172b676d7SmrgSiSSubsequentFillRectSolid(ScrnInfoPtr pScrn, int x, int y, int w, int h)
16272b676d7Smrg{
16372b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
16472b676d7Smrg    int destaddr, op;
16572b676d7Smrg
16672b676d7Smrg    destaddr = y * pSiS->CurrentLayout.displayWidth + x;
16772b676d7Smrg
16872b676d7Smrg    op = sisCMDBLT | sisSRCBG | sisTOP2BOTTOM | sisLEFT2RIGHT;
16972b676d7Smrg
17072b676d7Smrg    if(pSiS->ClipEnabled)
17172b676d7Smrg       op |= sisCLIPINTRN | sisCLIPENABL;
17272b676d7Smrg
17372b676d7Smrg    destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8);
17472b676d7Smrg
17572b676d7Smrg    sisBLTSync;
17672b676d7Smrg    sisSETHEIGHTWIDTH(h-1, w * (pSiS->CurrentLayout.bitsPerPixel/8)-1);
17772b676d7Smrg    sisSETDSTADDR(destaddr);
17872b676d7Smrg    sisSETCMD(op);
17972b676d7Smrg}
18072b676d7Smrg
18172b676d7Smrg#ifdef SIS_USE_XAA  /* ---------------------------- XAA -------------------------- */
18272b676d7Smrg
18372b676d7Smrg/* Clipping */
18472b676d7Smrgstatic void
18572b676d7SmrgSiSSetClippingRectangle(ScrnInfoPtr pScrn,
18672b676d7Smrg			int left, int top, int right, int bottom)
18772b676d7Smrg{
18872b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
18972b676d7Smrg
19072b676d7Smrg    sisBLTSync;
19172b676d7Smrg    sisSETCLIPTOP(left,top);
19272b676d7Smrg    sisSETCLIPBOTTOM(right,bottom);
19372b676d7Smrg    pSiS->ClipEnabled = TRUE;
19472b676d7Smrg}
19572b676d7Smrg
19672b676d7Smrgstatic void
19772b676d7SmrgSiSDisableClipping(ScrnInfoPtr pScrn)
19872b676d7Smrg{
19972b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
20072b676d7Smrg    pSiS->ClipEnabled = FALSE;
20172b676d7Smrg}
20272b676d7Smrg
20372b676d7Smrg/* 8x8 mono */
20472b676d7Smrgstatic void
20572b676d7SmrgSiSSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
20672b676d7Smrg			int fg, int bg, int rop, unsigned int planemask)
20772b676d7Smrg{
20872b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
20972b676d7Smrg    unsigned int  *patternRegPtr;
21072b676d7Smrg    int  i;
21172b676d7Smrg
21272b676d7Smrg    (void)XAAHelpPatternROP(pScrn, &fg, &bg, planemask, &rop);
21372b676d7Smrg
21472b676d7Smrg    sisBLTSync;
21572b676d7Smrg    if(bg != -1) {
21672b676d7Smrg       sisSETBGROPCOL(0xcc, bg);  /* copy */
21772b676d7Smrg    } else {
21872b676d7Smrg       sisSETBGROPCOL(0xAA, bg);  /* noop */
21972b676d7Smrg    }
22072b676d7Smrg    sisSETFGROPCOL(rop, fg);
22172b676d7Smrg    sisSETPITCH(0, pSiS->scrnOffset);
22272b676d7Smrg    sisSETSRCADDR(0);
22372b676d7Smrg    patternRegPtr =  (unsigned int *)sisSETPATREG();
22472b676d7Smrg    pSiS->sisPatternReg[0] = pSiS->sisPatternReg[2] = patternx ;
22572b676d7Smrg    pSiS->sisPatternReg[1] = pSiS->sisPatternReg[3] = patterny ;
22672b676d7Smrg    for(i = 0 ; i < 16 /* sisPatternHeight */ ; ) {
22772b676d7Smrg       patternRegPtr[i++] = patternx ;
22872b676d7Smrg       patternRegPtr[i++] = patterny ;
22972b676d7Smrg    }
23072b676d7Smrg}
23172b676d7Smrg
23272b676d7Smrgstatic void
23372b676d7SmrgSiSSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
23472b676d7Smrg			int patterny, int x, int y, int w, int h)
23572b676d7Smrg{
23672b676d7Smrg    SISPtr   pSiS = SISPTR(pScrn);
23772b676d7Smrg    register UChar  *patternRegPtr;
23872b676d7Smrg    register UChar  *srcPatternRegPtr;
23972b676d7Smrg    register unsigned int   *patternRegPtrL;
24072b676d7Smrg    UShort   tmp;
24172b676d7Smrg    int      dstaddr, i, k, shift;
24272b676d7Smrg    int      op  = sisCMDCOLEXP |
24372b676d7Smrg		  sisTOP2BOTTOM |
24472b676d7Smrg		  sisLEFT2RIGHT |
24572b676d7Smrg		       sisPATFG |
24672b676d7Smrg		       sisSRCBG;
24772b676d7Smrg
24872b676d7Smrg    if(pSiS->ClipEnabled)
24972b676d7Smrg       op |= sisCLIPINTRN | sisCLIPENABL;
25072b676d7Smrg
25172b676d7Smrg    dstaddr = ( y * pSiS->CurrentLayout.displayWidth + x ) *
25272b676d7Smrg			pSiS->CurrentLayout.bitsPerPixel / 8;
25372b676d7Smrg
25472b676d7Smrg    sisBLTSync;
25572b676d7Smrg
25672b676d7Smrg    patternRegPtr = sisSETPATREG();
25772b676d7Smrg    srcPatternRegPtr = (UChar *)pSiS->sisPatternReg ;
25872b676d7Smrg    shift = 8 - patternx ;
25972b676d7Smrg    for(i = 0, k = patterny ; i < 8 ; i++, k++ ) {
26072b676d7Smrg       tmp = srcPatternRegPtr[k]<<8 | srcPatternRegPtr[k] ;
26172b676d7Smrg       tmp >>= shift ;
26272b676d7Smrg       patternRegPtr[i] = tmp & 0xff;
26372b676d7Smrg    }
26472b676d7Smrg    patternRegPtrL = (unsigned int *)sisSETPATREG();
26572b676d7Smrg    for(i = 2 ; i < 16 /* sisPatternHeight */; ) {
26672b676d7Smrg       patternRegPtrL[i++] = patternRegPtrL[0];
26772b676d7Smrg       patternRegPtrL[i++] = patternRegPtrL[1];
26872b676d7Smrg    }
26972b676d7Smrg
27072b676d7Smrg    sisSETDSTADDR(dstaddr);
27172b676d7Smrg    sisSETHEIGHTWIDTH(h-1, w*(pSiS->CurrentLayout.bitsPerPixel/8)-1);
27272b676d7Smrg    sisSETCMD(op);
27372b676d7Smrg}
27472b676d7Smrg
27572b676d7Smrg/* Line */
27672b676d7Smrgstatic void
27772b676d7SmrgSiSSetupForSolidLine(ScrnInfoPtr pScrn,
27872b676d7Smrg			int color, int rop, unsigned int planemask)
27972b676d7Smrg{
28072b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
28172b676d7Smrg
28272b676d7Smrg    sisBLTSync;
28372b676d7Smrg    sisSETBGROPCOL(SiSGetCopyROP(rop), 0);
28472b676d7Smrg    sisSETFGROPCOL(SiSGetCopyROP(rop), color);
28572b676d7Smrg}
28672b676d7Smrg
28772b676d7Smrgstatic void
28872b676d7SmrgSiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
28972b676d7Smrg			int x1, int y1, int x2, int y2, int flags)
29072b676d7Smrg
29172b676d7Smrg{
29272b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
29372b676d7Smrg    int op, major, minor, err, K1, K2, tmp;
29472b676d7Smrg
29572b676d7Smrg    op = sisCMDLINE  | sisSRCFG;
29672b676d7Smrg
29772b676d7Smrg    if((flags & OMIT_LAST))
29872b676d7Smrg       op |= sisLASTPIX;
29972b676d7Smrg
30072b676d7Smrg    if(pSiS->ClipEnabled)
30172b676d7Smrg       op |= sisCLIPINTRN | sisCLIPENABL;
30272b676d7Smrg
30372b676d7Smrg    if((major = x2 - x1) <= 0)
30472b676d7Smrg       major = -major;
30572b676d7Smrg    else
30672b676d7Smrg       op |= sisXINCREASE;
30772b676d7Smrg
30872b676d7Smrg    if((minor = y2 - y1) <= 0)
30972b676d7Smrg       minor = -minor;
31072b676d7Smrg    else
31172b676d7Smrg       op |= sisYINCREASE;
31272b676d7Smrg
31372b676d7Smrg    if(minor >= major) {
31472b676d7Smrg       tmp = minor;
31572b676d7Smrg       minor = major;
31672b676d7Smrg       major = tmp;
31772b676d7Smrg    } else
31872b676d7Smrg       op |= sisXMAJOR;
31972b676d7Smrg
32072b676d7Smrg    K1 = (minor - major) << 1;
32172b676d7Smrg    K2 = minor << 1;
32272b676d7Smrg    err = (minor << 1) - major;
32372b676d7Smrg
32472b676d7Smrg    sisBLTSync;
32572b676d7Smrg    sisSETXStart(x1);
32672b676d7Smrg    sisSETYStart(y1);
32772b676d7Smrg    sisSETLineSteps((short)K1,(short)K2);
32872b676d7Smrg    sisSETLineErrorTerm((short)err);
32972b676d7Smrg    sisSETLineMajorCount((short)major);
33072b676d7Smrg    sisSETCMD(op);
33172b676d7Smrg}
33272b676d7Smrg
33372b676d7Smrgstatic void
33472b676d7SmrgSiSSubsequentSolidHorVertLine(ScrnInfoPtr pScrn,
33572b676d7Smrg				int x, int y, int len, int dir)
33672b676d7Smrg{
33772b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
33872b676d7Smrg    int destaddr, op;
33972b676d7Smrg
34072b676d7Smrg    destaddr = y * pSiS->CurrentLayout.displayWidth + x;
34172b676d7Smrg
34272b676d7Smrg    op = sisCMDBLT | sisSRCFG | sisTOP2BOTTOM | sisLEFT2RIGHT;
34372b676d7Smrg
34472b676d7Smrg    if(pSiS->ClipEnabled)
34572b676d7Smrg        op |= sisCLIPINTRN | sisCLIPENABL;
34672b676d7Smrg
34772b676d7Smrg    destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8);
34872b676d7Smrg
34972b676d7Smrg    sisBLTSync;
35072b676d7Smrg
35172b676d7Smrg    sisSETPITCH(pSiS->scrnOffset, pSiS->scrnOffset);
35272b676d7Smrg
35372b676d7Smrg    if(dir == DEGREES_0) {
35472b676d7Smrg        sisSETHEIGHTWIDTH(0, len * (pSiS->CurrentLayout.bitsPerPixel >> 3) - 1);
35572b676d7Smrg    } else {
35672b676d7Smrg        sisSETHEIGHTWIDTH(len - 1, (pSiS->CurrentLayout.bitsPerPixel >> 3) - 1);
35772b676d7Smrg    }
35872b676d7Smrg
35972b676d7Smrg    sisSETDSTADDR(destaddr);
36072b676d7Smrg    sisSETCMD(op);
36172b676d7Smrg}
36272b676d7Smrg
36372b676d7Smrg#ifdef CTSCE
36472b676d7Smrg/* ----- CPU To Screen Color Expand (scanline-wise) ------ */
36572b676d7Smrgstatic void
36672b676d7SmrgSiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
36772b676d7Smrg				int fg, int bg, int rop, unsigned int planemask)
36872b676d7Smrg{
36972b676d7Smrg    SISPtr pSiS=SISPTR(pScrn);
37072b676d7Smrg
37172b676d7Smrg    pSiS->CommandReg = 0;
37272b676d7Smrg
37372b676d7Smrg    pSiS->CommandReg |= (sisCMDECOLEXP |
37472b676d7Smrg			 sisLEFT2RIGHT |
37572b676d7Smrg			 sisTOP2BOTTOM);
37672b676d7Smrg
37772b676d7Smrg    sisBLTSync;
37872b676d7Smrg
37972b676d7Smrg    /* The combination of flags in the following
38072b676d7Smrg     * is not understandable. However, this is the
38172b676d7Smrg     * only combination that seems to work.
38272b676d7Smrg     */
38372b676d7Smrg    if(bg == -1) {
38472b676d7Smrg       sisSETROPBG(0xAA);             /* dst = dst (=noop) */
38572b676d7Smrg       pSiS->CommandReg |= sisSRCFG;
38672b676d7Smrg    } else {
38772b676d7Smrg       sisSETBGROPCOL(SiSGetPatternROP(rop), bg);
38872b676d7Smrg       pSiS->CommandReg |= sisSRCFG | sisPATBG;
38972b676d7Smrg    }
39072b676d7Smrg
39172b676d7Smrg    sisSETFGROPCOL(SiSGetCopyROP(rop), fg);
39272b676d7Smrg
39372b676d7Smrg    sisSETDSTPITCH(pSiS->scrnOffset);
39472b676d7Smrg}
39572b676d7Smrg
39672b676d7Smrg
39772b676d7Smrgstatic void
39872b676d7SmrgSiSSubsequentScanlineCPUToScreenColorExpandFill(
39972b676d7Smrg			ScrnInfoPtr pScrn, int x, int y, int w,
40072b676d7Smrg			int h, int skipleft)
40172b676d7Smrg{
40272b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
40372b676d7Smrg    int _x0, _y0, _x1, _y1;
40472b676d7Smrg    int op = pSiS->CommandReg;
40572b676d7Smrg
40672b676d7Smrg    if(skipleft > 0) {
40772b676d7Smrg       _x0 = x + skipleft;
40872b676d7Smrg       _y0 = y;
40972b676d7Smrg       _x1 = x + w;
41072b676d7Smrg       _y1 = y + h;
41172b676d7Smrg       sisSETCLIPTOP(_x0, _y0);
41272b676d7Smrg       sisSETCLIPBOTTOM(_x1, _y1);
41372b676d7Smrg       op |= sisCLIPENABL;
41472b676d7Smrg    } else {
41572b676d7Smrg       op &= (~(sisCLIPINTRN | sisCLIPENABL));
41672b676d7Smrg    }
41772b676d7Smrg
41872b676d7Smrg    sisSETSRCPITCH(((((w + 7) / 8) + 3) >> 2) * 4);
41972b676d7Smrg
42072b676d7Smrg    sisSETHEIGHTWIDTH(1-1, (w * (pSiS->CurrentLayout.bitsPerPixel/8)) - 1);
42172b676d7Smrg
42272b676d7Smrg    pSiS->xcurrent = x;
42372b676d7Smrg    pSiS->ycurrent = y;
42472b676d7Smrg
42572b676d7Smrg    pSiS->CommandReg = op;
42672b676d7Smrg}
42772b676d7Smrg
42872b676d7Smrgstatic void
42972b676d7SmrgSiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
43072b676d7Smrg{
43172b676d7Smrg    SISPtr pSiS = SISPTR(pScrn);
43272b676d7Smrg    unsigned long cbo = pSiS->ColorExpandBufferScreenOffset[bufno];
43372b676d7Smrg    int op = pSiS->CommandReg;
43472b676d7Smrg    int destaddr;
43572b676d7Smrg
43672b676d7Smrg    destaddr = (pSiS->ycurrent * pSiS->CurrentLayout.displayWidth) + pSiS->xcurrent;
43772b676d7Smrg    destaddr *= (pSiS->CurrentLayout.bitsPerPixel / 8);
43872b676d7Smrg
43972b676d7Smrg    /* Wait until there is no color expansion command in queue */
44072b676d7Smrg    /* sisBLTSync; */
44172b676d7Smrg
44272b676d7Smrg    sisSETSRCADDR(cbo);
44372b676d7Smrg
44472b676d7Smrg    sisSETDSTADDR(destaddr);
44572b676d7Smrg
44672b676d7Smrg    sisSETCMD(op);
44772b676d7Smrg
44872b676d7Smrg    pSiS->ycurrent++;
44972b676d7Smrg
45072b676d7Smrg    /* Wait for eventual color expand commands to finish */
45172b676d7Smrg    /* (needs to be done, otherwise the data in the buffer may
45272b676d7Smrg     *  be overwritten while accessed by the hardware)
45372b676d7Smrg     */
45472b676d7Smrg    while((SIS_MMIO_IN32(pSiS->IOBase, 0x8284) & 0x80000000)) {}
45572b676d7Smrg
45672b676d7Smrg    sisBLTSync;
45772b676d7Smrg}
45872b676d7Smrg#endif  /* CTSCE */
45972b676d7Smrg
46072b676d7Smrg#endif /* XAA */
46172b676d7Smrg
46272b676d7Smrg#ifdef SIS_USE_EXA  /* ---------------------------- EXA -------------------------- */
46372b676d7Smrg
46472b676d7Smrgstatic void
46572b676d7SmrgSiSEXASync(ScreenPtr pScreen, int marker)
46672b676d7Smrg{
46774c14cd6Smrg	SISPtr pSiS = SISPTR(xf86ScreenToScrn(pScreen));
46872b676d7Smrg
46972b676d7Smrg	sisBLTSync;
47072b676d7Smrg}
47172b676d7Smrg
47272b676d7Smrgstatic Bool
47372b676d7SmrgSiSPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
47472b676d7Smrg{
47574c14cd6Smrg	ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen);
47672b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
47772b676d7Smrg
47872b676d7Smrg	/* Planemask not supported */
47972b676d7Smrg	if((planemask & ((1 << pPixmap->drawable.depth) - 1)) !=
48072b676d7Smrg				(1 << pPixmap->drawable.depth) - 1) {
48172b676d7Smrg	   return FALSE;
48272b676d7Smrg	}
48372b676d7Smrg
48472b676d7Smrg	/* Since these old engines have no "dest color depth" register, I assume
48572b676d7Smrg	 * the 2D engine takes the bpp from the DAC... FIXME ? */
48672b676d7Smrg	if(pPixmap->drawable.bitsPerPixel != pSiS->CurrentLayout.bitsPerPixel)
48772b676d7Smrg	   return FALSE;
48872b676d7Smrg
48972b676d7Smrg	/* Check that the pitch matches the hardware's requirements. Should
49072b676d7Smrg	 * never be a problem due to pixmapPitchAlign and fbScreenInit.
49172b676d7Smrg	 */
49272b676d7Smrg	if(exaGetPixmapPitch(pPixmap) & 7)
49372b676d7Smrg	   return FALSE;
49472b676d7Smrg
49572b676d7Smrg	pSiS->fillPitch = exaGetPixmapPitch(pPixmap);
49672b676d7Smrg	pSiS->fillBpp = pPixmap->drawable.bitsPerPixel >> 3;
49772b676d7Smrg	pSiS->fillDstBase = (CARD32)exaGetPixmapOffset(pPixmap);
49872b676d7Smrg
49972b676d7Smrg	sisBLTSync;
50072b676d7Smrg	sisSETBGROPCOL(SiSGetCopyROP(alu), fg);
50172b676d7Smrg	sisSETFGROPCOL(SiSGetCopyROP(alu), fg);
50272b676d7Smrg	sisSETPITCH(pSiS->fillPitch, pSiS->fillPitch);
50372b676d7Smrg
50472b676d7Smrg	return TRUE;
50572b676d7Smrg}
50672b676d7Smrg
50772b676d7Smrgstatic void
50872b676d7SmrgSiSSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
50972b676d7Smrg{
51074c14cd6Smrg	ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen);
51172b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
51272b676d7Smrg
51372b676d7Smrg	sisBLTSync;
51472b676d7Smrg	sisSETHEIGHTWIDTH((y2 - y1) - 1, (x2 - x1) * pSiS->fillBpp - 1);
51572b676d7Smrg	sisSETDSTADDR((pSiS->fillDstBase + ((y1 * (pSiS->fillPitch / pSiS->fillBpp) + x1) * pSiS->fillBpp)));
51672b676d7Smrg	sisSETCMD((sisCMDBLT | sisSRCBG | sisTOP2BOTTOM | sisLEFT2RIGHT));
51772b676d7Smrg}
51872b676d7Smrg
51972b676d7Smrgstatic void
52072b676d7SmrgSiSDoneSolid(PixmapPtr pPixmap)
52172b676d7Smrg{
52272b676d7Smrg}
52372b676d7Smrg
52472b676d7Smrgstatic Bool
52572b676d7SmrgSiSPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir,
52672b676d7Smrg					int alu, Pixel planemask)
52772b676d7Smrg{
52874c14cd6Smrg	ScrnInfoPtr pScrn = xf86ScreenToScrn(pSrcPixmap->drawable.pScreen);
52972b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
53072b676d7Smrg
53172b676d7Smrg	/* Planemask not supported */
53272b676d7Smrg	if((planemask & ((1 << pSrcPixmap->drawable.depth) - 1)) !=
53372b676d7Smrg				(1 << pSrcPixmap->drawable.depth) - 1) {
53472b676d7Smrg	   return FALSE;
53572b676d7Smrg	}
53672b676d7Smrg
53772b676d7Smrg	/* Since these old engines have no "dest color depth" register, I assume
53872b676d7Smrg	 * the 2D engine takes the bpp from the DAC... FIXME ? */
53972b676d7Smrg	if(pDstPixmap->drawable.bitsPerPixel != pSiS->CurrentLayout.bitsPerPixel)
54072b676d7Smrg	   return FALSE;
54172b676d7Smrg
54272b676d7Smrg	/* Check that the pitch matches the hardware's requirements. Should
54372b676d7Smrg	 * never be a problem due to pixmapPitchAlign and fbScreenInit.
54472b676d7Smrg	 */
54572b676d7Smrg	if(exaGetPixmapPitch(pSrcPixmap) & 3)
54672b676d7Smrg	   return FALSE;
54772b676d7Smrg	if(exaGetPixmapPitch(pDstPixmap) & 7)
54872b676d7Smrg	   return FALSE;
54972b676d7Smrg
55072b676d7Smrg	pSiS->copyXdir = xdir;
55172b676d7Smrg	pSiS->copyYdir = ydir;
55272b676d7Smrg	pSiS->copyBpp = pSrcPixmap->drawable.bitsPerPixel >> 3;
55372b676d7Smrg	pSiS->copySPitch = exaGetPixmapPitch(pSrcPixmap);
55472b676d7Smrg	pSiS->copyDPitch = exaGetPixmapPitch(pDstPixmap);
55572b676d7Smrg	pSiS->copySrcBase = (CARD32)exaGetPixmapOffset(pSrcPixmap);
55672b676d7Smrg	pSiS->copyDstBase = (CARD32)exaGetPixmapOffset(pDstPixmap);
55772b676d7Smrg
55872b676d7Smrg	sisBLTSync;
55972b676d7Smrg	sisSETPITCH(pSiS->copySPitch, pSiS->copyDPitch);
56072b676d7Smrg	sisSETROP(SiSGetCopyROP(alu));
56172b676d7Smrg
56272b676d7Smrg	return TRUE;
56372b676d7Smrg}
56472b676d7Smrg
56572b676d7Smrgstatic void
56672b676d7SmrgSiSCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height)
56772b676d7Smrg{
56874c14cd6Smrg	ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
56972b676d7Smrg	SISPtr pSiS = SISPTR(pScrn);
57072b676d7Smrg	CARD32 srcbase, dstbase, cmd;
57172b676d7Smrg	int bpp = pSiS->copyBpp;
57272b676d7Smrg	int srcPixelPitch = pSiS->copySPitch / bpp;
57372b676d7Smrg	int dstPixelPitch = pSiS->copyDPitch / bpp;
57472b676d7Smrg
57572b676d7Smrg	cmd = sisCMDBLT | sisSRCVIDEO;
57672b676d7Smrg
57772b676d7Smrg	if(pSiS->copyYdir < 0) {
57872b676d7Smrg	   cmd |= sisBOTTOM2TOP;
57972b676d7Smrg	   srcbase = (srcY + height - 1) * srcPixelPitch;
58072b676d7Smrg	   dstbase = (dstY + height - 1) * dstPixelPitch;
58172b676d7Smrg	} else {
58272b676d7Smrg	   cmd |= sisTOP2BOTTOM;
58372b676d7Smrg	   srcbase = srcY * srcPixelPitch;
58472b676d7Smrg	   dstbase = dstY * dstPixelPitch;
58572b676d7Smrg	}
58672b676d7Smrg
58772b676d7Smrg	if(pSiS->copyXdir < 0) {
58872b676d7Smrg	   cmd |= sisRIGHT2LEFT;
58972b676d7Smrg	   srcbase += srcX + width - 1;
59072b676d7Smrg	   dstbase += dstX + width - 1;
59172b676d7Smrg	} else {
59272b676d7Smrg	   cmd |= sisLEFT2RIGHT;
59372b676d7Smrg	   srcbase += srcX;
59472b676d7Smrg	   dstbase += dstX;
59572b676d7Smrg	}
59672b676d7Smrg
59772b676d7Smrg	srcbase *= bpp;
59872b676d7Smrg	dstbase *= bpp;
59972b676d7Smrg	if(pSiS->copyXdir < 0) {
60072b676d7Smrg	   srcbase += bpp - 1;
60172b676d7Smrg	   dstbase += bpp - 1;
60272b676d7Smrg	}
60372b676d7Smrg
60472b676d7Smrg	srcbase += pSiS->copySrcBase;
60572b676d7Smrg	dstbase += pSiS->copyDstBase;
60672b676d7Smrg
60772b676d7Smrg	sisBLTSync;
60872b676d7Smrg	sisSETSRCADDR(srcbase);
60972b676d7Smrg	sisSETDSTADDR(dstbase);
61072b676d7Smrg	sisSETHEIGHTWIDTH(height - 1, width * bpp - 1);
61172b676d7Smrg	sisSETCMD(cmd);
61272b676d7Smrg}
61372b676d7Smrg
61472b676d7Smrgstatic void
61572b676d7SmrgSiSDoneCopy(PixmapPtr pDstPixmap)
61672b676d7Smrg{
61772b676d7Smrg}
61872b676d7Smrg
61972b676d7Smrg#endif /* EXA */
62072b676d7Smrg
62172b676d7Smrg/* For DGA usage */
62272b676d7Smrg
62372b676d7Smrgstatic void
62472b676d7SmrgSiSDGAFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, int color)
62572b676d7Smrg{
62672b676d7Smrg	SiSSetupForFillRectSolid(pScrn, color, GXcopy, ~0);
62772b676d7Smrg	SiSSubsequentFillRectSolid(pScrn, x, y, w, h);
62872b676d7Smrg}
62972b676d7Smrg
63072b676d7Smrgstatic void
63172b676d7SmrgSiSDGABlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int dstx, int dsty, int w, int h, int color)
63272b676d7Smrg{
63372b676d7Smrg	int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1;
63472b676d7Smrg	int ydir = (srcy < dsty) ? -1 : 1;
63572b676d7Smrg
63672b676d7Smrg	SiSSetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, (CARD32)~0, color);
63772b676d7Smrg	SiSSubsequentScreenToScreenCopy(pScrn, srcx, srcy, dstx, dsty, w, h);
63872b676d7Smrg}
63972b676d7Smrg
64072b676d7Smrg/* Initialisation */
64172b676d7Smrg
64272b676d7SmrgBool
64372b676d7SmrgSiSAccelInit(ScreenPtr pScreen)
64472b676d7Smrg{
64574c14cd6Smrg    ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
64672b676d7Smrg    SISPtr         pSiS = SISPTR(pScrn);
64772b676d7Smrg#ifdef SIS_USE_XAA
64872b676d7Smrg    XAAInfoRecPtr  infoPtr = NULL;
64972b676d7Smrg    int            topFB, reservedFbSize, usableFbSize, i;
65072b676d7Smrg    UChar          *AvailBufBase;
65172b676d7Smrg    BoxRec         Avail;
65272b676d7Smrg#endif
65372b676d7Smrg
65472b676d7Smrg    pSiS->ColorExpandBufferNumber = 0;
65572b676d7Smrg    pSiS->PerColorExpandBufferSize = 0;
65672b676d7Smrg    pSiS->RenderAccelArray = NULL;
65772b676d7Smrg#ifdef SIS_USE_XAA
65872b676d7Smrg    pSiS->AccelInfoPtr = NULL;
65972b676d7Smrg#endif
66072b676d7Smrg#ifdef SIS_USE_EXA
66172b676d7Smrg    pSiS->EXADriverPtr = NULL;
66272b676d7Smrg    pSiS->exa_scratch = NULL;
66372b676d7Smrg#endif
66472b676d7Smrg
66572b676d7Smrg    if(!pSiS->NoAccel) {
66672b676d7Smrg#ifdef SIS_USE_XAA
66772b676d7Smrg       if(!pSiS->useEXA) {
66872b676d7Smrg          pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec();
66972b676d7Smrg          if(!infoPtr) pSiS->NoAccel = TRUE;
67072b676d7Smrg       }
67172b676d7Smrg#endif
67272b676d7Smrg#ifdef SIS_USE_EXA
67372b676d7Smrg       if(pSiS->useEXA) {
67472b676d7Smrg	  if(!(pSiS->EXADriverPtr = exaDriverAlloc())) {
67572b676d7Smrg	     pSiS->NoAccel = TRUE;
67672b676d7Smrg	     pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */
67772b676d7Smrg	  }
67872b676d7Smrg       }
67972b676d7Smrg#endif
68072b676d7Smrg    }
68172b676d7Smrg
68272b676d7Smrg    if(!pSiS->NoAccel) {
68372b676d7Smrg
68472b676d7Smrg       SiSInitializeAccelerator(pScrn);
68572b676d7Smrg
68672b676d7Smrg       pSiS->InitAccel = SiSInitializeAccelerator;
68772b676d7Smrg       pSiS->SyncAccel = SiSSyncAccel;
68872b676d7Smrg       pSiS->FillRect  = SiSDGAFillRect;
68972b676d7Smrg       pSiS->BlitRect  = SiSDGABlitRect;
69072b676d7Smrg
69172b676d7Smrg#ifdef SIS_USE_XAA	/* ----------------------- XAA ----------------------- */
69272b676d7Smrg       if(!pSiS->useEXA) {
69372b676d7Smrg
69472b676d7Smrg	  infoPtr->Flags = LINEAR_FRAMEBUFFER |
69572b676d7Smrg			   OFFSCREEN_PIXMAPS |
69672b676d7Smrg			   PIXMAP_CACHE;
69772b676d7Smrg
69872b676d7Smrg	  /* Sync */
69972b676d7Smrg	  infoPtr->Sync = SiSSync;
70072b676d7Smrg
70172b676d7Smrg	  /* Screen To Screen copy */
70272b676d7Smrg	  infoPtr->SetupForScreenToScreenCopy =  SiSSetupForScreenToScreenCopy;
70372b676d7Smrg	  infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy;
70472b676d7Smrg	  infoPtr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK;
70572b676d7Smrg
70672b676d7Smrg	  /* Solid fill */
70772b676d7Smrg	  infoPtr->SetupForSolidFill = SiSSetupForFillRectSolid;
70872b676d7Smrg	  infoPtr->SubsequentSolidFillRect = SiSSubsequentFillRectSolid;
70972b676d7Smrg	  infoPtr->SolidFillFlags = NO_PLANEMASK;
71072b676d7Smrg
71172b676d7Smrg	  /* On 5597/5598 and 6326, clipping and lines only work
71272b676d7Smrg	     for 1024, 2048, 4096 logical width */
71372b676d7Smrg	  if(pSiS->ValidWidth) {
71472b676d7Smrg	     /* Clipping */
71572b676d7Smrg	     infoPtr->SetClippingRectangle = SiSSetClippingRectangle;
71672b676d7Smrg	     infoPtr->DisableClipping = SiSDisableClipping;
71772b676d7Smrg	     infoPtr->ClippingFlags = HARDWARE_CLIP_SOLID_LINE |
71872b676d7Smrg				      HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY |
71972b676d7Smrg				      HARDWARE_CLIP_MONO_8x8_FILL |
72072b676d7Smrg				      HARDWARE_CLIP_SOLID_FILL  ;
72172b676d7Smrg
72272b676d7Smrg	     /* Solid Lines */
72372b676d7Smrg	     infoPtr->SetupForSolidLine = SiSSetupForSolidLine;
72472b676d7Smrg	     infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine;
72572b676d7Smrg	     infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorVertLine;
72672b676d7Smrg	     infoPtr->SolidLineFlags = NO_PLANEMASK;
72772b676d7Smrg          }
72872b676d7Smrg
72972b676d7Smrg	  if(pScrn->bitsPerPixel != 24) {
73072b676d7Smrg	     /* 8x8 mono pattern */
73172b676d7Smrg	     infoPtr->SetupForMono8x8PatternFill = SiSSetupForMono8x8PatternFill;
73272b676d7Smrg	     infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMono8x8PatternFillRect;
73372b676d7Smrg	     infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
73472b676d7Smrg						HARDWARE_PATTERN_PROGRAMMED_BITS |
73572b676d7Smrg						HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
73672b676d7Smrg						BIT_ORDER_IN_BYTE_MSBFIRST;
73772b676d7Smrg	  }
73872b676d7Smrg
73972b676d7Smrg#ifdef CTSCE
74072b676d7Smrg	  if(pScrn->bitsPerPixel != 24) {
74172b676d7Smrg	     /* per-scanline color expansion (using indirect method) */
74272b676d7Smrg	     pSiS->ColorExpandBufferNumber = 4;
74372b676d7Smrg	     pSiS->ColorExpandBufferCountMask = 0x03;
74472b676d7Smrg	     pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31) / 32) * 4;
74572b676d7Smrg
74672b676d7Smrg	     infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber;
74772b676d7Smrg	     infoPtr->ScanlineColorExpandBuffers = (UChar **)&pSiS->ColorExpandBufferAddr[0];
74872b676d7Smrg
74972b676d7Smrg	     infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
75072b676d7Smrg				SiSSetupForScanlineCPUToScreenColorExpandFill;
75172b676d7Smrg	     infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
75272b676d7Smrg				SiSSubsequentScanlineCPUToScreenColorExpandFill;
75372b676d7Smrg	     infoPtr->SubsequentColorExpandScanline =
75472b676d7Smrg	                            SiSSubsequentColorExpandScanline;
75572b676d7Smrg	     infoPtr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK |
75672b676d7Smrg								CPU_TRANSFER_PAD_DWORD |
75772b676d7Smrg								SCANLINE_PAD_DWORD |
75872b676d7Smrg								BIT_ORDER_IN_BYTE_MSBFIRST |
75972b676d7Smrg								LEFT_EDGE_CLIPPING;
76072b676d7Smrg	  }
76172b676d7Smrg#endif
76272b676d7Smrg       } /* !exa */
76372b676d7Smrg#endif /* XAA */
76472b676d7Smrg
76572b676d7Smrg#ifdef SIS_USE_EXA	/* ----------------------- EXA ----------------------- */
76672b676d7Smrg       if(pSiS->useEXA) {
76772b676d7Smrg	  pSiS->EXADriverPtr->exa_major = 2;
76872b676d7Smrg	  pSiS->EXADriverPtr->exa_minor = 0;
76972b676d7Smrg
77072b676d7Smrg	  /* data */
77172b676d7Smrg	  pSiS->EXADriverPtr->memoryBase = pSiS->FbBase;
77272b676d7Smrg	  pSiS->EXADriverPtr->memorySize = pSiS->maxxfbmem;
77372b676d7Smrg	  pSiS->EXADriverPtr->offScreenBase = pScrn->virtualX * pScrn->virtualY
77472b676d7Smrg						* (pScrn->bitsPerPixel >> 3);
77572b676d7Smrg	  if(pSiS->EXADriverPtr->memorySize > pSiS->EXADriverPtr->offScreenBase) {
77672b676d7Smrg	     pSiS->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
77772b676d7Smrg	  } else {
77872b676d7Smrg	     pSiS->NoXvideo = TRUE;
77972b676d7Smrg	     xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
78072b676d7Smrg		"Not enough video RAM for offscreen memory manager. Xv disabled\n");
78172b676d7Smrg	  }
78272b676d7Smrg	  pSiS->EXADriverPtr->pixmapOffsetAlign = 8;	/* src/dst: double quad word boundary */
78372b676d7Smrg	  pSiS->EXADriverPtr->pixmapPitchAlign = 8;	/* could possibly be 1, but who knows for sure */
78472b676d7Smrg	  pSiS->EXADriverPtr->maxX = 2047;
78572b676d7Smrg	  pSiS->EXADriverPtr->maxY = 2047;
78672b676d7Smrg
78772b676d7Smrg	  /* Sync */
78872b676d7Smrg	  pSiS->EXADriverPtr->WaitMarker = SiSEXASync;
78972b676d7Smrg
79072b676d7Smrg	  /* Solid fill */
79172b676d7Smrg	  pSiS->EXADriverPtr->PrepareSolid = SiSPrepareSolid;
79272b676d7Smrg	  pSiS->EXADriverPtr->Solid = SiSSolid;
79372b676d7Smrg	  pSiS->EXADriverPtr->DoneSolid = SiSDoneSolid;
79472b676d7Smrg
79572b676d7Smrg	  /* Copy */
79672b676d7Smrg	  pSiS->EXADriverPtr->PrepareCopy = SiSPrepareCopy;
79772b676d7Smrg	  pSiS->EXADriverPtr->Copy = SiSCopy;
79872b676d7Smrg	  pSiS->EXADriverPtr->DoneCopy = SiSDoneCopy;
79972b676d7Smrg
80072b676d7Smrg	  /* Composite not supported */
80172b676d7Smrg
80272b676d7Smrg       }
80372b676d7Smrg#endif /* EXA */
80472b676d7Smrg
80572b676d7Smrg    }  /* NoAccel */
80672b676d7Smrg
80772b676d7Smrg    /* Offscreen memory manager
80872b676d7Smrg     *
80972b676d7Smrg     * Layout: (Sizes here do not reflect correct proportions)
81072b676d7Smrg     * |--------------++++++++++++++++++++|  ====================~~~~~~~~~~~~|
81172b676d7Smrg     *   UsableFbSize  ColorExpandBuffers |        TurboQueue     HWCursor
81272b676d7Smrg     *                                  topFB
81372b676d7Smrg     */
81472b676d7Smrg
81572b676d7Smrg#ifdef SIS_USE_XAA
81672b676d7Smrg    if(!pSiS->useEXA) {
81772b676d7Smrg
81872b676d7Smrg       topFB = pSiS->maxxfbmem;
81972b676d7Smrg
82072b676d7Smrg       reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize;
82172b676d7Smrg
82272b676d7Smrg       usableFbSize = topFB - reservedFbSize;
82372b676d7Smrg
82472b676d7Smrg       if(pSiS->ColorExpandBufferNumber) {
82572b676d7Smrg	  AvailBufBase = pSiS->FbBase + usableFbSize;
82672b676d7Smrg	  for(i = 0; i < pSiS->ColorExpandBufferNumber; i++) {
82772b676d7Smrg	     pSiS->ColorExpandBufferAddr[i] = AvailBufBase +
82872b676d7Smrg				i * pSiS->PerColorExpandBufferSize;
82972b676d7Smrg	     pSiS->ColorExpandBufferScreenOffset[i] = usableFbSize +
83072b676d7Smrg				i * pSiS->PerColorExpandBufferSize;
83172b676d7Smrg	  }
83272b676d7Smrg       }
83372b676d7Smrg
83472b676d7Smrg       Avail.x1 = 0;
83572b676d7Smrg       Avail.y1 = 0;
83672b676d7Smrg       Avail.x2 = pScrn->displayWidth;
83772b676d7Smrg       Avail.y2 = usableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel / 8) - 1;
83872b676d7Smrg
83972b676d7Smrg       if(Avail.y2 < 0) Avail.y2 = 32767;
84072b676d7Smrg
84172b676d7Smrg       if(Avail.y2 < pScrn->currentMode->VDisplay) {
84272b676d7Smrg	  xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
84372b676d7Smrg		"Not enough video RAM for accelerator: %dKB needed, %dKB available\n",
84472b676d7Smrg		((((pScrn->displayWidth * pScrn->bitsPerPixel/8)   /* +8 for make it sure */
84572b676d7Smrg		     * pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8,
84672b676d7Smrg		pSiS->maxxfbmem/1024);
84772b676d7Smrg	  pSiS->NoAccel = TRUE;
84872b676d7Smrg	  pSiS->NoXvideo = TRUE;
84972b676d7Smrg	  XAADestroyInfoRec(pSiS->AccelInfoPtr);
85072b676d7Smrg	  pSiS->AccelInfoPtr = NULL;
85172b676d7Smrg	  return FALSE;
85272b676d7Smrg       }
85372b676d7Smrg
85472b676d7Smrg       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
85572b676d7Smrg		"Framebuffer from (%d,%d) to (%d,%d)\n",
85672b676d7Smrg		Avail.x1, Avail.y1, Avail.x2 - 1, Avail.y2 - 1);
85772b676d7Smrg
85872b676d7Smrg       xf86InitFBManager(pScreen, &Avail);
85972b676d7Smrg
86072b676d7Smrg       if(!pSiS->NoAccel) {
86172b676d7Smrg	  return XAAInit(pScreen, infoPtr);
86272b676d7Smrg       }
86372b676d7Smrg    } /* !exa */
86472b676d7Smrg#endif
86572b676d7Smrg
86672b676d7Smrg#ifdef SIS_USE_EXA
86772b676d7Smrg    if(pSiS->useEXA) {
86872b676d7Smrg
86972b676d7Smrg       if(!pSiS->NoAccel) {
87072b676d7Smrg
87172b676d7Smrg          if(!exaDriverInit(pScreen, pSiS->EXADriverPtr)) {
87272b676d7Smrg	     pSiS->NoAccel = TRUE;
87372b676d7Smrg	     pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */
87472b676d7Smrg	     return FALSE;
87572b676d7Smrg          }
87672b676d7Smrg
87772b676d7Smrg          /* Reserve locked offscreen scratch area of 64K for glyph data */
87872b676d7Smrg	  pSiS->exa_scratch = exaOffscreenAlloc(pScreen, 64 * 1024, 16, TRUE,
87972b676d7Smrg						SiSScratchSave, pSiS);
88072b676d7Smrg	  if(pSiS->exa_scratch) {
88172b676d7Smrg	     pSiS->exa_scratch_next = pSiS->exa_scratch->offset;
88272b676d7Smrg	     pSiS->EXADriverPtr->UploadToScratch = SiSUploadToScratch;
88372b676d7Smrg	  }
88472b676d7Smrg
88572b676d7Smrg       } else {
88672b676d7Smrg
88772b676d7Smrg          pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */
88872b676d7Smrg
88972b676d7Smrg       }
89072b676d7Smrg
89172b676d7Smrg    }
89272b676d7Smrg#endif /* EXA */
89372b676d7Smrg
89472b676d7Smrg    return TRUE;
89572b676d7Smrg}
89672b676d7Smrg
89772b676d7Smrg
89872b676d7Smrg
89972b676d7Smrg
90072b676d7Smrg
90172b676d7Smrg
90272b676d7Smrg
903