diff options
author | George Sapountzis <gsap7@yahoo.gr> | 2006-08-05 03:15:42 +0300 |
---|---|---|
committer | George Sapountzis <gsap7@yahoo.gr> | 2006-08-05 03:15:42 +0300 |
commit | e203d86643d5d70bf18248712d05b72b79aee705 (patch) | |
tree | 4d8cfcd6c37a5d0b7250b2a0837148ccd4e3e9b7 /src | |
parent | dc1e289a611a17090e6dc7ae8a8d3f26d20df4eb (diff) |
[mach64] EXA support.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/atiaccel.c | 2 | ||||
-rw-r--r-- | src/aticonfig.c | 22 | ||||
-rw-r--r-- | src/atidga.c | 15 | ||||
-rw-r--r-- | src/atidri.c | 67 | ||||
-rw-r--r-- | src/atiload.c | 71 | ||||
-rw-r--r-- | src/atiload.h | 15 | ||||
-rw-r--r-- | src/atimach64.c | 5 | ||||
-rw-r--r-- | src/atimach64accel.c | 15 | ||||
-rw-r--r-- | src/atimach64accel.h | 6 | ||||
-rw-r--r-- | src/atimach64exa.c | 622 | ||||
-rw-r--r-- | src/atimach64io.h | 70 | ||||
-rw-r--r-- | src/atimach64xv.c | 139 | ||||
-rw-r--r-- | src/atimisc.c | 12 | ||||
-rw-r--r-- | src/atioption.c | 7 | ||||
-rw-r--r-- | src/atioption.h | 3 | ||||
-rw-r--r-- | src/atiscreen.c | 38 | ||||
-rw-r--r-- | src/atistruct.h | 18 |
18 files changed, 1071 insertions, 59 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 22172a7..d31ac24 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,6 +42,7 @@ ATIMISC_DGA_SOURCES = atidga.c endif if USE_EXA +ATIMISC_EXA_SOURCES = atimach64exa.c RADEON_EXA_SOURCES = radeon_exa.c endif @@ -65,7 +66,7 @@ atimisc_drv_la_SOURCES = \ atimach64i2c.c atimach64io.c atimach64xv.c atimode.c atipreinit.c \ atiprint.c atirgb514.c atiscreen.c atituner.c atiutil.c ativalid.c \ atixv.c atiload.c atimisc.c $(ATIMISC_DRI_SRCS) $(ATIMISC_DGA_SOURCES) \ - $(ATIMISC_CPIO_SOURCES) + $(ATIMISC_CPIO_SOURCES) $(ATIMISC_EXA_SOURCES) r128_drv_la_LTLIBRARIES = r128_drv.la r128_drv_la_LDFLAGS = -module -avoid-version diff --git a/src/atiaccel.c b/src/atiaccel.c index 050019d..f573a63 100644 --- a/src/atiaccel.c +++ b/src/atiaccel.c @@ -33,6 +33,7 @@ #include "atimach64accel.h" #include "atistruct.h" +#ifdef USE_XAA /* * ATIInitializeAcceleration -- * @@ -144,3 +145,4 @@ ATIResizeOffscreenLinear return pLinear; } +#endif /* USE_XAA */ diff --git a/src/aticonfig.c b/src/aticonfig.c index 33b9519..dffabc7 100644 --- a/src/aticonfig.c +++ b/src/aticonfig.c @@ -153,6 +153,7 @@ ATIProcessOptions # define ProbeClocks PublicOption[ATI_OPTION_PROBE_CLOCKS].value.bool # define ShadowFB PublicOption[ATI_OPTION_SHADOW_FB].value.bool # define SWCursor PublicOption[ATI_OPTION_SWCURSOR].value.bool +# define AccelMethod PublicOption[ATI_OPTION_ACCELMETHOD].value.str # define LCDSync PrivateOption[ATI_OPTION_LCDSYNC].value.bool # define ReferenceClock \ @@ -340,5 +341,26 @@ ATIProcessOptions } } + pATI->useEXA = FALSE; + if (pATI->OptionAccel) + { + MessageType from = X_DEFAULT; +#if defined(USE_EXA) +#if defined(USE_XAA) + if (AccelMethod != NULL) + { + from = X_CONFIG; + if (xf86NameCmp(AccelMethod, "EXA") == 0) + pATI->useEXA = TRUE; + } +#else /* USE_XAA */ + pATI->useEXA = TRUE; +#endif /* !USE_XAA */ +#endif /* USE_EXA */ + xf86DrvMsg(pScreenInfo->scrnIndex, from, + "Using %s acceleration architecture\n", + pATI->useEXA ? "EXA" : "XAA"); + } + xfree(PublicOption); } diff --git a/src/atidga.c b/src/atidga.c index fff28f5..1c652a7 100644 --- a/src/atidga.c +++ b/src/atidga.c @@ -188,6 +188,8 @@ ATIDGAFillRect ) { ATIPtr pATI = ATIPTR(pScreenInfo); +/*FIXME : use EXA if available */ +#ifdef USE_XAA XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo; (*pXAAInfo->SetupForSolidFill)(pScreenInfo, (int)colour, GXcopy, @@ -196,6 +198,7 @@ ATIDGAFillRect if (pScreenInfo->bitsPerPixel == pATI->bitsPerPixel) SET_SYNC_FLAG(pXAAInfo); +#endif } /* @@ -217,6 +220,8 @@ ATIDGABlitRect ) { ATIPtr pATI = ATIPTR(pScreenInfo); +/*FIXME : use EXA if available */ +#ifdef USE_XAA XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo; int xdir = ((xSrc < xDst) && (ySrc == yDst)) ? -1 : 1; int ydir = (ySrc < yDst) ? -1 : 1; @@ -228,6 +233,7 @@ ATIDGABlitRect if (pScreenInfo->bitsPerPixel == pATI->bitsPerPixel) SET_SYNC_FLAG(pXAAInfo); +#endif } /* @@ -250,6 +256,8 @@ ATIDGABlitTransRect ) { ATIPtr pATI = ATIPTR(pScreenInfo); +/*FIXME : use EXA if available */ +#ifdef USE_XAA XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo; int xdir = ((xSrc < xDst) && (ySrc == yDst)) ? -1 : 1; int ydir = (ySrc < yDst) ? -1 : 1; @@ -266,6 +274,7 @@ ATIDGABlitTransRect if (pScreenInfo->bitsPerPixel == pATI->bitsPerPixel) SET_SYNC_FLAG(pXAAInfo); +#endif } /* @@ -335,8 +344,10 @@ ATIDGAAddModes pDGAMode->flags |= DGA_PIXMAP_AVAILABLE; pDGAMode->address = pATI->pMemory; +#ifdef USE_XAA if (pATI->pXAAInfo) pDGAMode->flags &= ~DGA_CONCURRENT_ACCESS; +#endif } if ((pMode->Flags & V_DBLSCAN) || (pMode->VScan > 1)) pDGAMode->flags |= DGA_DOUBLESCAN; @@ -397,7 +408,9 @@ ATIDGAInit ATIPtr pATI ) { +#ifdef USE_XAA XAAInfoRecPtr pXAAInfo; +#endif int flags; if (!pATI->nDGAMode) @@ -422,6 +435,7 @@ ATIDGAInit pATI->ATIDGAFunctions.GetViewport = ATIDGAGetViewport; flags = 0; +#ifdef USE_XAA if ((pXAAInfo = pATI->pXAAInfo)) { pATI->ATIDGAFunctions.Sync = pXAAInfo->Sync; @@ -439,6 +453,7 @@ ATIDGAInit pATI->ATIDGAFunctions.BlitTransRect = ATIDGABlitTransRect; } } +#endif if (!flags) flags = DGA_CONCURRENT_ACCESS; diff --git a/src/atidri.c b/src/atidri.c index 5155820..720c96a 100644 --- a/src/atidri.c +++ b/src/atidri.c @@ -293,9 +293,9 @@ static void ATIEnterServer( ScreenPtr pScreen ) ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; ATIPtr pATI = ATIPTR(pScreenInfo); - if ( pATI->directRenderingEnabled && pATI->pXAAInfo ) { - pATI->pXAAInfo->NeedToSync = TRUE; - pATI->NeedDRISync = TRUE; + if ( pATI->directRenderingEnabled ) { + ATIDRIMarkSyncInt(pScreenInfo); + ATIDRIMarkSyncExt(pScreenInfo); } } @@ -333,6 +333,7 @@ static void ATIDRISwapContext( ScreenPtr pScreen, } } +#ifdef USE_XAA static void ATIDRITransitionTo2d(ScreenPtr pScreen) { ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; @@ -400,10 +401,49 @@ static void ATIDRITransitionTo3d(ScreenPtr pScreen) pATI->have3DWindows = TRUE; } +#endif /* USE_XAA */ + +#ifdef USE_EXA +static void ATIDRITransitionTo2d_EXA(ScreenPtr pScreen) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); +#if 0 + ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; + + exaEnableDisableFBAccess(pScreen->myNum, FALSE); + + pATI->pExa->offScreenBase = pATIDRIServer->backOffset; + + exaEnableDisableFBAccess(pScreen->myNum, TRUE); +#endif + + pATI->have3DWindows = FALSE; +} + +static void ATIDRITransitionTo3d_EXA(ScreenPtr pScreen) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); +#if 0 + ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; + + exaEnableDisableFBAccess(pScreen->myNum, FALSE); + + pATI->pExa->offScreenBase = pATIDRIServer->textureOffset + + pATIDRIServer->textureSize; + + exaEnableDisableFBAccess(pScreen->myNum, TRUE); +#endif + + pATI->have3DWindows = TRUE; +} +#endif /* USE_EXA */ /* Initialize the state of the back and depth buffers. */ static void ATIDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, CARD32 indx ) { +#ifdef USE_XAA ScreenPtr pScreen = pWin->drawable.pScreen; ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; ATIPtr pATI = ATIPTR(pScreenInfo); @@ -454,7 +494,8 @@ static void ATIDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, CARD32 indx ) pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - pXAAInfo->NeedToSync = TRUE; + ATIDRIMarkSyncInt(pScreenInfo); +#endif } /* Copy the back and depth buffers when the X server moves a window. @@ -469,6 +510,7 @@ static void ATIDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, CARD32 indx ) static void ATIDRIMoveBuffers( WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc, CARD32 indx ) { +#ifdef USE_XAA ScreenPtr pScreen = pWin->drawable.pScreen; ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; ATIPtr pATI = ATIPTR(pScreenInfo); @@ -632,7 +674,8 @@ static void ATIDRIMoveBuffers( WindowPtr pWin, DDXPointRec ptOldOrg, DEALLOCATE_LOCAL(pptNew1); DEALLOCATE_LOCAL(pboxNew1); - pXAAInfo->NeedToSync = TRUE; + ATIDRIMarkSyncInt(pScreenInfo); +#endif } /* Compute log base 2 of val. */ @@ -1204,8 +1247,18 @@ Bool ATIDRIScreenInit( ScreenPtr pScreen ) pDRIInfo->SwapContext = ATIDRISwapContext; pDRIInfo->InitBuffers = ATIDRIInitBuffers; pDRIInfo->MoveBuffers = ATIDRIMoveBuffers; - pDRIInfo->TransitionTo2d = ATIDRITransitionTo2d; - pDRIInfo->TransitionTo3d = ATIDRITransitionTo3d; +#ifdef USE_XAA + if (!pATI->useEXA) { + pDRIInfo->TransitionTo2d = ATIDRITransitionTo2d; + pDRIInfo->TransitionTo3d = ATIDRITransitionTo3d; + } +#endif /* USE_XAA */ +#ifdef USE_EXA + if (pATI->useEXA) { + pDRIInfo->TransitionTo2d = ATIDRITransitionTo2d_EXA; + pDRIInfo->TransitionTo3d = ATIDRITransitionTo3d_EXA; + } +#endif /* USE_EXA */ pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; pDRIInfo->createDummyCtx = TRUE; diff --git a/src/atiload.c b/src/atiload.c index 7c901f6..83165bc 100644 --- a/src/atiload.c +++ b/src/atiload.c @@ -144,6 +144,19 @@ const char *ATIshadowfbSymbols[] = NULL }; +#ifdef USE_EXA +const char *ATIexaSymbols[] = +{ + "exaDriverAlloc", + "exaDriverInit", + "exaDriverFini", + "exaOffscreenAlloc", + "exaOffscreenFree", + NULL +}; +#endif + +#ifdef USE_XAA const char *ATIxaaSymbols[] = { "XAACreateInfoRec", @@ -151,6 +164,7 @@ const char *ATIxaaSymbols[] = "XAAInit", NULL }; +#endif const char *ATIramdacSymbols[] = { @@ -205,21 +219,13 @@ ATILoadModules ATIPtr pATI ) { + pointer fbPtr = NULL; + /* Load shadow frame buffer code if needed */ if (pATI->OptionShadowFB && !ATILoadModule(pScreenInfo, "shadowfb", ATIshadowfbSymbols)) return NULL; - /* Load XAA if needed */ - if (pATI->OptionAccel && - !ATILoadModule(pScreenInfo, "xaa", ATIxaaSymbols)) - return NULL; - - /* Load ramdac module if needed */ - if ((pATI->Cursor > ATI_CURSOR_SOFTWARE) && - !ATILoadModule(pScreenInfo, "ramdac", ATIramdacSymbols)) - return NULL; - /* Load depth-specific entry points */ switch (pATI->bitsPerPixel) { @@ -227,10 +233,12 @@ ATILoadModules #ifndef AVOID_CPIO case 1: - return ATILoadModule(pScreenInfo, "xf1bpp", ATIxf1bppSymbols); + fbPtr = ATILoadModule(pScreenInfo, "xf1bpp", ATIxf1bppSymbols); + break; case 4: - return ATILoadModule(pScreenInfo, "xf4bpp", ATIxf4bppSymbols); + fbPtr = ATILoadModule(pScreenInfo, "xf4bpp", ATIxf4bppSymbols); + break; #endif /* AVOID_CPIO */ @@ -238,11 +246,48 @@ ATILoadModules case 16: case 24: case 32: - return ATILoadModule(pScreenInfo, "fb", ATIfbSymbols); + fbPtr = ATILoadModule(pScreenInfo, "fb", ATIfbSymbols); + break; default: return NULL; } + if (!fbPtr) + return NULL; + + /* Load ramdac module if needed */ + if ((pATI->Cursor > ATI_CURSOR_SOFTWARE) && + !ATILoadModule(pScreenInfo, "ramdac", ATIramdacSymbols)) + return NULL; + +#ifdef USE_EXA + /* Load EXA if needed */ + if (pATI->useEXA && pATI->OptionAccel) + { + /* Cannot use ATILoadModule(), because of version checking */ + XF86ModReqInfo req; + int errmaj, errmin; + + memset(&req, 0, sizeof(XF86ModReqInfo)); + req.majorversion = 2; + req.minorversion = 0; + if (!LoadSubModule(pScreenInfo->module, "exa", NULL, NULL, NULL, &req, + &errmaj, &errmin)) + { + LoaderErrorMsg(NULL, "exa", errmaj, errmin); + return NULL; + } + xf86LoaderReqSymLists(ATIexaSymbols, NULL); + } +#endif +#ifdef USE_XAA + /* Load XAA if needed */ + if (!pATI->useEXA && pATI->OptionAccel && + !ATILoadModule(pScreenInfo, "xaa", ATIxaaSymbols)) + return NULL; +#endif + + return fbPtr; } #endif /* XFree86LOADER */ diff --git a/src/atiload.h b/src/atiload.h index 96606e3..49f2bf2 100644 --- a/src/atiload.h +++ b/src/atiload.h @@ -47,7 +47,20 @@ extern const char *ATIint10Symbols[], *ATIddcSymbols[], *ATIvbeSymbols[], #endif /* XF86DRI_DEVEL */ - *ATIfbSymbols[], *ATIshadowfbSymbols[], *ATIxaaSymbols[], + *ATIfbSymbols[], *ATIshadowfbSymbols[], + +#ifdef USE_EXA + + *ATIexaSymbols[], + +#endif /* USE_EXA */ + +#ifdef USE_XAA + + *ATIxaaSymbols[], + +#endif /* USE_XAA */ + *ATIramdacSymbols[], *ATIi2cSymbols[]; extern pointer ATILoadModule(ScrnInfoPtr, const char *, const char **); diff --git a/src/atimach64.c b/src/atimach64.c index 2cdec78..5cb991d 100644 --- a/src/atimach64.c +++ b/src/atimach64.c @@ -854,9 +854,7 @@ ATIMach64Set outf(HOST_CNTL, pATIHW->host_cntl); /* Set host transfer window address and size clamp */ - pATI->pHOST_DATA = - (CARD8 *)pATI->pBlock[GetBits(HOST_DATA_0, BLOCK_SELECT)] + - (HOST_DATA_0 & MM_IO_SELECT); + pATI->pHOST_DATA = ATIHostDataAddr(HOST_DATA_0); pATI->nHostFIFOEntries = pATI->nFIFOEntries >> 1; if (pATI->nHostFIFOEntries > 16) pATI->nHostFIFOEntries = 16; @@ -980,6 +978,7 @@ ATIMach64Set CacheRegister(DP_BKGD_CLR); CacheRegister(DP_FRGD_CLR); CacheRegister(DP_WRITE_MASK); + CacheRegister(DP_PIX_WIDTH); CacheRegister(DP_MIX); CacheRegister(CLR_CMP_CLR); diff --git a/src/atimach64accel.c b/src/atimach64accel.c index 272de3d..b9d312e 100644 --- a/src/atimach64accel.c +++ b/src/atimach64accel.c @@ -79,7 +79,7 @@ /* * X-to-Mach64 mix translation table. */ -static CARD8 ATIMach64ALU[16] = +CARD8 ATIMach64ALU[16] = { MIX_0, /* GXclear */ MIX_AND, /* GXand */ @@ -105,7 +105,7 @@ static CARD8 ATIMach64ALU[16] = * This function ensures the current scissor settings do not interfere with * the current draw request. */ -static void +void ATIMach64ValidateClip ( ATIPtr pATI, @@ -162,6 +162,7 @@ ATIMach64Sync UncacheRegister(DP_BKGD_CLR); UncacheRegister(DP_FRGD_CLR); UncacheRegister(DP_WRITE_MASK); + UncacheRegister(DP_PIX_WIDTH); UncacheRegister(DP_MIX); UncacheRegister(CLR_CMP_CNTL); } @@ -207,6 +208,7 @@ ATIMach64Sync CacheRegister(DP_BKGD_CLR); CacheRegister(DP_FRGD_CLR); CacheRegister(DP_WRITE_MASK); + CacheRegister(DP_PIX_WIDTH); CacheRegister(DP_MIX); CacheRegister(CLR_CMP_CNTL); } @@ -245,8 +247,14 @@ ATIMach64Sync } } +#ifdef USE_EXA + /* EXA sets pEXA->needsSync to FALSE on its own */ +#endif + +#ifdef USE_XAA if (pATI->pXAAInfo) pATI->pXAAInfo->NeedToSync = FALSE; +#endif if (pATI->Chip >= ATI_CHIP_264VTB) { @@ -307,6 +315,7 @@ TestRegisterCachingDP(ScrnInfoPtr pScreenInfo) TestRegisterCaching(DP_BKGD_CLR); TestRegisterCaching(DP_FRGD_CLR); TestRegisterCaching(DP_WRITE_MASK); + TestRegisterCaching(DP_PIX_WIDTH); TestRegisterCaching(DP_MIX); TestRegisterCaching(CLR_CMP_CLR); @@ -373,6 +382,7 @@ TestRegisterCachingXV(ScrnInfoPtr pScreenInfo) TestRegisterCaching(SCALER_BUF1_OFFSET_V); } +#ifdef USE_XAA /* * ATIMach64SetupForScreenToScreenCopy -- * @@ -1031,3 +1041,4 @@ ATIMach64AccelInit return ATIMach64MaxY; } +#endif /* USE_XAA */ diff --git a/src/atimach64accel.h b/src/atimach64accel.h index a1b9426..2917b7a 100644 --- a/src/atimach64accel.h +++ b/src/atimach64accel.h @@ -27,11 +27,17 @@ #include "atipriv.h" #include "xaa.h" +#include "exa.h" #define ATIMach64MaxX 8191 #define ATIMach64MaxY 32767 +#ifdef USE_EXA +extern Bool ATIMach64ExaInit(ScreenPtr); +#endif +#ifdef USE_XAA extern int ATIMach64AccelInit(ATIPtr, XAAInfoRecPtr); +#endif extern void ATIMach64Sync(ScrnInfoPtr); #endif /* ___ATIMACH64ACCEL_H___ */ diff --git a/src/atimach64exa.c b/src/atimach64exa.c new file mode 100644 index 0000000..c68495b --- /dev/null +++ b/src/atimach64exa.c @@ -0,0 +1,622 @@ +/* + * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +/* + * Copyright 1999-2000 Precision Insight, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (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 + * PRECISION INSIGHT AND/OR ITS SUPPLIERS 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. + */ +/* + * DRI support by: + * Manuel Teira + * Leif Delgass <ldelgass@retinalburn.net> + * + * EXA support by: + * Jakub Stachowski <qbast@go2.pl> + * George Sapountzis <gsap7@yahoo.gr> + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "ati.h" +#include "atichip.h" +#include "atidri.h" +#include "atimach64accel.h" +#include "atimach64io.h" +#include "atipriv.h" +#include "atiregs.h" + +#ifdef XF86DRI_DEVEL +#include "mach64_dri.h" +#include "mach64_sarea.h" +#endif + +#ifdef USE_EXA +extern CARD8 ATIMach64ALU[]; + +extern void +ATIMach64ValidateClip +( + ATIPtr pATI, + int sc_left, + int sc_right, + int sc_top, + int sc_bottom +); + +#if 0 +#define MACH64_TRACE(x) \ +do { \ + ErrorF("Mach64(%s): ", __FUNCTION__); \ + ErrorF x; \ +} while(0) +#else +#define MACH64_TRACE(x) do { } while(0) +#endif + +#if 0 +#define MACH64_FALLBACK(x) \ +do { \ + ErrorF("Fallback(%s): ", __FUNCTION__); \ + ErrorF x; \ + return FALSE; \ +} while (0) +#else +#define MACH64_FALLBACK(x) return FALSE +#endif + +static void +Mach64WaitMarker(ScreenPtr pScreenInfo, int Marker) +{ + ATIMach64Sync(xf86Screens[pScreenInfo->myNum]); +} + +static Bool +Mach64GetDatatypeBpp(PixmapPtr pPix, CARD32 *pix_width) +{ + int bpp = pPix->drawable.bitsPerPixel; + + switch (bpp) { + case 8: + *pix_width = + SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) | + SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) | + SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); + break; + case 16: + *pix_width = + SetBits(PIX_WIDTH_16BPP, DP_DST_PIX_WIDTH) | + SetBits(PIX_WIDTH_16BPP, DP_SRC_PIX_WIDTH) | + SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); + break; + case 24: + *pix_width = + SetBits(PIX_WIDTH_8BPP, DP_DST_PIX_WIDTH) | + SetBits(PIX_WIDTH_8BPP, DP_SRC_PIX_WIDTH) | + SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); + break; + case 32: + *pix_width = + SetBits(PIX_WIDTH_32BPP, DP_DST_PIX_WIDTH) | + SetBits(PIX_WIDTH_32BPP, DP_SRC_PIX_WIDTH) | + SetBits(PIX_WIDTH_1BPP, DP_HOST_PIX_WIDTH); + break; + default: + MACH64_FALLBACK(("Unsupported bpp: %d\n", bpp)); + } + +#if X_BYTE_ORDER == X_LITTLE_ENDIAN + + *pix_width |= DP_BYTE_PIX_ORDER; + +#endif /* X_BYTE_ORDER */ + + return TRUE; +} + +static Bool +Mach64GetOffsetPitch(PixmapPtr pPix, int bpp, CARD32 *pitch_offset, + unsigned int offset, unsigned int pitch) +{ +#if 0 + ScrnInfoPtr pScreenInfo = xf86Screens[pPix->drawable.pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); + + if (pitch % pATI->pExa->pixmapPitchAlign != 0) + MACH64_FALLBACK(("Bad pitch 0x%08x\n", pitch)); + + if (offset % pATI->pExa->pixmapOffsetAlign != 0) + MACH64_FALLBACK(("Bad offset 0x%08x\n", offset)); +#endif + + /* pixels / 8 = ((bytes * 8) / bpp) / 8 = bytes / bpp */ + pitch = pitch / bpp; + + /* bytes / 8 */ + offset = offset >> 3; + + *pitch_offset = ((pitch << 22) | (offset << 0)); + + return TRUE; +} + +static Bool +Mach64GetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch_offset) +{ + CARD32 pitch, offset; + int bpp; + + bpp = pPix->drawable.bitsPerPixel; + if (bpp == 24) + bpp = 8; + + pitch = exaGetPixmapPitch(pPix); + offset = exaGetPixmapOffset(pPix); + + return Mach64GetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch); +} + +static Bool +Mach64PrepareCopy +( + PixmapPtr pSrcPixmap, + PixmapPtr pDstPixmap, + int xdir, + int ydir, + int alu, + Pixel planemask +) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); + CARD32 src_pitch_offset, dst_pitch_offset, dp_pix_width; + + ATIDRISync(pScreenInfo); + + if (!Mach64GetDatatypeBpp(pDstPixmap, &dp_pix_width)) + return FALSE; + if (!Mach64GetPixmapOffsetPitch(pSrcPixmap, &src_pitch_offset)) + return FALSE; + if (!Mach64GetPixmapOffsetPitch(pDstPixmap, &dst_pitch_offset)) + return FALSE; + + ATIMach64WaitForFIFO(pATI, 7); + outf(DP_WRITE_MASK, planemask); + outf(DP_PIX_WIDTH, dp_pix_width); + outf(SRC_OFF_PITCH, src_pitch_offset); + outf(DST_OFF_PITCH, dst_pitch_offset); + + outf(DP_SRC, DP_MONO_SRC_ALLONES | + SetBits(SRC_BLIT, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC)); + outf(DP_MIX, SetBits(ATIMach64ALU[alu], DP_FRGD_MIX)); + + outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE); + + pATI->dst_cntl = 0; + + if (ydir > 0) + pATI->dst_cntl |= DST_Y_DIR; + if (xdir > 0) + pATI->dst_cntl |= DST_X_DIR; + + if (pATI->XModifier == 1) + outf(DST_CNTL, pATI->dst_cntl); + else + pATI->dst_cntl |= DST_24_ROT_EN; + + return TRUE; +} + +static void +Mach64Copy +( + PixmapPtr pDstPixmap, + int srcX, + int srcY, + int dstX, + int dstY, + int w, + int h +) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); + + srcX *= pATI->XModifier; + dstY *= pATI->XModifier; + w *= pATI->XModifier; + + ATIDRISync(pScreenInfo); + + /* Disable clipping if it gets in the way */ + ATIMach64ValidateClip(pATI, dstX, dstX + w - 1, dstY, dstY + h - 1); + + if (!(pATI->dst_cntl & DST_X_DIR)) + { + srcX += w - 1; + dstX += w - 1; + } + + if (!(pATI->dst_cntl & DST_Y_DIR)) + { + srcY += h - 1; + dstY += h - 1; + } + + if (pATI->XModifier != 1) + outf(DST_CNTL, pATI->dst_cntl | SetBits((dstX / 4) % 6, DST_24_ROT)); + + ATIMach64WaitForFIFO(pATI, 4); + outf(SRC_Y_X, SetWord(srcX, 1) | SetWord(srcY, 0)); + outf(SRC_WIDTH1, w); + outf(DST_Y_X, SetWord(dstX, 1) | SetWord(dstY, 0)); + outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0)); + + /* + * On VTB's and later, the engine will randomly not wait for a copy + * operation to commit its results to video memory before starting the next + * one. The probability of such occurrences increases with GUI_WB_FLUSH + * (or GUI_WB_FLUSH_P) setting, bitsPerPixel and/or CRTC clock. This + * would point to some kind of video memory bandwidth problem were it noti + * for the fact that the problem occurs less often (but still occurs) when + * copying larger rectangles. + */ + if ((pATI->Chip >= ATI_CHIP_264VTB) && !pATI->OptionDevel) + { + exaMarkSync(pScreenInfo->pScreen); /* Force sync. */ + exaWaitSync(pScreenInfo->pScreen); /* Sync and notify EXA. */ + } +} + +static void Mach64DoneCopy(PixmapPtr pDstPixmap) { } + +static Bool +Mach64PrepareSolid +( + PixmapPtr pPixmap, + int alu, + Pixel planemask, + Pixel fg +) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pPixmap->drawable.pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); + CARD32 dst_pitch_offset, dp_pix_width; + + ATIDRISync(pScreenInfo); + + if (!Mach64GetDatatypeBpp(pPixmap, &dp_pix_width)) + return FALSE; + if (!Mach64GetPixmapOffsetPitch(pPixmap, &dst_pitch_offset)) + return FALSE; + + ATIMach64WaitForFIFO(pATI, 7); + outf(DP_WRITE_MASK, planemask); + outf(DP_PIX_WIDTH, dp_pix_width); + outf(DST_OFF_PITCH, dst_pitch_offset); + + outf(DP_SRC, DP_MONO_SRC_ALLONES | + SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC)); + outf(DP_FRGD_CLR, fg); + outf(DP_MIX, SetBits(ATIMach64ALU[alu], DP_FRGD_MIX)); + + outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE); + + if (pATI->XModifier == 1) + outf(DST_CNTL, DST_X_DIR | DST_Y_DIR); + + return TRUE; +} + +static void +Mach64Solid +( + PixmapPtr pPixmap, + int x1, + int y1, + int x2, + int y2 +) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pPixmap->drawable.pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); + + int x = x1; + int y = y1; + int w = x2-x1; + int h = y2-y1; + + ATIDRISync(pScreenInfo); + + if (pATI->XModifier != 1) + { + x *= pATI->XModifier; + w *= pATI->XModifier; + + outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) | + (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)); + } + + /* Disable clipping if it gets in the way */ + ATIMach64ValidateClip(pATI, x, x + w - 1, y, y + h - 1); + + ATIMach64WaitForFIFO(pATI, 2); + outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0)); + outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0)); +} + +static void Mach64DoneSolid(PixmapPtr pPixmap) { } + +/* Compute log base 2 of val. */ +static __inline__ int Mach64Log2(int val) +{ + int bits; + + for (bits = 0; val != 0; val >>= 1, ++bits) + ; + return bits - 1; +} + +/* + * Memory layour for EXA with DRI (no local_textures): + * | front | back | depth | textures | pixmaps, xv | c | + * + * 1024x768@16bpp with 8 MB: + * | 1.5 MB | 1.5 MB | 1.5 MB | 0 | ~3.5 MB | c | + * + * 1024x768@32bpp with 8 MB: + * | 3.0 MB | 3.0 MB | 1.5 MB | 0 | ~0.5 MB | c | + * + * "c" is the hw cursor which occupies 1KB + */ +static void +Mach64SetupMemEXA(ScreenPtr pScreen) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); + + int cpp = (pScreenInfo->bitsPerPixel + 7) / 8; + /* front and back buffer */ + int bufferSize = pScreenInfo->virtualY * pScreenInfo->displayWidth * cpp; + /* always 16-bit z-buffer */ + int depthSize = pScreenInfo->virtualY * pScreenInfo->displayWidth * 2; + + ExaDriverPtr pExa = pATI->pExa; + + pExa->memoryBase = pATI->pMemory; + pExa->memorySize = pScreenInfo->videoRam * 1024; + pExa->offScreenBase = bufferSize; + +#ifdef XF86DRI_DEVEL + if (pATI->directRenderingEnabled) + { + ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; + Bool is_pci = pATIDRIServer->IsPCI; + + int textureSize = 0; + int pixmapCache = 0; + int next = 0; + + /* front buffer */ + pATIDRIServer->frontOffset = 0; + pATIDRIServer->frontPitch = pScreenInfo->displayWidth; + next += bufferSize; + + /* back buffer */ + pATIDRIServer->backOffset = next; + pATIDRIServer->backPitch = pScreenInfo->displayWidth; + next += bufferSize; + + /* depth buffer */ + pATIDRIServer->depthOffset = next; + pATIDRIServer->depthPitch = pScreenInfo->displayWidth; + next += depthSize; + + /* ATIScreenInit does check for the this condition. */ + if (next > pExa->memorySize) + { + xf86DrvMsg(pScreen->myNum, X_WARNING, + "DRI static buffer allocation failed, disabling DRI --" + "need at least %d kB video memory\n", next / 1024 ); + ATIDRICloseScreen(pScreen); + pATI->directRenderingEnabled = FALSE; + } + + /* local textures */ + + /* Reserve approx. half of offscreen memory for local textures */ + textureSize = (pExa->memorySize - next) / 2; + + /* In case DRI requires more offscreen memory than available, + * should not happen as ATIScreenInit would have not enabled DRI */ + if (textureSize < 0) + textureSize = 0; + + /* Try for enough pixmap cache for a full viewport */ + pixmapCache = (pExa->memorySize - next) - textureSize; + if (pixmapCache < bufferSize) + textureSize = 0; + + /* Don't allocate a local texture heap for AGP unless requested */ + if ( !is_pci && !pATI->OptionLocalTextures ) + textureSize = 0; + + if (textureSize > 0) + { + int l = Mach64Log2(textureSize / MACH64_NR_TEX_REGIONS); + if (l < MACH64_LOG_TEX_GRANULARITY) + l = MACH64_LOG_TEX_GRANULARITY; + pATIDRIServer->logTextureGranularity = l; + + /* Round the texture size down to the nearest whole number of + * texture regions. + */ + textureSize = (textureSize >> l) << l; + } + + /* Set a minimum usable local texture heap size. This will fit + * two 256x256 textures. We check this after any rounding of + * the texture area. + */ + if (textureSize < 256*256 * cpp * 2) + textureSize = 0; + + /* Disable DRI for PCI if cannot allocate a local texture heap */ + if ( is_pci && textureSize == 0 ) + { + xf86DrvMsg(pScreen->myNum, X_WARNING, + "Not enough memory for local textures, disabling DRI\n"); + ATIDRICloseScreen(pScreen); + pATI->directRenderingEnabled = FALSE; + } + + pATIDRIServer->textureOffset = next; + pATIDRIServer->textureSize = textureSize; + next += textureSize; + + if (pATI->directRenderingEnabled) + pExa->offScreenBase = next; + } +#endif /* XF86DRI_DEVEL */ + + xf86DrvMsg(pScreen->myNum, X_INFO, + "EXA memory management initialized\n" + "\t base : %10p\n" + "\t offscreen: +%10lx\n" + "\t size : +%10lx\n" + "\t cursor : %10p\n", + pExa->memoryBase, + pExa->offScreenBase, + pExa->memorySize, + pATI->pCursorImage); + + if (TRUE || xf86GetVerbosity() > 1) + { + int offscreen = pExa->memorySize - pExa->offScreenBase; + int viewport = bufferSize; + int dvdframe = 720*480*cpp; /* enough for single-buffered DVD */ + + xf86DrvMsg(pScreen->myNum, X_INFO, + "Will use %d kB of offscreen memory for EXA\n" + "\t\t or %5.2f viewports (composite)\n" + "\t\t or %5.2f dvdframes (xvideo)\n", + offscreen / 1024, + 1.0 * offscreen / viewport, + 1.0 * offscreen / dvdframe); + } + +#ifdef XF86DRI_DEVEL + if (pATI->directRenderingEnabled) + { + ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo; + + xf86DrvMsg(pScreen->myNum, X_INFO, + "Will use back buffer at offset 0x%x\n", + pATIDRIServer->backOffset); + + xf86DrvMsg(pScreen->myNum, X_INFO, + "Will use depth buffer at offset 0x%x\n", + pATIDRIServer->depthOffset); + + if (pATIDRIServer->textureSize > 0) + { + xf86DrvMsg(pScreen->myNum, X_INFO, + "Will use %d kB for local textures at offset 0x%x\n", + pATIDRIServer->textureSize/1024, + pATIDRIServer->textureOffset); + } + } +#endif /* XF86DRI_DEVEL */ + + pExa->pixmapOffsetAlign = 64; + pExa->pixmapPitchAlign = 64; + + pExa->flags = EXA_OFFSCREEN_PIXMAPS; + + pExa->maxX = ATIMach64MaxX; + pExa->maxY = ATIMach64MaxY; +} + +Bool ATIMach64ExaInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum]; + ATIPtr pATI = ATIPTR(pScreenInfo); + ExaDriverPtr pExa; + + /* FIXME: which chips support EXA ? */ + if (pATI->Chip < ATI_CHIP_264CT) + { + xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR, + "EXA is not supported for ATI chips earlier than " + "the ATI Mach64.\n"); + return FALSE; + } + + pExa = exaDriverAlloc(); + if (!pExa) + return FALSE; + + pATI->pExa = pExa; + + pExa->exa_major = 2; + pExa->exa_minor = 0; + + Mach64SetupMemEXA(pScreen); + + pExa->WaitMarker = Mach64WaitMarker; + + pExa->PrepareSolid = Mach64PrepareSolid; + pExa->Solid = Mach64Solid; + pExa->DoneSolid = Mach64DoneSolid; + + pExa->PrepareCopy = Mach64PrepareCopy; + pExa->Copy = Mach64Copy; + pExa->DoneCopy = Mach64DoneCopy; + + if (!exaDriverInit(pScreen, pATI->pExa)) { + xfree(pATI->pExa); + pATI->pExa = NULL; + return FALSE; + } + + return TRUE; +} +#endif diff --git a/src/atimach64io.h b/src/atimach64io.h index 9dbf244..e2d3c7c 100644 --- a/src/atimach64io.h +++ b/src/atimach64io.h @@ -206,6 +206,10 @@ extern void ATIMach64PollEngineStatus(ATIPtr); #ifdef XF86DRI_DEVEL +/* + * DRI Sync and Lock definitions. + */ + #define ATIDRIWaitForIdle(_pATI) \ do { \ ATIDRIServerInfoPtr pATIDRIServer = _pATI->pDRIServerInfo; \ @@ -226,6 +230,53 @@ do { \ } \ } while (0) +/* + * Set upon DRISwapContext and when DRI accesses the GPU engine + * from within the server, see DRIInitBuffers/DRIMoveBuffers. + * + * Forces the EXA/XAA software paths to sync before accessing the FB memory. + */ +static __inline__ void ATIDRIMarkSyncInt(ScrnInfoPtr _pScrInfo) +{ + ATIPtr _pATI=ATIPTR(_pScrInfo); +#ifdef USE_EXA + if (_pATI->useEXA) + exaMarkSync(_pScrInfo->pScreen); +#endif +#ifdef USE_XAA + if (!_pATI->useEXA) + SET_SYNC_FLAG(_pATI->pXAAInfo); /* NeedToSync = TRUE */ +#endif +} + +/* + * Set upon DRISwapContext and when the server acquires the DRI lock. + * + * Forces the EXA/XAA accelerated paths to sync before accessing the GPU engine. + */ +static __inline__ void ATIDRIMarkSyncExt(ScrnInfoPtr _pScrInfo) +{ + ATIPtr _pATI=ATIPTR(_pScrInfo); + _pATI->NeedDRISync = TRUE; +} + +static __inline__ void ATIDRISync(ScrnInfoPtr _pScrInfo) +{ + ATIPtr _pATI=ATIPTR(_pScrInfo); +#ifdef USE_EXA + if (_pATI->directRenderingEnabled && _pATI->pExa) + { + if (_pATI->NeedDRISync) exaWaitSync(_pScrInfo->pScreen); + } +#endif +#ifdef USE_XAA + if (_pATI->directRenderingEnabled && _pATI->pXAAInfo) + { + if (_pATI->NeedDRISync) (*_pATI->pXAAInfo->Sync)(_pScrInfo); + } +#endif +} + #define ATIDRILock(_pScrInfo) \ do \ { \ @@ -233,7 +284,7 @@ do \ if (_pATI->directRenderingEnabled) \ { \ DRILock(_pScrInfo->pScreen, 0); \ - pATI->NeedDRISync = TRUE; \ + ATIDRIMarkSyncExt(_pScrInfo); \ } \ } while (0) @@ -247,16 +298,6 @@ do \ } \ } while (0) -#define ATIDRISync(_pScrInfo) \ -do \ -{ \ - ATIPtr _pATI=ATIPTR(_pScrInfo); \ - if (_pATI->directRenderingEnabled && _pATI->pXAAInfo) \ - { \ - if (_pATI->NeedDRISync) (*_pATI->pXAAInfo->Sync)(_pScrInfo); \ - } \ -} while (0) - #else /* XF86DRI_DEVEL */ @@ -368,4 +409,11 @@ extern void ATIMach64AccessPLLReg(ATIPtr, const CARD8, const Bool); #endif +/* + * Return the MMIO address of register, used for HOST_DATA_X only. + */ +#define ATIHostDataAddr(_Register) \ + ((CARD8 *)pATI->pBlock[GetBits(_Register, BLOCK_SELECT)] + \ + ((_Register) & MM_IO_SELECT)) + #endif /* ___ATIMACH64IO_H___ */ diff --git a/src/atimach64xv.c b/src/atimach64xv.c index 75cda6c..b72f88f 100644 --- a/src/atimach64xv.c +++ b/src/atimach64xv.c @@ -501,6 +501,25 @@ ATIMach64GetPortAttribute return Success; } +static pointer +ATIMach64XVMemAlloc +( + ScreenPtr pScreen, + pointer pVideo, + int size, + int *offset, + ATIPtr pATI +); + +static void +ATIMach64XVMemFree +( + ScreenPtr pScreen, + pointer pVideo, + ATIPtr pATI +); + +#ifdef USE_XAA /* * ATIMach64RemoveLinearCallback -- * @@ -519,6 +538,7 @@ ATIMach64RemoveLinearCallback pATI->pXVBuffer = NULL; outf(OVERLAY_SCALE_CNTL, SCALE_EN); } +#endif /* USE_XAA */ /* * ATIMach64StopVideo -- @@ -543,19 +563,23 @@ ATIMach64StopVideo REGION_EMPTY(pScreen, &pATI->VideoClip); - if (!Cleanup) +#ifdef USE_XAA + if (!pATI->useEXA && !Cleanup) { /* * Free offscreen buffer if/when its allocation is needed by XAA's * pixmap cache. */ - if (pATI->pXVBuffer) - pATI->pXVBuffer->RemoveLinearCallback = + FBLinearPtr linear = (FBLinearPtr)pATI->pXVBuffer; + if (linear) + linear->RemoveLinearCallback = ATIMach64RemoveLinearCallback; return; } +#endif /* USE_XAA */ - pATI->pXVBuffer = ATIResizeOffscreenLinear(pScreen, pATI->pXVBuffer, 0); + ATIMach64XVMemFree(pScreen, pATI->pXVBuffer, pATI); + pATI->pXVBuffer = NULL; outf(OVERLAY_SCALE_CNTL, SCALE_EN); } @@ -956,6 +980,7 @@ ATIMach64PutImage int SrcTop, SrcLeft, DstWidth, DstHeight; int Top, Bottom, Left, Right, nLine, nPixel, Offset; int OffsetV, OffsetU; + int XVOffset; int tmp; CARD8 *pDst; @@ -981,11 +1006,11 @@ ATIMach64PutImage */ DstPitch = /* bytes */ (DstWidth + DstWidth + 15) & ~15; - DstSize = /* pixels */ - ((DstPitch * DstHeight) + pATI->AdjustDepth - 1) / pATI->AdjustDepth; + DstSize = /* bytes */ + (DstPitch * DstHeight); - pATI->pXVBuffer = ATIResizeOffscreenLinear(pScreen, pATI->pXVBuffer, - (pATI->DoubleBuffer + 1) * DstSize); + pATI->pXVBuffer = ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer, + (pATI->DoubleBuffer + 1) * DstSize, &XVOffset, pATI); if (!pATI->pXVBuffer) { @@ -993,7 +1018,7 @@ ATIMach64PutImage return BadAlloc; pATI->pXVBuffer = - ATIResizeOffscreenLinear(pScreen, pATI->pXVBuffer, DstSize); + ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer, DstSize, &XVOffset, pATI); if (!pATI->pXVBuffer) return BadAlloc; @@ -1012,8 +1037,7 @@ ATIMach64PutImage /* Synchronise video memory accesses */ ATIMach64Sync(pScreenInfo); - Offset = (pATI->pXVBuffer->offset * pATI->AdjustDepth) + - (pATI->CurrentBuffer * DstSize * pATI->AdjustDepth); + Offset = XVOffset + pATI->CurrentBuffer * DstSize; pDst = pATI->pMemoryLE; pDst += Offset; @@ -1113,6 +1137,7 @@ ATIMach64AllocateSurface { ScreenPtr pScreen; ATIPtr pATI = ATIPTR(pScreenInfo); + int XVOffset; if (pATI->ActiveSurface) return BadAlloc; @@ -1126,13 +1151,12 @@ ATIMach64AllocateSurface pScreen = pScreenInfo->pScreen; - pATI->pXVBuffer = ATIResizeOffscreenLinear(pScreen, pATI->pXVBuffer, - ((Height * pATI->SurfacePitch) + pATI->AdjustDepth - 1) / - pATI->AdjustDepth); + pATI->pXVBuffer = ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer, + Height * pATI->SurfacePitch, &XVOffset, pATI); if (!pATI->pXVBuffer) return BadAlloc; - pATI->SurfaceOffset = pATI->pXVBuffer->offset * pATI->AdjustDepth; + pATI->SurfaceOffset = XVOffset; pSurface->pScrn = pScreenInfo; pSurface->id = ImageID; @@ -1167,8 +1191,8 @@ ATIMach64FreeSurface return Success; outf(OVERLAY_SCALE_CNTL, SCALE_EN); - pATI->pXVBuffer = ATIResizeOffscreenLinear(pSurface->pScrn->pScreen, - pATI->pXVBuffer, 0); + ATIMach64XVMemFree(pSurface->pScrn->pScreen, pATI->pXVBuffer, pATI); + pATI->pXVBuffer = NULL; pATI->ActiveSurface = FALSE; return Success; @@ -1498,3 +1522,84 @@ ATIMach64CloseXVideo REGION_UNINIT(pScreen, &pATI->VideoClip); } + +static pointer +ATIMach64XVMemAlloc +( + ScreenPtr pScreen, + pointer pVideo, + int size, + int *offset, + ATIPtr pATI +) +{ +#ifdef USE_EXA + if (pATI->useEXA) { + ExaOffscreenArea *area = (ExaOffscreenArea *)pVideo; + + if (area != NULL) { + if (area->size >= size) { + *offset = area->offset; + return area; + } + + exaOffscreenFree(pScreen, area); + } + + area = exaOffscreenAlloc(pScreen, size, 64, TRUE, NULL, NULL); + if (area != NULL) { + *offset = area->offset; + return area; + } + } +#endif /* USE_EXA */ + +#ifdef USE_XAA + if (!pATI->useEXA) { + FBLinearPtr linear = (FBLinearPtr)pVideo; + int cpp = pATI->AdjustDepth; + + /* XAA allocates in units of pixels at the screen bpp, so adjust size + * appropriately. + */ + size = (size + cpp - 1) / cpp; + + linear = ATIResizeOffscreenLinear(pScreen, linear, size); + if (linear != NULL) { + *offset = linear->offset * cpp; + return linear; + } + } +#endif /* USE_XAA */ + + *offset = 0; + return NULL; +} + +static void +ATIMach64XVMemFree +( + ScreenPtr pScreen, + pointer pVideo, + ATIPtr pATI +) +{ +#ifdef USE_EXA + if (pATI->useEXA) { + ExaOffscreenArea *area = (ExaOffscreenArea *)pVideo; + + if (area != NULL) + exaOffscreenFree(pScreen, area); + } +#endif /* USE_EXA */ + +#ifdef USE_XAA + if (!pATI->useEXA) { + FBLinearPtr linear = (FBLinearPtr)pVideo; + + if (linear != NULL) + ATIResizeOffscreenLinear(pScreen, linear, 0); + } +#endif /* USE_XAA */ +} + diff --git a/src/atimisc.c b/src/atimisc.c index de118c0..ee4b518 100644 --- a/src/atimisc.c +++ b/src/atimisc.c @@ -127,7 +127,19 @@ ATISetup ATIfbSymbols, ATIshadowfbSymbols, + +#ifdef USE_EXA + + ATIexaSymbols, + +#endif /* USE_EXA */ + +#ifdef USE_XAA + ATIxaaSymbols, + +#endif /* USE_XAA */ + ATIramdacSymbols, ATIi2cSymbols, NULL); diff --git a/src/atioption.c b/src/atioption.c index 6c862ed..28bac3a 100644 --- a/src/atioption.c +++ b/src/atioption.c @@ -219,6 +219,13 @@ const OptionInfoRec ATIPublicOptions[] = FALSE, }, { + ATI_OPTION_ACCELMETHOD, + "AccelMethod", + OPTV_STRING, + {0, }, + FALSE + }, + { -1, NULL, OPTV_NONE, diff --git a/src/atioption.h b/src/atioption.h index 51778a4..836e911 100644 --- a/src/atioption.h +++ b/src/atioption.h @@ -69,7 +69,8 @@ typedef enum ATI_OPTION_PROBE_CLOCKS, ATI_OPTION_REFERENCE_CLOCK, ATI_OPTION_SHADOW_FB, - ATI_OPTION_SWCURSOR + ATI_OPTION_SWCURSOR, + ATI_OPTION_ACCELMETHOD } ATIPublicOptionType; #ifdef TV_OUT diff --git a/src/atiscreen.c b/src/atiscreen.c index 134129c..7dff827 100644 --- a/src/atiscreen.c +++ b/src/atiscreen.c @@ -329,6 +329,10 @@ ATIScreenInit #endif /* AVOID_CPIO */ +#ifdef USE_XAA + + if (!pATI->useEXA) { + /* Memory manager setup */ #ifdef XF86DRI_DEVEL @@ -509,6 +513,21 @@ ATIScreenInit if (!ATIInitializeAcceleration(pScreen, pScreenInfo, pATI)) return FALSE; + } + +#endif /* USE_XAA */ + +#ifdef USE_EXA + + if (pATI->useEXA) { + /* EXA setups both memory manager and acceleration here */ + + if (pATI->OptionAccel && !ATIMach64ExaInit(pScreen)) + return FALSE; + } + +#endif /* USE_EXA */ + #ifndef AVOID_DGA /* Initialise DGA support */ @@ -623,11 +642,21 @@ ATICloseScreen ATICloseXVideo(pScreen, pScreenInfo, pATI); +#ifdef USE_EXA + if (pATI->pExa) + { + exaDriverFini(pScreen); + xfree(pATI->pExa); + pATI->pExa = NULL; + } +#endif +#ifdef USE_XAA if (pATI->pXAAInfo) { XAADestroyInfoRec(pATI->pXAAInfo); pATI->pXAAInfo = NULL; } +#endif if ((pScreen->CloseScreen = pATI->CloseScreen)) { @@ -645,9 +674,14 @@ ATICloseScreen ATILeaveGraphics(pScreenInfo, pATI); - xfree(pATI->ExpansionBitmapScanlinePtr[1]); - pATI->ExpansionBitmapScanlinePtr[0] = +#ifdef USE_XAA + if (!pATI->useEXA) + { + xfree(pATI->ExpansionBitmapScanlinePtr[1]); + pATI->ExpansionBitmapScanlinePtr[0] = NULL; pATI->ExpansionBitmapScanlinePtr[1] = NULL; + } +#endif xfree(pATI->pShadow); pATI->pShadow = NULL; diff --git a/src/atistruct.h b/src/atistruct.h index a84b0e8..2cb6625 100644 --- a/src/atistruct.h +++ b/src/atistruct.h @@ -52,7 +52,12 @@ #endif /* TV_OUT */ +#ifdef USE_EXA +#include "exa.h" +#endif +#ifdef USE_XAA #include "xaa.h" +#endif #include "xf86Cursor.h" #include "xf86Pci.h" #include "xf86Resources.h" @@ -296,15 +301,23 @@ typedef struct _ATIRec /* * XAA interface. */ + Bool useEXA; +#ifdef USE_EXA + ExaDriverPtr pExa; +#endif +#ifdef USE_XAA XAAInfoRecPtr pXAAInfo; +#endif int nAvailableFIFOEntries, nFIFOEntries, nHostFIFOEntries; CARD8 EngineIsBusy, EngineIsLocked, XModifier; CARD32 dst_cntl; /* For SetupFor/Subsequent communication */ CARD32 sc_left_right, sc_top_bottom; CARD16 sc_left, sc_right, sc_top, sc_bottom; /* Current scissors */ pointer pHOST_DATA; /* Current HOST_DATA_* transfer window address */ +#ifdef USE_XAA CARD32 *ExpansionBitmapScanlinePtr[2]; int ExpansionBitmapWidth; +#endif /* * Cursor-related definitions. @@ -382,7 +395,8 @@ typedef struct _ATIRec * XVideo-related data. */ DevUnion XVPortPrivate[1]; - FBLinearPtr pXVBuffer; + pointer pXVBuffer; /* USE_EXA: ExaOffscreenArea* + USE_XAA: FBLinearPtr */ RegionRec VideoClip; int SurfacePitch, SurfaceOffset; CARD8 AutoPaint, DoubleBuffer, CurrentBuffer, ActiveSurface; @@ -485,10 +499,12 @@ typedef struct _ATIRec Bool have3DWindows; /* offscreen memory management */ +#ifdef USE_XAA int backLines; FBAreaPtr backArea; int depthTexLines; FBAreaPtr depthTexArea; +#endif CARD8 OptionIsPCI; /* Force PCI mode */ CARD8 OptionDMAMode; /* async, sync, mmio */ CARD8 OptionAGPMode; /* AGP mode */ |