diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | ChangeLog | 117 | ||||
-rw-r--r-- | Makefile.am | 10 | ||||
-rw-r--r-- | configure.ac | 48 | ||||
-rw-r--r-- | man/mga.man | 15 | ||||
-rw-r--r-- | src/Makefile.am | 11 | ||||
-rw-r--r-- | src/mga.h | 62 | ||||
-rw-r--r-- | src/mga_dri.c | 26 | ||||
-rw-r--r-- | src/mga_driver.c | 79 | ||||
-rw-r--r-- | src/mga_exa.c | 810 | ||||
-rw-r--r-- | src/mga_reg.h | 114 | ||||
-rw-r--r-- | src/mga_storm.c | 58 | ||||
-rw-r--r-- | src/mga_video.c | 196 | ||||
-rw-r--r-- | util/Makefile.am | 2 |
14 files changed, 1334 insertions, 215 deletions
@@ -1,3 +1,4 @@ +ChangeLog Makefile Makefile.in *.la diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index f9abbb1..0000000 --- a/ChangeLog +++ /dev/null @@ -1,117 +0,0 @@ -2006-04-12 Adam Jackson <ajax@freedesktop.org> - - * src/mga_arc.c: - Bug #6562: s/MAXSHORT/SHRT_MAX/ for POSIX. (Matthieu Herrb) - -2006-04-07 Adam Jackson <ajax@freedesktop.org> - - * configure.ac: - * src/mga.h: - Bump to 1.4.1 for Xv changes. - -2006-04-07 Aaron Plattner <aplattner@nvidia.com> - - * src/mga_video.c: (MGAPutImage): - Add a DrawablePtr argument to the XV functions to pave the way for - redirected video. - -2006-04-07 Adam Jackson <ajax@freedesktop.org> - - * configure.ac: - * src/clientlx.c: - * src/mga.h: - * src/mga_arc.c: - * src/mga_bios.c: - * src/mga_dac3026.c: - * src/mga_dacG.c: - * src/mga_dga.c: - * src/mga_dh.c: - * src/mga_dri.c: - * src/mga_driver.c: - * src/mga_esc.c: - * src/mga_g450pll.c: - * src/mga_hwcurs.c: - * src/mga_merge.c: - * src/mga_shadow.c: - * src/mga_storm.c: - * src/mga_video.c: - Unlibcwrap. Bump server version requirement. Bump to 1.4.0. - -2006-04-01 Adam Jackson <ajax@freedesktop.org> - - * configure.ac: - * src/Makefile.am: - * src/mga.h: - * src/mga_bios.c: - * src/mga_dacG.c: - * src/mga_dga.c: - * src/mga_driver.c: - * src/mga_macros.h: - * src/mga_merge.c: - * src/mga_storm.c: - * src/mga_vga.c: - Bug #6328: Add support for Matrox G200SE chips. (Matrox) - -2006-03-20 Adam Jackson <ajax@freedesktop.org> - - * src/Makefile.am: - * src/mga.h: - * src/mga_dga.c: - * src/mga_dri.c: - * src/mga_macros.h: - * src/mga_map.h: - * src/mga_storm.c: - * src/mga_video.c: - Bug #5587: Refactor mga_storm.c to only build once for all color - depths. (Ian Romanick) - -2006-03-15 Adam Jackson <ajax@freedesktop.org> - - * src/mga_dri.c: - Coverity #92: Eliminate a dead code path. - Coverity #1009: Check for NULL first before assigning to pMGADRI. - -2005-12-20 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update package version for X11R7 release. - -2005-12-14 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update package version number for final X11R7 release candidate. - -2005-12-06 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * man/Makefile.am: - Change *man_SOURCES ==> *man_PRE to fix autotools warnings. - -2005-12-03 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update package version number for X11R7 RC3 release. - -2005-12-01 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Remove extraneous AC_MSG_RESULT. - -2005-11-20 Adam Jackson <ajax@freedesktop.org> - - * configure.ac: - Bump libdrm dep to 2.0. - -2005-11-29 Adam Jackson <ajax@freedesktop.org> - - * configure.ac: - Only build dlloader modules by default. - -2005-11-09 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update package version number for X11R7 RC2 release. - -2005-11-01 Kevin E. Martin <kem-at-freedesktop-dot-org> - - * configure.ac: - Update pkgcheck dependencies to work with separate build roots. diff --git a/Makefile.am b/Makefile.am index 4e76113..d05c5ca 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,4 +21,12 @@ AUTOMAKE_OPTIONS = foreign SUBDIRS = src man util -EXTRA_DIST = README_HALLIB mga_PInS.txt +CLEANFILES = ChangeLog +EXTRA_DIST = README_HALLIB mga_PInS.txt ChangeLog + +.PHONY: ChangeLog + +ChangeLog: + git-log > ChangeLog + +dist-hook: ChangeLog diff --git a/configure.ac b/configure.ac index ec8a5ca..8cddbac 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ AC_PREREQ(2.57) AC_INIT([xf86-video-mga], - 1.4.1, + 1.4.2, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xf86-video-mga) @@ -51,6 +51,11 @@ AC_ARG_ENABLE(dri, AC_HELP_STRING([--disable-dri], [Disable DRI support [[default=auto]]]), [DRI="$enableval"], [DRI=auto]) +AC_ARG_ENABLE(exa, + AC_HELP_STRING([--disable-exa], + [Disable EXA support [[default enabled]]]), + [EXA="$enableval"], + [EXA=yes]) # Checks for extensions XORG_DRIVER_CHECK_EXT(RANDR, randrproto) @@ -59,7 +64,7 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto) XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto) # Checks for pkg-config packages -PKG_CHECK_MODULES(XORG, [xorg-server >= 1.0.99.901 xproto fontsproto $REQUIRED_MODULES]) +PKG_CHECK_MODULES(XORG, [xorg-server >= 1.1.0 xproto fontsproto $REQUIRED_MODULES]) sdkdir=$(pkg-config --variable=sdkdir xorg-server) # Checks for libraries. @@ -95,6 +100,45 @@ if test "x$DRI" = xyes; then AC_DEFINE(XF86DRI_DEVEL,1,[Enable developmental DRI driver support]) fi +AM_CONDITIONAL(USE_XAA, true) +AC_DEFINE(USE_XAA, 1, [Build support for XAA]) + +# Properly handle EXA. +AC_MSG_CHECKING([whether to enable EXA support]) +if test "x$EXA" = xyes; then + AC_MSG_RESULT(yes) + + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $XORG_CFLAGS" + AC_CHECK_HEADER(exa.h, + [have_exa_h="yes"], [have_exa_h="no"]) + CPPFLAGS="$SAVE_CPPFLAGS" +else + AC_MSG_RESULT(no) +fi + +SAVE_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $XORG_CFLAGS" +if test "x$have_exa_h" = xyes; then + AC_MSG_CHECKING([whether EXA version is at least 2.0.0]) + AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[ +#include "exa.h" +#if EXA_VERSION_MAJOR < 2 +#error OLD EXA! +#endif + ]])], + [USE_EXA=yes], + [USE_EXA=no]) + AC_MSG_RESULT($USE_EXA) + + if test "x$USE_EXA" = xyes; then + AC_DEFINE(USE_EXA, 1, [Build support for Exa]) + fi +fi +CPPFLAGS="$SAVE_CPPFLAGS" + +AM_CONDITIONAL(USE_EXA, test "x$USE_EXA" = xyes) + AC_SUBST([DRI_CFLAGS]) AC_SUBST([XORG_CFLAGS]) AC_SUBST([moduledir]) diff --git a/man/mga.man b/man/mga.man index 6646096..2ad75bc 100644 --- a/man/mga.man +++ b/man/mga.man @@ -52,10 +52,10 @@ Productiva G100 Millennium G200 and Mystique G200 .TP .B G400 -Millenium G400, Millenium G400 MAX, Millenium G450, and Marvel G450 eTV +Millennium G400, Millennium G400 MAX, Millennium G450, and Marvel G450 eTV .TP .B G550 -Millenium G550 and Millenium G550 Dual DVI +Millennium G550 and Millennium G550 Dual DVI .SH "CONFIGURATION DETAILS" Please refer to __xconfigfile__(__filemansuffix__) for general configuration details. This section only covers configuration details specific to this @@ -107,6 +107,17 @@ specified in multihead configurations. Default: auto\-detected. .BI "Option \*qNoAccel\*q \*q" boolean \*q Disable or enable acceleration. Default: acceleration is enabled. .TP +.BI "Option \*qAccelMethod\*q \*q" "string" \*q +Chooses between available acceleration architectures. Valid options are +.B XAA +and +.B EXA. +XAA is the traditional acceleration architecture and support for it is very +stable. EXA is a newer acceleration architecture with better performance for +the Render and Composite extensions, but the rendering code for it is newer and +possibly unstable. The default is +.B XAA. +.TP .BI "Option \*qNoHal\*q \*q" boolean \*q Disable or enable loading the "mga_hal" module. Default: the module is loaded when available and when using hardware that it supports. diff --git a/src/Makefile.am b/src/Makefile.am index 0fa8d93..17211bb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -54,7 +54,6 @@ mga_drv_la_SOURCES = \ mga_reg.h \ mga_sarea.h \ mga_shadow.c \ - mga_storm.c \ mga_ucode.h \ mga_vga.c \ mga_video.c @@ -65,3 +64,13 @@ mga_drv_la_SOURCES += \ mga_dri.h \ mga_dripriv.h endif + +if USE_EXA +mga_drv_la_SOURCES += \ + mga_exa.c +endif + +if USE_XAA +mga_drv_la_SOURCES += \ + mga_storm.c +endif @@ -20,6 +20,7 @@ #include "compiler.h" #include "xaa.h" +#include "exa.h" #include "xf86Cursor.h" #include "vgaHW.h" #include "colormapst.h" @@ -81,7 +82,8 @@ typedef enum { OPTION_MONITOR2POS, OPTION_METAMODES, OPTION_OLDDMA, - OPTION_PCIDMA + OPTION_PCIDMA, + OPTION_ACCELMETHOD } MGAOpts; @@ -192,13 +194,20 @@ typedef struct { int contrast; Bool doubleBuffer; unsigned char currentBuffer; - FBLinearPtr linear; RegionRec clip; CARD32 colorKey; CARD32 videoStatus; Time offTime; Time freeTime; int lastPort; + +#ifdef USE_EXA + int size; + ExaOffscreenArea *off_screen; +#endif + + void *video_memory; + int video_offset; } MGAPortPrivRec, *MGAPortPrivPtr; typedef struct { @@ -447,6 +456,8 @@ typedef struct { MGARamdacRec Dac; Bool HasSDRAM; Bool NoAccel; + Bool Exa; + ExaDriverPtr ExaDriver; Bool SyncOnGreen; Bool HWCursor; Bool UsePCIRetry; @@ -566,6 +577,18 @@ typedef struct { Bool HALLoaded; #endif OptionInfoPtr Options; + + /* Exa */ + PicturePtr currentSrcPicture; + PicturePtr currentMaskPicture; + PixmapPtr currentSrc; + PixmapPtr currentMask; + int src_w2; + int src_h2; + int mask_w2; + int mask_h2; + CARD32 src_pitch; /* FIXME kill me */ + /* Merged Framebuffer data */ Bool MergedFB; @@ -626,12 +649,19 @@ void MGAAdjustGranularity(ScrnInfoPtr pScrn, int* x, int* y); void MGA2064SetupFuncs(ScrnInfoPtr pScrn); void MGAGSetupFuncs(ScrnInfoPtr pScrn); +/* #ifdef USE_XAA */ void MGAStormSync(ScrnInfoPtr pScrn); void MGAStormEngineInit(ScrnInfoPtr pScrn); Bool MGAStormAccelInit(ScreenPtr pScreen); +Bool mgaAccelInit(ScreenPtr pScreen); +/* #endif */ + +#ifdef USE_EXA +Bool mgaExaInit(ScreenPtr pScreen); +#endif + Bool MGAHWCursorInit(ScreenPtr pScreen); -Bool mgaAccelInit(ScreenPtr pScreen); void MGAPolyArcThinSolid(DrawablePtr, GCPtr, int, xArc*); @@ -720,4 +750,30 @@ void MGAFillDisplayModeStruct(DisplayModePtr pMode, LPMGAMODEINFO pModeInfo); /************************************************/ #endif +static __inline__ void +MGA_MARK_SYNC(MGAPtr pMga, ScrnInfoPtr pScrn) +{ +#ifdef USE_EXA + if (pMga->Exa) + exaMarkSync(pScrn->pScreen); +#endif +#ifdef USE_XAA + if (!pMga->Exa) + SET_SYNC_FLAG(pMga->AccelInfoRec); +#endif +} + +static __inline__ void +MGA_SYNC(MGAPtr pMga, ScrnInfoPtr pScrn) +{ +#ifdef USE_EXA + if (pMga->Exa) + exaWaitSync(pScrn->pScreen); +#endif +#ifdef USE_XAA + if (!pMga->Exa && pMga->AccelInfoRec && pMga->AccelInfoRec->NeedToSync) + pMga->AccelInfoRec->Sync(pScrn); +#endif +} + #endif diff --git a/src/mga_dri.c b/src/mga_dri.c index 56ad243..e8cd828 100644 --- a/src/mga_dri.c +++ b/src/mga_dri.c @@ -370,6 +370,9 @@ void MGAGetQuiescence( ScrnInfoPtr pScrn ) MGAWaitForIdleDMA( pScrn ); + /* FIXME what about EXA? */ +#ifdef USE_XAA + if (!pMga->Exa && pMga->AccelInfoRec) { WAITFIFO( 11 ); OUTREG( MGAREG_MACCESS, pMga->MAccess ); OUTREG( MGAREG_PITCH, pLayout->displayWidth ); @@ -390,7 +393,9 @@ void MGAGetQuiescence( ScrnInfoPtr pScrn ) OUTREG( MGAREG_YTOP, 0x00000000 ); /* minPixelPointer */ OUTREG( MGAREG_YBOT, 0x007FFFFF ); /* maxPixelPointer */ - pMga->AccelFlags &= ~CLIPPER_ON; + pMga->AccelFlags &= ~CLIPPER_ON; + } +#endif } } @@ -406,7 +411,12 @@ void MGAGetQuiescenceShared( ScrnInfoPtr pScrn ) if ( pMGAEnt->directRenderingEnabled ) { MGAWaitForIdleDMA( pMGAEnt->pScrn_1 ); - pMga->RestoreAccelState( pScrn ); + + /* FIXME what about EXA? */ +#ifdef USE_XAA + if (!pMga->Exa && pMga->AccelInfoRec) + pMga->RestoreAccelState( pScrn ); +#endif xf86SetLastScrnFlag( pScrn->entityList[0], pScrn->scrnIndex ); } } @@ -420,7 +430,8 @@ static void MGASwapContext( ScreenPtr pScreen ) * appropriate. */ pMga->haveQuiescense = 0; - pMga->AccelInfoRec->NeedToSync = TRUE; + + MGA_MARK_SYNC(pMga, pScrn); } static void MGASwapContextShared( ScreenPtr pScreen ) @@ -432,11 +443,10 @@ static void MGASwapContextShared( ScreenPtr pScreen ) pMga = MGAPTR(pMGAEnt->pScrn_1); - pMga->haveQuiescense = 0; - pMga->AccelInfoRec->NeedToSync = TRUE; + pMga->haveQuiescense = pMGA2->haveQuiescense = 0; - pMGA2->haveQuiescense = 0; - pMGA2->AccelInfoRec->NeedToSync = TRUE; + MGA_MARK_SYNC(pMga, pScrn); + MGA_MARK_SYNC(pMGA2, pMGAEnt->pScrn_2); } /* FIXME: This comment is out of date, since we aren't overriding @@ -486,6 +496,7 @@ MGADRISwapContextShared( ScreenPtr pScreen, DRISyncType syncType, } } +#ifdef USE_XAA void MGASelectBuffer( ScrnInfoPtr pScrn, int which ) { MGAPtr pMga = MGAPTR(pScrn); @@ -507,6 +518,7 @@ void MGASelectBuffer( ScrnInfoPtr pScrn, int which ) break; } } +#endif static unsigned int mylog2( unsigned int n ) diff --git a/src/mga_driver.c b/src/mga_driver.c index 94d7f29..fbaab0c 100644 --- a/src/mga_driver.c +++ b/src/mga_driver.c @@ -83,7 +83,10 @@ #include "mga_macros.h" #include "mga_maven.h" +#ifdef USE_XAA #include "xaa.h" +#endif + #include "xf86cmap.h" #include "shadowfb.h" #include "fbdevhw.h" @@ -292,6 +295,7 @@ static const OptionInfoRec MGAOptions[] = { { OPTION_METAMODES, "MetaModes", OPTV_ANYSTR, {0}, FALSE }, { OPTION_OLDDMA, "OldDmaInit", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_PCIDMA, "ForcePciDma", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ACCELMETHOD, "AccelMethod", OPTV_ANYSTR, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; @@ -336,6 +340,17 @@ static const char *xf8_32bppSymbols[] = { NULL }; +#ifdef USE_EXA +static const char *exaSymbols[] = { + "exaDriverInit", + "exaDriverFini", + "exaGetPixmapOffset", + "exaGetVersion", + NULL +}; +#endif + +#ifdef USE_XAA static const char *xaaSymbols[] = { "XAACachePlanarMonoStipple", "XAACreateInfoRec", @@ -346,6 +361,7 @@ static const char *xaaSymbols[] = { "XAA_888_plus_PICT_a8_to_8888", NULL }; +#endif static const char *ramdacSymbols[] = { "xf86CreateCursorInfoRec", @@ -513,7 +529,13 @@ mgaSetup(pointer module, pointer opts, int *errmaj, int *errmin) * Tell the loader about symbols from other modules that this module * might refer to. */ - LoaderRefSymLists(vgahwSymbols, xaaSymbols, + LoaderRefSymLists(vgahwSymbols, +#ifdef USE_XAA + xaaSymbols, +#endif +#ifdef USE_EXA + exaSymbols, +#endif xf8_32bppSymbols, ramdacSymbols, ddcSymbols, i2cSymbols, shadowSymbols, fbdevHWSymbols, vbeSymbols, @@ -1494,6 +1516,21 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) if (xf86ReturnOptValBool(pMga->Options, OPTION_NOACCEL, FALSE)) { pMga->NoAccel = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); + } else { + int from = X_DEFAULT; +#ifdef USE_EXA + char *s = xf86GetOptValString(pMga->Options, OPTION_ACCELMETHOD); +#endif + pMga->NoAccel = FALSE; + pMga->Exa = FALSE; +#ifdef USE_EXA + if (!xf86NameCmp(s, "EXA")) { + pMga->Exa = TRUE; + from = X_CONFIG; + } +#endif + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration\n", + pMga->Exa ? "EXA" : "XAA"); } if (xf86ReturnOptValBool(pMga->Options, OPTION_PCI_RETRY, FALSE)) { pMga->UsePCIRetry = TRUE; @@ -2235,11 +2272,23 @@ MGAPreInit(ScrnInfoPtr pScrn, int flags) /* Load XAA if needed */ if (!pMga->NoAccel) { - if (!xf86LoadSubModule(pScrn, "xaa")) { - MGAFreeRec(pScrn); - return FALSE; +#ifdef USE_EXA + if (pMga->Exa) { + if (!xf86LoadSubModule(pScrn, "exa")) { + MGAFreeRec(pScrn); + return FALSE; + } else xf86LoaderReqSymLists(exaSymbols, NULL); + } else { +#endif +#ifdef USE_XAA + if (!xf86LoadSubModule(pScrn, "xaa")) { + MGAFreeRec(pScrn); + return FALSE; + } else xf86LoaderReqSymLists(xaaSymbols, NULL); +#endif +#ifdef USE_EXA } - xf86LoaderReqSymLists(xaaSymbols, NULL); +#endif } /* Load ramdac if needed */ @@ -3227,8 +3276,16 @@ MGAScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if(!pMga->ShadowFB) /* hardware cursor needs to wrap this layer */ MGADGAInit(pScreen); - if (!pMga->NoAccel) - MGAStormAccelInit(pScreen); + if (!pMga->NoAccel) { +#ifdef USE_EXA + if (pMga->Exa) + mgaExaInit(pScreen); + else +#endif +#ifdef USE_XAA + MGAStormAccelInit(pScreen); +#endif + } miInitializeBackingStore(pScreen); xf86SetBackingStore(pScreen); @@ -3735,8 +3792,16 @@ MGACloseScreen(int scrnIndex, ScreenPtr pScreen) ); /* MGA_HAL */ #endif +#ifdef USE_XAA if (pMga->AccelInfoRec) XAADestroyInfoRec(pMga->AccelInfoRec); +#endif +#ifdef USE_EXA + if (pMga->ExaDriver) { + exaDriverFini(pScreen); + xfree(pMga->ExaDriver); + } +#endif if (pMga->CursorInfoRec) xf86DestroyCursorInfoRec(pMga->CursorInfoRec); if (pMga->ShadowPtr) diff --git a/src/mga_exa.c b/src/mga_exa.c new file mode 100644 index 0000000..3242ea8 --- /dev/null +++ b/src/mga_exa.c @@ -0,0 +1,810 @@ +/* + * Copyright 2006 Red Hat, Inc. + * + * 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 + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * them 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 MERCHANTIBILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS 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. + * + * Authors: + * Adam Jackson <ajax@nwnk.net> + * Tilman Sauerbeck <tilman@code-monkey.de> + */ + +/* + * Sources: + * - mga kdrive accel by Anders Carlsson + * - mga g400 Render accel by Damien Ciabrini + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" + +#include "mga.h" +#include "mga_reg.h" +#include "mga_macros.h" + +#include "exa.h" +#ifdef XF86DRI +#include "mga_dri.h" +#endif + +#include "xf86PciInfo.h" + +#if 0 +#define DEBUG_MSG(x) ErrorF x +#else +#define DEBUG_MSG(x) +#endif + +#define PMGA(x) \ + MGAPtr pMga = xf86Screens[x->drawable.pScreen->myNum]->driverPrivate; + +#define QUIESCE_DMA(x) \ + CHECK_DMA_QUIESCENT(pMga, xf86Screens[x->drawable.pScreen->myNum]); + +/* stuff stolen from mga_storm.c */ +#define BLIT_LEFT 1 +#define BLIT_UP 4 + +/* FIXME + * We could use MGADWG_BLK for GXcopy if HaveSDRAM is FALSE. + * That will only work in some situations though (see mga_storm.c + * for details). + */ +static const CARD32 mgaRop[16] = { + /* GXclear */ MGADWG_RPL | 0x00000000, /* 0 */ + /* GXand */ MGADWG_RSTR | 0x00080000, /* src AND dst */ + /* GXandReverse */ MGADWG_RSTR | 0x00040000, /* src AND NOT dst */ + /* GXcopy */ MGADWG_RSTR | 0x000c0000, /* src */ + /* GXandInverted */ MGADWG_RSTR | 0x00020000, /* NOT src AND dst */ + /* GXnoop */ MGADWG_RSTR | 0x000a0000, /* dst */ + /* GXxor */ MGADWG_RSTR | 0x00060000, /* src XOR dst */ + /* GXor */ MGADWG_RSTR | 0x000e0000, /* src OR dst */ + /* GXnor */ MGADWG_RSTR | 0x00010000, /* NOT src AND NOT dst */ + /* GXequiv */ MGADWG_RSTR | 0x00090000, /* NOT src XOR dst */ + /* GXinvert */ MGADWG_RSTR | 0x00050000, /* NOT dst */ + /* GXorReverse */ MGADWG_RSTR | 0x000d0000, /* src OR NOT dst */ + /* GXcopyInverted */ MGADWG_RPL | 0x00030000, /* NOT src */ + /* GXorInverted */ MGADWG_RSTR | 0x000b0000, /* NOT src OR dst */ + /* GXnand */ MGADWG_RSTR | 0x00070000, /* NOT src OR NOT dst */ + /* GXset */ MGADWG_RPL | 0x000f0000 /* 1 */ +}; + +static const struct { + Bool dst_alpha; + Bool src_alpha; + CARD32 blend_cntl; +} mgaBlendOp[] = { + /* Clear */ + {0, 0, MGA_SRC_ZERO | MGA_DST_ZERO}, + /* Src */ + {0, 0, MGA_SRC_ONE | MGA_DST_ZERO}, + /* Dst */ + {0, 0, MGA_SRC_ZERO | MGA_DST_ONE}, + /* Over */ + {0, 1, MGA_SRC_ONE | MGA_DST_ONE_MINUS_SRC_ALPHA}, + /* OverReverse */ + {1, 0, MGA_SRC_ONE_MINUS_DST_ALPHA | MGA_DST_ONE}, + /* In */ + {1, 0, MGA_SRC_DST_ALPHA | MGA_DST_ZERO}, + /* InReverse */ + {0, 1, MGA_SRC_ZERO | MGA_DST_SRC_ALPHA}, + /* Out */ + {1, 0, MGA_SRC_ONE_MINUS_DST_ALPHA | MGA_DST_ZERO}, + /* OutReverse */ + {0, 1, MGA_SRC_ZERO | MGA_DST_ONE_MINUS_SRC_ALPHA}, + /* Atop */ + {1, 1, MGA_SRC_DST_ALPHA | MGA_DST_ONE_MINUS_SRC_ALPHA}, + /* AtopReverse */ + {1, 1, MGA_SRC_ONE_MINUS_DST_ALPHA | MGA_DST_SRC_ALPHA}, + /* Xor */ + {1, 1, MGA_SRC_ONE_MINUS_DST_ALPHA | MGA_DST_ONE_MINUS_SRC_ALPHA}, + /* Add */ + {0, 0, MGA_SRC_ONE | MGA_DST_ONE}, +}; + +static CARD32 +mgaGetPixmapPitch(PixmapPtr pPix) +{ + return exaGetPixmapPitch(pPix) / (pPix->drawable.bitsPerPixel >> 3); +} + +static CARD32 +mgaGetMACCESS(PixmapPtr pixmap, PicturePtr pict) +{ + switch (pixmap->drawable.bitsPerPixel) { + case 8: + return MGAMAC_PW8 | MGAMAC_BYPASS332 | MGAMAC_NODITHER; + case 16: + if (pict && + (pict->format == PICT_x1r5g5b5 || pict->format == PICT_a1r5g5b5)) + return MGAMAC_PW16 | MGAMAC_DIT555; + else + return MGAMAC_PW16; + case 24: + return MGAMAC_PW24; + default: + return MGAMAC_PW32; + } +} + +static Bool +mgaSetup(MGAPtr pMga, PixmapPtr pixmap, PicturePtr pict, int wait) +{ + WAITFIFO(wait + 4); + + /* Set the format of the destination pixmap */ + OUTREG(MGAREG_MACCESS, mgaGetMACCESS(pixmap, pict)); + + OUTREG(MGAREG_CXBNDRY, 0xffff0000); + OUTREG(MGAREG_YTOP, 0x00000000); + OUTREG(MGAREG_YBOT, 0x007fffff); + + return TRUE; +} + +static void +mgaNoopDone(PixmapPtr pPixmap) +{ +} + +static Bool +mgaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg) +{ + PMGA(pPixmap); + int dwgctl; + + /* FIXME + * Is this needed here? We don't use DMA stuff here... + */ + QUIESCE_DMA(pPixmap); + + /* We must pad planemask and fg depending on the format of the + * destination pixmap + */ + switch (pPixmap->drawable.bitsPerPixel) { + case 8: + fg |= fg << 8; + planemask |= planemask << 8; + /* fall through */ + case 16: + fg |= fg << 16; + planemask |= planemask << 16; + break; + } + + dwgctl = MGADWG_TRAP | MGADWG_SOLID | MGADWG_ARZERO | + MGADWG_SGNZERO | MGADWG_SHIFTZERO | mgaRop[alu]; + + mgaSetup(pMga, pPixmap, NULL, 5); + + OUTREG(MGAREG_PITCH, mgaGetPixmapPitch(pPixmap)); + OUTREG(MGAREG_DSTORG, exaGetPixmapOffset(pPixmap)); + OUTREG(MGAREG_FCOL, fg); + OUTREG(MGAREG_PLNWT, planemask); + OUTREG(MGAREG_DWGCTL, dwgctl); + + return TRUE; +} + +static void +mgaSolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) +{ + PMGA(pPixmap); + + WAITFIFO(2); + OUTREG(MGAREG_FXBNDRY, (x2 << 16) | (x1 & 0xffff)); + OUTREG(MGAREG_YDSTLEN | MGAREG_EXEC, (y1 << 16) | (y2 - y1)); +} + +static Bool +mgaPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int xdir, int ydir, int alu, + Pixel planemask) +{ + PMGA(pSrc); + int blit_direction = 0; + int dwgctl = 0; + + /* FIXME + * Is this needed here? We don't use DMA stuff here... + */ + QUIESCE_DMA(pSrc); + + DEBUG_MSG(("s: %x@%x d: %x@%x xdir %d ydir %d alu %d pm %d\n", + exaGetPixmapOffset(pSrc), exaGetPixmapPitch(pSrc), + exaGetPixmapOffset(pDst), exaGetPixmapPitch(pDst), + xdir, ydir, alu, planemask)); + + if (xdir < 0) + blit_direction |= BLIT_LEFT; + + if (ydir < 0) + blit_direction |= BLIT_UP; + + pMga->BltScanDirection = blit_direction; + + dwgctl = mgaRop[alu] | MGADWG_SHIFTZERO | MGADWG_BITBLT | MGADWG_BFCOL; + pMga->src_pitch = mgaGetPixmapPitch(pSrc); + + mgaSetup(pMga, pDst, NULL, 7); + OUTREG(MGAREG_PITCH, mgaGetPixmapPitch(pDst)); + OUTREG(MGAREG_SRCORG, exaGetPixmapOffset(pSrc)); + OUTREG(MGAREG_DSTORG, exaGetPixmapOffset(pDst)); + OUTREG(MGAREG_DWGCTL, dwgctl); + OUTREG(MGAREG_SGN, blit_direction); + OUTREG(MGAREG_PLNWT, planemask); + OUTREG(MGAREG_AR5, (ydir < 0 ? -1 : 1) * pMga->src_pitch); + + return TRUE; +} + +static void +mgaCopy(PixmapPtr pDst, int srcx, int srcy, int dstx, int dsty, int w, int h) +{ + PMGA(pDst); + int start, end; + + DEBUG_MSG((" %d,%d -> %d,%d %dx%d\n", srcx, srcy, dstx,dsty, w, h)); + + w--; + + if (pMga->BltScanDirection & BLIT_UP) { + srcy += h - 1; + dsty += h - 1; + } + + start = end = srcy * pMga->src_pitch + srcx; + + if (pMga->BltScanDirection & BLIT_LEFT) + start += w; + else + end += w; + + DEBUG_MSG((" end %d start %d dstx %d dsty %d w %d h %d\n", + end, start, dstx, dsty, w, h)); + + WAITFIFO(4); + OUTREG(MGAREG_AR0, end); + OUTREG(MGAREG_AR3, start); + OUTREG(MGAREG_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff)); + OUTREG(MGAREG_YDSTLEN | MGAREG_EXEC, (dsty << 16) | h); +} + +static int +MGA_LOG2(int val) +{ + int ret = 0; + + if (val == 1) + return 0; + + while (val >> ret) + ret++; + + return ((1 << (ret - 1)) == val) ? (ret - 1) : ret; +} + +static CARD32 +mgaGetTexFormat(PicturePtr pPict) +{ + static const struct { + int fmt; + CARD32 card_fmt; + } *ptr, texformats[] = { + { PICT_a8r8g8b8, MGA_TW32 }, + { PICT_x8r8g8b8, MGA_TW32 }, + { PICT_r5g6b5, MGA_TW16 }, + { PICT_a1r5g5b5, MGA_TW15 }, + { PICT_x1r5g5b5, MGA_TW15 }, + { PICT_a4r4g4b4, MGA_TW12 }, + { PICT_x4r4g4b4, MGA_TW12 }, + { PICT_a8, MGA_TW8A }, + { 0, 0} + }; + + for (ptr = texformats; ptr->fmt; ptr++) + if (ptr->fmt == pPict->format) + return ptr->card_fmt; + + return 0; +} + +static Bool +mgaCheckSourceTexture(int tmu, PicturePtr pPict) +{ + int w = pPict->pDrawable->width; + int h = pPict->pDrawable->height; + + if ((w > 2047) || (h > 2047)){ + DEBUG_MSG(("Picture w/h too large (%dx%d)\n", w, h)); + return FALSE; + } + + if (!mgaGetTexFormat(pPict)) { + DEBUG_MSG(("Unsupported picture format 0x%x\n", pPict->format)); + return FALSE; + } + + if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0)) { + DEBUG_MSG(("NPOT repeat unsupported (%dx%d)\n", w, h)); + return FALSE; + } + + if (pPict->filter != PictFilterNearest && + pPict->filter != PictFilterBilinear) { + DEBUG_MSG(("Unsupported filter 0x%x\n", pPict->filter)); + return FALSE; + } + + return TRUE; +} + +static Bool +mgaCheckComposite(int op, PicturePtr pSrcPict, PicturePtr pMaskPict, + PicturePtr pDstPict) +{ + if (op >= sizeof(mgaBlendOp) / sizeof(mgaBlendOp[0])) { + DEBUG_MSG(("unsupported op %x\n", op)); + return FALSE; + } + + if (!mgaCheckSourceTexture(0, pSrcPict)) + return FALSE; + + if (pMaskPict) { + if (!mgaCheckSourceTexture(1, pMaskPict)) + return FALSE; + + if (pMaskPict->componentAlpha) { + DEBUG_MSG(("Component alpha unsupported\n")); + return FALSE; + } + } + + if (PICT_FORMAT_TYPE(pDstPict->format) == PICT_TYPE_ABGR) { + DEBUG_MSG(("render to (A)BGR unsupported\n")); + return FALSE; + } + + /* FIXME + * Doing this operation in hardware is broken atm :/ + */ + if (op == PictOpAdd && pSrcPict->format == PICT_a8 && + pDstPict->format == PICT_a8) + return FALSE; + + return TRUE; +} + +static void +PrepareSourceTexture(int tmu, PicturePtr pSrcPicture, PixmapPtr pSrc) +{ + PMGA(pSrc); + int pitch = mgaGetPixmapPitch(pSrc); + int w = pSrc->drawable.width; + int h = pSrc->drawable.height; + int w_log2 = MGA_LOG2(w); + int h_log2 = MGA_LOG2(h); + + int texctl = MGA_PITCHLIN | ((pitch & (2048 - 1)) << 9) | + MGA_NOPERSPECTIVE | MGA_TAKEY; + int texctl2 = MGA_G400_TC2_MAGIC | MGA_TC2_CKSTRANSDIS; + int texfilter = MGA_FILTERALPHA | (0x10 << 21); + + texctl |= mgaGetTexFormat(pSrcPicture); + + if (pSrcPicture->filter == PictFilterBilinear) + texfilter |= MGA_MAG_BILIN | MGA_MIN_BILIN; + else + texfilter |= MGA_MAG_NRST | MGA_MIN_NRST; + + if (!pSrcPicture->repeat) + texctl |= MGA_CLAMPUV; + + if (tmu == 1) + texctl2 |= MGA_TC2_DUALTEX | MGA_TC2_SELECT_TMU1; + + WAITFIFO(6); + OUTREG(MGAREG_TEXCTL2, texctl2); + OUTREG(MGAREG_TEXCTL, texctl); + + /* Source (texture) address + pitch */ + OUTREG(MGAREG_TEXORG, exaGetPixmapOffset(pSrc)); + OUTREG(MGAREG_TEXWIDTH, (w - 1) << 18 | ((8 - w_log2) & 63) << 9 | w_log2); + OUTREG(MGAREG_TEXHEIGHT, (h - 1) << 18 | ((8 - h_log2) & 63) << 9 | h_log2); + + /* Set blit filtering flags */ + OUTREG(MGAREG_TEXFILTER, texfilter); + + if (tmu == 1) { + WAITFIFO(1); + OUTREG(MGAREG_TEXCTL2, texctl2 & ~MGA_TC2_SELECT_TMU1); + } +} + +/* + * The formals params are the elements of the following matrix: + * + * Dest Transform Src + * coords coords + * / Xdst \ / X_incx X_incy X_init \ / Xsrc \ + * | Ydst | = | Y_incx Y_incy Y_init | x | Ysrc | + * \ 1 / \ H_incx H_incy H_init / \ 1 / + * + * matrix elements are 32bits fixed points (16.16) + * mga_fx_* is the size of the fixed point for the TMU + */ +static void +setTMIncrementsRegs(PixmapPtr pPix, int X_incx, int X_incy, int X_init, + int Y_incx, int Y_incy, int Y_init, + int H_incx, int H_incy, int H_init, + int mga_fx_width_size, int mga_fx_height_size) +{ + PMGA(pPix); + + int decalw = mga_fx_width_size - 16; + int decalh = mga_fx_height_size - 16; + + /* Convert 16 bits fixpoint -> MGA variable size fixpoint */ + if (decalw >= 0) { + X_incx <<= decalw; + X_incy <<= decalw; + X_init <<= decalw; + } else { + decalw = -decalw; + X_incx >>= decalw; + X_incy >>= decalw; + X_init >>= decalw; + } + + /* Convert 16 bits fixpoint -> MGA variable size fixpoint */ + if (decalh >= 0) { + Y_incx <<= decalh; + Y_incy <<= decalh; + Y_init <<= decalh; + } else { + decalh = -decalh; + Y_incx >>= decalh; + Y_incy >>= decalh; + Y_init >>= decalh; + } + + /* Set TM registers */ + WAITFIFO(9); + OUTREG(MGAREG_TMR0, X_incx); + OUTREG(MGAREG_TMR1, Y_incx); + OUTREG(MGAREG_TMR2, X_incy); + OUTREG(MGAREG_TMR3, Y_incy); + OUTREG(MGAREG_TMR4, H_incx); + OUTREG(MGAREG_TMR5, H_incy); + OUTREG(MGAREG_TMR6, X_init); + OUTREG(MGAREG_TMR7, Y_init); + OUTREG(MGAREG_TMR8, H_init); +} + +/* XXX these look like magic */ +#define C_ARG1_CUR 0x0 +#define C_ARG1_ALPHA MGA_TDS_COLOR_ARG1_REPLICATEALPHA +#define C_ARG2_DIFFUSE MGA_TDS_COLOR_ARG2_DIFFUSE +#define C_ARG2_FCOL MGA_TDS_COLOR_ARG2_FCOL +#define C_ARG2_PREV MGA_TDS_COLOR_ARG2_PREVSTAGE +#define C_ARG1_INV MGA_TDS_COLOR_ARG1_INV +#define C_ARG2_INV MGA_TDS_COLOR_ARG2_INV +#define COLOR_MUL MGA_TDS_COLOR_SEL_MUL +#define COLOR_ARG1 MGA_TDS_COLOR_SEL_ARG1 +#define COLOR_ARG2 MGA_TDS_COLOR_SEL_ARG2 +#define A_ARG1_CUR 0x0 +#define A_ARG2_IGN A_ARG2_DIFFUSE +#define A_ARG2_FCOL MGA_TDS_ALPHA_ARG2_FCOL +#define A_ARG2_DIFFUSE MGA_TDS_ALPHA_ARG2_DIFFUSE +#define A_ARG2_PREV MGA_TDS_ALPHA_ARG2_PREVSTAGE +#define ALPHA_MUL MGA_TDS_ALPHA_SEL_MUL +#define ALPHA_ARG1 MGA_TDS_ALPHA_SEL_ARG1 +#define ALPHA_ARG2 MGA_TDS_ALPHA_SEL_ARG2 + +static Bool +mgaPrepareComposite(int op, PicturePtr pSrcPict, PicturePtr pMaskPict, + PicturePtr pDstPict, PixmapPtr pSrc, PixmapPtr pMask, + PixmapPtr pDst) +{ + PMGA(pDst); + CARD32 fcol = 0xff000000, ds0 = 0, ds1 = 0, cmd, blendcntl; + + mgaSetup(pMga, pDst, pDstPict, 2); + OUTREG(MGAREG_DSTORG, exaGetPixmapOffset(pDst)); + OUTREG(MGAREG_PITCH, mgaGetPixmapPitch(pDst)); + + PrepareSourceTexture(0, pSrcPict, pSrc); + + if (pMask) + PrepareSourceTexture(1, pMaskPict, pMask); + else + PrepareSourceTexture(1, pSrcPict, pSrc); + + /* For A8 writes, the desired alpha value needs to be replicated + * to the color channels - if the source texture doesn't have an + * alpha channel, set it to 0xff instead. + * Otherwise, use the color channels if available, or set them + * to black. + */ + if (pDstPict->format == PICT_a8 && !PICT_FORMAT_A(pSrcPict->format)) { + fcol = 0xffffffff; + ds0 |= C_ARG2_FCOL | COLOR_ARG2; /* C = 0xff */ + } else if (pDstPict->format == PICT_a8) + ds0 |= C_ARG1_ALPHA | COLOR_ARG1; /* C = As */ + else if (pSrcPict->format == PICT_a8) + ds0 |= C_ARG2_FCOL | COLOR_ARG2; /* C = 0 */ + else + ds0 |= C_ARG1_CUR | COLOR_ARG1; /* C = Cs */ + + /* If the source texture has an alpha channel, use it. + * Otherwise, set the alpha channel to 0xff (see FCOL setting above). + */ + if (PICT_FORMAT_A(pSrcPict->format)) + ds0 |= A_ARG1_CUR | ALPHA_ARG1; /* A = As */ + else + ds0 |= A_ARG2_FCOL | ALPHA_ARG2; /* A = 0xff */ + + if (!pMask) + ds1 = ds0; + else { + /* As or Am might be NULL. in this case we don't multiply because, + * the alpha component holds garbage. + */ + if (!PICT_FORMAT_A(pMaskPict->format)) + ds1 |= C_ARG2_PREV | COLOR_ARG2; /* C = Cs */ + else + ds1 |= C_ARG1_ALPHA | C_ARG2_PREV | COLOR_MUL; /* C = Am * Cs */ + + if (!PICT_FORMAT_A(pMaskPict->format)) + ds1 |= A_ARG2_PREV | ALPHA_ARG2; /* A = As */ + else if (!PICT_FORMAT_A(pSrcPict->format)) + ds1 |= A_ARG1_CUR | ALPHA_ARG1; /* A = Am */ + else + ds1 |= A_ARG1_CUR | A_ARG2_PREV | ALPHA_MUL; /* A = Am * As */ + } + + cmd = MGADWG_TEXTURE_TRAP | MGADWG_I | 0x000c0000 | + MGADWG_SHIFTZERO | MGADWG_SGNZERO | MGADWG_ARZERO; + blendcntl = mgaBlendOp[op].blend_cntl; + + if (!PICT_FORMAT_A(pDstPict->format) && mgaBlendOp[op].dst_alpha) { + int sblend = blendcntl & MGA_SRC_BLEND_MASK; + + if (sblend == MGA_SRC_DST_ALPHA) + blendcntl = (blendcntl & ~MGA_SRC_BLEND_MASK) | MGA_SRC_ONE; + else if (sblend == MGA_SRC_ONE_MINUS_DST_ALPHA) + blendcntl = (blendcntl & ~MGA_SRC_BLEND_MASK) | MGA_SRC_ZERO; + } + + if (!PICT_FORMAT_A(pSrcPict->format) && mgaBlendOp[op].src_alpha) { + int dblend = blendcntl & MGA_DST_BLEND_MASK; + + if (dblend == MGA_DST_SRC_ALPHA) + blendcntl = (blendcntl & ~MGA_DST_BLEND_MASK) | MGA_DST_ONE; + else if (dblend == MGA_DST_ONE_MINUS_SRC_ALPHA) + blendcntl = (blendcntl & ~MGA_DST_BLEND_MASK) | MGA_DST_ZERO; + } + + WAITFIFO(5); + OUTREG(MGAREG_FCOL, fcol); + OUTREG(MGAREG_TDUALSTAGE0, ds0); + OUTREG(MGAREG_TDUALSTAGE1, ds1); + OUTREG(MGAREG_DWGCTL, cmd); + OUTREG(MGAREG_ALPHACTRL, MGA_ALPHACHANNEL | blendcntl); + + pMga->currentSrcPicture = pSrcPict; + pMga->currentMaskPicture = pMaskPict; + pMga->currentSrc = pSrc; + pMga->currentMask = pMask; + + pMga->src_w2 = MGA_LOG2 (pSrc->drawable.width); + pMga->src_h2 = MGA_LOG2 (pSrc->drawable.height); + + if (pMask) { + pMga->mask_w2 = MGA_LOG2 (pMask->drawable.width); + pMga->mask_h2 = MGA_LOG2 (pMask->drawable.height); + } + + return TRUE; +} + +static void +mgaComposite(PixmapPtr pDst, int srcx, int srcy, int maskx, int masky, + int dstx, int dsty, int w, int h) +{ + PMGA(pDst); + PictTransformPtr t; + int texctl2; + + srcx %= pMga->currentSrc->drawable.width; + srcy %= pMga->currentSrc->drawable.height; + + if (pMga->currentMask) { + maskx %= pMga->currentMask->drawable.width; + masky %= pMga->currentMask->drawable.height; + } + + t = pMga->currentSrcPicture->transform; + + if (t) + setTMIncrementsRegs(pMga->currentSrc, + t->matrix[0][0], + t->matrix[0][1], + t->matrix[0][2] + (srcx << 16), + t->matrix[1][0], + t->matrix[1][1], + t->matrix[1][2] + (srcy << 16), + t->matrix[2][0], + t->matrix[2][1], + t->matrix[2][2], + 20 - pMga->src_w2, + 20 - pMga->src_h2); + else + setTMIncrementsRegs(pMga->currentSrc, + 1 << 16, 0, srcx << 16, + 0, 1 << 16, srcy << 16, + 0, 0, 1 << 16, + 20 - pMga->src_w2, + 20 - pMga->src_h2); + + if (pMga->currentMask) { + texctl2 = MGA_G400_TC2_MAGIC | MGA_TC2_CKSTRANSDIS | MGA_TC2_DUALTEX; + + WAITFIFO(1); + OUTREG(MGAREG_TEXCTL2, texctl2 | MGA_TC2_SELECT_TMU1); + + t = pMga->currentMaskPicture->transform; + + if (t) + setTMIncrementsRegs(pMga->currentMask, + t->matrix[0][0], + t->matrix[0][1], + t->matrix[0][2] + (maskx << 16), + t->matrix[1][0], + t->matrix[1][1], + t->matrix[1][2] + (masky << 16), + t->matrix[2][0], + t->matrix[2][1], + t->matrix[2][2], + 20 - pMga->mask_w2, + 20 - pMga->mask_h2); + else + setTMIncrementsRegs(pMga->currentMask, + 1 << 16, 0, maskx << 16, + 0, 1 << 16, masky << 16, + 0, 0, 1 << 16, + 20 - pMga->mask_w2, + 20 - pMga->mask_h2); + + WAITFIFO(1); + OUTREG(MGAREG_TEXCTL2, texctl2 & ~MGA_TC2_SELECT_TMU1); + } + + WAITFIFO(2); + OUTREG(MGAREG_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff)); + OUTREG(MGAREG_YDSTLEN | MGAREG_EXEC, (dsty << 16) | (h & 0xffff)); +} + +static Bool +mgaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, + char *src, int src_pitch) +{ + PMGA(pDst); + int bytes_padded = ((pDst->drawable.bitsPerPixel * w + 31) / 32) * 4; + + QUIESCE_DMA(pDst); + + mgaSetup(pMga, pDst, NULL, 10); + + OUTREG(MGAREG_OPMODE, MGAOPM_DMA_BLIT); + OUTREG(MGAREG_DSTORG, exaGetPixmapOffset(pDst)); + OUTREG(MGAREG_PITCH, mgaGetPixmapPitch(pDst)); + OUTREG(MGAREG_PLNWT, 0xffffffff); + OUTREG(MGAREG_DWGCTL, MGADWG_ILOAD | MGADWG_BFCOL | + MGADWG_SGNZERO | MGADWG_SHIFTZERO | + MGADWG_RSTR | 0x000c0000); + OUTREG(MGAREG_AR0, w - 1); + OUTREG(MGAREG_AR3, 0); + OUTREG(MGAREG_AR5, 0); + OUTREG(MGAREG_FXBNDRY, ((x + w - 1) << 16) | (x & 0xffff)); + OUTREG(MGAREG_YDSTLEN | MGAREG_EXEC, (y << 16) | (h & 0xffff)); + + while (h--) { + memcpy (pMga->ILOADBase, src, bytes_padded); + src += src_pitch; + } + + return TRUE; +} + +static void +mgaWaitMarker(ScreenPtr pScreen, int marker) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MGAPtr pMga = pScrn->driverPrivate; + + WAITFIFO(1); + + OUTREG(MGAREG_CACHEFLUSH, 0); + + /* wait until the "drawing engine busy" bit is unset */ + while (INREG (MGAREG_Status) & 0x10000); +} + +Bool +mgaExaInit(ScreenPtr pScreen) +{ + ExaDriverPtr pExa; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MGAPtr pMga = pScrn->driverPrivate; + + pExa = exaDriverAlloc(); + if (!pExa) { + pMga->NoAccel = TRUE; + return FALSE; + } + + pMga->ExaDriver = pExa; + + pExa->exa_major = EXA_VERSION_MAJOR; + pExa->exa_minor = EXA_VERSION_MINOR; + + pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_OFFSCREEN_ALIGN_POT; + pExa->memoryBase = pMga->FbStart; + pExa->memorySize = pMga->FbUsableSize - 4096; + pExa->offScreenBase = (pScrn->virtualX * pScrn->virtualY * + pScrn->bitsPerPixel / 8) + 4096; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "X %d Y %d bpp %d\n", + pScrn->virtualX, pScrn->virtualY, pScrn->bitsPerPixel); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Start at %p, size %x, osb %x\n", + pExa->memoryBase, pExa->memorySize, pExa->offScreenBase); + + /* In PW24 mode, we need to align to "3 64-bytes" */ + pExa->pixmapOffsetAlign = 192; + + /* Pitch alignment is in sets of 32 pixels, and we need to cover + * 32bpp, so it's 128 bytes. + */ + pExa->pixmapPitchAlign = 128; + + pExa->maxX = 2048; + pExa->maxY = 2048; + + pExa->WaitMarker = mgaWaitMarker; + pExa->PrepareSolid = mgaPrepareSolid; + pExa->Solid = mgaSolid; + pExa->DoneSolid = mgaNoopDone; + pExa->PrepareCopy = mgaPrepareCopy; + pExa->Copy = mgaCopy; + pExa->DoneCopy = mgaNoopDone; + + if (pMga->Chipset == PCI_CHIP_MGAG400) { + pExa->CheckComposite = mgaCheckComposite; + pExa->PrepareComposite = mgaPrepareComposite; + pExa->Composite = mgaComposite; + pExa->DoneComposite = mgaNoopDone; + } + + pExa->UploadToScreen = mgaUploadToScreen; + + return exaDriverInit(pScreen, pExa); +} diff --git a/src/mga_reg.h b/src/mga_reg.h index 0d6a20b..874c4ed 100644 --- a/src/mga_reg.h +++ b/src/mga_reg.h @@ -109,6 +109,7 @@ #define MGAREG_FIFOSTATUS 0x1e10 #define MGAREG_Status 0x1e14 +#define MGAREG_CACHEFLUSH 0x1fff #define MGAREG_ICLEAR 0x1e18 #define MGAREG_IEN 0x1e1c @@ -132,6 +133,15 @@ #define MGAOPM_DMA_BLIT (0x01 << 2) #define MGAOPM_DMA_VECTOR (0x10 << 2) +/* MACCESS register additives */ +#define MGAMAC_PW8 0x00 +#define MGAMAC_PW16 0x01 +#define MGAMAC_PW24 0x03 /* not a typo */ +#define MGAMAC_PW32 0x02 /* not a typo */ +#define MGAMAC_BYPASS332 0x10000000 +#define MGAMAC_NODITHER 0x40000000 +#define MGAMAC_DIT555 0x80000000 + /* DWGCTL register additives */ /* Lines */ @@ -143,7 +153,7 @@ /* Trapezoids */ #define MGADWG_TRAP 0x04 -#define MGADWG_TEXTURE_TRAP 0x05 +#define MGADWG_TEXTURE_TRAP 0x06 /* BitBlts */ @@ -465,14 +475,116 @@ #define MGAREG_TEXWIDTH 0x2c28 #define MGAREG_TEXHEIGHT 0x2c2c #define MGAREG_TEXCTL 0x2c30 +# define MGA_TW4 (0x00000000) +# define MGA_TW8 (0x00000001) +# define MGA_TW15 (0x00000002) +# define MGA_TW16 (0x00000003) +# define MGA_TW12 (0x00000004) +# define MGA_TW32 (0x00000006) +# define MGA_TW8A (0x00000007) +# define MGA_TW8AL (0x00000008) +# define MGA_TW422 (0x0000000A) +# define MGA_TW422UYVY (0x0000000B) +# define MGA_PITCHLIN (0x00000100) +# define MGA_NOPERSPECTIVE (0x00200000) +# define MGA_TAKEY (0x02000000) +# define MGA_TAMASK (0x04000000) +# define MGA_CLAMPUV (0x18000000) +# define MGA_TEXMODULATE (0x20000000) #define MGAREG_TEXCTL2 0x2c3c +# define MGA_G400_TC2_MAGIC (0x00008000) +# define MGA_TC2_DECALBLEND (0x00000001) +# define MGA_TC2_IDECAL (0x00000002) +# define MGA_TC2_DECALDIS (0x00000004) +# define MGA_TC2_CKSTRANSDIS (0x00000010) +# define MGA_TC2_BORDEREN (0x00000020) +# define MGA_TC2_SPECEN (0x00000040) +# define MGA_TC2_DUALTEX (0x00000080) +# define MGA_TC2_TABLEFOG (0x00000100) +# define MGA_TC2_BUMPMAP (0x00000200) +# define MGA_TC2_SELECT_TMU1 (0x80000000) #define MGAREG_TEXTRANS 0x2c34 #define MGAREG_TEXTRANSHIGH 0x2c38 #define MGAREG_TEXFILTER 0x2c58 +# define MGA_MIN_NRST (0x00000000) +# define MGA_MIN_BILIN (0x00000002) +# define MGA_MIN_ANISO (0x0000000D) +# define MGA_MAG_NRST (0x00000000) +# define MGA_MAG_BILIN (0x00000020) +# define MGA_FILTERALPHA (0x00100000) #define MGAREG_ALPHASTART 0x2c70 #define MGAREG_ALPHAXINC 0x2c74 #define MGAREG_ALPHAYINC 0x2c78 #define MGAREG_ALPHACTRL 0x2c7c +# define MGA_SRC_ZERO (0x00000000) +# define MGA_SRC_ONE (0x00000001) +# define MGA_SRC_DST_COLOR (0x00000002) +# define MGA_SRC_ONE_MINUS_DST_COLOR (0x00000003) +# define MGA_SRC_ALPHA (0x00000004) +# define MGA_SRC_ONE_MINUS_SRC_ALPHA (0x00000005) +# define MGA_SRC_DST_ALPHA (0x00000006) +# define MGA_SRC_ONE_MINUS_DST_ALPHA (0x00000007) +# define MGA_SRC_SRC_ALPHA_SATURATE (0x00000008) +# define MGA_SRC_BLEND_MASK (0x0000000f) +# define MGA_DST_ZERO (0x00000000) +# define MGA_DST_ONE (0x00000010) +# define MGA_DST_SRC_COLOR (0x00000020) +# define MGA_DST_ONE_MINUS_SRC_COLOR (0x00000030) +# define MGA_DST_SRC_ALPHA (0x00000040) +# define MGA_DST_ONE_MINUS_SRC_ALPHA (0x00000050) +# define MGA_DST_DST_ALPHA (0x00000060) +# define MGA_DST_ONE_MINUS_DST_ALPHA (0x00000070) +# define MGA_DST_BLEND_MASK (0x00000070) +# define MGA_ALPHACHANNEL (0x00000100) +# define MGA_VIDEOALPHA (0x00000200) +# define MGA_DIFFUSEDALPHA (0x01000000) +# define MGA_MODULATEDALPHA (0x02000000) +#define MGAREG_TDUALSTAGE0 (0x2CF8) +#define MGAREG_TDUALSTAGE1 (0x2CFC) +# define MGA_TDS_COLOR_ARG2_DIFFUSE (0x00000000) +# define MGA_TDS_COLOR_ARG2_SPECULAR (0x00000001) +# define MGA_TDS_COLOR_ARG2_FCOL (0x00000002) +# define MGA_TDS_COLOR_ARG2_PREVSTAGE (0x00000003) +# define MGA_TDS_COLOR_ALPHA_DIFFUSE (0x00000000) +# define MGA_TDS_COLOR_ALPHA_FCOL (0x00000004) +# define MGA_TDS_COLOR_ALPHA_CURRTEX (0x00000008) +# define MGA_TDS_COLOR_ALPHA_PREVTEX (0x0000000c) +# define MGA_TDS_COLOR_ALPHA_PREVSTAGE (0x00000010) +# define MGA_TDS_COLOR_ARG1_REPLICATEALPHA (0x00000020) +# define MGA_TDS_COLOR_ARG1_INV (0x00000040) +# define MGA_TDS_COLOR_ARG2_REPLICATEALPHA (0x00000080) +# define MGA_TDS_COLOR_ARG2_INV (0x00000100) +# define MGA_TDS_COLOR_ALPHA1INV (0x00000200) +# define MGA_TDS_COLOR_ALPHA2INV (0x00000400) +# define MGA_TDS_COLOR_ARG1MUL_ALPHA1 (0x00000800) +# define MGA_TDS_COLOR_ARG2MUL_ALPHA2 (0x00001000) +# define MGA_TDS_COLOR_ARG1ADD_MULOUT (0x00002000) +# define MGA_TDS_COLOR_ARG2ADD_MULOUT (0x00004000) +# define MGA_TDS_COLOR_MODBRIGHT_2X (0x00008000) +# define MGA_TDS_COLOR_MODBRIGHT_4X (0x00010000) +# define MGA_TDS_COLOR_ADD_SUB (0x00000000) +# define MGA_TDS_COLOR_ADD_ADD (0x00020000) +# define MGA_TDS_COLOR_ADD2X (0x00040000) +# define MGA_TDS_COLOR_ADDBIAS (0x00080000) +# define MGA_TDS_COLOR_BLEND (0x00100000) +# define MGA_TDS_COLOR_SEL_ARG1 (0x00000000) +# define MGA_TDS_COLOR_SEL_ARG2 (0x00200000) +# define MGA_TDS_COLOR_SEL_ADD (0x00400000) +# define MGA_TDS_COLOR_SEL_MUL (0x00600000) +# define MGA_TDS_ALPHA_ARG1_INV (0x00800000) +# define MGA_TDS_ALPHA_ARG2_DIFFUSE (0x00000000) +# define MGA_TDS_ALPHA_ARG2_FCOL (0x01000000) +# define MGA_TDS_ALPHA_ARG2_PREVTEX (0x02000000) +# define MGA_TDS_ALPHA_ARG2_PREVSTAGE (0x03000000) +# define MGA_TDS_ALPHA_ARG2_INV (0x04000000) +# define MGA_TDS_ALPHA_ADD (0x08000000) +# define MGA_TDS_ALPHA_ADDBIAS (0x10000000) +# define MGA_TDS_ALPHA_ADD2X (0x20000000) +# define MGA_TDS_ALPHA_SEL_ARG1 (0x00000000) +# define MGA_TDS_ALPHA_SEL_ARG2 (0x40000000) +# define MGA_TDS_ALPHA_SEL_ADD (0x80000000) +# define MGA_TDS_ALPHA_SEL_MUL (0xc0000000) + #define MGAREG_DWGSYNC 0x2c4c #define MGAREG_AGP_PLL 0x1e4c diff --git a/src/mga_storm.c b/src/mga_storm.c index 88e8fe0..7fb66c9 100644 --- a/src/mga_storm.c +++ b/src/mga_storm.c @@ -304,6 +304,7 @@ Bool MGASetupForCPUToScreenAlphaTextureFaked( ScrnInfoPtr pScrn, int op, int height, int flags ) { int log2w, log2h, pitch, sizeNeeded, offset; + unsigned int texctl, dwgctl, alphactrl; MGAPtr pMga = MGAPTR(pScrn); if(op != PictOpOver) /* only one tested */ @@ -358,11 +359,19 @@ Bool MGASetupForCPUToScreenAlphaTextureFaked( ScrnInfoPtr pScrn, int op, ((width - 1) << 18)); OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) | ((height - 1) << 18)); - OUTREG(MGAREG_TEXCTL, 0x1A000106 | ((pitch & 0x07FF) << 9)); - OUTREG(MGAREG_TEXCTL2, 0x00000014); - OUTREG(MGAREG_DWGCTL, 0x000c7076); - OUTREG(MGAREG_TEXFILTER, 0x01e00020); - OUTREG(MGAREG_ALPHACTRL, 0x00000154); + + texctl = MGA_TW32 | MGA_PITCHLIN | MGA_TAKEY | MGA_CLAMPUV | + ((pitch & 0x07FF) << 9); + dwgctl = MGADWG_TEXTURE_TRAP | MGADWG_I | MGADWG_ARZERO | + MGADWG_SGNZERO | MGADWG_SHIFTZERO | 0xc0000; + alphactrl = MGA_SRC_ALPHA | MGA_DST_ONE_MINUS_SRC_ALPHA | + MGA_ALPHACHANNEL; + + OUTREG(MGAREG_TEXCTL, texctl); + OUTREG(MGAREG_TEXCTL2, MGA_TC2_DECALDIS | MGA_TC2_CKSTRANSDIS); + OUTREG(MGAREG_DWGCTL, dwgctl); + OUTREG(MGAREG_TEXFILTER, ((0x1e << 20) | MGA_MAG_BILIN)); + OUTREG(MGAREG_ALPHACTRL, alphactrl); return TRUE; } @@ -383,6 +392,7 @@ MGASetupForCPUToScreenAlphaTexture ( int flags ){ int log2w, log2h, i, pitch, sizeNeeded, offset; + unsigned int texctl, dwgctl, alphactrl; CARD8 *dst; MGAPtr pMga = MGAPTR(pScrn); @@ -456,11 +466,20 @@ MGASetupForCPUToScreenAlphaTexture ( ((width - 1) << 18)); OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) | ((height - 1) << 18)); - OUTREG(MGAREG_TEXCTL, 0x3A000107 | ((pitch & 0x07FF) << 9)); - OUTREG(MGAREG_TEXCTL2, 0x00000014); - OUTREG(MGAREG_DWGCTL, 0x000c7076); - OUTREG(MGAREG_TEXFILTER, 0x01e00020); - OUTREG(MGAREG_ALPHACTRL, 0x02000151); + + texctl = MGA_TW8A | MGA_PITCHLIN | MGA_TAKEY | MGA_CLAMPUV | + MGA_TEXMODULATE | + ((pitch & 0x07FF) << 9); + dwgctl = MGADWG_TEXTURE_TRAP | MGADWG_I | MGADWG_ARZERO | + MGADWG_SGNZERO | MGADWG_SHIFTZERO | 0xc0000; + alphactrl = MGA_SRC_ONE | MGA_DST_ONE_MINUS_SRC_ALPHA | + MGA_ALPHACHANNEL | MGA_MODULATEDALPHA; + + OUTREG(MGAREG_TEXCTL, texctl); + OUTREG(MGAREG_TEXCTL2, MGA_TC2_DECALDIS | MGA_TC2_CKSTRANSDIS); + OUTREG(MGAREG_DWGCTL, dwgctl); + OUTREG(MGAREG_TEXFILTER, ((0x1e << 20) | MGA_MAG_BILIN)); + OUTREG(MGAREG_ALPHACTRL, alphactrl); return TRUE; } @@ -478,6 +497,7 @@ MGASetupForCPUToScreenTexture ( int flags ){ int log2w, log2h, i, pitch, sizeNeeded, offset; + unsigned int texctl, dwgctl, alphactrl; MGAPtr pMga = MGAPTR(pScrn); if(op != PictOpOver) /* only one tested */ @@ -537,11 +557,19 @@ MGASetupForCPUToScreenTexture ( ((width - 1) << 18)); OUTREG(MGAREG_TEXHEIGHT, log2h | (((8 - log2h) & 63) << 9) | ((height - 1) << 18)); - OUTREG(MGAREG_TEXCTL, 0x1A000106 | ((pitch & 0x07FF) << 9)); - OUTREG(MGAREG_TEXCTL2, 0x00000014); - OUTREG(MGAREG_DWGCTL, 0x000c7076); - OUTREG(MGAREG_TEXFILTER, 0x01e00020); - OUTREG(MGAREG_ALPHACTRL, 0x00000151); + + texctl = MGA_TW32 | MGA_PITCHLIN | MGA_TAKEY | MGA_CLAMPUV | + ((pitch & 0x07FF) << 9); + dwgctl = MGADWG_TEXTURE_TRAP | MGADWG_I | MGADWG_ARZERO | + MGADWG_SGNZERO | MGADWG_SHIFTZERO | 0xc0000; + alphactrl = MGA_SRC_ONE | MGA_DST_ONE_MINUS_SRC_ALPHA | + MGA_ALPHACHANNEL; + + OUTREG(MGAREG_TEXCTL, texctl); + OUTREG(MGAREG_TEXCTL2, MGA_TC2_DECALDIS | MGA_TC2_CKSTRANSDIS); + OUTREG(MGAREG_DWGCTL, dwgctl); + OUTREG(MGAREG_TEXFILTER, ((0x1e << 20) | MGA_MAG_BILIN)); + OUTREG(MGAREG_ALPHACTRL, alphactrl); return TRUE; } diff --git a/src/mga_video.c b/src/mga_video.c index 1f0e87d..30ae6fc 100644 --- a/src/mga_video.c +++ b/src/mga_video.c @@ -19,7 +19,12 @@ #include "xf86xv.h" #include <X11/extensions/Xv.h> #include "xaa.h" + +#ifdef USE_XAA +#include "xaa.h" #include "xaalocal.h" +#endif + #include "dixstruct.h" #include "fourcc.h" @@ -52,7 +57,7 @@ static int MGAPutImage(ScrnInfoPtr, short, short, short, short, short, short, Bool, RegionPtr, pointer, DrawablePtr); static int MGAQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, unsigned short *, int *, int *); - +static void MGAFreeMemory(ScrnInfoPtr pScrn, void *mem_struct); static void MGAResetVideoOverlay(ScrnInfoPtr); @@ -63,6 +68,19 @@ static void MGAVideoTimerCallback(ScrnInfoPtr pScrn, Time time); static Atom xvBrightness, xvContrast, xvColorKey, xvDoubleBuffer; +#ifdef USE_EXA +static void +MGAVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + MGAPtr pMga = MGAPTR(pScrn); + MGAPortPrivPtr pPriv = pMga->portPrivate; + + if (pPriv->video_memory == area) + pPriv->video_memory = NULL; +} +#endif /* USE_EXA */ + void MGAInitVideo(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -331,9 +349,9 @@ MGAStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) if(shutdown) { if(pPriv->videoStatus & CLIENT_VIDEO_ON) OUTREG(MGAREG_BESCTL, 0); - if(pPriv->linear) { - xf86FreeOffscreenLinear(pPriv->linear); - pPriv->linear = NULL; + if (pPriv->video_memory) { + MGAFreeMemory(pScrn, pPriv->video_memory); + pPriv->video_memory = NULL; } pPriv->videoStatus = 0; } else { @@ -527,45 +545,109 @@ MGACopyMungedData( } -static FBLinearPtr +static CARD32 MGAAllocateMemory( ScrnInfoPtr pScrn, - FBLinearPtr linear, + void **mem_struct, int size ){ - ScreenPtr pScreen; - FBLinearPtr new_linear; + MGAPtr pMga = MGAPTR(pScrn); + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + int offset = 0; + +#ifdef USE_EXA + if (pMga->Exa) { + ExaOffscreenArea *area = *mem_struct; + + if (area) { + if (area->size >= size) + return area->offset; - if(linear) { - if(linear->size >= size) - return linear; - - if(xf86ResizeOffscreenLinear(linear, size)) - return linear; + exaOffscreenFree(pScrn->pScreen, area); + } + + area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE, MGAVideoSave, + NULL); + *mem_struct = area; + + if (!area) + return 0; - xf86FreeOffscreenLinear(linear); + offset = area->offset; } +#endif /* USE_EXA */ +#ifdef USE_XAA + FBLinearPtr linear = *mem_struct; + int cpp = pMga->CurrentLayout.bitsPerPixel / 8; + + /* XAA allocates in units of pixels at the screen bpp, so adjust size + * appropriately. + */ + size = (size + cpp - 1) / cpp; + + if (!pMga->Exa) { + if (linear) { + if (linear->size >= size) + return linear->offset * cpp; - pScreen = screenInfo.screens[pScrn->scrnIndex]; + if (xf86ResizeOffscreenLinear(linear, size)) + return linear->offset * cpp; - new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16, - NULL, NULL, NULL); + xf86FreeOffscreenLinear(linear); + } - if(!new_linear) { - int max_size; - xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, - PRIORITY_EXTREME); - - if(max_size < size) - return NULL; + linear = xf86AllocateOffscreenLinear(pScreen, size, 16, + NULL, NULL, NULL); + *mem_struct = linear; - xf86PurgeUnlockedOffscreenAreas(pScreen); - new_linear = xf86AllocateOffscreenLinear(pScreen, size, 16, - NULL, NULL, NULL); + if (!linear) { + int max_size; + + xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, + PRIORITY_EXTREME); + + if (max_size < size) + return 0; + + xf86PurgeUnlockedOffscreenAreas(pScreen); + + linear = xf86AllocateOffscreenLinear(pScreen, size, 16, + NULL, NULL, NULL); + *mem_struct = linear; + + if (!linear) + return 0; + } + + offset = linear->offset * cpp; } +#endif /* USE_XAA */ - return new_linear; + return offset; +} + +static void +MGAFreeMemory(ScrnInfoPtr pScrn, void *mem_struct) +{ + MGAPtr pMga = MGAPTR(pScrn); + +#ifdef USE_EXA + if (pMga->Exa) { + ExaOffscreenArea *area = mem_struct; + + if (area) + exaOffscreenFree(pScrn->pScreen, area); + } +#endif /* USE_EXA */ +#ifdef USE_XAA + if (!pMga->Exa) { + FBLinearPtr linear = mem_struct; + + if (linear) + xf86FreeOffscreenLinear(linear); + } +#endif /* USE_XAA */ } static void @@ -740,7 +822,7 @@ MGADisplayVideoTexture( pbox++; } - pMga->AccelInfoRec->NeedToSync = TRUE; + MGA_MARK_SYNC(pMga, pScrn); } static int @@ -762,7 +844,7 @@ MGAPutImage( unsigned char *dst_start; int new_size, offset, offset2 = 0, offset3 = 0; int srcPitch, srcPitch2 = 0, dstPitch; - int top, left, npixels, nlines, bpp; + int top, left, npixels, nlines; BoxRec dstBox; CARD32 tmp; @@ -788,10 +870,8 @@ MGAPutImage( dstBox.y2 -= pScrn->frameY0; } - bpp = pScrn->bitsPerPixel >> 3; - dstPitch = ((width << 1) + 15) & ~15; - new_size = ((dstPitch * height) + bpp - 1) / bpp; + new_size = dstPitch * height; switch(id) { case FOURCC_YV12: @@ -808,11 +888,12 @@ MGAPutImage( break; } - if(!(pPriv->linear = MGAAllocateMemory(pScrn, pPriv->linear, - pPriv->doubleBuffer ? (new_size << 1) : new_size))) - { + pPriv->video_offset = MGAAllocateMemory(pScrn, &pPriv->video_memory, + pPriv->doubleBuffer ? + (new_size << 1) : new_size); + if (!pPriv->video_offset) return BadAlloc; - } + pPriv->currentBuffer ^= 1; /* copy data */ @@ -821,16 +902,13 @@ MGAPutImage( npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; left <<= 1; - offset = pPriv->linear->offset * bpp; + offset = pPriv->video_offset; if(pPriv->doubleBuffer) - offset += pPriv->currentBuffer * new_size * bpp; + offset += pPriv->currentBuffer * new_size; dst_start = pMga->FbStart + offset + left + (top * dstPitch); - if(pMga->TexturedVideo && pMga->AccelInfoRec->NeedToSync && - ((long)data != pPriv->lastPort)) - { - MGAStormSync(pScrn); - } + if (pMga->TexturedVideo && ((long)data != pPriv->lastPort)) + MGA_SYNC(pMga, pScrn); switch(id) { case FOURCC_YV12: @@ -949,9 +1027,9 @@ MGAVideoTimerCallback(ScrnInfoPtr pScrn, Time time) } } else { /* FREE_TIMER */ if(pPriv->freeTime < time) { - if(pPriv->linear) { - xf86FreeOffscreenLinear(pPriv->linear); - pPriv->linear = NULL; + if (pPriv->video_memory) { + MGAFreeMemory(pScrn, pPriv->video_memory); + pPriv->video_memory = NULL; } pPriv->videoStatus = 0; pMga->VideoTimerCallback = NULL; @@ -965,7 +1043,7 @@ MGAVideoTimerCallback(ScrnInfoPtr pScrn, Time time) /****************** Offscreen stuff ***************/ typedef struct { - FBLinearPtr linear; + void *surface_memory; Bool isOn; } OffscreenPrivRec, * OffscreenPrivPtr; @@ -977,8 +1055,8 @@ MGAAllocateSurface( unsigned short h, XF86SurfacePtr surface ){ - FBLinearPtr linear; - int pitch, size, bpp; + void *surface_memory = NULL; + int pitch, size, bpp, offset; OffscreenPrivPtr pPriv; if((w > 1024) || (h > 1024)) @@ -989,35 +1067,36 @@ MGAAllocateSurface( bpp = pScrn->bitsPerPixel >> 3; size = ((pitch * h) + bpp - 1) / bpp; - if(!(linear = MGAAllocateMemory(pScrn, NULL, size))) + offset = MGAAllocateMemory(pScrn, &surface_memory, size); + if (!offset) return BadAlloc; surface->width = w; surface->height = h; if(!(surface->pitches = xalloc(sizeof(int)))) { - xf86FreeOffscreenLinear(linear); + MGAFreeMemory(pScrn, surface_memory); return BadAlloc; } if(!(surface->offsets = xalloc(sizeof(int)))) { xfree(surface->pitches); - xf86FreeOffscreenLinear(linear); + MGAFreeMemory(pScrn, surface_memory); return BadAlloc; } if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { xfree(surface->pitches); xfree(surface->offsets); - xf86FreeOffscreenLinear(linear); + MGAFreeMemory(pScrn, surface_memory); return BadAlloc; } - pPriv->linear = linear; + pPriv->surface_memory = surface_memory; pPriv->isOn = FALSE; surface->pScrn = pScrn; surface->id = id; surface->pitches[0] = pitch; - surface->offsets[0] = linear->offset * bpp; + surface->offsets[0] = offset; surface->devPrivate.ptr = (pointer)pPriv; return Success; @@ -1044,11 +1123,12 @@ static int MGAFreeSurface( XF86SurfacePtr surface ){ + ScrnInfoPtr pScrn = surface->pScrn; OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; if(pPriv->isOn) MGAStopSurface(surface); - xf86FreeOffscreenLinear(pPriv->linear); + MGAFreeMemory(pScrn, pPriv->surface_memory); xfree(surface->pitches); xfree(surface->offsets); xfree(surface->devPrivate.ptr); diff --git a/util/Makefile.am b/util/Makefile.am index 8f64bcf..734c7b3 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -1,7 +1,7 @@ # $XFree86: $ # this is not even built in the monolith, so don't install it -bin_PROGRAMS = stormdwg +noinst_PROGRAMS = stormdwg stormdwg_SOURCES = stormdwg.c |