summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--ChangeLog117
-rw-r--r--Makefile.am10
-rw-r--r--configure.ac48
-rw-r--r--man/mga.man15
-rw-r--r--src/Makefile.am11
-rw-r--r--src/mga.h62
-rw-r--r--src/mga_dri.c26
-rw-r--r--src/mga_driver.c79
-rw-r--r--src/mga_exa.c810
-rw-r--r--src/mga_reg.h114
-rw-r--r--src/mga_storm.c58
-rw-r--r--src/mga_video.c196
-rw-r--r--util/Makefile.am2
14 files changed, 1334 insertions, 215 deletions
diff --git a/.gitignore b/.gitignore
index f421710..564d950 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/src/mga.h b/src/mga.h
index 3969183..f9afea3 100644
--- a/src/mga.h
+++ b/src/mga.h
@@ -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