Files
xf86-video-sis/src/sis310_accel.c
Enrico Weigelt, metux IT consult ee451146c0 drop obsolete XAA
Since recent commits require xserver-1.18.0 or later to build against,
there's no reason leaving behind big chunks of code that can only build
against the XAA support removed in xserver-1.13.0 (released in 2012).

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/driver/xf86-video-sis/-/merge_requests/26>
2025-04-13 10:12:51 -07:00

707 lines
18 KiB
C

/*
* 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 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_EXA /* EXA */
void SiSScratchSave(ScreenPtr pScreen, ExaOffscreenArea *area);
Bool SiSUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst);
#endif /* EXA */
void SISWriteBlitPacket(SISPtr pSiS, CARD32 *packet);
extern unsigned char SiSGetCopyROP(int rop);
extern unsigned char SiSGetPatternROP(int rop);
CARD32 dummybuf;
#ifdef SIS_NEED_ARRAY
#define SiSRenderOpsMAX 0x2b
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 = XNFcallocarray(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(xf86ScreenToScrn(pScreen));
pSiS->exa_scratch = NULL;
}
#endif
static void
SiSSync(ScrnInfoPtr pScrn)
{
SISPtr pSiS = SISPTR(pScrn);
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);
pSiS->alphaBlitBusy = FALSE;
if(!pSiS->NoAccel) {
if(pSiS->ChipType == XGI_40) {
SiSSync(pScrn);
SiSDualPipe(1); /* 1 = disable, 0 = enable */
SiSSync(pScrn);
}
}
}
static void
SiSSetupForScreenToScreenCopy(ScrnInfoPtr pScrn,
int xdir, int ydir, int rop,
unsigned int planemask, int trans_color)
{
SISPtr pSiS = SISPTR(pScrn);
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
SiSCheckQueue(16 * 2);
SiSSetupSRCPitchDSTRect(pSiS->scrnOffset, pSiS->scrnOffset, DEV_HEIGHT)
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) */
}
SiSSyncWP
/* 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);
/* 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;
SiSCheckQueue(16 * 3);
SiSSetupSRCDSTBase(srcbase, dstbase)
SiSSetupSRCDSTXY(src_x, src_y, dst_x, dst_y)
SiSSetRectDoCMD(width,height)
}
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 */
}
}
SiSSetupDSTColorDepth(pSiS->SiS310_AccelDepth);
SiSCheckQueue(16 * 1);
SiSSetupPATFGDSTRect(color, pSiS->scrnOffset, DEV_HEIGHT)
SiSSetupROP(SiSGetPatternROP(rop))
SiSSetupCMDFlag(PATFG)
SiSSyncWP
}
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 */
SiSCheckQueue(16 * 2)
SiSSetupDSTXYRect(x, y, w, h)
SiSSetupDSTBaseDoCMD(dstbase)
}
#ifdef SIS_USE_EXA /* ---------------------------- EXA -------------------------- */
static void
SiSEXASync(ScreenPtr pScreen, int marker)
{
SISPtr pSiS = SISPTR(xf86ScreenToScrn(pScreen));
SiSIdle
}
static Bool
SiSPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen);
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 = xf86ScreenToScrn(pPixmap->drawable.pScreen);
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 = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
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 = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
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 = xf86ScreenToScrn(pDstPicture->pDrawable->pScreen);
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 = xf86ScreenToScrn(pDst->drawable.pScreen);
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 = xf86ScreenToScrn(pDst->drawable.pScreen);
SISPtr pSiS = SISPTR(pScrn);
#endif
}
static void
SiSDoneComposite(PixmapPtr pDst)
{
}
#endif
Bool
SiSUploadToScratch(PixmapPtr pSrc, PixmapPtr pDst)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pSrc->drawable.pScreen);
SISPtr pSiS = SISPTR(pScrn);
unsigned char *src, *dst;
int src_pitch = exaGetPixmapPitch(pSrc);
int dst_pitch, size, w, h;
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;
h = pSrc->drawable.height;
(pSiS->SyncAccel)(pScrn);
while(h--) {
SiSMemCopyToVideoRam(pSiS, dst, src, size);
src += src_pitch;
dst += dst_pitch;
}
return TRUE;
}
#endif /* EXA */
/* Helper for xv video blitter */
void
SISWriteBlitPacket(SISPtr pSiS, CARD32 *packet)
{
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;
}
/* 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 = xf86ScreenToScrn(pScreen);
SISPtr pSiS = SISPTR(pScrn);
pSiS->ColorExpandBufferNumber = 0;
pSiS->PerColorExpandBufferSize = 0;
pSiS->RenderAccelArray = NULL;
#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_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_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
}
#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_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;
}