diff options
Diffstat (limited to 'src/s3v_xaa.c')
-rw-r--r-- | src/s3v_xaa.c | 757 |
1 files changed, 757 insertions, 0 deletions
diff --git a/src/s3v_xaa.c b/src/s3v_xaa.c new file mode 100644 index 0000000..3983650 --- /dev/null +++ b/src/s3v_xaa.c @@ -0,0 +1,757 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3virge/s3v_accel.c,v 1.25 2003/11/06 18:38:05 tsi Exp $ */ + +/* +Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- +NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the XFree86 Project shall not +be used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the XFree86 Project. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "s3v.h" + +#include "miline.h" + /* fb includes are in s3v.h */ +#include "xaalocal.h" +#include "xaarop.h" + +#include "servermd.h" /* LOG2_BYTES_PER_SCANLINE_PAD */ + +static void S3VSetupForSolidFill( + ScrnInfoPtr pScrn, + int color, int rop, + unsigned int planemask); + +static void S3VSubsequentSolidFillRect( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h); + +static void S3VSubsequentSolidFillRectPlaneMask( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h); + +static void S3VSetupForMono8x8PatternFill( + ScrnInfoPtr pScrn, + int patx, int paty, + int fg, int bg, + int rop, unsigned int planemask); + +static void S3VSubsequentMono8x8PatternFillRect( + ScrnInfoPtr pScrn, + int patx, int paty, + int x, int y, + int w, int h); + +static void S3VSubsequentMono8x8PatternFillRectPlaneMask( + ScrnInfoPtr pScrn, + int patx, int paty, + int x, int y, + int w, int h); + +static void S3VSetupForScreenToScreenCopy( + ScrnInfoPtr pScrn, + int xdir, int ydir, + int rop, + unsigned int planemask, + int trans); + +static void S3VSubsequentScreenToScreenCopy( + ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2, + int w, int h); + +static void S3VSetupForCPUToScreenColorExpand( + ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask); + +static void S3VSubsequentCPUToScreenColorExpand( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft); + +static void S3VSetupForImageWrite( + ScrnInfoPtr pScrn, + int rop, unsigned int planemask, + int trans_color, int bpp, + int depth); + +static void S3VSubsequentImageWriteRect( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft); + +static void S3VSubsequentSolidHorVertLine( + ScrnInfoPtr pScrn, + int x, int y, + int len, int dir); + +static void S3VSubsequentSolidHorVertLinePlaneMask( + ScrnInfoPtr pScrn, + int x, int y, + int len, int dir); + +#if 0 +static void S3VSubsequentSolidBresenhamLine(ScrnInfoPtr, int, int, int, + int, int, int, int); +static void S3VPolylinesThinSolidWrapper(DrawablePtr, GCPtr, int, int, + DDXPointPtr); +static void S3VPolySegmentThinSolidWrapper(DrawablePtr, GCPtr, int, xSegment*); +#endif + + +Bool +S3VXAAInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + S3VPtr ps3v = S3VPTR(pScrn); + XAAInfoRecPtr xaaptr; + BoxRec AvailFBArea; + + /* General acceleration flags */ + if (!(xaaptr = ps3v->AccelInfoRec = XAACreateInfoRec())) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to allocate XAAInfoRec.\n"); + return FALSE; + } + + xaaptr->Flags = 0 + | PIXMAP_CACHE + | OFFSCREEN_PIXMAPS + | LINEAR_FRAMEBUFFER + ; + + xaaptr->Sync = S3VAccelSync; + + /* Problem reports with solid fill on trio3d */ + if(!S3_TRIO_3D_SERIES(ps3v->Chipset)) + { + /* Solid filled rects */ + xaaptr->SetupForSolidFill = + S3VSetupForSolidFill; + xaaptr->SubsequentSolidFillRect = + S3VSubsequentSolidFillRect; + } + + /* Screen to screen copies */ + xaaptr->SetupForScreenToScreenCopy = + S3VSetupForScreenToScreenCopy; + xaaptr->SubsequentScreenToScreenCopy = + S3VSubsequentScreenToScreenCopy; + xaaptr->ScreenToScreenCopyFlags = 0 + | NO_TRANSPARENCY; + + /* Mono 8x8 patterns */ + xaaptr->SetupForMono8x8PatternFill = + S3VSetupForMono8x8PatternFill; + xaaptr->SubsequentMono8x8PatternFillRect = + S3VSubsequentMono8x8PatternFillRect; + xaaptr->Mono8x8PatternFillFlags = 0 + | NO_TRANSPARENCY + | HARDWARE_PATTERN_PROGRAMMED_BITS + | HARDWARE_PATTERN_SCREEN_ORIGIN + | BIT_ORDER_IN_BYTE_MSBFIRST + ; + +#ifndef __alpha__ + + /* disable color expand on GX2 until we trace down */ + /* lockups. locate 'html' in an xterm is a good */ + /* test case for an AGP GX2. */ + if (!S3_ViRGE_GX2_SERIES(ps3v->Chipset)) + { + + /* CPU to screen color expansion */ + xaaptr->CPUToScreenColorExpandFillFlags = 0 + | ROP_NEEDS_SOURCE + | CPU_TRANSFER_PAD_DWORD + | SCANLINE_PAD_DWORD + | BIT_ORDER_IN_BYTE_MSBFIRST + | LEFT_EDGE_CLIPPING + ; + + if(ps3v->AccelFlags & MONO_TRANS_BUG) + xaaptr->CPUToScreenColorExpandFillFlags |= NO_TRANSPARENCY; + + xaaptr->ColorExpandRange = 0x8000; + xaaptr->ColorExpandBase = ps3v->MapBaseDense; + xaaptr->SetupForCPUToScreenColorExpandFill = + S3VSetupForCPUToScreenColorExpand; + xaaptr->SubsequentCPUToScreenColorExpandFill = + S3VSubsequentCPUToScreenColorExpand; + + } /* if(!GX2...) */ + + + /* Image Writes */ + xaaptr->ImageWriteFlags = 0 + | ROP_NEEDS_SOURCE + | NO_TRANSPARENCY + | CPU_TRANSFER_PAD_DWORD + | SCANLINE_PAD_DWORD + | NO_GXCOPY /* added - kjb */ + | LEFT_EDGE_CLIPPING + ; + + xaaptr->ImageWriteRange = 0x8000; + xaaptr->ImageWriteBase = ps3v->MapBaseDense; + xaaptr->SetupForImageWrite = S3VSetupForImageWrite; + xaaptr->SubsequentImageWriteRect = S3VSubsequentImageWriteRect; + + /* on alpha, I see corruption in the xscreensaver program "hypercube" + as the line acceleration is just stubs, it loses us nothing to + disable it on alphas */ + + /* Lines */ +#if 0 + /* Bresenham lines are broken when passed through fb to xaa + so I pulled all the line functions. This shouldn't hurt us + a whole lot, since the Subsequent..Bresen stuff doesn't have + any hardware accel yet anyway... And xaa will do horiz/vert + lines with the rect fill (like we are doing here) anyway. + KJB 9/11/00 + */ + infoPtr->SetupForSolidLine = S3VSetupForSolidFill; + infoPtr->SubsequentSolidHorVertLine = S3VSubsequentSolidHorVertLine; + infoPtr->SubsequentSolidBresenhamLine = S3VSubsequentSolidBresenhamLine; + infoPtr->PolySegmentThinSolid = S3VPolySegmentThinSolidWrapper; + infoPtr->PolylinesThinSolid = S3VPolylinesThinSolidWrapper; +#endif + +#endif /* !__alpha__ */ + + /* And these are screen parameters used to setup the Graphics Engine */ + + /* Bytes per pixel */ + ps3v->Bpp = pScrn->bitsPerPixel / 8; + ps3v->Width = pScrn->displayWidth; + /* Bytes per line */ + ps3v->Bpl = ps3v->Width * ps3v->Bpp; + /* ScissB is max height, minus 1k */ + /* for hwcursor?, then limited by */ + /* ViRGE max height register of */ + /* 2047 */ + ps3v->ScissB = (pScrn->videoRam * 1024 - 1024) / ps3v->Bpl; + if (ps3v->ScissB > 2047) + ps3v->ScissB = 2047; + + S3VEngineReset(pScrn); + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = (pScrn->videoRam * 1024 - 1024) / + (pScrn->displayWidth * pScrn->bitsPerPixel / 8); + + xf86InitFBManager(pScreen, &AvailFBArea); + + /* make sure offscreen pixmaps aren't bigger than our address space */ + xaaptr->maxOffPixWidth = 2048; + xaaptr->maxOffPixHeight = 2048; + + return XAAInit(pScreen, xaaptr); +} + +/* The sync function for the GE */ +void +S3VAccelSync(ScrnInfoPtr pScrn) +{ + S3VPtr ps3v = S3VPTR(pScrn); + + WAITIDLE(); +} + +static void +S3VWriteMask( + CARD32 *dstBase, + int dwords +){ + /* on alphas, be sure to call this with MapBaseDense, not MapBase! */ + int numLeft; + CARD32 *dst = dstBase; + + while(dwords >= 8192) { + numLeft = 8192; + while(numLeft) { + dst[0] = ~0; dst[1] = ~0; + dst[2] = ~0; dst[3] = ~0; + dst += 4; + numLeft -= 4; + } + dwords -= 8192; + dst = dstBase; + } + while(dwords >= 4) { + dst[0] = ~0; dst[1] = ~0; + dst[2] = ~0; dst[3] = ~0; + dst += 4; + dwords -= 4; + } + if(!dwords) return; + dst[0] = ~0; + if(dwords == 1) return; + dst[1] = ~0; + if(dwords == 2) return; + dst[2] = ~0; + + return; +} + + + /************************\ + | Solid Filled Rects | + \************************/ + +static void +S3VSetupForSolidFill( + ScrnInfoPtr pScrn, + int color, int rop, + unsigned int planemask +){ + S3VPtr ps3v = S3VPTR(pScrn); + int mix; + + mix = XAAHelpSolidROP(pScrn, &color, planemask, &rop); + + ps3v->AccelCmd = ps3v->CommonCmd | (rop << 17) | + CMD_XP | CMD_YP | CMD_AUTOEXEC | CMD_BITBLT; + + if(mix & ROP_SRC) { + ps3v->AccelCmd |= MIX_CPUDATA | CMD_ITA_DWORD | MIX_MONO_SRC; + ps3v->AccelInfoRec->SubsequentSolidFillRect = + S3VSubsequentSolidFillRectPlaneMask; + ps3v->AccelInfoRec->SubsequentSolidHorVertLine = + S3VSubsequentSolidHorVertLinePlaneMask; + WAITFIFO(5); + OUTREG(SRC_FG_CLR, planemask); + } else { + ps3v->AccelInfoRec->SubsequentSolidFillRect = + S3VSubsequentSolidFillRect; + ps3v->AccelInfoRec->SubsequentSolidHorVertLine = + S3VSubsequentSolidHorVertLine; + WAITFIFO(4); + } + + if(mix & ROP_PAT) { + ps3v->AccelCmd |= MIX_MONO_PATT; + OUTREG(PAT_FG_CLR, color); + OUTREG(MONO_PAT_0, ~0); + OUTREG(MONO_PAT_1, ~0); + } + + OUTREG(CMD_SET, ps3v->AccelCmd); +} + + +void +S3VSubsequentSolidFillRect( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h +){ + S3VPtr ps3v = S3VPTR(pScrn); + + CHECK_DEST_BASE(y,h); + + WAITFIFO(2); + OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h); + WAITCMD(); + OUTREG(RDEST_XY, (x << 16) | y); +} + + +void +S3VSubsequentSolidFillRectPlaneMask( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h +){ + S3VPtr ps3v = S3VPTR(pScrn); + int dwords; + + CHECK_DEST_BASE(y,h); + + dwords = ((w + 31) >> 5) * h; + + WAITFIFO(2); + OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h); + WAITCMD(); + OUTREG(RDEST_XY, (x << 16) | y); + S3VWriteMask((CARD32*)ps3v->MapBaseDense, dwords); +} + + + /**************************\ + | Screen to Screen Copies | + \**************************/ + +static void +S3VSetupForScreenToScreenCopy( + ScrnInfoPtr pScrn, + int xdir, int ydir, + int rop, + unsigned int planemask, + int trans +){ + S3VPtr ps3v = S3VPTR(pScrn); + + planemask &= ps3v->FullPlaneMask; + ps3v->AccelCmd = ps3v->CommonCmd | CMD_AUTOEXEC | CMD_BITBLT; + + if(planemask != ps3v->FullPlaneMask) { + ps3v->AccelCmd |= (XAAGetCopyROP_PM(rop) << 17) | MIX_MONO_PATT; + WAITFIFO(4); + OUTREG(PAT_FG_CLR, planemask); + OUTREG(MONO_PAT_0, ~0); + OUTREG(MONO_PAT_1, ~0); + } + else { + ps3v->AccelCmd |= XAAGetCopyROP(rop) << 17; + WAITFIFO(1); + } + if(xdir == 1) ps3v->AccelCmd |= CMD_XP; + if(ydir == 1) ps3v->AccelCmd |= CMD_YP; + + OUTREG(CMD_SET, ps3v->AccelCmd); +} + + +static void +S3VSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h) +{ + S3VPtr ps3v = S3VPTR(pScrn); + + CHECK_SRC_BASE(y1,h); + CHECK_DEST_BASE(y2,h); + + w--; + + if(!(ps3v->AccelCmd & CMD_YP)) { + y1 += h - 1; y2 += h - 1; + } + + if(!(ps3v->AccelCmd & CMD_XP)) { + x1 += w; x2 += w; + } + + WAITFIFO(3); + OUTREG(RWIDTH_HEIGHT, (w << 16) | h); + OUTREG(RSRC_XY, (x1 << 16) | y1); + WAITCMD(); + OUTREG(RDEST_XY, (x2 << 16) | y2); +} + + + /*********************\ + | 8x8 Pattern fills | + \*********************/ + + +static void +S3VSetupForMono8x8PatternFill( + ScrnInfoPtr pScrn, + int patx, int paty, + int fg, int bg, + int rop, unsigned int planemask +){ + S3VPtr ps3v = S3VPTR(pScrn); + int mix; + + mix = XAAHelpPatternROP(pScrn, &fg, &bg, planemask, &rop); + + ps3v->AccelCmd = ps3v->CommonCmd | (rop << 17) | + CMD_XP | CMD_YP | CMD_AUTOEXEC | CMD_BITBLT; + + if(mix & ROP_SRC) { + ps3v->AccelCmd |= MIX_CPUDATA | CMD_ITA_DWORD | MIX_MONO_SRC; + ps3v->AccelInfoRec->SubsequentMono8x8PatternFillRect = + S3VSubsequentMono8x8PatternFillRectPlaneMask; + WAITFIFO(6); + OUTREG(SRC_FG_CLR, planemask); + } else { + ps3v->AccelInfoRec->SubsequentMono8x8PatternFillRect = + S3VSubsequentMono8x8PatternFillRect; + WAITFIFO(5); + } + + if(mix & ROP_PAT) { + ps3v->AccelCmd |= MIX_MONO_PATT; + OUTREG(PAT_FG_CLR, fg); + OUTREG(PAT_BG_CLR, bg); + OUTREG(MONO_PAT_0, patx); + OUTREG(MONO_PAT_1, paty); + } + + OUTREG(CMD_SET, ps3v->AccelCmd); +} + + +static void +S3VSubsequentMono8x8PatternFillRect( + ScrnInfoPtr pScrn, + int patx, int paty, + int x, int y, int w, int h +){ + S3VPtr ps3v = S3VPTR(pScrn); + + CHECK_DEST_BASE(y,h); + + WAITFIFO(2); + OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h); + WAITCMD(); + OUTREG(RDEST_XY, (x << 16) | y); +} + + +static void +S3VSubsequentMono8x8PatternFillRectPlaneMask( + ScrnInfoPtr pScrn, + int patx, int paty, + int x, int y, int w, int h +){ + S3VPtr ps3v = S3VPTR(pScrn); + int dwords; + + CHECK_DEST_BASE(y,h); + + dwords = ((w + 31) >> 5) * h; + + WAITFIFO(2); + OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h); + WAITCMD(); + OUTREG(RDEST_XY, (x << 16) | y); + + S3VWriteMask((CARD32*)ps3v->MapBaseDense, dwords); +} + + /*********************************\ + | CPU to Screen Color Expansion | + \*********************************/ + + +static void +S3VSetupForCPUToScreenColorExpand( + ScrnInfoPtr pScrn, + int fg, int bg, + int rop, + unsigned int planemask +){ + S3VPtr ps3v = S3VPTR(pScrn); + + planemask &= ps3v->FullPlaneMask; + ps3v->AccelCmd = ps3v->CommonCmd | CMD_AUTOEXEC | CMD_BITBLT | + CMD_XP | CMD_YP | CMD_ITA_DWORD | CMD_HWCLIP | + MIX_CPUDATA | MIX_MONO_SRC; + + + if(planemask == ps3v->FullPlaneMask) { + ps3v->AccelCmd |= XAAGetCopyROP(rop) << 17; + WAITFIFO(3); + } else { + ps3v->AccelCmd |= (XAAGetCopyROP_PM(rop) << 17) | MIX_MONO_PATT; + WAITFIFO(6); + OUTREG(MONO_PAT_0, ~0); + OUTREG(MONO_PAT_1, ~0); + OUTREG(PAT_FG_CLR, planemask); + } + + if(bg == -1) + ps3v->AccelCmd |= MIX_MONO_TRANSP; + else + OUTREG(SRC_BG_CLR, bg); + + OUTREG(SRC_FG_CLR, fg); + OUTREG(CMD_SET, ps3v->AccelCmd); +} + + +void +S3VSubsequentCPUToScreenColorExpand( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft +){ + S3VPtr ps3v = S3VPTR(pScrn); + + CHECK_DEST_BASE(y,h); + WAITFIFO(3); + OUTREG(CLIP_L_R, ((x + skipleft) << 16) | 0xffff); + OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h); + WAITCMD(); + OUTREG(RDEST_XY, (x << 16) | y); +} + + + /****************\ + | Image Writes | + \****************/ + + +static void +S3VSetupForImageWrite( + ScrnInfoPtr pScrn, + int rop, unsigned int planemask, + int trans_color, int bpp, int depth +){ + S3VPtr ps3v = S3VPTR(pScrn); + + planemask &= ps3v->FullPlaneMask; + ps3v->AccelCmd = ps3v->CommonCmd | CMD_AUTOEXEC | CMD_BITBLT | + MIX_CPUDATA | CMD_ITA_DWORD | CMD_HWCLIP | CMD_XP | CMD_YP; + + if(planemask != ps3v->FullPlaneMask) { + ps3v->AccelCmd |= (XAAGetCopyROP_PM(rop) << 17) | MIX_MONO_PATT; + WAITFIFO(4); + OUTREG(PAT_FG_CLR, planemask); + OUTREG(MONO_PAT_0, ~0); + OUTREG(MONO_PAT_1, ~0); + } else { + ps3v->AccelCmd |= XAAGetCopyROP(rop) << 17; + WAITFIFO(1); + } + + OUTREG(CMD_SET, ps3v->AccelCmd); +} + + +static void +S3VSubsequentImageWriteRect( + ScrnInfoPtr pScrn, + int x, int y, + int w, int h, + int skipleft +){ + S3VPtr ps3v = S3VPTR(pScrn); + + CHECK_DEST_BASE(y,h); + + WAITFIFO(3); + OUTREG(CLIP_L_R, ((x + skipleft) << 16) | 0xffff); + OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h); + WAITCMD(); + OUTREG(RDEST_XY, (x << 16) | y); +} + + + /***********\ + | Lines | + \***********/ + + +#if 0 /* Some line funcs are disabled at the moment */ + +static void +S3VPolylinesThinSolidWrapper( + DrawablePtr pDraw, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr pPts +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + S3VPtr ps3v = S3VPTR(infoRec->pScrn); + ps3v->CurrentGC = pGC; + /* fb support */ + ps3v->CurrentDrawable = pDraw; + if(infoRec->NeedToSync) + S3VAccelSync(infoRec->pScrn); + XAAPolyLines(pDraw, pGC, mode, npt, pPts); +} + +static void +S3VPolySegmentThinSolidWrapper( + DrawablePtr pDraw, + GCPtr pGC, + int nseg, + xSegment *pSeg +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); + S3VPtr ps3v = S3VPTR(infoRec->pScrn); + ps3v->CurrentGC = pGC; + /* fb support */ + ps3v->CurrentDrawable = pDraw; + if(infoRec->NeedToSync) + S3VAccelSync(infoRec->pScrn); + XAAPolySegment(pDraw, pGC, nseg, pSeg); +} + +#endif + +static void +S3VSubsequentSolidHorVertLine( + ScrnInfoPtr pScrn, + int x, int y, + int len, int dir +){ + S3VPtr ps3v = S3VPTR(pScrn); + int w, h; + + if(dir == DEGREES_0) { + w = len; h = 1; + } else { + w = 1; h = len; + } + + CHECK_DEST_BASE(y,h); + + WAITFIFO(2); + OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h); + WAITCMD(); + OUTREG(RDEST_XY, (x << 16) | y); +} + +static void +S3VSubsequentSolidHorVertLinePlaneMask( + ScrnInfoPtr pScrn, + int x, int y, + int len, int dir +){ + S3VPtr ps3v = S3VPTR(pScrn); + int w, h, dwords; + + if(dir == DEGREES_0) { + w = len; h = 1; dwords = (len + 31) >> 5; + } else { + w = 1; h = len; dwords = len; + } + + CHECK_DEST_BASE(y,h); + + WAITFIFO(2); + OUTREG(RWIDTH_HEIGHT, ((w - 1) << 16) | h); + WAITCMD(); + OUTREG(RDEST_XY, (x << 16) | y); + + S3VWriteMask((CARD32*)ps3v->MapBaseDense, dwords); +} + +/*EOF*/ |