Index: Imakefile =================================================================== --- Imakefile (revision 79) +++ Imakefile (working copy) @@ -9,6 +9,11 @@ DRIDEFINES = $(GLX_DEFINES) #endif +#ifdef XF86EXA +EXAINCLUDES = -I$(XF86SRC)/exa +EXADEFINES = -DVIA_HAVE_EXA +#endif + SRCS = via_driver.c \ via_accel.c \ via_bandwidth.c \ @@ -57,10 +62,10 @@ -I$(XF86SRC)/rac -I$(XF86SRC)/int10 -I$(SERVERSRC)/render \ -I$(SERVERSRC)/include -I$(XINCLUDESRC) -I$(FONTINCSRC) \ -I$(EXTINCSRC) -I$(XF86SRC)/vbe -I$(XF86SRC)/shadowfb \ - -I$(SERVERSRC)/fb $(DRIINCLUDES) + -I$(SERVERSRC)/fb $(DRIINCLUDES) $(EXAINCLUDES) #endif -DEFINES = $(DRIDEFINES) +DEFINES = $(DRIDEFINES) $(EXADEFINES) #if MakeHasPosixVariableSubstitutions SubdirLibraryRule($(OBJS)) @@ -86,6 +91,7 @@ InstallDriverSDKNonExecFile(via_bios.h,$(DRIVERSDKDIR)/drivers/via) InstallDriverSDKNonExecFile(via_cursor.c,$(DRIVERSDKDIR)/drivers/via) InstallDriverSDKNonExecFile(via_dga.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_dmabuffer.h,$(DRIVERSDKDIR)/drivers/via) InstallDriverSDKNonExecFile(via_dri.c,$(DRIVERSDKDIR)/drivers/via) InstallDriverSDKNonExecFile(via_dri.h,$(DRIVERSDKDIR)/drivers/via) InstallDriverSDKNonExecFile(via_driver.c,$(DRIVERSDKDIR)/drivers/via) Index: via_memcpy.c =================================================================== --- via_memcpy.c (revision 79) +++ via_memcpy.c (working copy) @@ -546,7 +546,6 @@ double cpuFreq; VIAPtr pVia = VIAPTR(pScrn); - pScrn->pScreen = pScreen; if (NULL == (cpuInfoFile = fopen("/proc/cpuinfo","r"))) { return libc_YUV42X; } Index: via_driver.c =================================================================== --- via_driver.c (revision 79) +++ via_driver.c (working copy) @@ -124,6 +124,9 @@ OPTION_PCI_BURST, OPTION_PCI_RETRY, OPTION_NOACCEL, +#ifdef VIA_HAVE_EXA + OPTION_ACCELMETHOD, +#endif OPTION_SWCURSOR, OPTION_HWCURSOR, OPTION_SHADOW_FB, @@ -156,6 +159,9 @@ #endif /* HAVE_DEBUG */ {OPTION_VBEMODES, "VBEModes", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE}, +#ifdef VIA_HAVE_EXA + {OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE}, +#endif /* VIA_HAVE_EXA */ {OPTION_HWCURSOR, "HWCursor", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_SWCURSOR, "SWCursor", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE}, @@ -262,6 +268,17 @@ NULL }; +#ifdef VIA_HAVE_EXA +static const char *exaSymbols[] = { + "exaGetVersion", + "exaDriverInit", + "exaDriverFini", + "exaOffscreenAlloc", + "exaOffscreenFree", + NULL +}; +#endif + static const char *shadowSymbols[] = { "ShadowFBInit", NULL @@ -355,6 +372,9 @@ fbSymbols, ramdacSymbols, xaaSymbols, +#ifdef VIA_HAVE_EXA + exaSymbols, +#endif shadowSymbols, vbeSymbols, i2cSymbols, @@ -843,6 +863,23 @@ else { pVia->NoAccel = FALSE; } +#ifdef VIA_HAVE_EXA + if(!pVia->NoAccel) { + from = X_DEFAULT; + if((s = (char *)xf86GetOptValString(VIAOptions, OPTION_ACCELMETHOD))) { + if(!xf86NameCmp(s,"XAA")) { + from = X_CONFIG; + pVia->useEXA = FALSE; + } + else if(!xf86NameCmp(s,"EXA")) { + from = X_CONFIG; + pVia->useEXA = TRUE; + } + } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration architecture\n", + pVia->useEXA ? "EXA" : "XAA"); + } +#endif /* VIA_HAVE_EXA */ if (pVia->shadowFB && !pVia->NoAccel) { xf86DrvMsg(pScrn->scrnIndex, X_WARNING, @@ -1351,7 +1388,7 @@ NULL, /* list of line pitches */ 256, /* mini line pitch */ 3344, /* max line pitch */ - 16 * pScrn->bitsPerPixel, /* pitch inc (bits) */ + 32*8, /* pitch inc (bits) */ 128, /* min height */ 2508, /* max height */ pScrn->display->virtualX, /* virtual width */ @@ -1398,6 +1435,13 @@ return FALSE; } xf86LoaderReqSymLists(xaaSymbols, NULL); +#ifdef VIA_HAVE_EXA + if(!xf86LoadSubModule(pScrn, "exa")) { + VIAFreeRec(pScrn); + return FALSE; + } + xf86LoaderReqSymLists(exaSymbols, NULL); +#endif } if (pVia->hwcursor) { @@ -1475,7 +1519,7 @@ DRILock(screenInfo.screens[scrnIndex], 0); #endif - VIAAccelSync(pScrn); + viaAccelSync(pScrn); #ifdef XF86DRI @@ -1493,7 +1537,7 @@ #endif if (pVia->VQEnable) - ViaVQDisable(pScrn); + viaDisableVQ(pScrn); /* Save video status and turn off all video activities */ @@ -1875,7 +1919,8 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; vgaHWPtr hwp = VGAHWPTR(pScrn); VIAPtr pVia = VIAPTR(pScrn); - + + pScrn->pScreen = pScreen; DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAScreenInit\n")); if (!VIAMapFB(pScrn)) @@ -1961,30 +2006,8 @@ fbPictureInit(pScreen, 0, 0); if (!pVia->NoAccel) { - VIAInitAccel(pScreen); - } else { - /* - * This is needed because xf86InitFBManagerLinear in VIAInitLinear - * needs xf86InitFBManager to have been initialized, and - * xf86InitFBManager needs at least one line of free memory to - * work. This is only for Xv in Noaccel part, and since Xv is in some - * sense accelerated, it might be a better idea to disable it - * altogether. - */ - BoxRec AvailFBArea; - - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = pScrn->virtualY + 1; - /* - * Update FBFreeStart also for other memory managers, since - * we steal one line to make xf86InitFBManager work. - */ - pVia->FBFreeStart = (AvailFBArea.y2 + 1) * pVia->Bpl; - xf86InitFBManager(pScreen, &AvailFBArea); - } - + viaInitAccel(pScreen); + } miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); /*xf86SetSilkenMouse(pScreen);*/ @@ -2003,6 +2026,26 @@ } } + if (pVia->NoAccel) { + + /* + * This is only for Xv in Noaccel path, and since Xv is in some + * sense accelerated, it might be a better idea to disable it + * altogether. + */ + + BoxRec AvailFBArea; + + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = pScrn->virtualY + 1; + pVia->FBFreeStart=(AvailFBArea.y2 + 1)*pVia->Bpl; + xf86InitFBManager(pScreen, &AvailFBArea); + VIAInitLinear(pScreen); + pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart - pVia->Bpl); + } + if (pVia->shadowFB) ViaShadowFBInit(pScrn, pScreen); @@ -2027,19 +2070,20 @@ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- DPMS set up\n")); DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "- Color maps etc. set up\n")); + pVia->agpDMA = FALSE; #ifdef XF86DRI if (pVia->directRenderingEnabled) pVia->directRenderingEnabled = VIADRIFinishScreenInit(pScreen); - if (pVia->directRenderingEnabled) + if (pVia->directRenderingEnabled) { + VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering enabled\n"); - else { + pVia->agpDMA = pVia->dma2d && pVIADRI->ringBufActive; + } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "direct rendering disabled\n"); - VIAInitLinear(pScreen); } -#else - VIAInitLinear(pScreen); #endif viaInitVideo(pScreen); @@ -2120,7 +2164,7 @@ /* Enable the graphics engine. */ if (!pVia->NoAccel) - VIAInitialize2DEngine(pScrn); + viaInitialize2DEngine(pScrn); #ifdef XF86DRI VIAInitialize3DEngine(pScrn); @@ -2148,7 +2192,7 @@ DRILock(screenInfo.screens[scrnIndex], 0); #endif /* Wait Hardware Engine idle to exit graphical mode */ - VIAAccelSync(pScrn); + viaAccelSync(pScrn); #ifdef XF86DRI @@ -2160,22 +2204,19 @@ if (!pVia->IsSecondary) { /* Turn off all video activities */ - viaExitVideo(pScrn); + viaExitVideo(pScrn); VIAHideCursor(pScrn); } if (pVia->VQEnable) - ViaVQDisable(pScrn); + viaDisableVQ(pScrn); } #ifdef XF86DRI if (pVia->directRenderingEnabled) VIADRICloseScreen(pScreen); #endif - if (pVia->AccelInfoRec) { - XAADestroyInfoRec(pVia->AccelInfoRec); - pVia->AccelInfoRec = NULL; - } + viaExitAccel(pScreen); if (pVia->CursorInfoRec) { xf86DestroyCursorInfoRec(pVia->CursorInfoRec); pVia->CursorInfoRec = NULL; @@ -2276,7 +2317,7 @@ DRILock(screenInfo.screens[scrnIndex], 0); #endif - VIAAccelSync(pScrn); + viaAccelSync(pScrn); #ifdef XF86DRI if (pVia->directRenderingEnabled) @@ -2284,7 +2325,7 @@ #endif if (pVia->VQEnable) - ViaVQDisable(pScrn); + viaDisableVQ(pScrn); if (pVia->pVbe) ret = ViaVbeSetMode(pScrn, mode); Index: via_driver.h =================================================================== --- via_driver.h (revision 79) +++ via_driver.h (working copy) @@ -55,6 +55,7 @@ #include "via_bios.h" #include "via_priv.h" #include "via_swov.h" +#include "via_dmabuffer.h" #ifdef XF86DRI #define _XF86DRI_SERVER_ @@ -64,18 +65,18 @@ #include "via_dri.h" #endif +#ifdef VIA_HAVE_EXA +#include "exa.h" +#endif + #define DRIVER_NAME "via" #define VERSION_MAJOR 0 #define VERSION_MINOR 1 #define PATCHLEVEL 32 #define VIA_VERSION ((VERSION_MAJOR<<24) | (VERSION_MINOR<<16) | PATCHLEVEL) -#define VIA_MAX_ACCEL_X (2047) -#define VIA_MAX_ACCEL_Y (2047) -#define VIA_PIXMAP_CACHE_SIZE (4 * (VIA_MAX_ACCEL_X + 1) * (VIA_MAX_ACCEL_Y +1)) #define VIA_CURSOR_SIZE (4 * 1024) #define VIA_VQ_SIZE (256 * 1024) -#define VIA_CBUFFERSIZE 512 typedef struct { CARD8 SR08, SR0A, SR0F; @@ -134,15 +135,24 @@ typedef struct _twodContext { CARD32 mode; + CARD32 cmd; + CARD32 fgColor; + CARD32 bgColor; + CARD32 pattern0; + CARD32 pattern1; + CARD32 patternAddr; + unsigned srcOffset; + unsigned srcPitch; + unsigned Bpp; + unsigned bytesPPShift; + Bool clipping; + int clipX1; + int clipX2; + int clipY1; + int clipY2; } ViaTwodContext; typedef struct{ - unsigned curPos; - CARD32 buffer[VIA_CBUFFERSIZE]; - int status; -} ViaCBuffer; - -typedef struct{ /* textMode */ CARD8 *state, *pstate; /* SVGA state */ int statePage, stateSize, stateMode; @@ -155,13 +165,13 @@ VIARegRec SavedReg; xf86CursorInfoPtr CursorInfoRec; int Bpp, Bpl; - unsigned PlaneMask; Bool FirstInit; unsigned long videoRambytes; int videoRamKbytes; int FBFreeStart; int FBFreeEnd; + int driSize; int CursorStart; int VQStart; int VQEnd; @@ -179,11 +189,6 @@ unsigned char* FBBase; CARD8 MemClk; - /* Private memory pool management */ - int SWOVUsed[MEM_BLOCKS]; /* Free map for SWOV pool */ - unsigned long SWOVPool; /* Base of SWOV pool */ - unsigned long SWOVSize; /* Size of SWOV blocks */ - /* Here are all the Options */ Bool VQEnable; Bool pci_burst; @@ -212,17 +217,23 @@ /* Support for XAA acceleration */ XAAInfoRecPtr AccelInfoRec; - xRectangle Rect; - CARD32 SavedCmd; - CARD32 SavedFgColor; - CARD32 SavedBgColor; - CARD32 SavedPattern0; - CARD32 SavedPattern1; - CARD32 SavedPatternAddr; - int justSetup; ViaTwodContext td; - ViaCBuffer cBuf; - + ViaCommandBuffer cb; + int dgaMarker; + CARD32 markerOffset; + CARD32 *markerBuf; + CARD32 curMarker; + CARD32 lastMarkerRead; + Bool agpDMA; +#ifdef VIA_HAVE_EXA + ExaDriverPtr exaDriverPtr; + ExaOffscreenArea *exa_scratch; + unsigned int exa_scratch_next; + Bool useEXA; +#ifdef XF86DRI +#endif +#endif + /* BIOS Info Ptr */ VIABIOSInfoPtr pBIOSInfo; struct ViaCardIdStruct* Id; @@ -265,6 +276,10 @@ Bool IsPCI; Bool drixinerama; ViaXvMC xvmc; + int drmVerMajor; + int drmVerMinor; + int drmVerPL; + VIAMem driOffScreenMem; #endif Bool DRIIrqEnable; Bool agpEnable; @@ -329,10 +344,14 @@ void ViaCursorRestore(ScrnInfoPtr pScrn); /* In via_accel.c. */ -Bool VIAInitAccel(ScreenPtr); -void VIAInitialize2DEngine(ScrnInfoPtr); -void VIAAccelSync(ScrnInfoPtr); -void ViaVQDisable(ScrnInfoPtr pScrn); +Bool viaInitAccel(ScreenPtr); +void viaInitialize2DEngine(ScrnInfoPtr); +void viaAccelSync(ScrnInfoPtr); +void viaDisableVQ(ScrnInfoPtr); +void viaExitAccel(ScreenPtr); +void viaDGABlitRect(ScrnInfoPtr, int, int, int, int, int, int); +void viaDGAFillRect(ScrnInfoPtr, int, int, int, int, unsigned long); +void viaDGAWaitMarker(ScrnInfoPtr); /* In via_shadow.c */ void ViaShadowFBInit(ScrnInfoPtr pScrn, ScreenPtr pScreen); Index: via_dmabuffer.h =================================================================== --- via_dmabuffer.h (revision 0) +++ via_dmabuffer.h (revision 0) @@ -0,0 +1,66 @@ +/* + * Copyright (C) Thomas Hellstrom (2005) + * + * 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, sub license, + * 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 (including the + * next paragraph) 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, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#ifndef VIA_DMABUFFER_H +#define VIA_DMABUFFER_H + +typedef struct _ViaCommandBuffer { + ScrnInfoPtr pScrn; + CARD32 *buf; + CARD32 waitFlags; + unsigned pos; + unsigned bufSize; + int mode; + int header_start; + int rindex; + void (*flushFunc)(struct _ViaCommandBuffer *cb); +} ViaCommandBuffer; + +#define VIA_DMASIZE 16384 + +#define H1_ADDR(val) (((val) >> 2) | 0xF0000000) +#define WAITFLAGS(cb, flags) \ + (cb)->waitFlags |= (flags) + +#define BEGIN_RING_AGP(cb, size) \ + do { \ + if (cb->flushFunc && ((cb)->pos > ((cb)->bufSize-(size)))) { \ + cb->flushFunc(cb); \ + } \ + } while(0) + +#define OUT_RING_AGP(cb, val) do{ \ + (cb)->buf[(cb)->pos++] = (val); \ + } while(0); + +#define OUT_RING_QW_AGP(cb, val1, val2) \ + do { \ + (cb)->buf[(cb)->pos++] = (val1); \ + (cb)->buf[(cb)->pos++] = (val2); \ + } while (0) + +extern int viaSetupCBuffer(ScrnInfoPtr pScrn, ViaCommandBuffer *buf, unsigned size); +extern void viaTearDownCBuffer(ViaCommandBuffer *buf); +extern void viaFlushPCI(ViaCommandBuffer *buf); + +#endif Index: via_accel.c =================================================================== --- via_accel.c (revision 79) +++ via_accel.c (working copy) @@ -20,6 +20,8 @@ * 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. + * + * Mostly rewritten and modified for EXA support by Thomas Hellstrom 2005. */ /************************************************************************* @@ -41,742 +43,480 @@ #include "via_driver.h" #include "via_regs.h" #include "via_id.h" +#include "via_dmabuffer.h" -/* Forward declaration of functions used in the driver */ +#define VIAACCELPATTERNROP(vRop) (XAAGetPatternROP(vRop) << 24) +#define VIAACCELCOPYROP(vRop) (XAAGetCopyROP(vRop) << 24) -static void VIASetupForScreenToScreenCopy( - ScrnInfoPtr pScrn, - int xdir, - int ydir, - int rop, - unsigned planemask, - int trans_color); +/* + * Use PCI MMIO to flush the command buffer. When AGP DMA is not available. + */ -static void VIASubsequentScreenToScreenCopy( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2, - int w, - int h); +void +viaFlushPCI(ViaCommandBuffer * buf) +{ + unsigned size = buf->pos >> 1; + int i; + register CARD32 *bp = buf->buf; + unsigned loop = 0; + register unsigned offset; + register unsigned value; + VIAPtr pVia = VIAPTR(buf->pScrn); -static void VIASetupForSolidFill( - ScrnInfoPtr pScrn, - int color, - int rop, - unsigned planemask); + /* + * Not doing this wait will probably stall the processor + * for an unacceptable amount of time in VIASETREG while other high + * priority interrupts may be pending. + */ -static void VIASubsequentSolidFillRect( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h); + while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) + && (loop++ < MAXLOOP)) ; + while ((VIAGETREG(VIA_REG_STATUS) & (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY)) + && (loop++ < MAXLOOP)) ; -static void VIASetupForMono8x8PatternFill( - ScrnInfoPtr pScrn, - int pattern0, - int pattern1, - int fg, - int bg, - int rop, - unsigned planemask); + for (i = 0; i < size; ++i) { + offset = (*bp++ & 0x0FFFFFFF) << 2; + value = *bp++; + VIASETREG(offset, value); + } + buf->pos = 0; +} -static void VIASubsequentMono8x8PatternFillRect( - ScrnInfoPtr pScrn, - int patOffx, - int patOffy, - int x, - int y, - int w, - int h); +/* + * Use AGP DMA to flush the command buffer. If it fails it skips the current + * command buffer and reverts to PCI MMIO until the server is reset. + */ -static void VIASetupForColor8x8PatternFill( - ScrnInfoPtr pScrn, - int patternx, - int patterny, - int rop, - unsigned planemask, - int trans_color); +#ifdef XF86DRI +static void +viaFlushDRIEnabled(ViaCommandBuffer * cb) +{ + ScrnInfoPtr pScrn = cb->pScrn; + VIAPtr pVia = VIAPTR(pScrn); + char *tmp = (char *)cb->buf; + int tmpSize = cb->pos * sizeof(CARD32); + drm_via_cmdbuffer_t b; -static void VIASubsequentColor8x8PatternFillRect( - ScrnInfoPtr pScrn, - int patOffx, - int patOffy, - int x, - int y, - int w, - int h); + if (pVia->agpDMA) { + while (tmpSize > 0) { + b.size = (tmpSize > VIA_DMASIZE) ? VIA_DMASIZE : tmpSize; + tmpSize -= b.size; + b.buf = tmp; + tmp += b.size; + if (drmCommandWrite(pVia->drmFD, DRM_VIA_CMDBUFFER, &b, + sizeof(b))) { + ErrorF("AGP DMA command submission failed.\n"); + pVia->agpDMA = FALSE; + cb->flushFunc = viaFlushPCI; + return; + } + } + cb->pos = 0; + } else { + cb->flushFunc = viaFlushPCI; + viaFlushPCI(cb); + } +} +#endif -static void VIASetupForCPUToScreenColorExpandFill( - ScrnInfoPtr pScrn, - int fg, - int bg, - int rop, - unsigned planemask); +/* + * Initialize a command buffer. Some fields are currently not used since they + * are intended for Unichrome Pro group A video commands. + */ -static void VIASubsequentScanlineCPUToScreenColorExpandFill( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, - int skipleft); - -#if 0 /* Buggy. Temporarily disabled 2005-01-23 */ -static void VIASetupForScreenToScreenColorExpand( - ScrnInfoPtr pScrn, - int bg, - int fg, - int rop, - unsigned planemask); - -static void VIASubsequentScreenToScreenColorExpand( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, - int srcx, - int srcy, - int offset); +int +viaSetupCBuffer(ScrnInfoPtr pScrn, ViaCommandBuffer * buf, unsigned size) +{ + buf->pScrn = pScrn; + buf->bufSize = ((size == 0) ? VIA_DMASIZE : size) >> 2; + buf->buf = (CARD32 *) xcalloc(buf->bufSize, sizeof(CARD32)); + if (!buf->buf) + return BadAlloc; + buf->waitFlags = 0; + buf->pos = 0; + buf->mode = 0; + buf->header_start = 0; + buf->rindex = 0; +#ifdef XF86DRI + buf->flushFunc = viaFlushDRIEnabled; +#else + buf->flushFunc = viaFlushPCI; #endif + return Success; +} +/* + * Free resources associated with a command buffer. + */ -static void VIASetupForImageWrite( - ScrnInfoPtr pScrn, - int rop, - unsigned planemask, - int trans_color, - int bpp, - int depth); +void +viaTearDownCBuffer(ViaCommandBuffer * buf) +{ + if (buf && buf->buf) + xfree(buf->buf); + buf->buf = NULL; +} -static void VIASubsequentImageWriteRect( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, - int skipleft); +/* + * Leftover from VIAs code. + */ static void -VIASetupForSolidLine( - ScrnInfoPtr pScrn, - int color, - int rop, - unsigned int planemask); +viaInitAgp(VIAPtr pVia) +{ + VIASETREG(VIA_REG_TRANSET, 0x00100000); + VIASETREG(VIA_REG_TRANSPACE, 0x00000000); + VIASETREG(VIA_REG_TRANSPACE, 0x00333004); + VIASETREG(VIA_REG_TRANSPACE, 0x60000000); + VIASETREG(VIA_REG_TRANSPACE, 0x61000000); + VIASETREG(VIA_REG_TRANSPACE, 0x62000000); + VIASETREG(VIA_REG_TRANSPACE, 0x63000000); + VIASETREG(VIA_REG_TRANSPACE, 0x64000000); + VIASETREG(VIA_REG_TRANSPACE, 0x7D000000); -static void -VIASubsequentSolidTwoPointLine( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2, - int flags); + VIASETREG(VIA_REG_TRANSET, 0xfe020000); + VIASETREG(VIA_REG_TRANSPACE, 0x00000000); +} -static void -VIASubsequentSolidHorVertLine( - ScrnInfoPtr pScrn, - int x, - int y, - int len, - int dir); +/* + * Initialize the virtual command queue. Header 2 commands can be put + * in this queue for buffering. AFAIK it doesn't handle Header 1 + * commands, which is really a pity, since it has to be idled before + * issuing a H1 command. + */ static void -VIASetupForDashedLine( - ScrnInfoPtr pScrn, - int fg, - int bg, - int rop, - unsigned int planemask, - int length, - unsigned char *pattern); +viaEnableVQ(VIAPtr pVia) +{ + CARD32 + vqStartAddr = pVia->VQStart, + vqEndAddr = pVia->VQEnd, + vqStartL = 0x50000000 | (vqStartAddr & 0xFFFFFF), + vqEndL = 0x51000000 | (vqEndAddr & 0xFFFFFF), + vqStartEndH = 0x52000000 | ((vqStartAddr & 0xFF000000) >> 24) | + ((vqEndAddr & 0xFF000000) >> 16), + vqLen = 0x53000000 | (VIA_VQ_SIZE >> 3); -static void -VIASubsequentDashedTwoPointLine( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2, - int flags, - int phase); + VIASETREG(VIA_REG_TRANSET, 0x00fe0000); + VIASETREG(VIA_REG_TRANSPACE, 0x080003fe); + VIASETREG(VIA_REG_TRANSPACE, 0x0a00027c); + VIASETREG(VIA_REG_TRANSPACE, 0x0b000260); + VIASETREG(VIA_REG_TRANSPACE, 0x0c000274); + VIASETREG(VIA_REG_TRANSPACE, 0x0d000264); + VIASETREG(VIA_REG_TRANSPACE, 0x0e000000); + VIASETREG(VIA_REG_TRANSPACE, 0x0f000020); + VIASETREG(VIA_REG_TRANSPACE, 0x1000027e); + VIASETREG(VIA_REG_TRANSPACE, 0x110002fe); + VIASETREG(VIA_REG_TRANSPACE, 0x200f0060); -static void VIASetClippingRectangle( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2); + VIASETREG(VIA_REG_TRANSPACE, 0x00000006); + VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); + VIASETREG(VIA_REG_TRANSPACE, 0x44000000); + VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); + VIASETREG(VIA_REG_TRANSPACE, 0x46800408); -static void VIADisableClipping( ScrnInfoPtr ); + VIASETREG(VIA_REG_TRANSPACE, vqStartEndH); + VIASETREG(VIA_REG_TRANSPACE, vqStartL); + VIASETREG(VIA_REG_TRANSPACE, vqEndL); + VIASETREG(VIA_REG_TRANSPACE, vqLen); +} +/* + * Disable the virtual command queue. + */ + void -VIAInitialize2DEngine(ScrnInfoPtr pScrn) +viaDisableVQ(ScrnInfoPtr pScrn) { - VIAPtr pVia = VIAPTR(pScrn); - CARD32 dwVQStartAddr, dwVQEndAddr; - CARD32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH; - CARD32 dwGEMode; - ViaTwodContext *tdc = &pVia->td; + VIAPtr pVia = VIAPTR(pScrn); + VIASETREG(VIA_REG_TRANSET, 0x00fe0000); + VIASETREG(VIA_REG_TRANSPACE, 0x00000004); + VIASETREG(VIA_REG_TRANSPACE, 0x40008c0f); + VIASETREG(VIA_REG_TRANSPACE, 0x44000000); + VIASETREG(VIA_REG_TRANSPACE, 0x45080c04); + VIASETREG(VIA_REG_TRANSPACE, 0x46800408); +} - /* init 2D engine regs to reset 2D engine */ - VIASETREG(0x04, 0x0); - VIASETREG(0x08, 0x0); - VIASETREG(0x0c, 0x0); - VIASETREG(0x10, 0x0); - VIASETREG(0x14, 0x0); - VIASETREG(0x18, 0x0); - VIASETREG(0x1c, 0x0); - VIASETREG(0x20, 0x0); - VIASETREG(0x24, 0x0); - VIASETREG(0x28, 0x0); - VIASETREG(0x2c, 0x0); - VIASETREG(0x30, 0x0); - VIASETREG(0x34, 0x0); - VIASETREG(0x38, 0x0); - VIASETREG(0x3c, 0x0); - VIASETREG(0x40, 0x0); +/* + * Update our 2D state (TwoDContext) with a new mode. + */ - /* Init AGP and VQ regs */ - VIASETREG(0x43c, 0x00100000); - VIASETREG(0x440, 0x00000000); - VIASETREG(0x440, 0x00333004); - VIASETREG(0x440, 0x60000000); - VIASETREG(0x440, 0x61000000); - VIASETREG(0x440, 0x62000000); - VIASETREG(0x440, 0x63000000); - VIASETREG(0x440, 0x64000000); - VIASETREG(0x440, 0x7D000000); - - VIASETREG(0x43c, 0xfe020000); - VIASETREG(0x440, 0x00000000); - - if (pVia->VQStart != 0) { - /* Enable VQ */ - dwVQStartAddr = pVia->VQStart; - dwVQEndAddr = pVia->VQEnd; - dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF); - dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF); - dwVQStartEndH = 0x52000000 | ((dwVQStartAddr & 0xFF000000) >> 24) | - ((dwVQEndAddr & 0xFF000000) >> 16); - dwVQLen = 0x53000000 | (VIA_VQ_SIZE >> 3); - - VIASETREG(0x43c, 0x00fe0000); - VIASETREG(0x440, 0x080003fe); - VIASETREG(0x440, 0x0a00027c); - VIASETREG(0x440, 0x0b000260); - VIASETREG(0x440, 0x0c000274); - VIASETREG(0x440, 0x0d000264); - VIASETREG(0x440, 0x0e000000); - VIASETREG(0x440, 0x0f000020); - VIASETREG(0x440, 0x1000027e); - VIASETREG(0x440, 0x110002fe); - VIASETREG(0x440, 0x200f0060); - - VIASETREG(0x440, 0x00000006); - VIASETREG(0x440, 0x40008c0f); - VIASETREG(0x440, 0x44000000); - VIASETREG(0x440, 0x45080c04); - VIASETREG(0x440, 0x46800408); - - VIASETREG(0x440, dwVQStartEndH); - VIASETREG(0x440, dwVQStartL); - VIASETREG(0x440, dwVQEndL); - VIASETREG(0x440, dwVQLen); - } - else { - /* Diable VQ */ - VIASETREG(0x43c, 0x00fe0000); - VIASETREG(0x440, 0x00000004); - VIASETREG(0x440, 0x40008c0f); - VIASETREG(0x440, 0x44000000); - VIASETREG(0x440, 0x45080c04); - VIASETREG(0x440, 0x46800408); - } - - dwGEMode = 0; - - switch (pScrn->bitsPerPixel) { +static Bool +viaAccelSetMode(int bpp, ViaTwodContext * tdc) +{ + switch (bpp) { case 16: - dwGEMode |= VIA_GEM_16bpp; - break; + tdc->mode = VIA_GEM_16bpp; + tdc->bytesPPShift = 1; + return TRUE; case 32: - dwGEMode |= VIA_GEM_32bpp; - break; + tdc->mode = VIA_GEM_32bpp; + tdc->bytesPPShift = 2; + return TRUE; + case 8: + tdc->mode = VIA_GEM_8bpp; + tdc->bytesPPShift = 0; + return TRUE; default: - dwGEMode |= VIA_GEM_8bpp; - break; + tdc->bytesPPShift = 0; + return FALSE; } - - /* Set BPP and Pitch */ - tdc->mode = dwGEMode; } +/* + * Initialize the 2D engine and set the 2D context mode to the + * current screen depth. Also enable the virtual queue. + */ -#define CLEAR_CBUFFER(buf, pVia) \ - (buf)->curPos = 0; \ - (pVia)->justSetup = 1; - -#define COND_CLEAR_CBUFFER(buf, pVia) \ - if ((pVia)->justSetup == 1) { \ - (pVia)->justSetup = 0; \ - } else { \ - (buf)->curPos = 0; \ - } - -#define CBUFFER(buf,offset,value) \ - (buf)->buffer[(buf)->curPos++] = ((offset) >> 2) | 0xF0000000; \ - (buf)->buffer[(buf)->curPos++] = (value); \ - - -static void dispatchCBuffer(VIAPtr pVia, ViaCBuffer *buf) +void +viaInitialize2DEngine(ScrnInfoPtr pScrn) { - unsigned size = buf->curPos >> 1; + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; int i; - register CARD32 *bp = buf->buffer; - unsigned loop = 0; - register unsigned offset; - register unsigned value; - - /* - * Not doing this wait will probably stall the processor - * for an unacceptable amount of time in VIASETREG while other high - * priority interrupts may be pending. + + /* + * init 2D engine regs to reset 2D engine */ - - mem_barrier(); - while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP)); - while ((VIAGETREG(VIA_REG_STATUS) & - (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY )) && - (loop++ < MAXLOOP)); - - for(i=0; ibuffer); - b.size = buf->curPos*sizeof(CARD32); + viaInitAgp(pVia); - if (pVia->directRenderingEnabled && pVia->agpEnable && pVia->dma2d) { - VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; - if (pVIADRI->ringBufActive) { - if (drmCommandWrite(pVia->drmFD,DRM_VIA_CMDBUFFER,&b,sizeof(b))) - dispatchCBuffer(pVia,buf); /* No success using AGP. Try PCI instead. */ - return; - } + if (pVia->VQStart != 0) { + viaEnableVQ(pVia); + } else { + viaDisableVQ(pScrn); } -#endif - /* - * No AGP ringbuffer or no DRI. - */ - dispatchCBuffer(pVia,buf); + viaAccelSetMode(pScrn->bitsPerPixel, tdc); } +/* + * Wait for acceleration engines idle. An expensive way to sync. + */ -/* Acceleration init function, sets up pointers to our accelerated functions */ -Bool -VIAInitAccel(ScreenPtr pScreen) +void +viaAccelSync(ScrnInfoPtr pScrn) { - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - VIAPtr pVia = VIAPTR(pScrn); - XAAInfoRecPtr xaaptr; - BoxRec AvailFBArea; - unsigned long cacheEnd; - unsigned long cacheEndTmp; - + VIAPtr pVia = VIAPTR(pScrn); + int loop = 0; - pVia->VQStart = 0; - if (((pVia->FBFreeEnd - pVia->FBFreeStart) >= VIA_VQ_SIZE) && - pVia->VQEnable) { - /* Reserved space for VQ */ - pVia->VQStart = pVia->FBFreeEnd - VIA_VQ_SIZE; - pVia->VQEnd = pVia->VQStart + VIA_VQ_SIZE - 1; - pVia->FBFreeEnd -= VIA_VQ_SIZE; - } - if (pVia->hwcursor) { - pVia->FBFreeEnd -= VIA_CURSOR_SIZE; - pVia->CursorStart = pVia->FBFreeEnd; - } + mem_barrier(); - VIAInitialize2DEngine(pScrn); + while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) + && (loop++ < MAXLOOP)) ; - if (pScrn->depth == 8) { - pVia->PlaneMask = 0xFF; - } - else if (pScrn->depth == 15) { - pVia->PlaneMask = 0x7FFF; - } - else if (pScrn->depth == 16) { - pVia->PlaneMask = 0xFFFF; - } - else if (pScrn->depth == 24) { - pVia->PlaneMask = 0xFFFFFF; - } + while ((VIAGETREG(VIA_REG_STATUS) & + (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && + (loop++ < MAXLOOP)) ; +} - /* General acceleration flags */ - if (!(xaaptr = pVia->AccelInfoRec = XAACreateInfoRec())) - return FALSE; +/* + * Set 2D state clipping on. + */ - xaaptr->Flags = PIXMAP_CACHE | - OFFSCREEN_PIXMAPS | - LINEAR_FRAMEBUFFER | - MICROSOFT_ZERO_LINE_BIAS | - 0; +static void +viaSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; - if (pScrn->bitsPerPixel == 8) - xaaptr->CachePixelGranularity = 128; + tdc->clipping = TRUE; + tdc->clipX1 = x1; + tdc->clipY1 = y1; + tdc->clipX2 = x2; + tdc->clipY2 = y2; +} - /* Clipping */ - xaaptr->SetClippingRectangle = VIASetClippingRectangle; - xaaptr->DisableClipping = VIADisableClipping; - xaaptr->ClippingFlags = HARDWARE_CLIP_SOLID_FILL | - HARDWARE_CLIP_SOLID_LINE | - HARDWARE_CLIP_DASHED_LINE | - HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | - HARDWARE_CLIP_MONO_8x8_FILL | - HARDWARE_CLIP_COLOR_8x8_FILL | - HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND | - 0; +/* + * Set 2D state clipping off. + */ - xaaptr->Sync = VIAAccelSync; +static void +viaDisableClipping(ScrnInfoPtr pScrn) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; - /* ScreenToScreen copies */ - xaaptr->SetupForScreenToScreenCopy = VIASetupForScreenToScreenCopy; - xaaptr->SubsequentScreenToScreenCopy = VIASubsequentScreenToScreenCopy; - xaaptr->ScreenToScreenCopyFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + tdc->clipping = FALSE; +} - /* Solid filled rectangles */ - xaaptr->SetupForSolidFill = VIASetupForSolidFill; - xaaptr->SubsequentSolidFillRect = VIASubsequentSolidFillRect; - xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; +/* + * Emit clipping borders to the command buffer and update the 2D context + * current command with clipping info. + */ - /* Mono 8x8 pattern fills */ - xaaptr->SetupForMono8x8PatternFill = VIASetupForMono8x8PatternFill; - xaaptr->SubsequentMono8x8PatternFillRect = - VIASubsequentMono8x8PatternFillRect; - xaaptr->Mono8x8PatternFillFlags = NO_PLANEMASK | - HARDWARE_PATTERN_PROGRAMMED_BITS | - HARDWARE_PATTERN_PROGRAMMED_ORIGIN | - BIT_ORDER_IN_BYTE_MSBFIRST | - 0; +static int +viaAccelClippingHelper(ViaCommandBuffer * cb, int refY, ViaTwodContext * tdc) +{ + if (tdc->clipping) { + refY = (refY < tdc->clipY1) ? refY : tdc->clipY1; + tdc->cmd |= VIA_GEC_CLIP_ENABLE; + BEGIN_RING_AGP(cb, 4); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_CLIPTL), + ((tdc->clipY1 - refY) << 16) | tdc->clipX1); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_CLIPBR), + ((tdc->clipY2 - refY) << 16) | tdc->clipX2); + } else { + tdc->cmd &= ~VIA_GEC_CLIP_ENABLE; + } + return refY; - /* Color 8x8 pattern fills */ - xaaptr->SetupForColor8x8PatternFill = VIASetupForColor8x8PatternFill; - xaaptr->SubsequentColor8x8PatternFillRect = - VIASubsequentColor8x8PatternFillRect; - xaaptr->Color8x8PatternFillFlags = NO_PLANEMASK | - NO_TRANSPARENCY | - HARDWARE_PATTERN_PROGRAMMED_BITS | - HARDWARE_PATTERN_PROGRAMMED_ORIGIN | - 0; +} -#if 0 /* Buggy. Temporarily disabled 2005-01-23 */ +/* + * Emit a solid blit operation to the command buffer. + */ - /* Screen to Screen color expansion. */ - xaaptr->SetupForScreenToScreenColorExpandFill = - VIASetupForScreenToScreenColorExpand; - xaaptr->SubsequentScreenToScreenColorExpandFill = - VIASubsequentScreenToScreenColorExpand; - xaaptr->ScreenToScreenColorExpandFillFlags = NO_PLANEMASK | - BIT_ORDER_IN_BYTE_MSBFIRST | - ROP_NEEDS_SOURCE | - 0; -#endif +static void +viaAccelSolidHelper(ViaCommandBuffer * cb, int x, int y, int w, int h, + unsigned fbBase, CARD32 mode, unsigned pitch, CARD32 fg, CARD32 cmd) +{ + BEGIN_RING_AGP(cb, 14); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GEMODE), mode); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTBASE), fbBase >> 3); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_PITCH), VIA_PITCH_ENABLE | + (pitch >> 3) << 16); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTPOS), (y << 16) | x); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DIMENSION), + ((h - 1) << 16) | (w - 1)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_FGCOLOR), fg); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GECMD), cmd); +} - /* Solid lines */ - xaaptr->SetupForSolidLine = VIASetupForSolidLine; - xaaptr->SubsequentSolidTwoPointLine = VIASubsequentSolidTwoPointLine; - xaaptr->SubsequentSolidHorVertLine = VIASubsequentSolidHorVertLine; - xaaptr->SolidBresenhamLineErrorTermBits = 14; - xaaptr->SolidLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; +/* + * Emit transparency state and color to the command buffer. + */ - /* dashed line */ - xaaptr->SetupForDashedLine = VIASetupForDashedLine; - xaaptr->SubsequentDashedTwoPointLine = VIASubsequentDashedTwoPointLine; - xaaptr->DashPatternMaxLength = 8; - xaaptr->DashedLineFlags = NO_PLANEMASK | - ROP_NEEDS_SOURCE | - LINE_PATTERN_POWER_OF_2_ONLY | - LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | - 0; +static void +viaAccelTransparentHelper(ViaCommandBuffer * cb, CARD32 keyControl, + CARD32 transColor) +{ + BEGIN_RING_AGP(cb, 4); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_KEYCONTROL), keyControl); + if (keyControl) { + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_SRCCOLORKEY), transColor); + } +} - /* CPU to Screen color expansion */ - xaaptr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | - CPU_TRANSFER_PAD_DWORD | - SCANLINE_PAD_DWORD | - BIT_ORDER_IN_BYTE_MSBFIRST | - LEFT_EDGE_CLIPPING | - ROP_NEEDS_SOURCE | - 0; +/* + * Emit a copy blit operation to the command buffer. + */ - xaaptr->SetupForScanlineCPUToScreenColorExpandFill = - VIASetupForCPUToScreenColorExpandFill; - xaaptr->SubsequentScanlineCPUToScreenColorExpandFill = - VIASubsequentScanlineCPUToScreenColorExpandFill; - xaaptr->ColorExpandBase = pVia->BltBase; - xaaptr->ColorExpandRange = VIA_MMIO_BLTSIZE; +static void +viaAccelCopyHelper(ViaCommandBuffer * cb, int xs, int ys, int xd, int yd, + int w, int h, unsigned srcFbBase, unsigned dstFbBase, CARD32 mode, + unsigned srcPitch, unsigned dstPitch, CARD32 cmd) +{ + if (cmd & VIA_GEC_DECY) { + ys += h - 1; + yd += h - 1; + } - /* ImageWrite */ - xaaptr->ImageWriteFlags = NO_PLANEMASK | - CPU_TRANSFER_PAD_DWORD | - SCANLINE_PAD_DWORD | - BIT_ORDER_IN_BYTE_MSBFIRST | - LEFT_EDGE_CLIPPING | - ROP_NEEDS_SOURCE | - SYNC_AFTER_IMAGE_WRITE | - 0; - - /* - * CLE266 has fast direct processor access to the framebuffer. - * Therefore, disable the PCI GXcopy. - */ - - if (pVia->Chipset == VIA_CLE266) - xaaptr->ImageWriteFlags |= NO_GXCOPY; + if (cmd & VIA_GEC_DECX) { + xs += w - 1; + xd += w - 1; + } - xaaptr->SetupForImageWrite = VIASetupForImageWrite; - xaaptr->SubsequentImageWriteRect = VIASubsequentImageWriteRect; - xaaptr->ImageWriteBase = pVia->BltBase; - xaaptr->ImageWriteRange = VIA_MMIO_BLTSIZE; - - /* We reserve space for pixel cache */ - - cacheEnd = pVia->FBFreeEnd / pVia->Bpl; - cacheEndTmp = (pVia->FBFreeStart + VIA_PIXMAP_CACHE_SIZE + pVia->Bpl-1) - / pVia->Bpl; - - /* - * Use only requested pixmap size if it is less than available - * offscreen memory. - */ - - if(cacheEnd > cacheEndTmp) - cacheEnd = cacheEndTmp; - /* - * Clip to the blitter limit - */ - - if (cacheEnd > VIA_MAX_ACCEL_Y) - cacheEnd = VIA_MAX_ACCEL_Y; - - pVia->FBFreeStart = (cacheEnd + 1) *pVia->Bpl; - - /* - * Finally, we set up the video memory space available to the pixmap - * cache - */ - - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = cacheEnd; - - xf86InitFBManager(pScreen, &AvailFBArea); - DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d lines for offscreen memory.\n", - AvailFBArea.y2 - pScrn->virtualY )); - - pVia->justSetup = 0; - return XAAInit(pScreen, xaaptr); + BEGIN_RING_AGP(cb, 16); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GEMODE), mode); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_SRCBASE), srcFbBase >> 3); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTBASE), dstFbBase >> 3); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_PITCH), VIA_PITCH_ENABLE | + ((dstPitch >> 3) << 16) | (srcPitch >> 3)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_SRCPOS), (ys << 16) | xs); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTPOS), (yd << 16) | xd); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DIMENSION), + ((h - 1) << 16) | (w - 1)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GECMD), cmd); } /* - * The sync function for the GE + * XAA functions. Note that the 2047 line blitter limit has been worked around by adding + * min(y1, y2, clipping y) * stride to the offset (which is recommended by VIA docs). + * The y values (including clipping) must be subtracted accordingly. */ -void -VIAAccelSync(ScrnInfoPtr pScrn) -{ - VIAPtr pVia = VIAPTR(pScrn); - int loop = 0; - - mem_barrier(); - - while (!(VIAGETREG(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP)) - ; - - while ((VIAGETREG(VIA_REG_STATUS) & - (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) && - (loop++ < MAXLOOP)) - ; -} -/* These are the ScreenToScreen bitblt functions. We support all ROPs, all - * directions. - * - */ - static void -VIASetupForScreenToScreenCopy( - ScrnInfoPtr pScrn, - int xdir, - int ydir, - int rop, - unsigned planemask, - int trans_color) +viaSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, + unsigned planemask, int trans_color) { - VIAPtr pVia = VIAPTR(pScrn); - int cmd; - ViaCBuffer *buf = &pVia->cBuf; + VIAPtr pVia = VIAPTR(pScrn); + CARD32 cmd; + ViaCommandBuffer *cb = &pVia->cb; ViaTwodContext *tdc = &pVia->td; - cmd = VIA_GEC_BLT | (XAAGetCopyROP(rop) << 24); + cmd = VIA_GEC_BLT | VIAACCELCOPYROP(rop); if (xdir < 0) - cmd |= VIA_GEC_DECX; + cmd |= VIA_GEC_DECX; if (ydir < 0) - cmd |= VIA_GEC_DECY; + cmd |= VIA_GEC_DECY; - pVia->SavedCmd = cmd; - - CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - if (trans_color != -1) { - /* Transparent Bitblt */ - CBUFFER(buf,VIA_REG_SRCCOLORKEY, trans_color); - CBUFFER(buf,VIA_REG_KEYCONTROL, 0x4000); - } - else { - /* Disable Transparent Bitblt */ - CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0); - } + tdc->cmd = cmd; + viaAccelTransparentHelper(cb, (trans_color != -1) ? 0x4000 : 0x0000, + trans_color); } static void -VIASubsequentScreenToScreenCopy( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2, - int w, - int h) +viaSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int w, int h) { VIAPtr pVia = VIAPTR(pScrn); - ViaCBuffer *buf = &pVia->cBuf; + ViaCommandBuffer *cb = &pVia->cb; ViaTwodContext *tdc = &pVia->td; - CARD32 srcBase, dstBase; + int sub; if (!w || !h) - return; + return; - srcBase = y1*pVia->Bpl + x1*pVia->Bpp; - dstBase = y2*pVia->Bpl + x2*pVia->Bpp; - - x1 = (srcBase & 31); - x2 = (dstBase & 31); - - switch (pScrn->bitsPerPixel) { - case 16: - x1 >>= 1; - x2 >>= 1; - break; - case 32: - x1 >>= 2; - x2 >>= 2; - break; - default: - break; - } - - y1 = 0; - y2 = 0; - - if (pVia->SavedCmd & VIA_GEC_DECX) { - x1 += (w - 1); - x2 += (w - 1); - } - - if (pVia->SavedCmd & VIA_GEC_DECY) { - y1 += (h - 1); - y2 += (h - 1); - } - - COND_CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode ); - /* Set Src and Dst base address and pitch, pitch is qword */ - CBUFFER(buf,VIA_REG_SRCBASE, (srcBase & ~31) >> 3); - CBUFFER(buf,VIA_REG_DSTBASE, (dstBase & ~31) >> 3); - CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | - (pVia->Bpl >> 3) | ((pVia->Bpl >> 3) << 16)); - CBUFFER(buf,VIA_REG_SRCPOS, ((y1 << 16) | x1)); - CBUFFER(buf,VIA_REG_DSTPOS, ((y2 << 16) | x2)); - CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); - CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); - dispatchCBufferAGP(pVia, buf); + sub = viaAccelClippingHelper(cb, y2, tdc); + viaAccelCopyHelper(cb, x1, 0, x2, y2 - sub, w, h, + pScrn->fbOffset + pVia->Bpl * y1, pScrn->fbOffset + pVia->Bpl * sub, + tdc->mode, pVia->Bpl, pVia->Bpl, tdc->cmd); + cb->flushFunc(cb); } - /* * SetupForSolidFill is also called to set up for lines. */ static void -VIASetupForSolidFill( - ScrnInfoPtr pScrn, - int color, - int rop, +viaSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, unsigned planemask) { - VIAPtr pVia = VIAPTR(pScrn); - int cmd; + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; - cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | - (XAAGetPatternROP(rop) << 24); - - pVia->SavedCmd = cmd; - pVia->SavedFgColor = color; + tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop); + tdc->fgColor = color; } - static void -VIASubsequentSolidFillRect( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h) +viaSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) { VIAPtr pVia = VIAPTR(pScrn); - ViaCBuffer *buf = &pVia->cBuf; + ViaCommandBuffer *cb = &pVia->cb; ViaTwodContext *tdc = &pVia->td; + int sub; if (!w || !h) - return; + return; - COND_CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - /* Set Src and Dst base address and pitch, pitch is qword */ - CBUFFER(buf,VIA_REG_SRCBASE, 0x0); - CBUFFER(buf,VIA_REG_DSTBASE, 0x0); - CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | - ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | - (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); - - CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); - CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); - CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); - CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); - dispatchCBufferAGP(pVia, buf); - + sub = viaAccelClippingHelper(cb, y, tdc); + viaAccelSolidHelper(cb, x, y - sub, w, h, + pScrn->fbOffset + pVia->Bpl * sub, tdc->mode, pVia->Bpl, tdc->fgColor, + tdc->cmd); + cb->flushFunc(cb); } - /* + * Original VIA comment: * The meaning of the two pattern paremeters to Setup & Subsequent for * Mono8x8Patterns varies depending on the flag bits. We specify * HW_PROGRAMMED_BITS, which means our hardware can handle 8x8 patterns @@ -789,639 +529,1006 @@ */ static void -VIASetupForMono8x8PatternFill( - ScrnInfoPtr pScrn, - int pattern0, - int pattern1, - int fg, - int bg, - int rop, - unsigned planemask) +viaSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattern0, int pattern1, + int fg, int bg, int rop, unsigned planemask) { - VIAPtr pVia = VIAPTR(pScrn); - int cmd; + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + ViaTwodContext *tdc = &pVia->td; cmd = VIA_GEC_BLT | VIA_GEC_PAT_REG | VIA_GEC_PAT_MONO | - (XAAGetPatternROP(rop) << 24); + VIAACCELPATTERNROP(rop); if (bg == -1) { - /* transparent mono pattern */ - cmd |= VIA_GEC_MPAT_TRANS; + cmd |= VIA_GEC_MPAT_TRANS; } - pVia->SavedCmd = cmd; - pVia->SavedFgColor = fg; - pVia->SavedBgColor = bg; - pVia->SavedPattern0 = pattern0; - pVia->SavedPattern1 = pattern1; + tdc->cmd = cmd; + tdc->fgColor = fg; + tdc->bgColor = bg; + tdc->pattern0 = pattern0; + tdc->pattern1 = pattern1; } - static void -VIASubsequentMono8x8PatternFillRect( - ScrnInfoPtr pScrn, - int patOffx, - int patOffy, - int x, - int y, - int w, - int h) +viaSubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patOffx, + int patOffy, int x, int y, int w, int h) { - VIAPtr pVia = VIAPTR(pScrn); - CARD32 dwPatOffset; - ViaCBuffer *buf = &pVia->cBuf; + VIAPtr pVia = VIAPTR(pScrn); + CARD32 patOffset; + ViaCommandBuffer *cb = &pVia->cb; ViaTwodContext *tdc = &pVia->td; + CARD32 dstBase; + int sub; if (!w || !h) - return; + return; - dwPatOffset = ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26); + patOffset = ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26); + sub = viaAccelClippingHelper(cb, y, tdc); + dstBase = pScrn->fbOffset + sub * pVia->Bpl; - COND_CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - /* Set Src and Dst base address and pitch, pitch is qword */ - CBUFFER(buf,VIA_REG_SRCBASE, 0x0); - CBUFFER(buf,VIA_REG_DSTBASE, 0x0); - CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | - ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | - (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + BEGIN_RING_AGP(cb, 22); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GEMODE), tdc->mode); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTBASE), dstBase >> 3); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_PITCH), VIA_PITCH_ENABLE | + ((pVia->Bpl >> 3) << 16)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTPOS), ((y - sub) << 16) | x); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DIMENSION), + (((h - 1) << 16) | (w - 1))); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_PATADDR), patOffset); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_FGCOLOR), tdc->fgColor); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_BGCOLOR), tdc->bgColor); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_MONOPAT0), tdc->pattern0); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_MONOPAT1), tdc->pattern1); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GECMD), tdc->cmd); + cb->flushFunc(cb); +} - CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); - CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); - CBUFFER(buf,VIA_REG_PATADDR, dwPatOffset); - CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); - CBUFFER(buf,VIA_REG_BGCOLOR, pVia->SavedBgColor); - CBUFFER(buf,VIA_REG_MONOPAT0, pVia->SavedPattern0); - CBUFFER(buf,VIA_REG_MONOPAT1, pVia->SavedPattern1); - CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); - dispatchCBufferAGP(pVia, buf); +static void +viaSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patternx, int patterny, + int rop, unsigned planemask, int trans_color) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + tdc->cmd = VIA_GEC_BLT | VIAACCELPATTERNROP(rop); + tdc->patternAddr = (patternx * pVia->Bpp + patterny * pVia->Bpl); } static void -VIASetupForColor8x8PatternFill( - ScrnInfoPtr pScrn, - int patternx, - int patterny, - int rop, - unsigned planemask, - int trans_color) +viaSubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patOffx, + int patOffy, int x, int y, int w, int h) { - VIAPtr pVia = VIAPTR(pScrn); - int cmd; + VIAPtr pVia = VIAPTR(pScrn); + CARD32 patAddr; + ViaCommandBuffer *cb = &pVia->cb; + ViaTwodContext *tdc = &pVia->td; + CARD32 dstBase; + int sub; - cmd = VIA_GEC_BLT | (XAAGetPatternROP(rop) << 24); + if (!w || !h) + return; - pVia->SavedCmd = cmd; - pVia->SavedPatternAddr = (patternx * pVia->Bpp + patterny * pVia->Bpl); + patAddr = (tdc->patternAddr >> 3) | + ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26); + sub = viaAccelClippingHelper(cb, y, tdc); + dstBase = pScrn->fbOffset + sub * pVia->Bpl; + + BEGIN_RING_AGP(cb, 14); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GEMODE), tdc->mode); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTBASE), dstBase >> 3); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_PITCH), VIA_PITCH_ENABLE | + ((pVia->Bpl >> 3) << 16)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTPOS), ((y - sub) << 16) | x); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DIMENSION), + (((h - 1) << 16) | (w - 1))); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_PATADDR), patAddr); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GECMD), tdc->cmd); + cb->flushFunc(cb); } +/* + * CPU to screen functions cannot use AGP due to complicated syncing. Therefore the + * command buffer is flushed before new command emissions and viaFluchPCI is called + * explicitly instead of cb->flushFunc() at the end of each CPU to screen function. + * Should the buffer get completely filled again by a CPU to screen command emission, + * a horrible error will occur. + */ static void -VIASubsequentColor8x8PatternFillRect( - ScrnInfoPtr pScrn, - int patOffx, - int patOffy, - int x, - int y, - int w, - int h) +viaSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, + int rop, unsigned planemask) { - VIAPtr pVia = VIAPTR(pScrn); - CARD32 dwPatAddr; - ViaCBuffer *buf = &pVia->cBuf; + VIAPtr pVia = VIAPTR(pScrn); + int cmd; + ViaCommandBuffer *cb = &pVia->cb; ViaTwodContext *tdc = &pVia->td; - if (!w || !h) - return; + cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIA_GEC_SRC_MONO | + VIAACCELCOPYROP(rop); - dwPatAddr = (pVia->SavedPatternAddr >> 3) | - ((patOffy & 0x7) << 29) | ((patOffx & 0x7) << 26); + if (bg == -1) { + cmd |= VIA_GEC_MSRC_TRANS; + } - /* Set Src and Dst base address and pitch, pitch is qword */ - COND_CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - CBUFFER(buf,VIA_REG_SRCBASE, 0x0); - CBUFFER(buf,VIA_REG_DSTBASE, 0x0); - CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | - ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | - (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + tdc->cmd = cmd; + tdc->fgColor = fg; + tdc->bgColor = bg; - CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); - CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); - CBUFFER(buf,VIA_REG_PATADDR, dwPatAddr); - CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); - dispatchCBufferAGP(pVia, buf); + cb->flushFunc(cb); + viaAccelTransparentHelper(cb, 0x0, 0x0); } static void -VIASetupForCPUToScreenColorExpandFill( - ScrnInfoPtr pScrn, - int fg, - int bg, - int rop, - unsigned planemask) +viaSubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, + int y, int w, int h, int skipleft) { - VIAPtr pVia = VIAPTR(pScrn); - int cmd; - ViaCBuffer *buf = &pVia->cBuf; + VIAPtr pVia = VIAPTR(pScrn); + ViaCommandBuffer *cb = &pVia->cb; ViaTwodContext *tdc = &pVia->td; + int sub; - cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIA_GEC_SRC_MONO | - (XAAGetCopyROP(rop) << 24); - - if (bg == -1) { - cmd |= VIA_GEC_MSRC_TRANS; + if (skipleft) { + viaSetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), + (y + h - 1)); } - pVia->SavedCmd = cmd; - pVia->SavedFgColor = fg; - pVia->SavedBgColor = bg; + sub = viaAccelClippingHelper(cb, y, tdc); + BEGIN_RING_AGP(cb, 4); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_BGCOLOR), tdc->bgColor); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_FGCOLOR), tdc->fgColor); + viaAccelCopyHelper(cb, 0, 0, x, y - sub, w, h, 0, + pScrn->fbOffset + sub * pVia->Bpl, tdc->mode, pVia->Bpl, pVia->Bpl, + tdc->cmd); - /* Disable Transparent Bitblt */ - CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0); + viaFlushPCI(cb); + viaDisableClipping(pScrn); } +static void +viaSetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned planemask, + int trans_color, int bpp, int depth) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaCommandBuffer *cb = &pVia->cb; + ViaTwodContext *tdc = &pVia->td; + tdc->cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | VIAACCELCOPYROP(rop); + cb->flushFunc(cb); + viaAccelTransparentHelper(cb, (trans_color != -1) ? 0x4000 : 0x0000, + trans_color); +} + static void -VIASubsequentScanlineCPUToScreenColorExpandFill( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, +viaSubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, int skipleft) { VIAPtr pVia = VIAPTR(pScrn); - ViaCBuffer *buf = &pVia->cBuf; + ViaCommandBuffer *cb = &pVia->cb; ViaTwodContext *tdc = &pVia->td; + int sub; - /* XAA will be sending bitmap data next. */ - /* We should probably wait for empty/idle here. */ - if (skipleft) { - VIASetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), (y + h -1)); + viaSetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), + (y + h - 1)); } - /* Set Src and Dst base address and pitch, pitch is qword */ - COND_CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - CBUFFER(buf,VIA_REG_SRCBASE, 0x0); - CBUFFER(buf,VIA_REG_DSTBASE, 0x0); - CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | - ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | - (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + sub = viaAccelClippingHelper(cb, y, tdc); + viaAccelCopyHelper(cb, 0, 0, x, y - sub, w, h, 0, + pScrn->fbOffset + pVia->Bpl * sub, tdc->mode, pVia->Bpl, pVia->Bpl, + tdc->cmd); - CBUFFER(buf,VIA_REG_SRCPOS, 0); - CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); - CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); - CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); - CBUFFER(buf,VIA_REG_BGCOLOR, pVia->SavedBgColor); - CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); - dispatchCBuffer(pVia, buf); - + viaFlushPCI(cb); + viaDisableClipping(pScrn); } -#if 0 /* Buggy. Temporarily disabled 2005-01-23 */ static void -VIASetupForScreenToScreenColorExpand( - ScrnInfoPtr pScrn, - int fg, - int bg, - int rop, +viaSetupForSolidLine(ScrnInfoPtr pScrn, int color, int rop, unsigned int planemask) { - VIAPtr pVia = VIAPTR(pScrn); - int cmd; - ViaCBuffer *buf = &pVia->cBuf; + VIAPtr pVia = VIAPTR(pScrn); + ViaCommandBuffer *cb = &pVia->cb; + ViaTwodContext *tdc = &pVia->td; - cmd = VIA_GEC_BLT | VIA_GEC_SRC_MONO | (XAAGetCopyROP(rop) << 24); + tdc->cmd = VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop); + tdc->fgColor = color; - if (bg == -1) { - cmd |= VIA_GEC_MSRC_TRANS; + BEGIN_RING_AGP(cb, 6); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GEMODE), tdc->mode); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_MONOPAT0), 0xFF); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_FGCOLOR), tdc->fgColor); +} + +static void +viaSubsequentSolidTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, + int x2, int y2, int flags) +{ + VIAPtr pVia = VIAPTR(pScrn); + int dx, dy, cmd, tmp, error = 1; + ViaCommandBuffer *cb = &pVia->cb; + ViaTwodContext *tdc = &pVia->td; + CARD32 dstBase; + int sub; + + cmd = tdc->cmd | VIA_GEC_LINE; + + dx = x2 - x1; + if (dx < 0) { + dx = -dx; + cmd |= VIA_GEC_DECX; /* line will be drawn from right */ + error = 0; } - pVia->SavedCmd = cmd; - pVia->SavedFgColor = fg; - pVia->SavedBgColor = bg; + dy = y2 - y1; + if (dy < 0) { + dy = -dy; + cmd |= VIA_GEC_DECY; /* line will be drawn from bottom */ + } - /* Disable Transparent Bitblt */ - CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0); + if (dy > dx) { + tmp = dy; + dy = dx; + dx = tmp; /* Swap 'dx' and 'dy' */ + cmd |= VIA_GEC_Y_MAJOR; /* Y major line */ + } + + if (flags & OMIT_LAST) { + cmd |= VIA_GEC_LASTPIXEL_OFF; + } + + sub = viaAccelClippingHelper(cb, (y1 < y2) ? y1 : y2, tdc); + + dstBase = pScrn->fbOffset + sub * pVia->Bpl; + y1 -= sub; + y2 -= sub; + + BEGIN_RING_AGP(cb, 14); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTBASE), dstBase >> 3); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_PITCH), VIA_PITCH_ENABLE | + ((pVia->Bpl >> 3) << 16)); + + /* + * major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1) + * K1 = 2*dmin K2 = 2*(dmin - dmax) + * Error Term = (StartXflushFunc(cb); + } +static void +viaSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, + int dir) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaCommandBuffer *cb = &pVia->cb; + ViaTwodContext *tdc = &pVia->td; + CARD32 dstBase; + int sub; + sub = viaAccelClippingHelper(cb, y, tdc); + dstBase = pScrn->fbOffset + sub * pVia->Bpl; + + BEGIN_RING_AGP(cb, 10); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTBASE), dstBase >> 3); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_PITCH), VIA_PITCH_ENABLE | + ((pVia->Bpl >> 3) << 16)); + + if (dir == DEGREES_0) { + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTPOS), ((y - sub) << 16) | x); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DIMENSION), (len - 1)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GECMD), tdc->cmd | VIA_GEC_BLT); + } else { + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DSTPOS), ((y - sub) << 16) | x); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_DIMENSION), ((len - 1) << 16)); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GECMD), tdc->cmd | VIA_GEC_BLT); + } + cb->flushFunc(cb); +} + static void -VIASubsequentScreenToScreenColorExpand( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, - int srcx, - int srcy, - int offset) +viaSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop, + unsigned int planemask, int length, unsigned char *pattern) { VIAPtr pVia = VIAPTR(pScrn); - ViaCBuffer *buf = &pVia->cBuf; + int cmd; + CARD32 pat = *(CARD32 *) pattern; + ViaCommandBuffer *cb = &pVia->cb; ViaTwodContext *tdc = &pVia->td; - CARD32 srcBase,dstBase; - srcBase = srcy*pVia->Bpl + srcx*pVia->Bpp; - dstBase = y*pVia->Bpl + x*pVia->Bpp; + cmd = VIA_GEC_LINE | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(rop); - x = (dstBase & 31); - srcx = srcBase & 7; + if (bg == -1) { + cmd |= VIA_GEC_MPAT_TRANS; + } - switch (pScrn->bitsPerPixel) { + tdc->cmd = cmd; + tdc->fgColor = fg; + tdc->bgColor = bg; + + switch (length) { + case 2: + pat |= pat << 2; /* fall through */ + case 4: + pat |= pat << 4; /* fall through */ + case 8: + pat |= pat << 8; /* fall through */ case 16: - x >>= 1; - break; - case 32: - x >>= 2; - break; - default: - break; + pat |= pat << 16; } - srcy = 0; - y = 0; + tdc->pattern0 = pat; - /* Set Src and Dst base address and pitch, pitch is qword */ - COND_CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0); - CBUFFER(buf,VIA_REG_SRCBASE, (srcBase & ~7) >> 3); - CBUFFER(buf,VIA_REG_DSTBASE, (dstBase & ~31) >> 3); - CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | - ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | - (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); - CBUFFER(buf,VIA_REG_SRCPOS, (srcx << 6) | offset); - CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); - CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); - CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); - CBUFFER(buf,VIA_REG_BGCOLOR, pVia->SavedBgColor); - CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); + BEGIN_RING_AGP(cb, 8); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_GEMODE), tdc->mode); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_FGCOLOR), tdc->fgColor); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_BGCOLOR), tdc->bgColor); + OUT_RING_QW_AGP(cb, H1_ADDR(VIA_REG_MONOPAT0), tdc->pattern0); +} - dispatchCBufferAGP(pVia, buf); +static void +viaSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, int x1, int y1, int x2, + int y2, int flags, int phase) +{ + viaSubsequentSolidTwoPointLine(pScrn, x1, y1, x2, y2, flags); } -#endif +static int +viaInitXAA(ScreenPtr pScreen) +{ -static void -VIASetupForImageWrite( - ScrnInfoPtr pScrn, - int rop, - unsigned planemask, - int trans_color, - int bpp, - int depth) + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + XAAInfoRecPtr xaaptr; + + /* + * General acceleration flags + */ + + if (!(xaaptr = pVia->AccelInfoRec = XAACreateInfoRec())) + return FALSE; + + xaaptr->Flags = PIXMAP_CACHE | + OFFSCREEN_PIXMAPS | LINEAR_FRAMEBUFFER | MICROSOFT_ZERO_LINE_BIAS | 0; + + if (pScrn->bitsPerPixel == 8) + xaaptr->CachePixelGranularity = 128; + + xaaptr->SetClippingRectangle = viaSetClippingRectangle; + xaaptr->DisableClipping = viaDisableClipping; + xaaptr->ClippingFlags = HARDWARE_CLIP_SOLID_FILL | + HARDWARE_CLIP_SOLID_LINE | + HARDWARE_CLIP_DASHED_LINE | + HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY | + HARDWARE_CLIP_MONO_8x8_FILL | + HARDWARE_CLIP_COLOR_8x8_FILL | + HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND | 0; + + xaaptr->Sync = viaAccelSync; + + xaaptr->SetupForScreenToScreenCopy = viaSetupForScreenToScreenCopy; + xaaptr->SubsequentScreenToScreenCopy = viaSubsequentScreenToScreenCopy; + xaaptr->ScreenToScreenCopyFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + + xaaptr->SetupForSolidFill = viaSetupForSolidFill; + xaaptr->SubsequentSolidFillRect = viaSubsequentSolidFillRect; + xaaptr->SolidFillFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + + xaaptr->SetupForMono8x8PatternFill = viaSetupForMono8x8PatternFill; + xaaptr->SubsequentMono8x8PatternFillRect = + viaSubsequentMono8x8PatternFillRect; + xaaptr->Mono8x8PatternFillFlags = NO_PLANEMASK | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | BIT_ORDER_IN_BYTE_MSBFIRST | 0; + + xaaptr->SetupForColor8x8PatternFill = viaSetupForColor8x8PatternFill; + xaaptr->SubsequentColor8x8PatternFillRect = + viaSubsequentColor8x8PatternFillRect; + xaaptr->Color8x8PatternFillFlags = NO_PLANEMASK | + NO_TRANSPARENCY | + HARDWARE_PATTERN_PROGRAMMED_BITS | + HARDWARE_PATTERN_PROGRAMMED_ORIGIN | 0; + + xaaptr->SetupForSolidLine = viaSetupForSolidLine; + xaaptr->SubsequentSolidTwoPointLine = viaSubsequentSolidTwoPointLine; + xaaptr->SubsequentSolidHorVertLine = viaSubsequentSolidHorVertLine; + xaaptr->SolidBresenhamLineErrorTermBits = 14; + xaaptr->SolidLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + + xaaptr->SetupForDashedLine = viaSetupForDashedLine; + xaaptr->SubsequentDashedTwoPointLine = viaSubsequentDashedTwoPointLine; + xaaptr->DashPatternMaxLength = 8; + xaaptr->DashedLineFlags = NO_PLANEMASK | + ROP_NEEDS_SOURCE | + LINE_PATTERN_POWER_OF_2_ONLY | LINE_PATTERN_MSBFIRST_LSBJUSTIFIED | 0; + + xaaptr->ScanlineCPUToScreenColorExpandFillFlags = NO_PLANEMASK | + CPU_TRANSFER_PAD_DWORD | + SCANLINE_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | + LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | 0; + + xaaptr->SetupForScanlineCPUToScreenColorExpandFill = + viaSetupForCPUToScreenColorExpandFill; + xaaptr->SubsequentScanlineCPUToScreenColorExpandFill = + viaSubsequentScanlineCPUToScreenColorExpandFill; + xaaptr->ColorExpandBase = pVia->BltBase; + xaaptr->ColorExpandRange = VIA_MMIO_BLTSIZE; + + xaaptr->ImageWriteFlags = NO_PLANEMASK | + CPU_TRANSFER_PAD_DWORD | + SCANLINE_PAD_DWORD | + BIT_ORDER_IN_BYTE_MSBFIRST | + LEFT_EDGE_CLIPPING | ROP_NEEDS_SOURCE | SYNC_AFTER_IMAGE_WRITE | 0; + + /* + * Most Unichromes are much faster using processor to + * framebuffer writes than using the 2D engine for this. + * test with x11perf -shmput500! + */ + + if (pVia->Chipset != VIA_K8M800) + xaaptr->ImageWriteFlags |= NO_GXCOPY; + + xaaptr->SetupForImageWrite = viaSetupForImageWrite; + xaaptr->SubsequentImageWriteRect = viaSubsequentImageWriteRect; + xaaptr->ImageWriteBase = pVia->BltBase; + xaaptr->ImageWriteRange = VIA_MMIO_BLTSIZE; + + return XAAInit(pScreen, xaaptr); + +} + +/* + * Mark Sync using the 2D blitter for AGP. NoOp for PCI. + * In the future one could even launch a NULL PCI DMA command + * to have an interrupt generated, provided it is possible to + * write to the PCI DMA engines from the AGP command stream. + */ + +static int +viaAccelMarkSync(ScreenPtr pScreen) { - VIAPtr pVia = VIAPTR(pScrn); - int cmd; - ViaCBuffer *buf = &pVia->cBuf; - ViaTwodContext *tdc = &pVia->td; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaCommandBuffer *cb = &pVia->cb; - /* We don't record bpp and depth because we assume bpp is equal to - bpp of screen. Is this assume correct ? */ + ++pVia->curMarker; - cmd = VIA_GEC_BLT | VIA_GEC_SRC_SYS | (XAAGetCopyROP(rop) << 24); + /* + * Wrap around without possibly affecting the int sign bit. + */ - pVia->SavedCmd = cmd; + pVia->curMarker &= 0x7FFFFFFF; - CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - if (trans_color != -1) { - /* Transparent Bitblt */ - CBUFFER(buf,VIA_REG_SRCCOLORKEY, trans_color); - CBUFFER(buf,VIA_REG_KEYCONTROL, 0x4000); + if (pVia->agpDMA) { + + viaAccelSolidHelper(&pVia->cb, 0, 0, 1, 1, pVia->markerOffset, + VIA_GEM_32bpp, 4, pVia->curMarker, + (0xF0 << 24) | VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT); + cb->flushFunc(cb); } - else { - /* Disable Transparent Bitblt */ - CBUFFER(buf,VIA_REG_KEYCONTROL, 0x0); - } + return pVia->curMarker; } +/* + * Wait for the value to get blitted, or in the PCI case for engine idle. + */ static void -VIASubsequentImageWriteRect( - ScrnInfoPtr pScrn, - int x, - int y, - int w, - int h, - int skipleft) +viaAccelWaitMarker(ScreenPtr pScreen, int marker) { - VIAPtr pVia = VIAPTR(pScrn); - ViaCBuffer *buf = &pVia->cBuf; - ViaTwodContext *tdc = &pVia->td; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + CARD32 uMarker = marker; - if (skipleft) { - VIASetClippingRectangle(pScrn, (x + skipleft), y, (x + w - 1), (y + h -1)); + if (pVia->agpDMA) { + while ((pVia->lastMarkerRead - uMarker) > (1 << 24)) + pVia->lastMarkerRead = *pVia->markerBuf; + } else { + viaAccelSync(pScrn); } +} - /* Set Src and Dst base address and pitch, pitch is qword */ - COND_CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - CBUFFER(buf,VIA_REG_SRCBASE, 0x0); - CBUFFER(buf,VIA_REG_DSTBASE, 0x0); - CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | - ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | - (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); +#ifdef VIA_HAVE_EXA - CBUFFER(buf,VIA_REG_SRCPOS, 0); - CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); - CBUFFER(buf,VIA_REG_DIMENSION, (((h - 1) << 16) | (w - 1))); - CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd); - dispatchCBuffer(pVia, buf); +/* + * Exa functions. It is assumed that EXA does not exceed the blitter limits. + */ +static Bool +viaExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaCommandBuffer *cb = &pVia->cb; + ViaTwodContext *tdc = &pVia->td; + + if (exaGetPixmapPitch(pPixmap) & 7) + return FALSE; + + if (!viaAccelSetMode(pPixmap->drawable.depth, tdc)) + return FALSE; + + viaAccelTransparentHelper(cb, 0x0, 0x0); + + tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(alu); + + tdc->fgColor = fg; + + return TRUE; } +static void +viaExaSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaCommandBuffer *cb = &pVia->cb; + ViaTwodContext *tdc = &pVia->td; + CARD32 dstPitch, dstOffset; -/* Setup for XAA solid lines. */ + int w = x2 - x1, h = y2 - y1; + + dstPitch = exaGetPixmapPitch(pPixmap); + dstOffset = exaGetPixmapOffset(pPixmap); + + viaAccelSolidHelper(cb, x1, y1, w, h, dstOffset, + tdc->mode, dstPitch, tdc->fgColor, tdc->cmd); + cb->flushFunc(cb); +} + static void -VIASetupForSolidLine( - ScrnInfoPtr pScrn, - int color, - int rop, - unsigned int planemask) +viaExaDoneSolidCopy(PixmapPtr pPixmap) { - VIAPtr pVia = VIAPTR(pScrn); - int cmd; - ViaCBuffer *buf = &pVia->cBuf; +} + +static Bool +viaExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, + int ydir, int alu, Pixel planeMask) +{ + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaCommandBuffer *cb = &pVia->cb; ViaTwodContext *tdc = &pVia->td; - CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - /* we move VIA_GEC_LINE from here to the place firing command */ - cmd = VIA_GEC_FIXCOLOR_PAT | (XAAGetPatternROP(rop) << 24); + if ((planeMask & ((1 << pSrcPixmap->drawable.depth) - 1)) != + (1 << pSrcPixmap->drawable.depth) - 1) { + return FALSE; + } - pVia->SavedCmd = cmd; - pVia->SavedFgColor = color; + if (pSrcPixmap->drawable.bitsPerPixel != + pDstPixmap->drawable.bitsPerPixel) + return FALSE; - /* set solid line pattern */ - CBUFFER(buf,VIA_REG_MONOPAT0, 0xFF); - CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); + if ((tdc->srcPitch = exaGetPixmapPitch(pSrcPixmap)) & 3) + return FALSE; + if (exaGetPixmapPitch(pDstPixmap) & 7) + return FALSE; + + tdc->srcOffset = exaGetPixmapOffset(pSrcPixmap); + + tdc->cmd = VIA_GEC_BLT | VIAACCELCOPYROP(alu); + if (xdir < 0) + tdc->cmd |= VIA_GEC_DECX; + if (ydir < 0) + tdc->cmd |= VIA_GEC_DECY; + + if (!viaAccelSetMode(pDstPixmap->drawable.bitsPerPixel, tdc)) + return FALSE; + + viaAccelTransparentHelper(cb, 0x0, 0x0); + + return TRUE; } - static void -VIASubsequentSolidTwoPointLine( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2, - int flags) +viaExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, + int width, int height) { - VIAPtr pVia = VIAPTR(pScrn); - int dx, dy, cmd, tmp, error = 1; - ViaCBuffer *buf = &pVia->cBuf; + ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ViaCommandBuffer *cb = &pVia->cb; ViaTwodContext *tdc = &pVia->td; + CARD32 srcOffset = tdc->srcOffset; + CARD32 dstOffset = exaGetPixmapOffset(pDstPixmap); - COND_CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); - cmd = pVia->SavedCmd | VIA_GEC_LINE; + if (!width || !height) + return; - dx = x2 - x1; - if (dx < 0) { - dx = -dx; - cmd |= VIA_GEC_DECX; /* line will be drawn from right */ - error = 0; + viaAccelCopyHelper(cb, srcX, srcY, dstX, dstY, width, height, + srcOffset, dstOffset, tdc->mode, tdc->srcPitch, + exaGetPixmapPitch(pDstPixmap), tdc->cmd); + cb->flushFunc(cb); +} + +#ifdef XF86DRI + +/* + * Use PCI DMA if we can. Really, if the system alignments don't match it is worth doing + * an extra copy to avoid reading from the frame-buffer which is painfully slow. + */ + +static Bool +viaExaDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, + char *dst, int dst_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + drm_via_dmablit_t blit; + unsigned srcPitch = exaGetPixmapPitch(pSrc); + unsigned bytesPerPixel = pSrc->drawable.bitsPerPixel >> 3; + unsigned srcOffset = + exaGetPixmapOffset(pSrc) + y * srcPitch + x * bytesPerPixel; + int err; + char *bounce = NULL; + char *bounceAligned = NULL; + unsigned bouncePitch = 0; + + if (!pVia->directRenderingEnabled) + return FALSE; + + if ((srcPitch & 3) || (srcOffset & 3)) { + ErrorF("VIA EXA download src_pitch misaligned\n"); + return FALSE; } - dy = y2 - y1; - if (dy < 0) { - dy = -dy; - cmd |= VIA_GEC_DECY; /* line will be drawn from bottom */ + blit.num_lines = h; + blit.line_length = w * bytesPerPixel; + blit.fb_addr = srcOffset; + blit.fb_stride = srcPitch; + blit.mem_addr = dst; + blit.mem_stride = dst_pitch; + blit.bounce_buffer = 0; + blit.to_fb = 0; + + if (((unsigned long)dst & 15) || (dst_pitch & 15)) { + bouncePitch = (w * bytesPerPixel + 15) & ~15; + bounce = (char *)xalloc(bouncePitch * h + 15); + if (!bounce) + return FALSE; + bounceAligned = (char *)(((unsigned long)bounce + 15) & ~15); + blit.mem_addr = bounceAligned; + blit.mem_stride = bouncePitch; } - if (dy > dx) { - tmp = dy; - dy = dx; - dx = tmp; /* Swap 'dx' and 'dy' */ - cmd |= VIA_GEC_Y_MAJOR; /* Y major line */ + while (-EAGAIN == (err = + drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, &blit, + sizeof(blit)))) ; + if (!err) { + while (-EAGAIN == (err = + drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC, &blit.sync, + sizeof(blit.sync)))) ; } + if (!err && bounce) { + unsigned i; - if (flags & OMIT_LAST) { - cmd |= VIA_GEC_LASTPIXEL_OFF; + for (i = 0; i < h; ++i) { + memcpy(dst, bounceAligned, blit.line_length); + dst += dst_pitch; + bounceAligned += bouncePitch; + } } + if (bounce) + xfree(bounce); + return (err == 0); +} - /* Set Src and Dst base address and pitch, pitch is qword */ - CBUFFER(buf,VIA_REG_SRCBASE, 0x0); - CBUFFER(buf,VIA_REG_DSTBASE, 0x0); - CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | - ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | - (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); +/* + * I'm not sure upload is necessary. Seems buggy for widths below 65, and I'd guess that in + * most situations, CPU direct writes are faster. Use DMA only when alignments match. At least + * it saves some CPU cycles. + */ - /* major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1) */ - /* K1 = 2*dmin K2 = 2*(dmin - dmax) */ - /* Error Term = (StartXdrawable.pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + drm_via_dmablit_t blit; + unsigned dstPitch = exaGetPixmapPitch(pDst); + unsigned bytesPerPixel = pDst->drawable.bitsPerPixel >> 3; + unsigned dstOffset = + exaGetPixmapOffset(pDst) + y * dstPitch + x * bytesPerPixel; + int err; -} + if (!pVia->directRenderingEnabled) + return FALSE; + if (((unsigned long)src & 15) || (src_pitch & 15)) + return FALSE; -/* Subsequent XAA solid horizontal and vertical lines */ -static void -VIASubsequentSolidHorVertLine( - ScrnInfoPtr pScrn, - int x, - int y, - int len, - int dir) -{ - VIAPtr pVia = VIAPTR(pScrn); - ViaCBuffer *buf = &pVia->cBuf; - ViaTwodContext *tdc = &pVia->td; + if ((dstPitch & 3) || (dstOffset & 3)) + return FALSE; - /* Set Src and Dst base address and pitch, pitch is qword */ - COND_CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); - CBUFFER(buf,VIA_REG_SRCBASE, 0x0); - CBUFFER(buf,VIA_REG_DSTBASE, 0x0); - CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | - ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | - (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + blit.line_length = w * bytesPerPixel; + if (blit.line_length < 65) + return FALSE; - if (dir == DEGREES_0) { - CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); - CBUFFER(buf,VIA_REG_DIMENSION, (len - 1)); - CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd | VIA_GEC_BLT); - } - else { - CBUFFER(buf,VIA_REG_DSTPOS, ((y << 16) | x)); - CBUFFER(buf,VIA_REG_DIMENSION, ((len - 1) << 16)); - CBUFFER(buf,VIA_REG_GECMD, pVia->SavedCmd | VIA_GEC_BLT); - } - dispatchCBufferAGP(pVia, buf); + blit.num_lines = h; + blit.fb_addr = dstOffset; + blit.fb_stride = dstPitch; + blit.mem_addr = src; + blit.mem_stride = src_pitch; + blit.bounce_buffer = 0; + blit.to_fb = 1; + + while (-EAGAIN == (err = + drmCommandWriteRead(pVia->drmFD, DRM_VIA_DMA_BLIT, &blit, + sizeof(blit)))) ; + if (err < 0) + return FALSE; + + while (-EAGAIN == (err = drmCommandWrite(pVia->drmFD, DRM_VIA_BLIT_SYNC, + &blit.sync, sizeof(blit.sync)))) ; + return (err == 0); } +#endif -static void -VIASetupForDashedLine( - ScrnInfoPtr pScrn, - int fg, - int bg, - int rop, - unsigned int planemask, - int length, - unsigned char *pattern) +/* + * Init EXA. Alignments are 2D engine constraints. + */ + +static ExaDriverPtr +viaInitExa(ScreenPtr pScreen) { - VIAPtr pVia = VIAPTR(pScrn); - int cmd; - CARD32 pat = *(CARD32 *)pattern; - ViaCBuffer *buf = &pVia->cBuf; - ViaTwodContext *tdc = &pVia->td; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + ExaDriverPtr pExa = (ExaDriverPtr) xnfcalloc(sizeof(ExaDriverRec), 1); - cmd = VIA_GEC_LINE | VIA_GEC_FIXCOLOR_PAT | (XAAGetPatternROP(rop) << 24); + if (!pExa) + return NULL; - if (bg == -1) { - /* transparent mono pattern */ - cmd |= VIA_GEC_MPAT_TRANS; + pExa->card.memoryBase = pVia->FBBase; + pExa->card.memorySize = pVia->FBFreeEnd; + pExa->card.offScreenBase = pScrn->virtualY * pVia->Bpl; + pExa->card.pixmapOffsetAlign = 32; + pExa->card.pixmapPitchAlign = 16; + pExa->card.flags = EXA_OFFSCREEN_PIXMAPS; + pExa->card.maxX = 2047; + pExa->card.maxY = 2047; + + pExa->accel.WaitMarker = viaAccelWaitMarker; + pExa->accel.MarkSync = viaAccelMarkSync; + pExa->accel.PrepareSolid = viaExaPrepareSolid; + pExa->accel.Solid = viaExaSolid; + pExa->accel.DoneSolid = viaExaDoneSolidCopy; + pExa->accel.PrepareCopy = viaExaPrepareCopy; + pExa->accel.Copy = viaExaCopy; + pExa->accel.DoneCopy = viaExaDoneSolidCopy; + +#if defined(XF86DRI) && defined(linux) + if (pVia->directRenderingEnabled) { + if ((pVia->drmVerMajor > 2) || + ((pVia->drmVerMajor == 2) && (pVia->drmVerMinor >= 7))) { + pExa->accel.UploadToScreen = viaExaUploadToScreen; + pExa->accel.DownloadFromScreen = viaExaDownloadFromScreen; + } } +#endif - pVia->SavedCmd = cmd; - pVia->SavedFgColor = fg; - pVia->SavedBgColor = bg; + /* + * Composite not supported. Could we use the 3D engine? + */ - switch (length) { - case 2: pat |= pat << 2; /* fall through */ - case 4: pat |= pat << 4; /* fall through */ - case 8: pat |= pat << 8; /* fall through */ - case 16: pat |= pat << 16; + if (!exaDriverInit(pScreen, pExa)) { + xfree(pExa); + return NULL; } - pVia->SavedPattern0 = pat; - CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); - CBUFFER(buf,VIA_REG_BGCOLOR, pVia->SavedBgColor); - CBUFFER(buf,VIA_REG_MONOPAT0, pVia->SavedPattern0); - + return pExa; } +#endif /* VIA_HAVE_EXA */ -static void -VIASubsequentDashedTwoPointLine( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2, - int flags, - int phase) +/* + * Acceleration init function. Sets up offscreen memory disposition, initializes engines + * and acceleration method. + */ + +Bool +viaInitAccel(ScreenPtr pScreen) { - VIAPtr pVia = VIAPTR(pScrn); - int dx, dy, cmd, tmp, error = 1; - ViaCBuffer *buf = &pVia->cBuf; - ViaTwodContext *tdc = &pVia->td; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VIAPtr pVia = VIAPTR(pScrn); + BoxRec AvailFBArea; + int maxY; - COND_CLEAR_CBUFFER( buf, pVia); - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); - CBUFFER(buf,VIA_REG_FGCOLOR, pVia->SavedFgColor); - cmd = pVia->SavedCmd; + pVia->VQStart = 0; + if (((pVia->FBFreeEnd - pVia->FBFreeStart) >= VIA_VQ_SIZE) && + pVia->VQEnable) { + pVia->VQStart = pVia->FBFreeEnd - VIA_VQ_SIZE; + pVia->VQEnd = pVia->VQStart + VIA_VQ_SIZE - 1; + pVia->FBFreeEnd -= VIA_VQ_SIZE; + } - dx = x2 - x1; - if (dx < 0) { - dx = -dx; - cmd |= VIA_GEC_DECX; /* line will be drawn from right */ - error = 0; + viaInitialize2DEngine(pScrn); + + if (pVia->hwcursor) { + pVia->FBFreeEnd -= VIA_CURSOR_SIZE; + pVia->CursorStart = pVia->FBFreeEnd; } - dy = y2 - y1; - if (dy < 0) { - dy = -dy; - cmd |= VIA_GEC_DECY; /* line will be drawn from bottom */ + if (Success != viaSetupCBuffer(pScrn, &pVia->cb, 0)) { + pVia->NoAccel = TRUE; + return FALSE; } - if (dy > dx) { - tmp = dy; - dy = dx; - dx = tmp; /* Swap 'dx' and 'dy' */ - cmd |= VIA_GEC_Y_MAJOR; /* Y major line */ + /* + * Sync marker space. + */ + + pVia->FBFreeEnd -= 32; + pVia->markerOffset = (pVia->FBFreeEnd + 31) & ~31; + pVia->markerBuf = (CARD32 *) ((char *)pVia->FBBase + pVia->markerOffset); + +#ifdef VIA_HAVE_EXA + + if (pVia->useEXA) { + pVia->exaDriverPtr = viaInitExa(pScreen); + if (!pVia->exaDriverPtr) { + + /* + * Docs recommend turning off also Xv here, but we handle this + * case with the old linear offscreen FB manager through + * VIAInitLinear. + */ + + pVia->NoAccel = TRUE; + return FALSE; + } + + pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) / 2; + + return TRUE; } +#endif - if (flags & OMIT_LAST) { - cmd |= VIA_GEC_LASTPIXEL_OFF; + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + + /* + * Memory distribution for XAA is tricky. We'd like to make the + * pixmap cache no larger than 3 x visible screen size, otherwise + * XAA may get slow for some reason. + */ + +#ifdef XF86DRI + if (pVia->directRenderingEnabled) { + pVia->driSize = (pVia->FBFreeEnd - pVia->FBFreeStart) / 2; + maxY = pScrn->virtualY + (pVia->driSize / pVia->Bpl); + } else +#endif + { + maxY = pVia->FBFreeEnd / pVia->Bpl; } + if (maxY > 4 * pScrn->virtualY) + maxY = 4 * pScrn->virtualY; - /* Set Src and Dst base address and pitch, pitch is qword */ - CBUFFER(buf,VIA_REG_SRCBASE, 0x0); - CBUFFER(buf,VIA_REG_DSTBASE, 0x0); - CBUFFER(buf,VIA_REG_PITCH, VIA_PITCH_ENABLE | - ((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) | - (((pScrn->displayWidth * pScrn->bitsPerPixel >> 3) >> 3) << 16)); + pVia->FBFreeStart = (maxY + 1) * pVia->Bpl; - /* major = 2*dmaj, minor = 2*dmin, err = -dmaj - ((bias >> octant) & 1) */ - /* K1 = 2*dmin K2 = 2*(dmin - dmax) */ - /* Error Term = (StartXdriSize = (pVia->FBFreeEnd - pVia->FBFreeStart - pVia->Bpl); + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d lines for offscreen memory.\n", + AvailFBArea.y2 - pScrn->virtualY)); + + return viaInitXAA(pScreen); } +/* + * Free used acceleration resources. + */ -static void -VIASetClippingRectangle( - ScrnInfoPtr pScrn, - int x1, - int y1, - int x2, - int y2) +void +viaExitAccel(ScreenPtr pScreen) { + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; VIAPtr pVia = VIAPTR(pScrn); - ViaCBuffer *buf = &pVia->cBuf; - ViaTwodContext *tdc = &pVia->td; - COND_CLEAR_CBUFFER( buf, pVia); - pVia->justSetup = 0; - CBUFFER(buf,VIA_REG_GEMODE, tdc->mode); -#ifdef DEBUG_EXTRA - ErrorF("ClipRect, (%4d,%4d)-(%4d,%4d) \n", x1, y1, x2, y2 ); + viaAccelSync(pScrn); + +#ifdef VIA_HAVE_EXA + if (pVia->useEXA) { + if (pVia->exaDriverPtr) { + exaDriverFini(pScreen); + } + xfree(pVia->exaDriverPtr); + pVia->exaDriverPtr = NULL; + viaTearDownCBuffer(&pVia->cb); + return; + } #endif + if (pVia->AccelInfoRec) { + XAADestroyInfoRec(pVia->AccelInfoRec); + pVia->AccelInfoRec = NULL; + viaTearDownCBuffer(&pVia->cb); + } +} - CBUFFER(buf,VIA_REG_CLIPTL, ((y1 << 16) | x1)); - CBUFFER(buf,VIA_REG_CLIPBR, ((y2 << 16) | x2)); - pVia->SavedCmd |= VIA_GEC_CLIP_ENABLE; - dispatchCBufferAGP(pVia, buf); +/* + * DGA accelerated functions go here and let them be independent of acceleration + * method. + */ +void +viaDGABlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h, + int dstx, int dsty) +{ + VIAPtr pVia = VIAPTR(pScrn); + ViaTwodContext *tdc = &pVia->td; + ViaCommandBuffer *cb = &pVia->cb; + unsigned dstOffset = pScrn->fbOffset + dsty * pVia->Bpl; + unsigned srcOffset = pScrn->fbOffset + srcy * pVia->Bpl; + + if (!w || !h) + return; + + if (!pVia->NoAccel) { + + int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; + int ydir = (srcy < dsty) ? -1 : 1; + CARD32 cmd = VIA_GEC_BLT | VIAACCELCOPYROP(GXcopy); + + if (xdir < 0) + cmd |= VIA_GEC_DECX; + if (ydir < 0) + cmd |= VIA_GEC_DECY; + + viaAccelSetMode(pScrn->bitsPerPixel, tdc); + viaAccelTransparentHelper(cb, 0x0, 0x0); + viaAccelCopyHelper(cb, srcx, 0, dstx, 0, w, h, srcOffset, dstOffset, + tdc->mode, pVia->Bpl, pVia->Bpl, cmd); + pVia->dgaMarker = viaAccelMarkSync(pScrn->pScreen); + cb->flushFunc(cb); + } } - -static void VIADisableClipping(ScrnInfoPtr pScrn) +void +viaDGAFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, + unsigned long color) { VIAPtr pVia = VIAPTR(pScrn); + unsigned dstBase = pScrn->fbOffset + y * pVia->Bpl; + ViaTwodContext *tdc = &pVia->td; + ViaCommandBuffer *cb = &pVia->cb; + CARD32 cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | + VIAACCELPATTERNROP(GXcopy); -#ifdef DEBUG_EXTRA - ErrorF("Kill ClipRect\n"); -#endif + if (!w || !h) + return; - pVia->SavedCmd &= ~VIA_GEC_CLIP_ENABLE; + if (!pVia->NoAccel) { + viaAccelSetMode(pScrn->bitsPerPixel, tdc); + viaAccelTransparentHelper(cb, 0x0, 0x0); + viaAccelSolidHelper(cb, x, 0, w, h, dstBase, tdc->mode, + pVia->Bpl, color, cmd); + pVia->dgaMarker = viaAccelMarkSync(pScrn->pScreen); + cb->flushFunc(cb); + } } -/* - * - */ -void -ViaVQDisable(ScrnInfoPtr pScrn) +void +viaDGAWaitMarker(ScrnInfoPtr pScrn) { VIAPtr pVia = VIAPTR(pScrn); - VIASETREG(VIA_REG_TRANSET, 0x00FE0000); - VIASETREG(VIA_REG_TRANSPACE, 0x00000004); + + viaAccelWaitMarker(pScrn->pScreen, pVia->dgaMarker); } Index: via_memory.c =================================================================== --- via_memory.c (revision 79) +++ via_memory.c (working copy) @@ -43,47 +43,68 @@ #endif /* - * Isolate the wonders of X memory allocation, DRI memory allocation + * Isolate the wonders of X memory allocation and DRI memory allocation * and 4.3 or 4.4 differences in once abstraction * * The pool code indicates who provided the memory * 0 - nobody - * 1 - xf86 linear (Used in 4.4 only - current) + * 1 - xf86 linear * 2 - DRM - * 3 - Preallocated buffer (Used in 4.3 only - removed) */ void VIAFreeLinear(VIAMemPtr mem) { DEBUG(ErrorF("Freed %lu (pool %d)\n", mem->base, mem->pool)); - switch(mem->pool) - { - case 1: - xf86FreeOffscreenLinear(mem->linear); + switch(mem->pool) { + case 0: + return; + case 1: +#ifdef VIA_HAVE_EXA + { + VIAPtr pVia = VIAPTR(mem->pScrn); + if (pVia->useEXA && !pVia->NoAccel) { + exaOffscreenFree(mem->pScrn->pScreen, mem->exa); mem->linear = NULL; mem->pool = 0; return; - case 2: + } + } +#endif + xf86FreeOffscreenLinear(mem->linear); + mem->linear = NULL; + mem->pool = 0; + return; + case 2: #ifdef XF86DRI - if(drmCommandWrite(mem->drm_fd, DRM_VIA_FREEMEM, + if(drmCommandWriteRead(mem->drm_fd, DRM_VIA_FREEMEM, &mem->drm, sizeof(drm_via_mem_t)) < 0) - ErrorF("DRM module failed free.\n"); + ErrorF("DRM module failed free.\n"); #endif - mem->pool = 0; - return; - case 0: - case 3: /* deprecated */ - default: - return; - } + mem->pool = 0; + return; + } } - static unsigned long offScreenLinear(VIAMemPtr mem, ScrnInfoPtr pScrn, unsigned long size) { - int depth = (pScrn->bitsPerPixel + 7) >> 3; - /* Make sure we don't truncate requested size */ + int depth = pScrn->bitsPerPixel >> 3; + +#ifdef VIA_HAVE_EXA + VIAPtr pVia = VIAPTR(pScrn); + + if (pVia->useEXA && !pVia->NoAccel) { + + mem->exa = exaOffscreenAlloc(pScrn->pScreen, size, + 32, TRUE, NULL,NULL); + if (mem->exa == NULL) + return BadAlloc; + mem->base = mem->exa->offset; + mem->pool = 1; + return Success; + } +#endif + mem->linear = xf86AllocateOffscreenLinear(pScrn->pScreen, ( size + depth - 1 ) / depth, 32, NULL, NULL, NULL); @@ -98,44 +119,47 @@ unsigned long VIAAllocLinear(VIAMemPtr mem, ScrnInfoPtr pScrn, unsigned long size) { +#ifdef XF86DRI + VIAPtr pVia = VIAPTR(pScrn); + int ret; + if(mem->pool) ErrorF("VIA Double Alloc.\n"); + + if(pVia->directRenderingEnabled) { + mem->pScrn = pScrn; + mem->drm_fd = pVia->drmFD; + mem->drm.context = 1; + mem->drm.size = size; + mem->drm.type = VIA_MEM_VIDEO; + ret = drmCommandWriteRead(mem->drm_fd, DRM_VIA_ALLOCMEM, &mem->drm, + sizeof(drm_via_mem_t)); + if (ret || (size != mem->drm.size)) { -#ifdef XF86DRI - { - VIAPtr pVia = VIAPTR(pScrn); - int ret; - - if(pVia->directRenderingEnabled) { - mem->drm_fd = pVia->drmFD; - mem->drm.context = 1; - mem->drm.size = size; - mem->drm.type = VIA_MEM_VIDEO; - ret = drmCommandWriteRead(mem->drm_fd, DRM_VIA_ALLOCMEM, &mem->drm, - sizeof(drm_via_mem_t)); - if (ret || (size != mem->drm.size)) { - /* - * Try XY Fallback before failing. - */ + /* + * Try X Offsceen fallback before failing. + */ + + if (Success == offScreenLinear(mem, pScrn, size)) + return Success; + ErrorF("DRM memory allocation failed\n"); + return BadAlloc; + } - if (Success == offScreenLinear(mem, pScrn, size)) - return Success; - ErrorF("DRM memory allocation failed\n"); - return BadAlloc; - } - - mem->base = mem->drm.offset; - mem->pool = 2; - DEBUG(ErrorF("Fulfilled via DRI at %lu\n", mem->base)); - return 0; - } + mem->base = mem->drm.offset; + mem->pool = 2; + DEBUG(ErrorF("Fulfilled via DRI at %lu\n", mem->base)); + return Success; } -#endif /* XF86DRI */ - - if (Success == offScreenLinear(mem, pScrn, size)) - return Success; - ErrorF("Linear memory allocation failed\n"); - return BadAlloc; +#endif + { + mem->pScrn = pScrn; + if (Success == offScreenLinear(mem, pScrn, size)) + return Success; + ErrorF("Linear memory allocation failed\n"); + return BadAlloc; + } + return Success; } void VIAInitLinear(ScreenPtr pScreen) @@ -143,13 +167,15 @@ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; VIAPtr pVia = VIAPTR(pScrn); - /* - * In the 44 path we must take care not to truncate offset and size so - * that we get overlaps. If there is available memory below line 2048 - * we use it. - */ - unsigned long offset = (pVia->FBFreeStart + pVia->Bpp - 1 ) / pVia->Bpp; - unsigned long size = pVia->FBFreeEnd / pVia->Bpp - offset; - if (size > 0) xf86InitFBManagerLinear(pScreen, offset, size); +#ifdef VIA_HAVE_EXA + if (pVia->useEXA && !pVia->NoAccel) { + return; + } else +#endif + { + unsigned long offset = (pVia->FBFreeStart + pVia->Bpp - 1 ) / pVia->Bpp; + long size = pVia->FBFreeEnd / pVia->Bpp - offset; + if (size > 0) xf86InitFBManagerLinear(pScreen, offset, size); + } } Index: via_vbe.c =================================================================== --- via_vbe.c (revision 79) +++ via_vbe.c (working copy) @@ -161,7 +161,7 @@ pScrn->vtSema = TRUE; if (!pVia->NoAccel) - VIAInitialize2DEngine(pScrn); + viaInitialize2DEngine(pScrn); #ifdef XF86DRI VIAInitialize3DEngine(pScrn); Index: via_cursor.c =================================================================== --- via_cursor.c (revision 79) +++ via_cursor.c (working copy) @@ -115,7 +115,7 @@ VIAPtr pVia = VIAPTR(pScrn); CARD32 dwCursorMode; - VIAAccelSync(pScrn); + viaAccelSync(pScrn); dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE); Index: via_dri.c =================================================================== --- via_dri.c (revision 79) +++ via_dri.c (working copy) @@ -333,12 +333,41 @@ } static Bool VIADRIFBInit(ScreenPtr pScreen, VIAPtr pVia) { - int FBSize = pVia->FBFreeEnd-pVia->FBFreeStart; - int FBOffset = pVia->FBFreeStart; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + int FBSize = pVia->driSize; + int FBOffset; VIADRIPtr pVIADRI = pVia->pDRIInfo->devPrivate; + + if (FBSize < pVia->Bpl) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] No DRM framebuffer heap available.\n"); + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] Please increase the frame buffer\n"); + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] memory area in BIOS. Disabling DRI.\n"); + return FALSE; + } + if (FBSize < (pScrn->virtualY * pVia->Bpl)) { + xf86DrvMsg(pScreen->myNum, X_WARNING, + "[drm] The DRM Heap and Pixmap cache memory could be too small\n"); + xf86DrvMsg(pScreen->myNum, X_WARNING, + "[drm] for optimal performance. Please increase the frame buffer\n"); + xf86DrvMsg(pScreen->myNum, X_WARNING, + "[drm] memory area in BIOS.\n"); + } + + pVia->driOffScreenMem.pool = 0; + if (Success != VIAAllocLinear(&pVia->driOffScreenMem, pScrn, FBSize)) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] failed to allocate offscreen frame buffer area\n"); + return FALSE; + } + + FBOffset = pVia->driOffScreenMem.base; + pVIADRI->fbOffset = FBOffset; - pVIADRI->fbSize = pVia->videoRambytes; - + pVIADRI->fbSize = FBSize; + { drm_via_fb_t fb; fb.offset = FBOffset; @@ -351,9 +380,7 @@ return FALSE; } else { xf86DrvMsg(pScreen->myNum, X_INFO, - "[drm] FBFreeStart= 0x%08x FBFreeEnd= 0x%08x " - "FBSize= 0x%08x\n", - pVia->FBFreeStart, pVia->FBFreeEnd, FBSize); + "[drm] Using %d bytes for DRM memory heap.\n", FBSize); return TRUE; } } @@ -594,6 +621,7 @@ VIAPtr pVia = VIAPTR(pScrn); DRIInfoPtr pDRIInfo; VIADRIPtr pVIADRI; + drmVersionPtr drmVer; /* if symbols or version check fails, we still want this to be NULL */ pVia->pDRIInfo = NULL; @@ -697,6 +725,15 @@ return FALSE; } + if (NULL == (drmVer = drmGetVersion(pVia->drmFD))) { + VIADRICloseScreen(pScreen); + return FALSE; + } + pVia->drmVerMajor = drmVer->version_major; + pVia->drmVerMinor = drmVer->version_minor; + pVia->drmVerPL = drmVer->version_patchlevel; + drmFreeVersion(drmVer); + if (!(VIAInitVisualConfigs(pScreen))) { VIADRICloseScreen(pScreen); @@ -739,8 +776,8 @@ drmAgpRelease(pVia->drmFD); } - DRICloseScreen(pScreen); + VIAFreeLinear(&pVia->driOffScreenMem); if (pVia->pDRIInfo) { if ((pVIADRI = (VIADRIPtr) pVia->pDRIInfo->devPrivate)) { Index: via_priv.h =================================================================== --- via_priv.h (revision 79) +++ via_priv.h (working copy) @@ -4,6 +4,9 @@ #ifdef XF86DRI #include "via_drm.h" #endif +#ifdef VIA_HAVE_EXA +#include "exa.h" +#endif /* * Alignment macro functions @@ -116,9 +119,12 @@ int drm_fd; /* Fd in DRM mode */ drm_via_mem_t drm; /* DRM management object */ #endif - int slot; /* Pool 3 slot */ void *pVia; /* VIA driver pointer */ FBLinearPtr linear; /* X linear pool info ptr */ +#ifdef VIA_HAVE_EXA + ExaOffscreenArea *exa; +#endif + ScrnInfoPtr pScrn; } VIAMem; typedef VIAMem *VIAMemPtr; Index: via_dga.c =================================================================== --- via_dga.c (revision 79) +++ via_dga.c (working copy) @@ -36,10 +36,7 @@ static Bool VIADGASetMode(ScrnInfoPtr, DGAModePtr); static int VIADGAGetViewport(ScrnInfoPtr); static void VIADGASetViewport(ScrnInfoPtr, int, int, int); -static void VIADGAFillRect(ScrnInfoPtr, int, int, int, int, unsigned long); -static void VIADGABlitRect(ScrnInfoPtr, int, int, int, int, int, int); - static DGAFunctionRec VIADGAFuncs = { VIADGAOpenFramebuffer, @@ -47,9 +44,9 @@ VIADGASetMode, VIADGASetViewport, VIADGAGetViewport, - VIAAccelSync, - VIADGAFillRect, - VIADGABlitRect, + viaDGAWaitMarker, + viaDGAFillRect, + viaDGABlitRect, NULL /* BlitTransRect */ }; @@ -303,39 +300,6 @@ pVia->DGAViewportStatus = 0; /* MGAAdjustFrame loops until finished */ } - -static void -VIADGAFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned long color) -{ - VIAPtr pVia = VIAPTR(pScrn); - - if (pVia->AccelInfoRec) { - (*pVia->AccelInfoRec->SetupForSolidFill)(pScrn, color, GXcopy, ~0); - (*pVia->AccelInfoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); - SET_SYNC_FLAG(pVia->AccelInfoRec); - } -} - - -static void -VIADGABlitRect(ScrnInfoPtr pScrn, int srcx, int srcy, int w, int h, - int dstx, int dsty) -{ - VIAPtr pVia = VIAPTR(pScrn); - - if (pVia->AccelInfoRec) { - int xdir = ((srcx < dstx) && (srcy == dsty)) ? -1 : 1; - int ydir = (srcy < dsty) ? -1 : 1; - - (*pVia->AccelInfoRec->SetupForScreenToScreenCopy)( - pScrn, xdir, ydir, GXcopy, ~0, -1); - (*pVia->AccelInfoRec->SubsequentScreenToScreenCopy)( - pScrn, srcx, srcy, dstx, dsty, w, h); - SET_SYNC_FLAG(pVia->AccelInfoRec); - } -} - - static Bool VIADGAOpenFramebuffer( ScrnInfoPtr pScrn,