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