2427 lines
62 KiB
C
2427 lines
62 KiB
C
/* $XFree86$ */
|
|
/* $XdotOrg: driver/xf86-video-sis/src/sis310_accel.c,v 1.31 2006-03-09 06:06:25 anholt Exp $ */
|
|
/*
|
|
* 2D Acceleration for SiS 315, 330 and 340 series
|
|
*
|
|
* Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1) Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2) Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3) The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*
|
|
* Author: Thomas Winischhofer <thomas@winischhofer.net>
|
|
*
|
|
* 2003/08/18: Rewritten for using VRAM command queue
|
|
*
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "sis.h"
|
|
#define SIS_NEED_MYMMIO
|
|
#define SIS_NEED_ACCELBUF
|
|
#include "sis_regs.h"
|
|
#include "sis310_accel.h"
|
|
|
|
#if 0
|
|
#define ACCELDEBUG
|
|
#endif
|
|
|
|
#define FBOFFSET (pSiS->dhmOffset)
|
|
|
|
#define DEV_HEIGHT 0xfff /* "Device height of destination bitmap" */
|
|
|
|
#undef SIS_NEED_ARRAY
|
|
|
|
/* For XAA */
|
|
|
|
#ifdef SIS_USE_XAA
|
|
|
|
#undef TRAP /* Use/Don't use Trapezoid Fills
|
|
* DOES NOT WORK. XAA sometimes provides illegal
|
|
* trapezoid data (left and right edges cross each
|
|
* other) which causes drawing errors. Since
|
|
* checking the trapezoid for such a case is very
|
|
* time-intensive, it is faster to let it be done
|
|
* by the generic polygon functions.
|
|
* Does not work on 330 series at all, hangs the engine.
|
|
* Even with correct trapezoids, this is slower than
|
|
* doing it by the CPU.
|
|
*/
|
|
|
|
#undef CTSCE /* Use/Don't use CPUToScreenColorExpand. Disabled
|
|
* because it is slower than doing it by the CPU.
|
|
* Indirect mode does not work in VRAM queue mode.
|
|
* Does not work on 330 series (even in MMIO mode).
|
|
*/
|
|
#undef CTSCE_DIRECT /* Use direct method - This works (on both 315 and 330 at
|
|
* least in VRAM queue mode) but we don't use this either,
|
|
* because it's slower than doing it by the CPU. (Using it
|
|
* would require defining CTSCE)
|
|
*/
|
|
|
|
#undef STSCE /* Use/Don't use ScreenToScreenColorExpand - does not work,
|
|
* see comments below.
|
|
*/
|
|
|
|
#define INCL_RENDER /* Use/Don't use RENDER extension acceleration */
|
|
|
|
#ifdef INCL_RENDER
|
|
# ifdef RENDER
|
|
# include "mipict.h"
|
|
# include "dixstruct.h"
|
|
# define SIS_NEED_ARRAY
|
|
# undef SISNEWRENDER
|
|
# ifdef XORG_VERSION_CURRENT
|
|
# if XORG_VERSION_CURRENT > XORG_VERSION_NUMERIC(6,7,0,0,0)
|
|
# define SISNEWRENDER
|
|
# endif
|
|
# endif
|
|
# endif
|
|
#endif
|
|
|
|
#endif /* XAA */
|
|
|
|
/* For EXA */
|
|
|
|
#ifdef SIS_USE_EXA
|
|
#if 0
|
|
#define SIS_HAVE_COMPOSITE /* Have our own EXA composite */
|
|
#endif
|
|
#ifdef SIS_HAVE_COMPOSITE
|
|
#ifndef SIS_NEED_ARRAY
|
|
#define SIS_NEED_ARRAY
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef SIS_USE_XAA /* XAA */
|
|
#ifdef INCL_RENDER
|
|
#ifdef RENDER
|
|
static CARD32 SiSAlphaTextureFormats[2] = { PICT_a8 , 0 };
|
|
static CARD32 SiSTextureFormats[2] = { PICT_a8r8g8b8, 0 };
|
|
#ifdef SISNEWRENDER
|
|
static CARD32 SiSDstTextureFormats16[2] = { PICT_r5g6b5 , 0 };
|
|
static CARD32 SiSDstTextureFormats32[3] = { PICT_x8r8g8b8, PICT_a8r8g8b8, 0 };
|
|
#endif
|
|
#endif /* RENDER */
|
|
#endif /* INCL_RENDER */
|
|
#endif /* XAA */
|
|
|
|
#ifdef SIS_USE_EXA /* EXA */
|
|
void SiSScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area);
|
|
Bool SiSUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch);
|
|
Bool SiSUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst);
|
|
Bool SiSDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch);
|
|
#endif /* EXA */
|
|
|
|
#ifdef INCL_YUV_BLIT_ADAPTOR
|
|
void SISWriteBlitPacket(SISPtr pSiS, CARD32 *packet);
|
|
#endif
|
|
|
|
extern unsigned char SiSGetCopyROP(int rop);
|
|
extern unsigned char SiSGetPatternROP(int rop);
|
|
|
|
CARD32 dummybuf;
|
|
|
|
#ifdef SIS_NEED_ARRAY
|
|
#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
|
|
#define SiSRenderOpsMAX 0x2b
|
|
#else
|
|
#define SiSRenderOpsMAX 0x0f
|
|
#endif
|
|
static const CARD8 SiSRenderOps[] = { /* PictOpXXX 1 = supported, 0 = unsupported */
|
|
1, 1, 1, 1,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
1, 1, 1, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
1, 1, 1, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0
|
|
};
|
|
#endif /* NEED ARRAY */
|
|
|
|
#ifdef SIS_NEED_ARRAY
|
|
static void
|
|
SiSCalcRenderAccelArray(ScrnInfoPtr pScrn)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
#ifdef SISDUALHEAD
|
|
SISEntPtr pSiSEnt = pSiS->entityPrivate;;
|
|
#endif
|
|
|
|
if(((pScrn->bitsPerPixel == 16) || (pScrn->bitsPerPixel == 32)) && pSiS->doRender) {
|
|
int i, j;
|
|
#ifdef SISDUALHEAD
|
|
if(pSiSEnt) pSiS->RenderAccelArray = pSiSEnt->RenderAccelArray;
|
|
#endif
|
|
if(!pSiS->RenderAccelArray) {
|
|
if((pSiS->RenderAccelArray = xnfcalloc(65536, 1))) {
|
|
#ifdef SISDUALHEAD
|
|
if(pSiSEnt) pSiSEnt->RenderAccelArray = pSiS->RenderAccelArray;
|
|
#endif
|
|
for(i = 0; i < 256; i++) {
|
|
for(j = 0; j < 256; j++) {
|
|
pSiS->RenderAccelArray[(i << 8) + j] = (i * j) / 255;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#ifdef SIS_USE_EXA
|
|
void
|
|
SiSScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area)
|
|
{
|
|
SISPtr pSiS = SISPTR(xf86Screens[pScreen->myNum]);
|
|
|
|
pSiS->exa_scratch = NULL;
|
|
}
|
|
#endif
|
|
|
|
static void
|
|
SiSSync(ScrnInfoPtr pScrn)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
#ifdef SIS_USE_XAA
|
|
if(!pSiS->useEXA) {
|
|
#ifdef CTSCE
|
|
#ifdef CTSCE_DIRECT
|
|
if(pSiS->DoColorExpand) {
|
|
SiSDoCMD
|
|
pSiS->ColorExpandBusy = TRUE;
|
|
}
|
|
#endif
|
|
#endif
|
|
pSiS->DoColorExpand = FALSE;
|
|
}
|
|
#endif
|
|
|
|
pSiS->alphaBlitBusy = FALSE;
|
|
|
|
SiSIdle
|
|
}
|
|
|
|
static void
|
|
SiSSyncAccel(ScrnInfoPtr pScrn)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
if(!pSiS->NoAccel) SiSSync(pScrn);
|
|
}
|
|
|
|
static void
|
|
SiSInitializeAccelerator(ScrnInfoPtr pScrn)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
#ifdef SIS_USE_XAA
|
|
pSiS->DoColorExpand = FALSE;
|
|
#endif
|
|
pSiS->alphaBlitBusy = FALSE;
|
|
|
|
if(!pSiS->NoAccel) {
|
|
|
|
#ifndef SISVRAMQ
|
|
if(pSiS->ChipFlags & SiSCF_Integrated) {
|
|
CmdQueLen = 0;
|
|
} else {
|
|
CmdQueLen = ((128 * 1024) / 4) - 64;
|
|
}
|
|
#endif
|
|
|
|
#ifdef SISVRAMQ
|
|
if(pSiS->ChipType == XGI_40) {
|
|
SiSSync(pScrn);
|
|
SiSDualPipe(1); /* 1 = disable, 0 = enable */
|
|
SiSSync(pScrn);
|
|
}
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
static void
|
|
SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
|
|
int xdir, int ydir, int rop,
|
|
unsigned int planemask, int trans_color)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
|
|
SiSCheckQueue(16 * 2);
|
|
SiSSetupSRCPitchDSTRect(pSiS->scrnOffset, pSiS->scrnOffset, DEV_HEIGHT)
|
|
#else
|
|
SiSSetupDSTColorDepth(pSiS->DstColor);
|
|
SiSSetupSRCPitch(pSiS->scrnOffset)
|
|
SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
|
|
#endif
|
|
|
|
if(trans_color != -1) {
|
|
SiSSetupROP(0x0A)
|
|
SiSSetupSRCTrans(trans_color)
|
|
SiSSetupCMDFlag(TRANSPARENT_BITBLT)
|
|
} else {
|
|
SiSSetupROP(SiSGetCopyROP(rop))
|
|
/* Set command - not needed, both 0 */
|
|
/* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
|
|
}
|
|
|
|
#ifndef SISVRAMQ
|
|
SiSSetupCMDFlag(pSiS->SiS310_AccelDepth)
|
|
#endif
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSyncWP
|
|
#endif
|
|
|
|
/* The chip is smart enough to know the direction */
|
|
}
|
|
|
|
static void
|
|
SiSSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
|
|
int src_x, int src_y, int dst_x, int dst_y,
|
|
int width, int height)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD32 srcbase, dstbase;
|
|
int mymin, mymax;
|
|
|
|
srcbase = dstbase = 0;
|
|
mymin = min(src_y, dst_y);
|
|
mymax = max(src_y, dst_y);
|
|
|
|
/* Libxaa.a has a bug: The tilecache cannot operate
|
|
* correctly if there are 512x512 slots, but no 256x256
|
|
* slots. This leads to catastrophic data fed to us.
|
|
* Filter this out here and warn the user.
|
|
* Fixed in 4.3.99.10 (?) and Debian's 4.3.0.1
|
|
*/
|
|
#if (XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,10,0)) && (XF86_VERSION_CURRENT != XF86_VERSION_NUMERIC(4,3,0,1,0))
|
|
if((src_x < 0) ||
|
|
(dst_x < 0) ||
|
|
(src_y < 0) ||
|
|
(dst_y < 0) ||
|
|
(width <= 0) ||
|
|
(height <= 0)) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"BitBlit fatal error: Illegal coordinates:\n");
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"Source x %d y %d, dest x %d y %d, width %d height %d\n",
|
|
src_x, src_y, dst_x, dst_y, width, height);
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"This is very probably caused by a known bug in libxaa.a.\n");
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"Please update libxaa.a to avoid this error.\n");
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
/* Although the chip knows the direction to use
|
|
* if the source and destination areas overlap,
|
|
* that logic fails if we fiddle with the bitmap
|
|
* addresses. Therefore, we check if the source
|
|
* and destination blitting areas overlap and
|
|
* adapt the bitmap addresses synchronously
|
|
* if the coordinates exceed the valid range.
|
|
* The the areas do not overlap, we do our
|
|
* normal check.
|
|
*/
|
|
if((mymax - mymin) < height) {
|
|
if((src_y >= 2048) || (dst_y >= 2048)) {
|
|
srcbase = pSiS->scrnOffset * mymin;
|
|
dstbase = pSiS->scrnOffset * mymin;
|
|
src_y -= mymin;
|
|
dst_y -= mymin;
|
|
}
|
|
} else {
|
|
if(src_y >= 2048) {
|
|
srcbase = pSiS->scrnOffset * src_y;
|
|
src_y = 0;
|
|
}
|
|
if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) {
|
|
dstbase = pSiS->scrnOffset * dst_y;
|
|
dst_y = 0;
|
|
}
|
|
}
|
|
|
|
srcbase += FBOFFSET;
|
|
dstbase += FBOFFSET;
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSCheckQueue(16 * 3);
|
|
SiSSetupSRCDSTBase(srcbase, dstbase)
|
|
SiSSetupSRCDSTXY(src_x, src_y, dst_x, dst_y)
|
|
SiSSetRectDoCMD(width,height)
|
|
#else
|
|
SiSSetupSRCBase(srcbase);
|
|
SiSSetupDSTBase(dstbase);
|
|
SiSSetupRect(width, height)
|
|
SiSSetupSRCXY(src_x, src_y)
|
|
SiSSetupDSTXY(dst_x, dst_y)
|
|
SiSDoCMD
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
SiSSetupForSolidFill(ScrnInfoPtr pScrn, int color,
|
|
int rop, unsigned int planemask)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
if(pSiS->disablecolorkeycurrent) {
|
|
if((CARD32)color == pSiS->colorKey) {
|
|
rop = 5; /* NOOP */
|
|
}
|
|
}
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
|
|
SiSCheckQueue(16 * 1);
|
|
SiSSetupPATFGDSTRect(color, pSiS->scrnOffset, DEV_HEIGHT)
|
|
SiSSetupROP(SiSGetPatternROP(rop))
|
|
SiSSetupCMDFlag(PATFG)
|
|
SiSSyncWP
|
|
#else
|
|
SiSSetupPATFG(color)
|
|
SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
|
|
SiSSetupDSTColorDepth(pSiS->DstColor);
|
|
SiSSetupROP(SiSGetPatternROP(rop))
|
|
SiSSetupCMDFlag(PATFG | pSiS->SiS310_AccelDepth)
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
SiSSubsequentSolidFillRect(ScrnInfoPtr pScrn,
|
|
int x, int y, int w, int h)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD32 dstbase = 0;
|
|
|
|
if(y >= 2048) {
|
|
dstbase = pSiS->scrnOffset * y;
|
|
y = 0;
|
|
}
|
|
|
|
dstbase += FBOFFSET;
|
|
|
|
pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
|
|
T_L_X_INC | T_L_Y_INC |
|
|
T_R_X_INC | T_R_Y_INC |
|
|
TRAPAZOID_FILL);
|
|
|
|
/* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSCheckQueue(16 * 2)
|
|
SiSSetupDSTXYRect(x, y, w, h)
|
|
SiSSetupDSTBaseDoCMD(dstbase)
|
|
#else
|
|
SiSSetupDSTBase(dstbase)
|
|
SiSSetupDSTXY(x, y)
|
|
SiSSetupRect(w, h)
|
|
SiSDoCMD
|
|
#endif
|
|
}
|
|
|
|
#ifdef SIS_USE_XAA /* ---------------------------- XAA -------------------------- */
|
|
|
|
/* Trapezoid */
|
|
/* This would work better if XAA would provide us with valid trapezoids.
|
|
* In fact, with small trapezoids the left and the right edge often cross
|
|
* each other which causes drawing errors (filling over whole scanline).
|
|
* DOES NOT WORK ON 330 SERIES, HANGS THE ENGINE.
|
|
*/
|
|
#ifdef TRAP
|
|
static void
|
|
SiSSubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
|
|
int left, int dxL, int dyL, int eL,
|
|
int right, int dxR, int dyR, int eR )
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD32 dstbase = 0;
|
|
|
|
if(y >= 2048) {
|
|
dstbase = pSiS->scrnOffset * y;
|
|
y = 0;
|
|
}
|
|
|
|
dstbase += FBOFFSET;
|
|
|
|
#ifdef SISVRAMQ /* Not optimized yet */
|
|
SiSCheckQueue(16 * 10)
|
|
#else
|
|
SiSSetupDSTBase(dstbase)
|
|
#endif
|
|
|
|
#if 1
|
|
SiSSetupPATFG(0xff0000) /* FOR TESTING */
|
|
#endif
|
|
|
|
/* Clear CommandReg because SetUp can be used for Rect and Trap */
|
|
pSiS->CommandReg &= ~(T_L_X_INC | T_L_Y_INC |
|
|
T_R_X_INC | T_R_Y_INC |
|
|
T_XISMAJORL | T_XISMAJORR |
|
|
BITBLT);
|
|
|
|
xf86DrvMsg(0, X_INFO, "Trap (%d %d %d %d) dxL %d dyL %d eL %d dxR %d dyR %d eR %d\n",
|
|
left, right, y, h, dxL, dyL, eL, dxR, dyR, eR);
|
|
|
|
/* Determine egde angles */
|
|
if(dxL < 0) { dxL = -dxL; }
|
|
else { SiSSetupCMDFlag(T_L_X_INC) }
|
|
if(dxR < 0) { dxR = -dxR; }
|
|
else { SiSSetupCMDFlag(T_R_X_INC) }
|
|
|
|
/* (Y direction always positive - do this anyway) */
|
|
if(dyL < 0) { dyL = -dyL; }
|
|
else { SiSSetupCMDFlag(T_L_Y_INC) }
|
|
if(dyR < 0) { dyR = -dyR; }
|
|
else { SiSSetupCMDFlag(T_R_Y_INC) }
|
|
|
|
/* Determine major axis */
|
|
if(dxL >= dyL) { SiSSetupCMDFlag(T_XISMAJORL) }
|
|
if(dxR >= dyR) { SiSSetupCMDFlag(T_XISMAJORR) }
|
|
|
|
SiSSetupCMDFlag(TRAPAZOID_FILL);
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupYHLR(y, h, left, right)
|
|
SiSSetupdLdR(dxL, dyL, dxR, dyR)
|
|
SiSSetupELER(eL, eR)
|
|
SiSSetupDSTBaseDoCMD(dstbase)
|
|
#else
|
|
/* Set up deltas */
|
|
SiSSetupdL(dxL, dyL)
|
|
SiSSetupdR(dxR, dyR)
|
|
/* Set up y, h, left, right */
|
|
SiSSetupYH(y, h)
|
|
SiSSetupLR(left, right)
|
|
/* Set up initial error term */
|
|
SiSSetupEL(eL)
|
|
SiSSetupER(eR)
|
|
SiSDoCMD
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
static void
|
|
SiSSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop,
|
|
unsigned int planemask)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
|
|
SiSCheckQueue(16 * 3);
|
|
SiSSetupLineCountPeriod(1, 1)
|
|
SiSSetupPATFGDSTRect(color, pSiS->scrnOffset, DEV_HEIGHT)
|
|
SiSSetupROP(SiSGetPatternROP(rop))
|
|
SiSSetupCMDFlag(PATFG | LINE)
|
|
SiSSyncWP
|
|
#else
|
|
SiSSetupLineCount(1)
|
|
SiSSetupPATFG(color)
|
|
SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
|
|
SiSSetupDSTColorDepth(pSiS->DstColor)
|
|
SiSSetupROP(SiSGetPatternROP(rop))
|
|
SiSSetupCMDFlag(PATFG | LINE | pSiS->SiS310_AccelDepth)
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
SiSSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
|
|
int x1, int y1, int x2, int y2, int flags)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
int miny, maxy;
|
|
CARD32 dstbase = 0;
|
|
|
|
miny = (y1 > y2) ? y2 : y1;
|
|
maxy = (y1 > y2) ? y1 : y2;
|
|
if(maxy >= 2048) {
|
|
dstbase = pSiS->scrnOffset*miny;
|
|
y1 -= miny;
|
|
y2 -= miny;
|
|
}
|
|
|
|
dstbase += FBOFFSET;
|
|
|
|
if(flags & OMIT_LAST) {
|
|
SiSSetupCMDFlag(NO_LAST_PIXEL)
|
|
} else {
|
|
pSiS->CommandReg &= ~(NO_LAST_PIXEL);
|
|
}
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSCheckQueue(16 * 2);
|
|
SiSSetupX0Y0X1Y1(x1, y1, x2, y2)
|
|
SiSSetupDSTBaseDoCMD(dstbase)
|
|
#else
|
|
SiSSetupDSTBase(dstbase)
|
|
SiSSetupX0Y0(x1, y1)
|
|
SiSSetupX1Y1(x2, y2)
|
|
SiSDoCMD
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
SiSSubsequentSolidHorzVertLine(ScrnInfoPtr pScrn,
|
|
int x, int y, int len, int dir)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD32 dstbase = 0;
|
|
|
|
len--; /* starting point is included! */
|
|
|
|
if((y >= 2048) || ((y + len) >= 2048)) {
|
|
dstbase = pSiS->scrnOffset * y;
|
|
y = 0;
|
|
}
|
|
|
|
dstbase += FBOFFSET;
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSCheckQueue(16 * 2);
|
|
if(dir == DEGREES_0) {
|
|
SiSSetupX0Y0X1Y1(x, y, (x + len), y)
|
|
} else {
|
|
SiSSetupX0Y0X1Y1(x, y, x, (y + len))
|
|
}
|
|
SiSSetupDSTBaseDoCMD(dstbase)
|
|
#else
|
|
SiSSetupDSTBase(dstbase)
|
|
SiSSetupX0Y0(x,y)
|
|
if(dir == DEGREES_0) {
|
|
SiSSetupX1Y1(x + len, y);
|
|
} else {
|
|
SiSSetupX1Y1(x, y + len);
|
|
}
|
|
SiSDoCMD
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
SiSSetupForDashedLine(ScrnInfoPtr pScrn,
|
|
int fg, int bg, int rop, unsigned int planemask,
|
|
int length, unsigned char *pattern)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
|
|
SiSCheckQueue(16 * 3);
|
|
SiSSetupLineCountPeriod(1, (length - 1))
|
|
SiSSetupStyle(*pattern,*(pattern + 4))
|
|
SiSSetupPATFGDSTRect(fg, pSiS->scrnOffset, DEV_HEIGHT)
|
|
#else
|
|
SiSSetupLineCount(1)
|
|
SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
|
|
SiSSetupDSTColorDepth(pSiS->DstColor);
|
|
SiSSetupStyleLow(*pattern)
|
|
SiSSetupStyleHigh(*(pattern + 4))
|
|
SiSSetupStylePeriod(length - 1);
|
|
SiSSetupPATFG(fg)
|
|
#endif
|
|
|
|
SiSSetupROP(SiSGetPatternROP(rop))
|
|
|
|
SiSSetupCMDFlag(LINE | LINE_STYLE)
|
|
|
|
if(bg != -1) {
|
|
SiSSetupPATBG(bg)
|
|
} else {
|
|
SiSSetupCMDFlag(TRANSPARENT)
|
|
}
|
|
#ifndef SISVRAMQ
|
|
SiSSetupCMDFlag(pSiS->SiS310_AccelDepth)
|
|
#endif
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSyncWP
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
SiSSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn,
|
|
int x1, int y1, int x2, int y2,
|
|
int flags, int phase)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD32 dstbase, miny, maxy;
|
|
|
|
dstbase = 0;
|
|
miny = (y1 > y2) ? y2 : y1;
|
|
maxy = (y1 > y2) ? y1 : y2;
|
|
if(maxy >= 2048) {
|
|
dstbase = pSiS->scrnOffset * miny;
|
|
y1 -= miny;
|
|
y2 -= miny;
|
|
}
|
|
|
|
dstbase += FBOFFSET;
|
|
|
|
if(flags & OMIT_LAST) {
|
|
SiSSetupCMDFlag(NO_LAST_PIXEL)
|
|
} else {
|
|
pSiS->CommandReg &= ~(NO_LAST_PIXEL);
|
|
}
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSCheckQueue(16 * 2);
|
|
SiSSetupX0Y0X1Y1(x1, y1, x2, y2)
|
|
SiSSetupDSTBaseDoCMD(dstbase)
|
|
#else
|
|
SiSSetupDSTBase(dstbase)
|
|
SiSSetupX0Y0(x1, y1)
|
|
SiSSetupX1Y1(x2, y2)
|
|
SiSDoCMD
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
SiSSetupForMonoPatternFill(ScrnInfoPtr pScrn,
|
|
int patx, int paty, int fg, int bg,
|
|
int rop, unsigned int planemask)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
|
|
SiSCheckQueue(16 * 3);
|
|
SiSSetupPATFGDSTRect(fg, pSiS->scrnOffset, DEV_HEIGHT)
|
|
#else
|
|
SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
|
|
SiSSetupDSTColorDepth(pSiS->DstColor);
|
|
#endif
|
|
|
|
SiSSetupMONOPAT(patx,paty)
|
|
|
|
SiSSetupROP(SiSGetPatternROP(rop))
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupCMDFlag(PATMONO)
|
|
#else
|
|
SiSSetupPATFG(fg)
|
|
SiSSetupCMDFlag(PATMONO | pSiS->SiS310_AccelDepth)
|
|
#endif
|
|
|
|
if(bg != -1) {
|
|
SiSSetupPATBG(bg)
|
|
} else {
|
|
SiSSetupCMDFlag(TRANSPARENT)
|
|
}
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSyncWP
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
SiSSubsequentMonoPatternFill(ScrnInfoPtr pScrn,
|
|
int patx, int paty,
|
|
int x, int y, int w, int h)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD32 dstbase = 0;
|
|
|
|
if(y >= 2048) {
|
|
dstbase = pSiS->scrnOffset * y;
|
|
y = 0;
|
|
}
|
|
|
|
dstbase += FBOFFSET;
|
|
|
|
/* Clear commandReg because Setup can be used for Rect and Trap */
|
|
pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
|
|
T_L_X_INC | T_L_Y_INC |
|
|
T_R_X_INC | T_R_Y_INC |
|
|
TRAPAZOID_FILL);
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSCheckQueue(16 * 2);
|
|
SiSSetupDSTXYRect(x,y,w,h)
|
|
SiSSetupDSTBaseDoCMD(dstbase)
|
|
#else
|
|
SiSSetupDSTBase(dstbase)
|
|
SiSSetupDSTXY(x,y)
|
|
SiSSetupRect(w,h)
|
|
SiSDoCMD
|
|
#endif
|
|
}
|
|
|
|
/* --- Trapezoid --- */
|
|
|
|
/* Does not work at all on 330 series */
|
|
|
|
#ifdef TRAP
|
|
static void
|
|
SiSSubsequentMonoPatternFillTrap(ScrnInfoPtr pScrn,
|
|
int patx, int paty,
|
|
int y, int h,
|
|
int left, int dxL, int dyL, int eL,
|
|
int right, int dxR, int dyR, int eR)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD32 dstbase = 0;
|
|
|
|
if(y >= 2048) {
|
|
dstbase=pSiS->scrnOffset*y;
|
|
y = 0;
|
|
}
|
|
|
|
dstbase += FBOFFSET;
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSCheckQueue(16 * 4);
|
|
#else
|
|
SiSSetupDSTBase(dstbase)
|
|
#endif
|
|
|
|
/* Clear CommandReg because SetUp can be used for Rect and Trap */
|
|
pSiS->CommandReg &= ~(T_XISMAJORL | T_XISMAJORR |
|
|
T_L_X_INC | T_L_Y_INC |
|
|
T_R_X_INC | T_R_Y_INC |
|
|
BITBLT);
|
|
|
|
if(dxL < 0) { dxL = -dxL; }
|
|
else { SiSSetupCMDFlag(T_L_X_INC) }
|
|
if(dxR < 0) { dxR = -dxR; }
|
|
else { SiSSetupCMDFlag(T_R_X_INC) }
|
|
|
|
if(dyL < 0) { dyL = -dyL; }
|
|
else { SiSSetupCMDFlag(T_L_Y_INC) }
|
|
if(dyR < 0) { dyR = -dyR; }
|
|
else { SiSSetupCMDFlag(T_R_Y_INC) }
|
|
|
|
/* Determine major axis */
|
|
if(dxL >= dyL) { SiSSetupCMDFlag(T_XISMAJORL) }
|
|
if(dxR >= dyR) { SiSSetupCMDFlag(T_XISMAJORR) }
|
|
|
|
SiSSetupCMDFlag(TRAPAZOID_FILL);
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupYHLR(y, h, left, right)
|
|
SiSSetupdLdR(dxL, dyL, dxR, dyR)
|
|
SiSSetupELER(eL, eR)
|
|
SiSSetupDSTBaseDoCMD(dstbase)
|
|
#else
|
|
SiSSetupYH(y, h)
|
|
SiSSetupLR(left, right)
|
|
SiSSetupdL(dxL, dyL)
|
|
SiSSetupdR(dxR, dyR)
|
|
SiSSetupEL(eL)
|
|
SiSSetupER(eR)
|
|
SiSDoCMD
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
/* Color 8x8 pattern */
|
|
|
|
#ifdef SISVRAMQ
|
|
static void
|
|
SiSSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny,
|
|
int rop, unsigned int planemask, int trans_col)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
int j = pScrn->bitsPerPixel >> 3;
|
|
CARD32 *patadr = (CARD32 *)(pSiS->FbBase + (patterny * pSiS->scrnOffset) +
|
|
(patternx * j));
|
|
|
|
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
|
|
SiSCheckQueue(16 * 3);
|
|
|
|
SiSSetupDSTRectBurstHeader(pSiS->scrnOffset, DEV_HEIGHT, PATTERN_REG, (pScrn->bitsPerPixel << 1))
|
|
|
|
while(j--) {
|
|
SiSSetupPatternRegBurst(patadr[0], patadr[1], patadr[2], patadr[3]);
|
|
SiSSetupPatternRegBurst(patadr[4], patadr[5], patadr[6], patadr[7]);
|
|
SiSSetupPatternRegBurst(patadr[8], patadr[9], patadr[10], patadr[11]);
|
|
SiSSetupPatternRegBurst(patadr[12], patadr[13], patadr[14], patadr[15]);
|
|
patadr += 16; /* = 64 due to (CARD32 *) */
|
|
}
|
|
|
|
SiSSetupROP(SiSGetPatternROP(rop))
|
|
|
|
SiSSetupCMDFlag(PATPATREG)
|
|
|
|
SiSSyncWP
|
|
}
|
|
|
|
static void
|
|
SiSSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patternx,
|
|
int patterny, int x, int y, int w, int h)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD32 dstbase = 0;
|
|
|
|
if(y >= 2048) {
|
|
dstbase = pSiS->scrnOffset * y;
|
|
y = 0;
|
|
}
|
|
|
|
dstbase += FBOFFSET;
|
|
|
|
/* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */
|
|
|
|
SiSCheckQueue(16 * 2)
|
|
SiSSetupDSTXYRect(x, y, w, h)
|
|
SiSSetupDSTBaseDoCMD(dstbase)
|
|
}
|
|
#endif
|
|
|
|
/* ---- CPUToScreen Color Expand --- */
|
|
|
|
#ifdef CTSCE
|
|
|
|
#ifdef CTSCE_DIRECT
|
|
|
|
/* Direct method */
|
|
|
|
/* This is somewhat a fake. We let XAA copy its data not to an
|
|
* aperture, but to video RAM, and then do a ScreenToScreen
|
|
* color expansion.
|
|
* Since the data is sent AFTER the call to Subsequent, we
|
|
* don't execute the command here, but set a flag and do
|
|
* that in the (subsequent) call to Sync()
|
|
*/
|
|
|
|
static void
|
|
SiSSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
|
|
int fg, int bg, int rop, unsigned int planemask)
|
|
{
|
|
SISPtr pSiS=SISPTR(pScrn);
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
|
|
SiSSetupROP(SiSGetCopyROP(rop));
|
|
SiSSetupSRCFGDSTRect(fg, pSiS->scrnOffset, DEV_HEIGHT)
|
|
if(bg == -1) {
|
|
SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO);
|
|
} else {
|
|
SiSSetupSRCBG(bg);
|
|
SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO);
|
|
}
|
|
SiSSyncWP
|
|
#else
|
|
SiSSetupSRCXY(0,0);
|
|
SiSSetupROP(SiSGetCopyROP(rop));
|
|
SiSSetupSRCFG(fg);
|
|
SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT);
|
|
SiSSetupDSTColorDepth(pSiS->DstColor);
|
|
if(bg == -1) {
|
|
SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO
|
|
| pSiS->SiS310_AccelDepth);
|
|
} else {
|
|
SiSSetupSRCBG(bg);
|
|
SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO | pSiS->SiS310_AccelDepth);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
SiSSubsequentCPUToScreenColorExpandFill(
|
|
ScrnInfoPtr pScrn, int x, int y, int w,
|
|
int h, int skipleft)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
int _x0, _y0, _x1, _y1;
|
|
CARD32 srcbase, dstbase;
|
|
|
|
srcbase = pSiS->ColorExpandBase;
|
|
|
|
dstbase = 0;
|
|
if(y >= 2048) {
|
|
dstbase = pSiS->scrnOffset*y;
|
|
y = 0;
|
|
}
|
|
|
|
srcbase += FBOFFSET;
|
|
dstbase += FBOFFSET;
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupSRCDSTBase(srcbase,dstbase);
|
|
#else
|
|
SiSSetupSRCBase(srcbase);
|
|
SiSSetupDSTBase(dstbase)
|
|
#endif
|
|
|
|
if(skipleft > 0) {
|
|
_x0 = x + skipleft;
|
|
_y0 = y;
|
|
_x1 = x + w;
|
|
_y1 = y + h;
|
|
#ifdef SISVRAMQ
|
|
SiSSetupClip(_x0, _y0, _x1, _y1);
|
|
#else
|
|
SiSSetupClipLT(_x0, _y0);
|
|
SiSSetupClipRB(_x1, _y1);
|
|
#endif
|
|
SiSSetupCMDFlag(CLIPENABLE);
|
|
} else {
|
|
pSiS->CommandReg &= (~CLIPENABLE);
|
|
}
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupRectSRCPitch(w, h, ((((w + 7) >> 3) + 3) >> 2) << 2);
|
|
SiSSetupSRCDSTXY(0, 0, x, y);
|
|
#else
|
|
SiSSetupRect(w, h);
|
|
SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4);
|
|
SiSSetupDSTXY(x, y);
|
|
#endif
|
|
|
|
if(pSiS->ColorExpandBusy) {
|
|
pSiS->ColorExpandBusy = FALSE;
|
|
SiSIdle
|
|
}
|
|
|
|
pSiS->DoColorExpand = TRUE;
|
|
}
|
|
|
|
#else
|
|
|
|
/* Indirect method */
|
|
|
|
/* This is SLOW, slower than the CPU on most chipsets */
|
|
/* Does not work in VRAM queue mode. */
|
|
|
|
static void
|
|
SiSSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
|
|
int fg, int bg, int rop, unsigned int planemask)
|
|
{
|
|
SISPtr pSiS=SISPTR(pScrn);
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
|
|
#endif
|
|
|
|
/* !!! DOES NOT WORK IN VRAM QUEUE MODE !!! */
|
|
|
|
/* (hence this is not optimized for VRAM mode) */
|
|
#ifndef SISVRAMQ
|
|
SiSIdle
|
|
#endif
|
|
SiSSetupSRCXY(0,0);
|
|
|
|
SiSSetupROP(SiSGetCopyROP(rop));
|
|
SiSSetupSRCFG(fg);
|
|
SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT);
|
|
#ifndef SISVRAMQ
|
|
SiSSetupDSTColorDepth(pSiS->DstColor);
|
|
#endif
|
|
if(bg == -1) {
|
|
#ifdef SISVRAMQ
|
|
SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO);
|
|
#else
|
|
SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCCPUBLITBUF
|
|
| pSiS->SiS310_AccelDepth);
|
|
#endif
|
|
} else {
|
|
SiSSetupSRCBG(bg);
|
|
#ifdef SISVRAMQ
|
|
SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF);
|
|
#else
|
|
SiSSetupCMDFlag(ENCOLOREXP | SRCCPUBLITBUF | pSiS->SiS310_AccelDepth);
|
|
#endif
|
|
};
|
|
|
|
}
|
|
|
|
static void
|
|
SiSSubsequentScanlineCPUToScreenColorExpandFill(
|
|
ScrnInfoPtr pScrn, int x, int y, int w,
|
|
int h, int skipleft)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
int _x0, _y0, _x1, _y1;
|
|
CARD32 dstbase = 0;
|
|
|
|
if(y >= 2048) {
|
|
dstbase = pSiS->scrnOffset*y;
|
|
y = 0;
|
|
}
|
|
|
|
dstbase += FBOFFSET;
|
|
|
|
#ifndef SISVRAMQ
|
|
if((SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {
|
|
SiSIdle;
|
|
}
|
|
#endif
|
|
|
|
SiSSetupDSTBase(dstbase)
|
|
|
|
if(skipleft > 0) {
|
|
_x0 = x+skipleft;
|
|
_y0 = y;
|
|
_x1 = x+w;
|
|
_y1 = y+h;
|
|
#ifdef SISVRAMQ
|
|
SiSSetupClip(_x0, _y0, _x1, _y1);
|
|
#else
|
|
SiSSetupClipLT(_x0, _y0);
|
|
SiSSetupClipRB(_x1, _y1);
|
|
#endif
|
|
SiSSetupCMDFlag(CLIPENABLE);
|
|
} else {
|
|
pSiS->CommandReg &= (~CLIPENABLE);
|
|
}
|
|
SiSSetupRect(w, 1);
|
|
SiSSetupSRCPitch(((((w+7)/8)+3) >> 2) * 4);
|
|
pSiS->ycurrent = y;
|
|
pSiS->xcurrent = x;
|
|
|
|
}
|
|
|
|
static void
|
|
SiSSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD32 cbo;
|
|
|
|
cbo = pSiS->ColorExpandBufferScreenOffset[bufno];
|
|
cbo += FBOFFSET;
|
|
|
|
#ifndef SISVRAMQ
|
|
if((SIS_MMIO_IN16(pSiS->IOBase, Q_STATUS+2) & 0x8000) != 0x8000) {
|
|
SiSIdle;
|
|
}
|
|
#endif
|
|
|
|
SiSSetupSRCBase(cbo);
|
|
|
|
SiSSetupDSTXY(pSiS->xcurrent, pSiS->ycurrent);
|
|
|
|
SiSDoCMD
|
|
|
|
pSiS->ycurrent++;
|
|
#ifndef SISVRAMQ
|
|
SiSIdle
|
|
#endif
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
/* --- Screen To Screen Color Expand --- */
|
|
|
|
/* This method blits in a single task; this does not work because
|
|
* the hardware does not use the source pitch as scanline offset
|
|
* but to calculate pattern address from source X and Y and to
|
|
* limit the drawing width (similar to width set by SetupRect).
|
|
* XAA provides the pattern bitmap with scrnOffset (displayWidth * bpp/8)
|
|
* offset, but this is not supported by the hardware.
|
|
* DOES NOT WORK ON 330 SERIES, HANGS ENGINE.
|
|
*/
|
|
|
|
#ifdef STSCE
|
|
static void
|
|
SiSSetupForScreenToScreenColorExpand(ScrnInfoPtr pScrn,
|
|
int fg, int bg,
|
|
int rop, unsigned int planemask)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
|
|
#else
|
|
SiSSetupDSTColorDepth(pSiS->DstColor)
|
|
#endif
|
|
SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
|
|
SiSSetupROP(SiSGetCopyROP(rop))
|
|
SiSSetupSRCFG(fg)
|
|
/* SiSSetupSRCXY(0,0) */
|
|
|
|
if(bg == -1) {
|
|
SiSSetupCMDFlag(TRANSPARENT | ENCOLOREXP | SRCVIDEO);
|
|
} else {
|
|
SiSSetupSRCBG(bg);
|
|
SiSSetupCMDFlag(ENCOLOREXP | SRCVIDEO);
|
|
};
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSyncWP
|
|
#endif
|
|
}
|
|
|
|
/* For testing, these are the methods: (use only one at a time!) */
|
|
|
|
#undef npitch /* Normal: Use srcx/y as srcx/y, use scrnOffset as source pitch
|
|
* Does not work on 315 series, because the hardware does not
|
|
* regard the src x and y. Apart from this problem:
|
|
* This would work if the hareware used the source pitch for
|
|
* incrementing the source address after each scanline - but
|
|
* it doesn't do this! The first line of the area is correctly
|
|
* color expanded, but since the source pitch is ignored and
|
|
* the source address not incremented correctly, the following
|
|
* lines are color expanded with any bit pattern that is left
|
|
* in the unused space of the source bitmap (which is organized
|
|
* with the depth of the screen framebuffer hence with a pitch
|
|
* of scrnOffset).
|
|
*/
|
|
|
|
#undef pitchdw /* Use source pitch "displayWidth / 8" instead
|
|
* of scrnOffset (=displayWidth * bpp / 8)
|
|
* This can't work, because the pitch of the source
|
|
* bitmap is scrnoffset!
|
|
*/
|
|
|
|
#define nopitch /* Calculate srcbase with srcx and srcy, set the
|
|
* pitch to scrnOffset (which IS the correct pitch
|
|
* for the source bitmap) and set srcx and srcy both
|
|
* to 0.
|
|
* This would work if the hareware used the source pitch for
|
|
* incrementing the source address after each scanline - but
|
|
* it doesn't do this! Again: The first line of the area is
|
|
* correctly color expanded, but since the source pitch is
|
|
* ignored for scanline address incremention, the following
|
|
* lines are not correctly color expanded.
|
|
* This is the only way it works (apart from the problem
|
|
* described above). The hardware does not regard the src
|
|
* x and y values in any way.
|
|
*/
|
|
|
|
static void
|
|
SiSSubsequentScreenToScreenColorExpand(ScrnInfoPtr pScrn,
|
|
int x, int y, int w, int h,
|
|
int srcx, int srcy, int skipleft)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD32 srcbase, dstbase;
|
|
#if 0
|
|
int _x0, _y0, _x1, _y1;
|
|
#endif
|
|
#ifdef pitchdw
|
|
int newsrcx, newsrcy;
|
|
|
|
/* srcx and srcy are provided based on a scrnOffset pitch ( = displayWidth * bpp / 8 )
|
|
* We recalulate srcx and srcy based on pitch = displayWidth / 8
|
|
*/
|
|
newsrcy = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) /
|
|
(pScrn->displayWidth/8);
|
|
newsrcx = ((pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8))) %
|
|
(pScrn->displayWidth/8);
|
|
#endif
|
|
xf86DrvMsg(0, X_INFO, "Sub ScreenToScreen ColorExp(%d,%d, %d,%d, %d,%d, %d)\n",
|
|
x, y, w, h, srcx, srcy, skipleft);
|
|
|
|
srcbase = dstbase = 0;
|
|
|
|
#ifdef pitchdw
|
|
if(newsrcy >= 2048) {
|
|
srcbase = (pScrn->displayWidth / 8) * newsrcy;
|
|
newsrcy = 0;
|
|
}
|
|
#endif
|
|
#ifdef nopitch
|
|
srcbase = (pSiS->scrnOffset * srcy) + (srcx * ((pScrn->bitsPerPixel+7)/8));
|
|
#endif
|
|
#ifdef npitch
|
|
if(srcy >= 2048) {
|
|
srcbase = pSiS->scrnOffset * srcy;
|
|
srcy = 0;
|
|
}
|
|
#endif
|
|
if(y >= 2048) {
|
|
dstbase = pSiS->scrnOffset * y;
|
|
y = 0;
|
|
}
|
|
|
|
srcbase += FBOFFSET;
|
|
dstbase += FBOFFSET;
|
|
|
|
SiSSetupSRCBase(srcbase)
|
|
SiSSetupDSTBase(dstbase)
|
|
|
|
/* 315 series seem to treat the src pitch as
|
|
* a "drawing limit", but still (as 300 series)
|
|
* does not use it for incrementing the
|
|
* address pointer for the next scanline. ARGH!
|
|
*/
|
|
|
|
#ifdef pitchdw
|
|
SiSSetupSRCPitch(pScrn->displayWidth/8)
|
|
#endif
|
|
#ifdef nopitch
|
|
SiSSetupSRCPitch(pScrn->displayWidth/8)
|
|
/* SiSSetupSRCPitch(1024/8) */ /* For test */
|
|
#endif
|
|
#ifdef npitch
|
|
SiSSetupSRCPitch(pScrn->displayWidth/8)
|
|
/* SiSSetupSRCPitch(pSiS->scrnOffset) */
|
|
#endif
|
|
|
|
SiSSetupRect(w,h)
|
|
|
|
#if 0 /* How do I implement the offset? Not this way, that's for sure.. */
|
|
if (skipleft > 0) {
|
|
_x0 = x+skipleft;
|
|
_y0 = y;
|
|
_x1 = x+w;
|
|
_y1 = y+h;
|
|
SiSSetupClipLT(_x0, _y0);
|
|
SiSSetupClipRB(_x1, _y1);
|
|
SiSSetupCMDFlag(CLIPENABLE);
|
|
}
|
|
#endif
|
|
#ifdef pitchdw
|
|
SiSSetupSRCXY(newsrcx, newsrcy)
|
|
#endif
|
|
#ifdef nopitch
|
|
SiSSetupSRCXY(0,0)
|
|
#endif
|
|
#ifdef npitch
|
|
SiSSetupSRCXY(srcx, srcy)
|
|
#endif
|
|
|
|
SiSSetupDSTXY(x,y)
|
|
|
|
SiSDoCMD
|
|
#ifdef SISVRAMQ
|
|
/* We MUST sync here, there must not be 2 or more color expansion commands in the queue */
|
|
SiSIdle
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef SISDUALHEAD
|
|
static void
|
|
SiSRestoreAccelState(ScrnInfoPtr pScrn)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
pSiS->ColorExpandBusy = FALSE;
|
|
pSiS->alphaBlitBusy = FALSE;
|
|
SiSIdle
|
|
}
|
|
#endif
|
|
|
|
/* ---- RENDER ---- */
|
|
|
|
#ifdef INCL_RENDER
|
|
#ifdef RENDER
|
|
static void
|
|
SiSRenderCallback(ScrnInfoPtr pScrn)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
if((currentTime.milliseconds > pSiS->RenderTime) && pSiS->AccelLinearScratch) {
|
|
xf86FreeOffscreenLinear(pSiS->AccelLinearScratch);
|
|
pSiS->AccelLinearScratch = NULL;
|
|
}
|
|
|
|
if(!pSiS->AccelLinearScratch) {
|
|
pSiS->RenderCallback = NULL;
|
|
}
|
|
}
|
|
|
|
#define RENDER_DELAY 15000
|
|
|
|
static Bool
|
|
SiSAllocateLinear(ScrnInfoPtr pScrn, int sizeNeeded)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
pSiS->RenderTime = currentTime.milliseconds + RENDER_DELAY;
|
|
pSiS->RenderCallback = SiSRenderCallback;
|
|
|
|
if(pSiS->AccelLinearScratch) {
|
|
if(pSiS->AccelLinearScratch->size >= sizeNeeded) {
|
|
return TRUE;
|
|
} else {
|
|
if(pSiS->alphaBlitBusy) {
|
|
pSiS->alphaBlitBusy = FALSE;
|
|
SiSIdle
|
|
}
|
|
if(xf86ResizeOffscreenLinear(pSiS->AccelLinearScratch, sizeNeeded)) {
|
|
return TRUE;
|
|
}
|
|
xf86FreeOffscreenLinear(pSiS->AccelLinearScratch);
|
|
pSiS->AccelLinearScratch = NULL;
|
|
}
|
|
}
|
|
|
|
pSiS->AccelLinearScratch = xf86AllocateOffscreenLinear(
|
|
pScrn->pScreen, sizeNeeded, 32,
|
|
NULL, NULL, NULL);
|
|
|
|
return(pSiS->AccelLinearScratch != NULL);
|
|
}
|
|
|
|
static Bool
|
|
SiSSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn,
|
|
int op, CARD16 red, CARD16 green,
|
|
CARD16 blue, CARD16 alpha,
|
|
#ifdef SISNEWRENDER
|
|
CARD32 alphaType, CARD32 dstType,
|
|
#else
|
|
int alphaType,
|
|
#endif
|
|
CARD8 *alphaPtr,
|
|
int alphaPitch, int width,
|
|
int height, int flags)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
unsigned char *renderaccelarray;
|
|
CARD32 *dstPtr;
|
|
int x, pitch, sizeNeeded;
|
|
int sbpp = pSiS->CurrentLayout.bitsPerPixel >> 3;
|
|
int sbppshift = sbpp >> 1; /* 8->0, 16->1, 32->2 */
|
|
CARD8 myalpha;
|
|
Bool docopy = TRUE;
|
|
|
|
#ifdef ACCELDEBUG
|
|
xf86DrvMsg(0, X_INFO, "AT(1): op %d t %x ARGB %x %x %x %x, w %d h %d pch %d\n",
|
|
op, alphaType, /*dstType, */alpha, red, green, blue, width, height, alphaPitch);
|
|
#endif
|
|
|
|
if((width > 2048) || (height > 2048)) return FALSE;
|
|
|
|
#ifdef SISVRAMQ
|
|
if(op > SiSRenderOpsMAX) return FALSE;
|
|
if(!SiSRenderOps[op]) return FALSE;
|
|
#else
|
|
if(op != PictOpOver) return FALSE;
|
|
#endif
|
|
|
|
if(!((renderaccelarray = pSiS->RenderAccelArray)))
|
|
return FALSE;
|
|
|
|
#ifdef ACCELDEBUG
|
|
xf86DrvMsg(0, X_INFO, "AT(2): op %d t %x ARGB %x %x %x %x, w %d h %d pch %d\n",
|
|
op, alphaType, alpha, red, green, blue, width, height, alphaPitch);
|
|
#endif
|
|
|
|
pitch = (width + 31) & ~31;
|
|
sizeNeeded = (pitch << 2) * height; /* Source a8 (=8bit), expand to A8R8G8B8 (=32bit) */
|
|
|
|
if(!SiSAllocateLinear(pScrn, (sizeNeeded + sbpp - 1) >> sbppshift))
|
|
return FALSE;
|
|
|
|
red &= 0xff00;
|
|
green &= 0xff00;
|
|
blue &= 0xff00;
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
|
|
switch(op) {
|
|
case PictOpClear:
|
|
#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
|
|
case PictOpDisjointClear:
|
|
case PictOpConjointClear:
|
|
#endif
|
|
SiSSetupPATFGDSTRect(0, pSiS->scrnOffset, DEV_HEIGHT)
|
|
/* SiSSetupROP(0x00) - is already 0 */
|
|
SiSSetupCMDFlag(PATFG)
|
|
docopy = FALSE;
|
|
break;
|
|
case PictOpSrc:
|
|
#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
|
|
case PictOpDisjointSrc:
|
|
case PictOpConjointSrc:
|
|
#endif
|
|
SiSSetupSRCPitchDSTRect((pitch << 2), pSiS->scrnOffset, DEV_HEIGHT);
|
|
SiSSetupAlpha(0xff)
|
|
SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_NODESTALPHA)
|
|
break;
|
|
case PictOpDst:
|
|
#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
|
|
case PictOpDisjointDst:
|
|
case PictOpConjointDst:
|
|
#endif
|
|
SiSSetupSRCPitchDSTRect((pitch << 2), pSiS->scrnOffset, DEV_HEIGHT);
|
|
SiSSetupAlpha(0x00)
|
|
SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_CONSTANTALPHA)
|
|
docopy = FALSE;
|
|
break;
|
|
case PictOpOver:
|
|
SiSSetupSRCPitchDSTRect((pitch << 2), pSiS->scrnOffset, DEV_HEIGHT);
|
|
SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA)
|
|
break;
|
|
}
|
|
SiSSyncWP
|
|
#else
|
|
SiSSetupDSTColorDepth(pSiS->DstColor);
|
|
SiSSetupSRCPitch((pitch << 2));
|
|
SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
|
|
SiSSetupROP(0)
|
|
SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA | pSiS->SiS310_AccelDepth)
|
|
#endif
|
|
|
|
/* Don't need source for clear and dest */
|
|
if(!docopy) return TRUE;
|
|
|
|
dstPtr = (CARD32*)(pSiS->FbBase + (pSiS->AccelLinearScratch->offset << sbppshift));
|
|
|
|
if(pSiS->alphaBlitBusy) {
|
|
pSiS->alphaBlitBusy = FALSE;
|
|
SiSIdle
|
|
}
|
|
|
|
if(alpha == 0xffff) {
|
|
|
|
while(height--) {
|
|
for(x = 0; x < width; x++) {
|
|
myalpha = alphaPtr[x];
|
|
dstPtr[x] = (renderaccelarray[red + myalpha] << 16) |
|
|
(renderaccelarray[green + myalpha] << 8) |
|
|
renderaccelarray[blue + myalpha] |
|
|
myalpha << 24;
|
|
}
|
|
dstPtr += pitch;
|
|
alphaPtr += alphaPitch;
|
|
}
|
|
|
|
} else {
|
|
|
|
alpha &= 0xff00;
|
|
|
|
while(height--) {
|
|
for(x = 0; x < width; x++) {
|
|
myalpha = alphaPtr[x];
|
|
dstPtr[x] = (renderaccelarray[alpha + myalpha] << 24) |
|
|
(renderaccelarray[red + myalpha] << 16) |
|
|
(renderaccelarray[green + myalpha] << 8) |
|
|
renderaccelarray[blue + myalpha];
|
|
}
|
|
dstPtr += pitch;
|
|
alphaPtr += alphaPitch;
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static Bool
|
|
SiSSetupForCPUToScreenTexture(ScrnInfoPtr pScrn,
|
|
int op,
|
|
#ifdef SISNEWRENDER
|
|
CARD32 texType, CARD32 dstType,
|
|
#else
|
|
int texType,
|
|
#endif
|
|
CARD8 *texPtr,
|
|
int texPitch, int width,
|
|
int height, int flags)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD8 *dst;
|
|
int pitch, sizeNeeded;
|
|
int sbpp = pSiS->CurrentLayout.bitsPerPixel >> 3;
|
|
int sbppshift = sbpp >> 1; /* 8->0, 16->1, 32->2 */
|
|
int bppshift = PICT_FORMAT_BPP(texType) >> 4; /* 8->0, 16->1, 32->2 */
|
|
Bool docopy = TRUE;
|
|
|
|
#ifdef ACCELDEBUG
|
|
xf86DrvMsg(0, X_INFO, "T: type %x op %d w %d h %d T-pitch %d\n",
|
|
texType, op, width, height, texPitch);
|
|
#endif
|
|
|
|
#ifdef SISVRAMQ
|
|
if(op > SiSRenderOpsMAX) return FALSE;
|
|
if(!SiSRenderOps[op]) return FALSE;
|
|
#else
|
|
if(op != PictOpOver) return FALSE;
|
|
#endif
|
|
|
|
if((width > 2048) || (height > 2048)) return FALSE;
|
|
|
|
pitch = (width + 31) & ~31;
|
|
sizeNeeded = (pitch << bppshift) * height;
|
|
|
|
#ifdef ACCELDEBUG
|
|
xf86DrvMsg(0, X_INFO, "T: %x op %x w %d h %d T-pitch %d size %d (%d %d %d)\n",
|
|
texType, op, width, height, texPitch, sizeNeeded, sbpp, sbppshift, bppshift);
|
|
#endif
|
|
|
|
if(!SiSAllocateLinear(pScrn, (sizeNeeded + sbpp - 1) >> sbppshift))
|
|
return FALSE;
|
|
|
|
width <<= bppshift; /* -> bytes (for engine and memcpy) */
|
|
pitch <<= bppshift; /* -> bytes */
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
|
|
switch(op) {
|
|
case PictOpClear:
|
|
#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
|
|
case PictOpDisjointClear:
|
|
case PictOpConjointClear:
|
|
#endif
|
|
SiSSetupPATFGDSTRect(0, pSiS->scrnOffset, DEV_HEIGHT)
|
|
/* SiSSetupROP(0x00) - is already zero */
|
|
SiSSetupCMDFlag(PATFG)
|
|
docopy = FALSE;
|
|
break;
|
|
case PictOpSrc:
|
|
#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
|
|
case PictOpDisjointSrc:
|
|
case PictOpConjointSrc:
|
|
#endif
|
|
SiSSetupSRCPitchDSTRect(pitch, pSiS->scrnOffset, DEV_HEIGHT);
|
|
SiSSetupAlpha(0xff)
|
|
SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_NODESTALPHA)
|
|
break;
|
|
case PictOpDst:
|
|
#if XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4,2,0,0,0)
|
|
case PictOpDisjointDst:
|
|
case PictOpConjointDst:
|
|
#endif
|
|
SiSSetupSRCPitchDSTRect(pitch, pSiS->scrnOffset, DEV_HEIGHT);
|
|
SiSSetupAlpha(0x00)
|
|
SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_CONSTANTALPHA)
|
|
docopy = FALSE;
|
|
break;
|
|
case PictOpOver:
|
|
SiSSetupSRCPitchDSTRect(pitch, pSiS->scrnOffset, DEV_HEIGHT);
|
|
SiSSetupAlpha(0x00)
|
|
SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA)
|
|
break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
SiSSyncWP
|
|
#else
|
|
SiSSetupDSTColorDepth(pSiS->DstColor);
|
|
SiSSetupSRCPitch(pitch);
|
|
SiSSetupDSTRect(pSiS->scrnOffset, DEV_HEIGHT)
|
|
SiSSetupAlpha(0x00)
|
|
SiSSetupCMDFlag(ALPHA_BLEND | SRCVIDEO | A_PERPIXELALPHA | pSiS->SiS310_AccelDepth)
|
|
#endif
|
|
|
|
/* Don't need source for clear and dest */
|
|
if(!docopy) return TRUE;
|
|
|
|
dst = (CARD8*)(pSiS->FbBase + (pSiS->AccelLinearScratch->offset << sbppshift));
|
|
|
|
if(pSiS->alphaBlitBusy) {
|
|
pSiS->alphaBlitBusy = FALSE;
|
|
SiSIdle
|
|
}
|
|
|
|
while(height--) {
|
|
memcpy(dst, texPtr, width);
|
|
texPtr += texPitch;
|
|
dst += pitch;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
SiSSubsequentCPUToScreenTexture(ScrnInfoPtr pScrn,
|
|
int dst_x, int dst_y,
|
|
int src_x, int src_y,
|
|
int width, int height)
|
|
{
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD32 srcbase, dstbase;
|
|
|
|
srcbase = pSiS->AccelLinearScratch->offset << 1;
|
|
if(pScrn->bitsPerPixel == 32) srcbase <<= 1;
|
|
|
|
#ifdef ACCELDEBUG
|
|
xf86DrvMsg(0, X_INFO, "FIRE: scrbase %x dx %d dy %d w %d h %d\n",
|
|
srcbase, dst_x, dst_y, width, height);
|
|
#endif
|
|
|
|
dstbase = 0;
|
|
if((dst_y >= pScrn->virtualY) || (dst_y >= 2048)) {
|
|
dstbase = pSiS->scrnOffset * dst_y;
|
|
dst_y = 0;
|
|
}
|
|
|
|
srcbase += FBOFFSET;
|
|
dstbase += FBOFFSET;
|
|
|
|
#ifdef SISVRAMQ
|
|
SiSCheckQueue(16 * 3)
|
|
SiSSetupSRCDSTBase(srcbase,dstbase);
|
|
SiSSetupSRCDSTXY(src_x, src_y, dst_x, dst_y)
|
|
SiSSetRectDoCMD(width,height)
|
|
#else
|
|
SiSSetupSRCBase(srcbase);
|
|
SiSSetupDSTBase(dstbase);
|
|
SiSSetupRect(width, height)
|
|
SiSSetupSRCXY(src_x, src_y)
|
|
SiSSetupDSTXY(dst_x, dst_y)
|
|
SiSDoCMD
|
|
#endif
|
|
pSiS->alphaBlitBusy = TRUE;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#endif /* XAA */
|
|
|
|
#ifdef SIS_USE_EXA /* ---------------------------- EXA -------------------------- */
|
|
|
|
static void
|
|
SiSEXASync(ScreenPtr pScreen, int marker)
|
|
{
|
|
SISPtr pSiS = SISPTR(xf86Screens[pScreen->myNum]);
|
|
|
|
SiSIdle
|
|
}
|
|
|
|
static Bool
|
|
SiSPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
/* Planemask not supported */
|
|
if((planemask & ((1 << pPixmap->drawable.depth) - 1)) !=
|
|
(1 << pPixmap->drawable.depth) - 1) {
|
|
return FALSE;
|
|
}
|
|
|
|
if((pPixmap->drawable.bitsPerPixel != 8) &&
|
|
(pPixmap->drawable.bitsPerPixel != 16) &&
|
|
(pPixmap->drawable.bitsPerPixel != 32))
|
|
return FALSE;
|
|
|
|
if(pSiS->disablecolorkeycurrent) {
|
|
if((CARD32)fg == pSiS->colorKey) {
|
|
alu = 5; /* NOOP */
|
|
}
|
|
}
|
|
|
|
/* Check that the pitch matches the hardware's requirements. Should
|
|
* never be a problem due to pixmapPitchAlign and fbScreenInit.
|
|
*/
|
|
if(exaGetPixmapPitch(pPixmap) & 3)
|
|
return FALSE;
|
|
|
|
SiSSetupDSTColorDepth((pPixmap->drawable.bitsPerPixel >> 4) << 16);
|
|
SiSCheckQueue(16 * 1);
|
|
SiSSetupPATFGDSTRect(fg, exaGetPixmapPitch(pPixmap), DEV_HEIGHT)
|
|
SiSSetupROP(SiSGetPatternROP(alu))
|
|
SiSSetupCMDFlag(PATFG)
|
|
SiSSyncWP
|
|
|
|
pSiS->fillDstBase = (CARD32)exaGetPixmapOffset(pPixmap) + FBOFFSET;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
SiSSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
/* SiSSetupCMDFlag(BITBLT) - BITBLT = 0 */
|
|
|
|
SiSCheckQueue(16 * 2)
|
|
SiSSetupDSTXYRect(x1, y1, x2-x1, y2-y1)
|
|
SiSSetupDSTBaseDoCMD(pSiS->fillDstBase)
|
|
}
|
|
|
|
static void
|
|
SiSDoneSolid(PixmapPtr pPixmap)
|
|
{
|
|
}
|
|
|
|
static Bool
|
|
SiSPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir,
|
|
int alu, Pixel planemask)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
CARD32 srcbase, dstbase;
|
|
|
|
/* Planemask not supported */
|
|
if((planemask & ((1 << pSrcPixmap->drawable.depth) - 1)) !=
|
|
(1 << pSrcPixmap->drawable.depth) - 1) {
|
|
return FALSE;
|
|
}
|
|
|
|
if((pDstPixmap->drawable.bitsPerPixel != 8) &&
|
|
(pDstPixmap->drawable.bitsPerPixel != 16) &&
|
|
(pDstPixmap->drawable.bitsPerPixel != 32))
|
|
return FALSE;
|
|
|
|
/* Check that the pitch matches the hardware's requirements. Should
|
|
* never be a problem due to pixmapPitchAlign and fbScreenInit.
|
|
*/
|
|
if(exaGetPixmapPitch(pSrcPixmap) & 3)
|
|
return FALSE;
|
|
if(exaGetPixmapPitch(pDstPixmap) & 3)
|
|
return FALSE;
|
|
|
|
srcbase = (CARD32)exaGetPixmapOffset(pSrcPixmap) + FBOFFSET;
|
|
|
|
dstbase = (CARD32)exaGetPixmapOffset(pDstPixmap) + FBOFFSET;
|
|
|
|
/* TODO: Will there eventually be overlapping blits?
|
|
* If so, good night. Then we must calculate new base addresses
|
|
* which are identical for source and dest, otherwise
|
|
* the chips direction-logic will fail. Certainly funny
|
|
* to re-calculate x and y then...
|
|
*/
|
|
|
|
SiSSetupDSTColorDepth((pDstPixmap->drawable.bitsPerPixel >> 4) << 16);
|
|
SiSCheckQueue(16 * 3);
|
|
SiSSetupSRCPitchDSTRect(exaGetPixmapPitch(pSrcPixmap),
|
|
exaGetPixmapPitch(pDstPixmap), DEV_HEIGHT)
|
|
SiSSetupROP(SiSGetCopyROP(alu))
|
|
SiSSetupSRCDSTBase(srcbase, dstbase)
|
|
SiSSyncWP
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
SiSCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
SiSCheckQueue(16 * 2);
|
|
SiSSetupSRCDSTXY(srcX, srcY, dstX, dstY)
|
|
SiSSetRectDoCMD(width, height)
|
|
}
|
|
|
|
static void
|
|
SiSDoneCopy(PixmapPtr pDstPixmap)
|
|
{
|
|
}
|
|
|
|
#ifdef SIS_HAVE_COMPOSITE
|
|
static Bool
|
|
SiSCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
|
|
PicturePtr pDstPicture)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum];
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
|
|
xf86DrvMsg(0, 0, "CC: %d Src %x (fi %d ca %d) Msk %x (%d %d) Dst %x (%d %d)\n",
|
|
op, pSrcPicture->format, pSrcPicture->filter, pSrcPicture->componentAlpha,
|
|
pMaskPicture ? pMaskPicture->format : 0x2011, pMaskPicture ? pMaskPicture->filter : -1,
|
|
pMaskPicture ? pMaskPicture->componentAlpha : -1,
|
|
pDstPicture->format, pDstPicture->filter, pDstPicture->componentAlpha);
|
|
|
|
if(pSrcPicture->transform || (pMaskPicture && pMaskPicture->transform) || pDstPicture->transform) {
|
|
xf86DrvMsg(0, 0, "CC: src tr %p msk %p dst %p !!!!!!!!!!!!!!!\n",
|
|
pSrcPicture->transform,
|
|
pMaskPicture ? pMaskPicture->transform : 0,
|
|
pDstPicture->transform);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static Bool
|
|
SiSPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
|
|
PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
|
|
{
|
|
#if 0
|
|
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
SiSComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY,
|
|
int width, int height)
|
|
{
|
|
#if 0
|
|
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
#endif
|
|
}
|
|
|
|
static void
|
|
SiSDoneComposite(PixmapPtr pDst)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
Bool
|
|
SiSUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
unsigned char *dst = pDst->devPrivate.ptr;
|
|
int dst_pitch = exaGetPixmapPitch(pDst);
|
|
|
|
(pSiS->SyncAccel)(pScrn);
|
|
|
|
if(pDst->drawable.bitsPerPixel < 8)
|
|
return FALSE;
|
|
|
|
dst += (x * pDst->drawable.bitsPerPixel / 8) + (y * src_pitch);
|
|
while(h--) {
|
|
SiSMemCopyToVideoRam(pSiS, dst, (unsigned char *)src,
|
|
(w * pDst->drawable.bitsPerPixel / 8));
|
|
src += src_pitch;
|
|
dst += dst_pitch;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
Bool
|
|
SiSUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
unsigned char *src, *dst;
|
|
int src_pitch = exaGetPixmapPitch(pSrc);
|
|
int dst_pitch, size, w, h, bytes;
|
|
|
|
w = pSrc->drawable.width;
|
|
|
|
dst_pitch = ((w * (pSrc->drawable.bitsPerPixel >> 3)) +
|
|
pSiS->EXADriverPtr->pixmapPitchAlign - 1) &
|
|
~(pSiS->EXADriverPtr->pixmapPitchAlign - 1);
|
|
|
|
size = dst_pitch * pSrc->drawable.height;
|
|
|
|
if(size > pSiS->exa_scratch->size)
|
|
return FALSE;
|
|
|
|
pSiS->exa_scratch_next = (pSiS->exa_scratch_next +
|
|
pSiS->EXADriverPtr->pixmapOffsetAlign - 1) &
|
|
~(pSiS->EXADriverPtr->pixmapOffsetAlign - 1);
|
|
|
|
if(pSiS->exa_scratch_next + size >
|
|
pSiS->exa_scratch->offset + pSiS->exa_scratch->size) {
|
|
(pSiS->EXADriverPtr->WaitMarker)(pSrc->drawable.pScreen, 0);
|
|
pSiS->exa_scratch_next = pSiS->exa_scratch->offset;
|
|
}
|
|
|
|
memcpy(pDst, pSrc, sizeof(*pDst));
|
|
pDst->devKind = dst_pitch;
|
|
pDst->devPrivate.ptr = pSiS->EXADriverPtr->memoryBase + pSiS->exa_scratch_next;
|
|
|
|
pSiS->exa_scratch_next += size;
|
|
|
|
src = pSrc->devPrivate.ptr;
|
|
src_pitch = exaGetPixmapPitch(pSrc);
|
|
dst = pDst->devPrivate.ptr;
|
|
|
|
bytes = (src_pitch < dst_pitch) ? src_pitch : dst_pitch;
|
|
|
|
h = pSrc->drawable.height;
|
|
|
|
(pSiS->SyncAccel)(pScrn);
|
|
|
|
while(h--) {
|
|
SiSMemCopyToVideoRam(pSiS, dst, src, size);
|
|
src += src_pitch;
|
|
dst += dst_pitch;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
Bool
|
|
SiSDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
unsigned char *src = pSrc->devPrivate.ptr;
|
|
int src_pitch = exaGetPixmapPitch(pSrc);
|
|
int size = src_pitch < dst_pitch ? src_pitch : dst_pitch;
|
|
|
|
(pSiS->SyncAccel)(pScrn);
|
|
|
|
if(pSrc->drawable.bitsPerPixel < 8)
|
|
return FALSE;
|
|
|
|
src += (x * pSrc->drawable.bitsPerPixel / 8) + (y * src_pitch);
|
|
while(h--) {
|
|
SiSMemCopyFromVideoRam(pSiS, (unsigned char *)dst, src, size);
|
|
src += src_pitch;
|
|
dst += dst_pitch;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
#endif /* EXA */
|
|
|
|
/* Helper for xv video blitter */
|
|
|
|
#ifdef INCL_YUV_BLIT_ADAPTOR
|
|
void
|
|
SISWriteBlitPacket(SISPtr pSiS, CARD32 *packet)
|
|
{
|
|
CARD32 dummybuf;
|
|
|
|
SiSWritePacketPart(packet[0], packet[1], packet[2], packet[3]);
|
|
SiSWritePacketPart(packet[4], packet[5], packet[6], packet[7]);
|
|
SiSWritePacketPart(packet[8], packet[9], packet[10], packet[11]);
|
|
SiSWritePacketPart(packet[12], packet[13], packet[14], packet[15]);
|
|
SiSWritePacketPart(packet[16], packet[17], packet[18], packet[19]);
|
|
SiSSyncWP;
|
|
(void)dummybuf; /* Suppress compiler warning */
|
|
}
|
|
#endif
|
|
|
|
/* For DGA usage */
|
|
|
|
static void
|
|
SiSDGAFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, int color)
|
|
{
|
|
SiSSetupForSolidFill(pScrn, color, GXcopy, ~0);
|
|
SiSSubsequentSolidFillRect(pScrn, x, y, w, h);
|
|
}
|
|
|
|
static void
|
|
SiSDGABlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int dstx, int dsty, int w, int h, int color)
|
|
{
|
|
/* Don't need xdir, ydir */
|
|
SiSSetupForScreenToScreenCopy(pScrn, 0, 0, GXcopy, (CARD32)~0, color);
|
|
SiSSubsequentScreenToScreenCopy(pScrn, srcx, srcy, dstx, dsty, w, h);
|
|
}
|
|
|
|
/* Initialisation */
|
|
|
|
Bool
|
|
SiS315AccelInit(ScreenPtr pScreen)
|
|
{
|
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
|
SISPtr pSiS = SISPTR(pScrn);
|
|
#ifdef SIS_USE_XAA
|
|
XAAInfoRecPtr infoPtr = NULL;
|
|
int topFB, reservedFbSize, usableFbSize;
|
|
BoxRec Avail;
|
|
#ifdef CTSCE
|
|
unsigned char *AvailBufBase;
|
|
#ifndef CTSCE_DIRECT
|
|
int i;
|
|
#endif
|
|
#endif
|
|
#endif /* XAA */
|
|
|
|
pSiS->ColorExpandBufferNumber = 0;
|
|
pSiS->PerColorExpandBufferSize = 0;
|
|
pSiS->RenderAccelArray = NULL;
|
|
#ifdef SIS_USE_XAA
|
|
pSiS->AccelInfoPtr = NULL;
|
|
#endif
|
|
#ifdef SIS_USE_EXA
|
|
pSiS->EXADriverPtr = NULL;
|
|
pSiS->exa_scratch = NULL;
|
|
#endif
|
|
|
|
if((pScrn->bitsPerPixel != 8) &&
|
|
(pScrn->bitsPerPixel != 16) &&
|
|
(pScrn->bitsPerPixel != 32)) {
|
|
pSiS->NoAccel = TRUE;
|
|
}
|
|
|
|
if(!pSiS->NoAccel) {
|
|
#ifdef SIS_USE_XAA
|
|
if(!pSiS->useEXA) {
|
|
pSiS->AccelInfoPtr = infoPtr = XAACreateInfoRec();
|
|
if(!infoPtr) pSiS->NoAccel = TRUE;
|
|
}
|
|
#endif
|
|
#ifdef SIS_USE_EXA
|
|
if(pSiS->useEXA) {
|
|
if(!(pSiS->EXADriverPtr = exaDriverAlloc())) {
|
|
pSiS->NoAccel = TRUE;
|
|
pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if(!pSiS->NoAccel) {
|
|
|
|
SiSInitializeAccelerator(pScrn);
|
|
|
|
pSiS->InitAccel = SiSInitializeAccelerator;
|
|
pSiS->SyncAccel = SiSSyncAccel;
|
|
pSiS->FillRect = SiSDGAFillRect;
|
|
pSiS->BlitRect = SiSDGABlitRect;
|
|
|
|
#ifdef SIS_USE_XAA /* ----------------------- XAA ----------------------- */
|
|
if(!pSiS->useEXA) {
|
|
|
|
infoPtr->Flags = LINEAR_FRAMEBUFFER |
|
|
OFFSCREEN_PIXMAPS |
|
|
PIXMAP_CACHE;
|
|
|
|
/* sync */
|
|
infoPtr->Sync = SiSSync;
|
|
|
|
/* BitBlt */
|
|
infoPtr->SetupForScreenToScreenCopy = SiSSetupForScreenToScreenCopy;
|
|
infoPtr->SubsequentScreenToScreenCopy = SiSSubsequentScreenToScreenCopy;
|
|
infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK | TRANSPARENCY_GXCOPY_ONLY;
|
|
|
|
/* solid fills */
|
|
infoPtr->SetupForSolidFill = SiSSetupForSolidFill;
|
|
infoPtr->SubsequentSolidFillRect = SiSSubsequentSolidFillRect;
|
|
#ifdef TRAP
|
|
if((pSiS->Chipset != PCI_CHIP_SIS660) &&
|
|
(pSiS->Chipset != PCI_CHIP_SIS330) &&
|
|
(pSiS->Chipset != PCI_CHIP_SIS340) &&
|
|
(pSiS->Chipset != PCI_CHIP_XGIXG20) &&
|
|
(pSiS->Chipset != PCI_CHIP_XGIXG40)) {
|
|
infoPtr->SubsequentSolidFillTrap = SiSSubsequentSolidFillTrap;
|
|
}
|
|
#endif
|
|
infoPtr->SolidFillFlags = NO_PLANEMASK;
|
|
|
|
/* solid line */
|
|
infoPtr->SetupForSolidLine = SiSSetupForSolidLine;
|
|
infoPtr->SubsequentSolidTwoPointLine = SiSSubsequentSolidTwoPointLine;
|
|
infoPtr->SubsequentSolidHorVertLine = SiSSubsequentSolidHorzVertLine;
|
|
infoPtr->SolidLineFlags = NO_PLANEMASK;
|
|
|
|
/* dashed line */
|
|
infoPtr->SetupForDashedLine = SiSSetupForDashedLine;
|
|
infoPtr->SubsequentDashedTwoPointLine = SiSSubsequentDashedTwoPointLine;
|
|
infoPtr->DashPatternMaxLength = 64;
|
|
infoPtr->DashedLineFlags = NO_PLANEMASK |
|
|
LINE_PATTERN_MSBFIRST_LSBJUSTIFIED;
|
|
|
|
/* 8x8 mono pattern fill */
|
|
infoPtr->SetupForMono8x8PatternFill = SiSSetupForMonoPatternFill;
|
|
infoPtr->SubsequentMono8x8PatternFillRect = SiSSubsequentMonoPatternFill;
|
|
#ifdef TRAP
|
|
if((pSiS->Chipset != PCI_CHIP_SIS660) &&
|
|
(pSiS->Chipset != PCI_CHIP_SIS330) &&
|
|
(pSiS->Chipset != PCI_CHIP_SIS340) &&
|
|
(pSiS->Chipset != PCI_CHIP_XGIXG20) &&
|
|
(pSiS->Chipset != PCI_CHIP_XGIXG40)) {
|
|
infoPtr->SubsequentMono8x8PatternFillTrap = SiSSubsequentMonoPatternFillTrap;
|
|
}
|
|
#endif
|
|
infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK |
|
|
HARDWARE_PATTERN_SCREEN_ORIGIN |
|
|
HARDWARE_PATTERN_PROGRAMMED_BITS |
|
|
BIT_ORDER_IN_BYTE_MSBFIRST;
|
|
|
|
#ifdef SISVRAMQ
|
|
/* 8x8 color pattern fill (MMIO support not implemented) */
|
|
infoPtr->SetupForColor8x8PatternFill = SiSSetupForColor8x8PatternFill;
|
|
infoPtr->SubsequentColor8x8PatternFillRect = SiSSubsequentColor8x8PatternFillRect;
|
|
infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK |
|
|
HARDWARE_PATTERN_SCREEN_ORIGIN |
|
|
NO_TRANSPARENCY;
|
|
#endif
|
|
|
|
#ifdef STSCE
|
|
/* Screen To Screen Color Expand */
|
|
/* The hardware does not support this the way we need it, because
|
|
* the mono-bitmap is not provided with a pitch of (width), but
|
|
* with a pitch of scrnOffset (= width * bpp / 8).
|
|
*/
|
|
infoPtr->SetupForScreenToScreenColorExpandFill =
|
|
SiSSetupForScreenToScreenColorExpand;
|
|
infoPtr->SubsequentScreenToScreenColorExpandFill =
|
|
SiSSubsequentScreenToScreenColorExpand;
|
|
infoPtr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK |
|
|
BIT_ORDER_IN_BYTE_MSBFIRST ;
|
|
#endif
|
|
|
|
#ifdef CTSCE
|
|
#ifdef CTSCE_DIRECT
|
|
/* CPU color expansion - direct method
|
|
*
|
|
* We somewhat fake this function here in the following way:
|
|
* XAA copies its mono-bitmap data not into an aperture, but
|
|
* into our video RAM buffer. We then do a ScreenToScreen
|
|
* color expand.
|
|
* Unfortunately, XAA sends the data to the aperture AFTER
|
|
* the call to Subsequent(), therefore we do not execute the
|
|
* command in Subsequent, but in the following call to Sync().
|
|
* (Hence, the SYNC_AFTER_COLOR_EXPAND flag MUST BE SET)
|
|
*
|
|
* This is slower than doing it by the CPU.
|
|
*/
|
|
|
|
pSiS->ColorExpandBufferNumber = 48;
|
|
pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4;
|
|
infoPtr->SetupForCPUToScreenColorExpandFill = SiSSetupForCPUToScreenColorExpandFill;
|
|
infoPtr->SubsequentCPUToScreenColorExpandFill = SiSSubsequentCPUToScreenColorExpandFill;
|
|
infoPtr->ColorExpandRange = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize;
|
|
infoPtr->CPUToScreenColorExpandFillFlags =
|
|
NO_PLANEMASK |
|
|
CPU_TRANSFER_PAD_DWORD |
|
|
SCANLINE_PAD_DWORD |
|
|
BIT_ORDER_IN_BYTE_MSBFIRST |
|
|
LEFT_EDGE_CLIPPING |
|
|
SYNC_AFTER_COLOR_EXPAND;
|
|
#else
|
|
/* CPU color expansion - per-scanline / indirect method
|
|
*
|
|
* SLOW! SLOWER! SLOWEST!
|
|
*
|
|
* Does not work on 330 series, hangs the engine (both VRAM and MMIO).
|
|
* Does not work in VRAM queue mode.
|
|
*/
|
|
#ifndef SISVRAMQ
|
|
if((pSiS->Chipset != PCI_CHIP_SIS650) &&
|
|
(pSiS->Chipset != PCI_CHIP_SIS660) &&
|
|
(pSiS->Chipset != PCI_CHIP_SIS330) &&
|
|
(pSiS->Chipset != PCI_CHIP_SIS340) &&
|
|
(pSiS->Chipset != PCI_CHIP_XGIXG20) &&
|
|
(pSiS->Chipset != PCI_CHIP_XGIXG40)) {
|
|
pSiS->ColorExpandBufferNumber = 16;
|
|
pSiS->ColorExpandBufferCountMask = 0x0F;
|
|
pSiS->PerColorExpandBufferSize = ((pScrn->virtualX + 31)/32) * 4;
|
|
infoPtr->NumScanlineColorExpandBuffers = pSiS->ColorExpandBufferNumber;
|
|
infoPtr->ScanlineColorExpandBuffers = (unsigned char **)&pSiS->ColorExpandBufferAddr[0];
|
|
infoPtr->SetupForScanlineCPUToScreenColorExpandFill = SiSSetupForScanlineCPUToScreenColorExpandFill;
|
|
infoPtr->SubsequentScanlineCPUToScreenColorExpandFill = SiSSubsequentScanlineCPUToScreenColorExpandFill;
|
|
infoPtr->SubsequentColorExpandScanline = SiSSubsequentColorExpandScanline;
|
|
infoPtr->ScanlineCPUToScreenColorExpandFillFlags =
|
|
NO_PLANEMASK |
|
|
CPU_TRANSFER_PAD_DWORD |
|
|
SCANLINE_PAD_DWORD |
|
|
BIT_ORDER_IN_BYTE_MSBFIRST |
|
|
LEFT_EDGE_CLIPPING;
|
|
}
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef INCL_RENDER
|
|
#ifdef RENDER
|
|
/* Render */
|
|
SiSCalcRenderAccelArray(pScrn);
|
|
|
|
if(pSiS->RenderAccelArray) {
|
|
pSiS->AccelLinearScratch = NULL;
|
|
|
|
#ifdef SISNEWRENDER
|
|
infoPtr->SetupForCPUToScreenAlphaTexture2 = SiSSetupForCPUToScreenAlphaTexture;
|
|
infoPtr->CPUToScreenAlphaTextureDstFormats = (pScrn->bitsPerPixel == 16) ?
|
|
SiSDstTextureFormats16 : SiSDstTextureFormats32;
|
|
#else
|
|
infoPtr->SetupForCPUToScreenAlphaTexture = SiSSetupForCPUToScreenAlphaTexture;
|
|
#endif
|
|
infoPtr->SubsequentCPUToScreenAlphaTexture = SiSSubsequentCPUToScreenTexture;
|
|
infoPtr->CPUToScreenAlphaTextureFormats = SiSAlphaTextureFormats;
|
|
infoPtr->CPUToScreenAlphaTextureFlags = XAA_RENDER_NO_TILE;
|
|
|
|
#ifdef SISNEWRENDER
|
|
infoPtr->SetupForCPUToScreenTexture2 = SiSSetupForCPUToScreenTexture;
|
|
infoPtr->CPUToScreenTextureDstFormats = (pScrn->bitsPerPixel == 16) ?
|
|
SiSDstTextureFormats16 : SiSDstTextureFormats32;
|
|
#else
|
|
infoPtr->SetupForCPUToScreenTexture = SiSSetupForCPUToScreenTexture;
|
|
#endif
|
|
infoPtr->SubsequentCPUToScreenTexture = SiSSubsequentCPUToScreenTexture;
|
|
infoPtr->CPUToScreenTextureFormats = SiSTextureFormats;
|
|
infoPtr->CPUToScreenTextureFlags = XAA_RENDER_NO_TILE;
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RENDER acceleration enabled\n");
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef SISDUALHEAD
|
|
if(pSiS->DualHeadMode) {
|
|
infoPtr->RestoreAccelState = SiSRestoreAccelState;
|
|
}
|
|
#endif
|
|
} /* !EXA */
|
|
#endif /* XAA */
|
|
|
|
#ifdef SIS_USE_EXA /* ----------------------- EXA ----------------------- */
|
|
if(pSiS->useEXA) {
|
|
pSiS->EXADriverPtr->exa_major = 2;
|
|
pSiS->EXADriverPtr->exa_minor = 0;
|
|
|
|
/* data */
|
|
pSiS->EXADriverPtr->memoryBase = pSiS->FbBase;
|
|
pSiS->EXADriverPtr->memorySize = pSiS->maxxfbmem;
|
|
pSiS->EXADriverPtr->offScreenBase = pScrn->virtualX * pScrn->virtualY
|
|
* ((pScrn->bitsPerPixel + 7) / 8);
|
|
if(pSiS->EXADriverPtr->memorySize > pSiS->EXADriverPtr->offScreenBase) {
|
|
pSiS->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
|
|
} else {
|
|
pSiS->NoXvideo = TRUE;
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"Not enough video RAM for offscreen memory manager. Xv disabled\n");
|
|
}
|
|
pSiS->EXADriverPtr->pixmapOffsetAlign = 16; /* src/dst: double quad word boundary */
|
|
pSiS->EXADriverPtr->pixmapPitchAlign = 4; /* pitch: double word boundary */
|
|
pSiS->EXADriverPtr->maxX = 4095;
|
|
pSiS->EXADriverPtr->maxY = 4095;
|
|
|
|
/* Sync */
|
|
pSiS->EXADriverPtr->WaitMarker = SiSEXASync;
|
|
|
|
/* Solid fill */
|
|
pSiS->EXADriverPtr->PrepareSolid = SiSPrepareSolid;
|
|
pSiS->EXADriverPtr->Solid = SiSSolid;
|
|
pSiS->EXADriverPtr->DoneSolid = SiSDoneSolid;
|
|
|
|
/* Copy */
|
|
pSiS->EXADriverPtr->PrepareCopy = SiSPrepareCopy;
|
|
pSiS->EXADriverPtr->Copy = SiSCopy;
|
|
pSiS->EXADriverPtr->DoneCopy = SiSDoneCopy;
|
|
|
|
/* Composite */
|
|
#ifdef SIS_HAVE_COMPOSITE
|
|
SiSCalcRenderAccelArray(pScrn);
|
|
if(pSiS->RenderAccelArray) {
|
|
pSiS->EXADriverPtr->CheckComposite = SiSCheckComposite;
|
|
pSiS->EXADriverPtr->PrepareComposite = SiSPrepareComposite;
|
|
pSiS->EXADriverPtr->Composite = SiSComposite;
|
|
pSiS->EXADriverPtr->DoneComposite = SiSDoneComposite;
|
|
}
|
|
#endif
|
|
|
|
/* Upload, download to/from Screen */
|
|
pSiS->EXADriverPtr->UploadToScreen = SiSUploadToScreen;
|
|
pSiS->EXADriverPtr->DownloadFromScreen = SiSDownloadFromScreen;
|
|
|
|
}
|
|
#endif
|
|
|
|
} /* NoAccel */
|
|
|
|
/* Init framebuffer memory manager */
|
|
|
|
/* Traditional layout:
|
|
* |-----------------++++++++++++++++++++^************==========~~~~~~~~~~~~|
|
|
* | UsableFbSize ColorExpandBuffers | DRI-Heap HWCursor CommandQueue
|
|
* FbBase topFB
|
|
* +-------------maxxfbmem---------------+
|
|
*
|
|
* On SiS76x with UMA+LFB:
|
|
* |UUUUUUUUUUUUUUU--------------++++++++++++++++++++^==========~~~~~~~~~~~~|
|
|
* DRI heap |UsableFbSize ColorExpandBuffers | HWCursor CommandQueue
|
|
* (in UMA and FbBase topFB
|
|
* eventually +---------- maxxfbmem ------------+
|
|
* beginning of
|
|
* LFB)
|
|
*/
|
|
|
|
#ifdef SIS_USE_XAA
|
|
if(!pSiS->useEXA) {
|
|
|
|
topFB = pSiS->maxxfbmem; /* relative to FbBase */
|
|
|
|
reservedFbSize = pSiS->ColorExpandBufferNumber * pSiS->PerColorExpandBufferSize;
|
|
|
|
usableFbSize = topFB - reservedFbSize;
|
|
|
|
#ifdef CTSCE
|
|
AvailBufBase = pSiS->FbBase + usableFbSize;
|
|
if(pSiS->ColorExpandBufferNumber) {
|
|
#ifdef CTSCE_DIRECT
|
|
infoPtr->ColorExpandBase = (unsigned char *)AvailBufBase;
|
|
pSiS->ColorExpandBase = usableFbSize;
|
|
#else
|
|
for(i = 0; i < pSiS->ColorExpandBufferNumber; i++) {
|
|
pSiS->ColorExpandBufferAddr[i] = AvailBufBase +
|
|
i * pSiS->PerColorExpandBufferSize;
|
|
pSiS->ColorExpandBufferScreenOffset[i] = usableFbSize +
|
|
i * pSiS->PerColorExpandBufferSize;
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
Avail.x1 = 0;
|
|
Avail.y1 = 0;
|
|
Avail.x2 = pScrn->displayWidth;
|
|
Avail.y2 = (usableFbSize / (pScrn->displayWidth * pScrn->bitsPerPixel/8)) - 1;
|
|
|
|
if(Avail.y2 < 0) Avail.y2 = 32767;
|
|
|
|
if(Avail.y2 < pScrn->currentMode->VDisplay) {
|
|
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
|
"Not enough video RAM for accelerator. At least "
|
|
"%dKB needed, %dKB available\n",
|
|
((((pScrn->displayWidth * pScrn->bitsPerPixel/8) /* +8 for make it sure */
|
|
* pScrn->currentMode->VDisplay) + reservedFbSize) / 1024) + 8,
|
|
pSiS->maxxfbmem/1024);
|
|
pSiS->NoAccel = TRUE;
|
|
pSiS->NoXvideo = TRUE;
|
|
XAADestroyInfoRec(pSiS->AccelInfoPtr);
|
|
pSiS->AccelInfoPtr = NULL;
|
|
return FALSE; /* Don't even init fb manager */
|
|
}
|
|
|
|
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
|
"Framebuffer from (%d,%d) to (%d,%d)\n",
|
|
Avail.x1, Avail.y1, Avail.x2 - 1, Avail.y2 - 1);
|
|
|
|
xf86InitFBManager(pScreen, &Avail);
|
|
|
|
if(!pSiS->NoAccel) {
|
|
return XAAInit(pScreen, infoPtr);
|
|
}
|
|
} /* !EXA */
|
|
#endif /* XAA */
|
|
|
|
#ifdef SIS_USE_EXA
|
|
if(pSiS->useEXA) {
|
|
|
|
if(!pSiS->NoAccel) {
|
|
|
|
if(!exaDriverInit(pScreen, pSiS->EXADriverPtr)) {
|
|
pSiS->NoAccel = TRUE;
|
|
pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */
|
|
return FALSE;
|
|
}
|
|
|
|
/* Reserve locked offscreen scratch area of 128K for glyph data */
|
|
pSiS->exa_scratch = exaOffscreenAlloc(pScreen, 128 * 1024, 16, TRUE,
|
|
SiSScratchSave, pSiS);
|
|
if(pSiS->exa_scratch) {
|
|
pSiS->exa_scratch_next = pSiS->exa_scratch->offset;
|
|
pSiS->EXADriverPtr->UploadToScratch = SiSUploadToScratch;
|
|
}
|
|
|
|
} else {
|
|
|
|
pSiS->NoXvideo = TRUE; /* No fbmem manager -> no xv */
|
|
|
|
}
|
|
|
|
}
|
|
#endif /* EXA */
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|