summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Fufutos <fufutos610@hotmail.com>2006-04-15 22:44:23 +0300
committerLuc Verhaegen <libv@skynet.be>2006-04-16 16:45:48 +0200
commitdd2cdd7bcd84334042e2f4db84d268792f4d9802 (patch)
tree560b8fb91007c77223bf6957d68deb4639c1877b
parentb01bf3cead708e6d758091c2e40846646c38ca9e (diff)
[PATCH] EXA support.
-rw-r--r--configure.ac36
-rw-r--r--src/Makefile.am7
-rw-r--r--src/ati.c19
-rw-r--r--src/atiaccel.c8
-rw-r--r--src/aticonfig.c22
-rw-r--r--src/atidga.c15
-rw-r--r--src/atidri.c30
-rw-r--r--src/atiload.c53
-rw-r--r--src/atiload.h15
-rw-r--r--src/atimach64.c4
-rw-r--r--src/atimach64accel.c184
-rw-r--r--src/atimach64accel.h6
-rw-r--r--src/atimach64exa.c526
-rw-r--r--src/atimach64io.h71
-rw-r--r--src/atimach64xv.c139
-rw-r--r--src/atioption.c7
-rw-r--r--src/atioption.h3
-rw-r--r--src/atiscreen.c401
-rw-r--r--src/atistruct.h17
19 files changed, 1225 insertions, 338 deletions
diff --git a/configure.ac b/configure.ac
index d0f794b..f19ea5f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,6 +56,11 @@ AC_ARG_ENABLE(dri, AC_HELP_STRING([--disable-dri],
[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(XINERAMA, xineramaproto)
@@ -155,7 +160,36 @@ if test "x$ATIMISC_TV_OUT" = xyes; then
fi
AC_DEFINE(USE_XAA, 1, [Build support for XAA])
-AC_DEFINE(USE_EXA, 1, [Build support for Exa])
+
+# Properly handle EXA.
+AC_MSG_CHECKING([whether to enable EXA support])
+if test "x$EXA" = xyes; then
+ echo "yes"
+ AC_CHECK_FILE([${sdkdir}/exa.h],
+ [have_exa_h="yes"], [have_exa_h="no"])
+else
+ echo "no"
+fi
+
+if test "x$have_exa_h" = xyes; then
+ AC_MSG_CHECKING([wether EXA version is at least 2.0.0])
+ AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[
+#include "${sdkdir}/exa.h"
+#if EXA_VERSION_MAJOR < 2
+#error OLD EXA!
+#endif
+ ]])],
+ [USE_EXA=yes],
+ [USE_EXA=no])
+ if test "x$USE_EXA" = xyes; then
+ echo "yes."
+ AC_DEFINE(USE_EXA, 1, [Build support for Exa])
+ else
+ echo "no."
+ fi
+fi
+
+AM_CONDITIONAL(USE_EXA, test "x$USE_EXA" = xyes)
AC_SUBST([XORG_CFLAGS])
AC_SUBST([DRI_CFLAGS])
diff --git a/src/Makefile.am b/src/Makefile.am
index 298060f..c739559 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -38,6 +38,10 @@ if ATIMISC_DGA
ATIMISC_DGA_SOURCES = atidga.c
endif
+if USE_EXA
+ATIMISC_EXA_SOURCES = atimach64exa.c
+endif
+
AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@
mach64_drv_la_LTLIBRARIES = mach64_drv.la
@@ -50,7 +54,8 @@ mach64_drv_la_SOURCES = \
atimach64cursor.c atimach64i2c.c atimach64io.c atimach64xv.c \
atimode.c atipreinit.c atiprint.c atirgb514.c atiscreen.c \
atituner.c atiutil.c ativalid.c atixv.c atiload.c ati.c \
- $(ATIMISC_DRI_SRCS) $(ATIMISC_DGA_SOURCES) $(ATI_CPIO_SOURCES)
+ $(ATIMISC_DRI_SRCS) $(ATIMISC_DGA_SOURCES) $(ATI_CPIO_SOURCES) \
+ $(ATIMISC_EXA_SOURCES)
EXTRA_DIST = \
atiaccel.h \
diff --git a/src/ati.c b/src/ati.c
index 33905b6..75c1a5e 100644
--- a/src/ati.c
+++ b/src/ati.c
@@ -189,6 +189,19 @@ const char *ATIshadowfbSymbols[] =
NULL
};
+#ifdef USE_EXA
+const char *ATIexaSymbols[] =
+{
+ "exaDriverAlloc",
+ "exaDriverInit",
+ "exaDriverFini",
+ "exaOffscreenAlloc",
+ "exaOffscreenFree",
+ NULL
+};
+#endif
+
+#ifdef USE_XAA
const char *ATIxaaSymbols[] =
{
"XAACreateInfoRec",
@@ -196,6 +209,7 @@ const char *ATIxaaSymbols[] =
"XAAInit",
NULL
};
+#endif
const char *ATIramdacSymbols[] =
{
@@ -244,7 +258,12 @@ ATISetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor)
#endif /* XF86DRI_DEVEL */
ATIfbSymbols,
ATIshadowfbSymbols,
+#ifdef USE_EXA
+ ATIexaSymbols,
+#endif /* USE_EXA */
+#ifdef USE_XAA
ATIxaaSymbols,
+#endif /* USE_XAA */
ATIramdacSymbols,
ATIi2cSymbols,
NULL );
diff --git a/src/atiaccel.c b/src/atiaccel.c
index 89c2b59..81baf6e 100644
--- a/src/atiaccel.c
+++ b/src/atiaccel.c
@@ -32,6 +32,7 @@
#include "atimach64accel.h"
#include "atistruct.h"
+#ifdef USE_XAA
/*
* ATIInitializeAcceleration --
*
@@ -63,10 +64,10 @@ ATIInitializeAcceleration
#ifdef XF86DRI_DEVEL
- /* If DRI is enabled, we've already set up the FB manager in ATIScreenInit */
- if (!pATI->directRenderingEnabled)
+ /* If DRI is enabled, we've already set up the FB manager in ATIScreenInit */
+ if (!pATI->directRenderingEnabled)
-#endif /* XF86DRI */
+#endif /* XF86DRI_DEVEL */
{
/*
* Note: If PixelArea exceeds the engine's maximum, the excess is
@@ -134,3 +135,4 @@ ATIResizeOffscreenLinear
return pLinear;
}
+#endif /* USE_XAA */
diff --git a/src/aticonfig.c b/src/aticonfig.c
index 91731f8..1c8750c 100644
--- a/src/aticonfig.c
+++ b/src/aticonfig.c
@@ -152,6 +152,7 @@ ATIProcessOptions
# define ProbeClocks PublicOption[ATI_OPTION_PROBE_CLOCKS].value.bool
# define ShadowFB PublicOption[ATI_OPTION_SHADOW_FB].value.bool
# define SWCursor PublicOption[ATI_OPTION_SWCURSOR].value.bool
+# define AccelMethod PublicOption[ATI_OPTION_ACCELMETHOD].value.str
# define LCDSync PrivateOption[ATI_OPTION_LCDSYNC].value.bool
# define ReferenceClock \
@@ -322,5 +323,26 @@ ATIProcessOptions
}
}
+ pATI->useEXA = FALSE;
+ if (pATI->OptionAccel)
+ {
+ MessageType from = X_DEFAULT;
+#if defined(USE_EXA)
+#if defined(USE_XAA)
+ if (AccelMethod != NULL)
+ {
+ from = X_CONFIG;
+ if (xf86NameCmp(AccelMethod, "EXA") == 0)
+ pATI->useEXA = TRUE;
+ }
+#else /* USE_XAA */
+ pATI->useEXA = TRUE;
+#endif /* !USE_XAA */
+#endif /* USE_EXA */
+ xf86DrvMsg(pScreenInfo->scrnIndex, from,
+ "Using %s acceleration architecture\n",
+ pATI->useEXA ? "EXA" : "XAA");
+ }
+
xfree(PublicOption);
}
diff --git a/src/atidga.c b/src/atidga.c
index 8a623ef..f447485 100644
--- a/src/atidga.c
+++ b/src/atidga.c
@@ -187,6 +187,8 @@ ATIDGAFillRect
)
{
ATIPtr pATI = ATIPTR(pScreenInfo);
+/*FIXME : use EXA if available */
+#ifdef USE_XAA
XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo;
(*pXAAInfo->SetupForSolidFill)(pScreenInfo, (int)colour, GXcopy,
@@ -195,6 +197,7 @@ ATIDGAFillRect
if (pScreenInfo->bitsPerPixel == pATI->bitsPerPixel)
SET_SYNC_FLAG(pXAAInfo);
+#endif
}
/*
@@ -216,6 +219,8 @@ ATIDGABlitRect
)
{
ATIPtr pATI = ATIPTR(pScreenInfo);
+/*FIXME : use EXA if available */
+#ifdef USE_XAA
XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo;
int xdir = ((xSrc < xDst) && (ySrc == yDst)) ? -1 : 1;
int ydir = (ySrc < yDst) ? -1 : 1;
@@ -227,6 +232,7 @@ ATIDGABlitRect
if (pScreenInfo->bitsPerPixel == pATI->bitsPerPixel)
SET_SYNC_FLAG(pXAAInfo);
+#endif
}
/*
@@ -249,6 +255,8 @@ ATIDGABlitTransRect
)
{
ATIPtr pATI = ATIPTR(pScreenInfo);
+/*FIXME : use EXA if available */
+#ifdef USE_XAA
XAAInfoRecPtr pXAAInfo = pATI->pXAAInfo;
int xdir = ((xSrc < xDst) && (ySrc == yDst)) ? -1 : 1;
int ydir = (ySrc < yDst) ? -1 : 1;
@@ -265,6 +273,7 @@ ATIDGABlitTransRect
if (pScreenInfo->bitsPerPixel == pATI->bitsPerPixel)
SET_SYNC_FLAG(pXAAInfo);
+#endif
}
/*
@@ -334,8 +343,10 @@ ATIDGAAddModes
pDGAMode->flags |= DGA_PIXMAP_AVAILABLE;
pDGAMode->address = pATI->pMemory;
+#ifdef USE_XAA
if (pATI->pXAAInfo)
pDGAMode->flags &= ~DGA_CONCURRENT_ACCESS;
+#endif
}
if ((pMode->Flags & V_DBLSCAN) || (pMode->VScan > 1))
pDGAMode->flags |= DGA_DOUBLESCAN;
@@ -396,7 +407,9 @@ ATIDGAInit
ATIPtr pATI
)
{
+#ifdef USE_XAA
XAAInfoRecPtr pXAAInfo;
+#endif
int flags;
if (!pATI->nDGAMode)
@@ -421,6 +434,7 @@ ATIDGAInit
pATI->ATIDGAFunctions.GetViewport = ATIDGAGetViewport;
flags = 0;
+#ifdef USE_XAA
if ((pXAAInfo = pATI->pXAAInfo))
{
pATI->ATIDGAFunctions.Sync = pXAAInfo->Sync;
@@ -438,6 +452,7 @@ ATIDGAInit
pATI->ATIDGAFunctions.BlitTransRect = ATIDGABlitTransRect;
}
}
+#endif
if (!flags)
flags = DGA_CONCURRENT_ACCESS;
diff --git a/src/atidri.c b/src/atidri.c
index b6b701e..2c15483 100644
--- a/src/atidri.c
+++ b/src/atidri.c
@@ -120,7 +120,7 @@ static Bool ATIInitVisualConfigs( ScreenPtr pScreen )
}
i = 0;
- for (db = 0; db <= 1; db++) {
+ for (db = 1; db >= 0; db--) {
for ( accum = 0 ; accum <= ATI_USE_ACCUM ; accum++ ) {
for ( stencil = 0 ; stencil <= ATI_USE_STENCIL ; stencil++ ) {
pATIConfigPtrs[i] = &pATIConfigs[i];
@@ -201,7 +201,7 @@ static Bool ATIInitVisualConfigs( ScreenPtr pScreen )
}
i = 0;
- for (db = 0; db <= 1; db++) {
+ for (db = 1; db >= 0; db--) {
for ( accum = 0 ; accum <= ATI_USE_ACCUM ; accum++ ) {
for ( stencil = 0 ; stencil <= ATI_USE_STENCIL ; stencil++ ) {
pATIConfigPtrs[i] = &pATIConfigs[i];
@@ -292,9 +292,9 @@ static void ATIEnterServer( ScreenPtr pScreen )
ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
ATIPtr pATI = ATIPTR(pScreenInfo);
- if ( pATI->directRenderingEnabled && pATI->pXAAInfo ) {
- pATI->pXAAInfo->NeedToSync = TRUE;
- pATI->NeedDRISync = TRUE;
+ if ( pATI->directRenderingEnabled ) {
+ ATIDRIMarkSyncInt(pScreenInfo);
+ ATIDRIMarkSyncExt(pScreenInfo);
}
}
@@ -337,6 +337,10 @@ static void ATIDRITransitionTo2d(ScreenPtr pScreen)
ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
ATIPtr pATI = ATIPTR(pScreenInfo);
+#ifdef USE_XAA
+ if (pATI->useEXA)
+ return;
+
if (pATI->backArea) {
xf86FreeOffscreenArea(pATI->backArea);
pATI->backArea = NULL;
@@ -345,6 +349,8 @@ static void ATIDRITransitionTo2d(ScreenPtr pScreen)
xf86FreeOffscreenArea(pATI->depthTexArea);
pATI->depthTexArea = NULL;
}
+#endif
+
pATI->have3DWindows = FALSE;
}
@@ -352,9 +358,14 @@ static void ATIDRITransitionTo3d(ScreenPtr pScreen)
{
ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
ATIPtr pATI = ATIPTR(pScreenInfo);
+#ifdef USE_XAA
FBAreaPtr fbArea;
int width, height;
+ /* EXA allocates these areas up front, in memory manager setup */
+ if (pATI->useEXA)
+ return;
+
xf86PurgeUnlockedOffscreenAreas(pScreen);
xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0);
@@ -396,6 +407,7 @@ static void ATIDRITransitionTo3d(ScreenPtr pScreen)
if (fbArea)
xf86FreeOffscreenArea(fbArea);
+#endif
pATI->have3DWindows = TRUE;
}
@@ -403,6 +415,7 @@ static void ATIDRITransitionTo3d(ScreenPtr pScreen)
/* Initialize the state of the back and depth buffers. */
static void ATIDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, CARD32 indx )
{
+#ifdef USE_XAA
ScreenPtr pScreen = pWin->drawable.pScreen;
ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
ATIPtr pATI = ATIPTR(pScreenInfo);
@@ -453,7 +466,8 @@ static void ATIDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, CARD32 indx )
pbox->x2 - pbox->x1,
pbox->y2 - pbox->y1);
- pXAAInfo->NeedToSync = TRUE;
+ ATIDRIMarkSyncInt(pScreenInfo);
+#endif
}
/* Copy the back and depth buffers when the X server moves a window.
@@ -468,6 +482,7 @@ static void ATIDRIInitBuffers( WindowPtr pWin, RegionPtr prgn, CARD32 indx )
static void ATIDRIMoveBuffers( WindowPtr pWin, DDXPointRec ptOldOrg,
RegionPtr prgnSrc, CARD32 indx )
{
+#ifdef USE_XAA
ScreenPtr pScreen = pWin->drawable.pScreen;
ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
ATIPtr pATI = ATIPTR(pScreenInfo);
@@ -631,7 +646,8 @@ static void ATIDRIMoveBuffers( WindowPtr pWin, DDXPointRec ptOldOrg,
DEALLOCATE_LOCAL(pptNew1);
DEALLOCATE_LOCAL(pboxNew1);
- pXAAInfo->NeedToSync = TRUE;
+ ATIDRIMarkSyncInt(pScreenInfo);
+#endif
}
/* Compute log base 2 of val. */
diff --git a/src/atiload.c b/src/atiload.c
index 16a1446..82adb95 100644
--- a/src/atiload.c
+++ b/src/atiload.c
@@ -30,6 +30,8 @@
#ifdef XFree86LOADER
+#include <string.h>
+
#include "ati.h"
#include "aticursor.h"
#include "atiload.h"
@@ -69,32 +71,61 @@ ATILoadModules
ATIPtr pATI
)
{
+ pointer fbPtr = NULL;
+
/* Load shadow frame buffer code if needed */
if (pATI->OptionShadowFB &&
!ATILoadModule(pScreenInfo, "shadowfb", ATIshadowfbSymbols))
return NULL;
- /* Load XAA if needed */
- if (pATI->OptionAccel &&
- !ATILoadModule(pScreenInfo, "xaa", ATIxaaSymbols))
- return NULL;
-
- /* Load ramdac module if needed */
- if ((pATI->Cursor > ATI_CURSOR_SOFTWARE) &&
- !ATILoadModule(pScreenInfo, "ramdac", ATIramdacSymbols))
- return NULL;
-
/* Load depth-specific entry points */
switch (pATI->bitsPerPixel) {
case 8:
case 16:
case 24:
case 32:
- return ATILoadModule(pScreenInfo, "fb", ATIfbSymbols);
+ fbPtr = ATILoadModule(pScreenInfo, "fb", ATIfbSymbols);
+ break;
default:
return NULL;
}
+ if (!fbPtr)
+ return NULL;
+
+ /* Load ramdac module if needed */
+ if ((pATI->Cursor > ATI_CURSOR_SOFTWARE) &&
+ !ATILoadModule(pScreenInfo, "ramdac", ATIramdacSymbols))
+ return NULL;
+
+#ifdef USE_EXA
+ /* Load EXA if needed */
+ if (pATI->useEXA && pATI->OptionAccel)
+ {
+ /* Cannot use ATILoadModule(), because of version checking */
+ XF86ModReqInfo req;
+ int errmaj, errmin;
+
+ memset(&req, 0, sizeof(XF86ModReqInfo));
+ req.majorversion = 2;
+ req.minorversion = 0;
+ if (!LoadSubModule(pScreenInfo->module, "exa", NULL, NULL, NULL, &req,
+ &errmaj, &errmin))
+ {
+ LoaderErrorMsg(NULL, "exa", errmaj, errmin);
+ return NULL;
+ }
+ xf86LoaderReqSymLists(ATIexaSymbols, NULL);
+ }
+#endif
+#ifdef USE_XAA
+ /* Load XAA if needed */
+ if (!pATI->useEXA && pATI->OptionAccel &&
+ !ATILoadModule(pScreenInfo, "xaa", ATIxaaSymbols))
+ return NULL;
+#endif
+
+ return fbPtr;
}
#endif /* XFree86LOADER */
diff --git a/src/atiload.h b/src/atiload.h
index bf78eea..976ef3c 100644
--- a/src/atiload.h
+++ b/src/atiload.h
@@ -41,7 +41,20 @@ extern const char *ATIint10Symbols[], *ATIddcSymbols[], *ATIvbeSymbols[],
#endif /* XF86DRI_DEVEL */
- *ATIfbSymbols[], *ATIshadowfbSymbols[], *ATIxaaSymbols[],
+ *ATIfbSymbols[], *ATIshadowfbSymbols[],
+
+#ifdef USE_EXA
+
+ *ATIexaSymbols[],
+
+#endif /* USE_EXA */
+
+#ifdef USE_XAA
+
+ *ATIxaaSymbols[],
+
+#endif /* USE_XAA */
+
*ATIramdacSymbols[], *ATIi2cSymbols[];
extern pointer ATILoadModule(ScrnInfoPtr, const char *, const char **);
diff --git a/src/atimach64.c b/src/atimach64.c
index deaa81f..d5d1035 100644
--- a/src/atimach64.c
+++ b/src/atimach64.c
@@ -825,9 +825,7 @@ ATIMach64Set
outf(HOST_CNTL, pATIHW->host_cntl);
/* Set host transfer window address and size clamp */
- pATI->pHOST_DATA =
- (CARD8 *)pATI->pBlock[GetBits(HOST_DATA_0, BLOCK_SELECT)] +
- (HOST_DATA_0 & MM_IO_SELECT);
+ pATI->pHOST_DATA = ATIHostDataAddr(HOST_DATA_0);
pATI->nHostFIFOEntries = pATI->nFIFOEntries >> 1;
if (pATI->nHostFIFOEntries > 16)
pATI->nHostFIFOEntries = 16;
diff --git a/src/atimach64accel.c b/src/atimach64accel.c
index 1ecb13b..f567358 100644
--- a/src/atimach64accel.c
+++ b/src/atimach64accel.c
@@ -79,7 +79,7 @@
/*
* X-to-Mach64 mix translation table.
*/
-static CARD8 ATIMach64ALU[16] =
+CARD8 ATIMach64ALU[16] =
{
MIX_0, /* GXclear */
MIX_AND, /* GXand */
@@ -105,7 +105,7 @@ static CARD8 ATIMach64ALU[16] =
* This function ensures the current scissor settings do not interfere with
* the current draw request.
*/
-static void
+void
ATIMach64ValidateClip
(
ATIPtr pATI,
@@ -130,6 +130,67 @@ ATIMach64ValidateClip
}
}
+static __inline__ void TestRegisterCachingXV
+(
+ ScrnInfoPtr pScreenInfo
+)
+{
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ if (pATI->Block1Base)
+ {
+ TestRegisterCaching(OVERLAY_Y_X_START);
+ TestRegisterCaching(OVERLAY_Y_X_END);
+
+ TestRegisterCaching(OVERLAY_GRAPHICS_KEY_CLR);
+ TestRegisterCaching(OVERLAY_GRAPHICS_KEY_MSK);
+
+ TestRegisterCaching(OVERLAY_KEY_CNTL);
+
+ TestRegisterCaching(OVERLAY_SCALE_INC);
+ TestRegisterCaching(OVERLAY_SCALE_CNTL);
+
+ TestRegisterCaching(SCALER_HEIGHT_WIDTH);
+
+ TestRegisterCaching(SCALER_TEST);
+
+ TestRegisterCaching(VIDEO_FORMAT);
+
+ if (pATI->Chip < ATI_CHIP_264VTB)
+ {
+ TestRegisterCaching(BUF0_OFFSET);
+ TestRegisterCaching(BUF0_PITCH);
+ TestRegisterCaching(BUF1_OFFSET);
+ TestRegisterCaching(BUF1_PITCH);
+ }
+ else
+ {
+ TestRegisterCaching(SCALER_BUF0_OFFSET);
+ TestRegisterCaching(SCALER_BUF1_OFFSET);
+ TestRegisterCaching(SCALER_BUF_PITCH);
+
+ TestRegisterCaching(OVERLAY_EXCLUSIVE_HORZ);
+ TestRegisterCaching(OVERLAY_EXCLUSIVE_VERT);
+
+ if (pATI->Chip >= ATI_CHIP_264GTPRO)
+ {
+ TestRegisterCaching(SCALER_COLOUR_CNTL);
+
+ TestRegisterCaching(SCALER_H_COEFF0);
+ TestRegisterCaching(SCALER_H_COEFF1);
+ TestRegisterCaching(SCALER_H_COEFF2);
+ TestRegisterCaching(SCALER_H_COEFF3);
+ TestRegisterCaching(SCALER_H_COEFF4);
+
+ TestRegisterCaching(SCALER_BUF0_OFFSET_U);
+ TestRegisterCaching(SCALER_BUF0_OFFSET_V);
+ TestRegisterCaching(SCALER_BUF1_OFFSET_U);
+ TestRegisterCaching(SCALER_BUF1_OFFSET_V);
+ }
+ }
+ }
+}
+
/*
* ATIMach64Sync --
*
@@ -219,58 +280,7 @@ ATIMach64Sync
TestRegisterCaching(CLR_CMP_CLR);
TestRegisterCaching(CLR_CMP_MSK);
- if (pATI->Block1Base)
- {
- TestRegisterCaching(OVERLAY_Y_X_START);
- TestRegisterCaching(OVERLAY_Y_X_END);
-
- TestRegisterCaching(OVERLAY_GRAPHICS_KEY_CLR);
- TestRegisterCaching(OVERLAY_GRAPHICS_KEY_MSK);
-
- TestRegisterCaching(OVERLAY_KEY_CNTL);
-
- TestRegisterCaching(OVERLAY_SCALE_INC);
- TestRegisterCaching(OVERLAY_SCALE_CNTL);
-
- TestRegisterCaching(SCALER_HEIGHT_WIDTH);
-
- TestRegisterCaching(SCALER_TEST);
-
- TestRegisterCaching(VIDEO_FORMAT);
-
- if (pATI->Chip < ATI_CHIP_264VTB)
- {
- TestRegisterCaching(BUF0_OFFSET);
- TestRegisterCaching(BUF0_PITCH);
- TestRegisterCaching(BUF1_OFFSET);
- TestRegisterCaching(BUF1_PITCH);
- }
- else
- {
- TestRegisterCaching(SCALER_BUF0_OFFSET);
- TestRegisterCaching(SCALER_BUF1_OFFSET);
- TestRegisterCaching(SCALER_BUF_PITCH);
-
- TestRegisterCaching(OVERLAY_EXCLUSIVE_HORZ);
- TestRegisterCaching(OVERLAY_EXCLUSIVE_VERT);
-
- if (pATI->Chip >= ATI_CHIP_264GTPRO)
- {
- TestRegisterCaching(SCALER_COLOUR_CNTL);
-
- TestRegisterCaching(SCALER_H_COEFF0);
- TestRegisterCaching(SCALER_H_COEFF1);
- TestRegisterCaching(SCALER_H_COEFF2);
- TestRegisterCaching(SCALER_H_COEFF3);
- TestRegisterCaching(SCALER_H_COEFF4);
-
- TestRegisterCaching(SCALER_BUF0_OFFSET_U);
- TestRegisterCaching(SCALER_BUF0_OFFSET_V);
- TestRegisterCaching(SCALER_BUF1_OFFSET_U);
- TestRegisterCaching(SCALER_BUF1_OFFSET_V);
- }
- }
- }
+ TestRegisterCachingXV(pScreenInfo);
}
pATI->NeedDRISync = FALSE;
@@ -322,73 +332,28 @@ ATIMach64Sync
TestRegisterCaching(CLR_CMP_MSK);
TestRegisterCaching(CLR_CMP_CNTL);
- if (pATI->Block1Base)
- {
- TestRegisterCaching(OVERLAY_Y_X_START);
- TestRegisterCaching(OVERLAY_Y_X_END);
-
- TestRegisterCaching(OVERLAY_GRAPHICS_KEY_CLR);
- TestRegisterCaching(OVERLAY_GRAPHICS_KEY_MSK);
-
- TestRegisterCaching(OVERLAY_KEY_CNTL);
-
- TestRegisterCaching(OVERLAY_SCALE_INC);
- TestRegisterCaching(OVERLAY_SCALE_CNTL);
-
- TestRegisterCaching(SCALER_HEIGHT_WIDTH);
-
- TestRegisterCaching(SCALER_TEST);
-
- TestRegisterCaching(VIDEO_FORMAT);
-
- if (pATI->Chip < ATI_CHIP_264VTB)
- {
- TestRegisterCaching(BUF0_OFFSET);
- TestRegisterCaching(BUF0_PITCH);
- TestRegisterCaching(BUF1_OFFSET);
- TestRegisterCaching(BUF1_PITCH);
- }
- else
- {
- TestRegisterCaching(SCALER_BUF0_OFFSET);
- TestRegisterCaching(SCALER_BUF1_OFFSET);
- TestRegisterCaching(SCALER_BUF_PITCH);
-
- TestRegisterCaching(OVERLAY_EXCLUSIVE_HORZ);
- TestRegisterCaching(OVERLAY_EXCLUSIVE_VERT);
-
- if (pATI->Chip >= ATI_CHIP_264GTPRO)
- {
- TestRegisterCaching(SCALER_COLOUR_CNTL);
-
- TestRegisterCaching(SCALER_H_COEFF0);
- TestRegisterCaching(SCALER_H_COEFF1);
- TestRegisterCaching(SCALER_H_COEFF2);
- TestRegisterCaching(SCALER_H_COEFF3);
- TestRegisterCaching(SCALER_H_COEFF4);
-
- TestRegisterCaching(SCALER_BUF0_OFFSET_U);
- TestRegisterCaching(SCALER_BUF0_OFFSET_V);
- TestRegisterCaching(SCALER_BUF1_OFFSET_U);
- TestRegisterCaching(SCALER_BUF1_OFFSET_V);
- }
- }
- }
+ TestRegisterCachingXV(pScreenInfo);
}
}
+#ifdef USE_EXA
+ /* EXA sets pEXA->needsSync to FALSE on its own */
+#endif
+#ifdef USE_XAA
+ if (pATI->pXAAInfo)
+ pATI->pXAAInfo->NeedToSync = FALSE;
+#endif
+
/*
* For VTB's and later, the first CPU read of the framebuffer will return
* zeroes, so do it here. This appears to be due to some kind of engine
* caching of framebuffer data I haven't found any way of disabling, or
* otherwise circumventing. Thanks to Mark Vojkovich for the suggestion.
*/
- if (pATI->pXAAInfo)
- pATI->pXAAInfo->NeedToSync = FALSE;
-
pATI = *(volatile ATIPtr *)pATI->pMemory;
}
+#ifdef USE_XAA
/*
* ATIMach64SetupForScreenToScreenCopy --
*
@@ -1035,3 +1000,4 @@ ATIMach64AccelInit
return ATIMach64MaxY;
}
+#endif /* USE_XAA */
diff --git a/src/atimach64accel.h b/src/atimach64accel.h
index a1b9426..2917b7a 100644
--- a/src/atimach64accel.h
+++ b/src/atimach64accel.h
@@ -27,11 +27,17 @@
#include "atipriv.h"
#include "xaa.h"
+#include "exa.h"
#define ATIMach64MaxX 8191
#define ATIMach64MaxY 32767
+#ifdef USE_EXA
+extern Bool ATIMach64ExaInit(ScreenPtr);
+#endif
+#ifdef USE_XAA
extern int ATIMach64AccelInit(ATIPtr, XAAInfoRecPtr);
+#endif
extern void ATIMach64Sync(ScrnInfoPtr);
#endif /* ___ATIMACH64ACCEL_H___ */
diff --git a/src/atimach64exa.c b/src/atimach64exa.c
new file mode 100644
index 0000000..cab8c4e
--- /dev/null
+++ b/src/atimach64exa.c
@@ -0,0 +1,526 @@
+/*
+ * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright 1999-2000 Precision Insight, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * DRI support by:
+ * Manuel Teira
+ * Leif Delgass <ldelgass@retinalburn.net>
+ *
+ * EXA support by:
+ * http://aeris.hypair.net:8001/
+ * George Fufutos
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ati.h"
+#include "atichip.h"
+#include "atidri.h"
+#include "atimach64accel.h"
+#include "atimach64io.h"
+#include "atipriv.h"
+#include "atiregs.h"
+
+#ifdef XF86DRI_DEVEL
+#include "mach64_dri.h"
+#include "mach64_sarea.h"
+#endif
+
+#ifdef USE_EXA
+extern CARD8 ATIMach64ALU[];
+
+extern void
+ATIMach64ValidateClip
+(
+ ATIPtr pATI,
+ int sc_left,
+ int sc_right,
+ int sc_top,
+ int sc_bottom
+);
+
+static void
+ATIMach64WaitMarker(ScreenPtr pScreenInfo, int Marker)
+{
+ ATIMach64Sync(xf86Screens[pScreenInfo->myNum]);
+}
+
+static void
+ATIGetOffsetPitch(int bpp, CARD32 *pitch_offset, int offset, int pitch)
+{
+ if (bpp == 24)
+ bpp = 8;
+
+ /* pixels / 8 = ((bytes * 8) / bpp) / 8 = bytes / bpp */
+ pitch = pitch / bpp;
+
+ /* bytes / 8 */
+ offset = offset >> 3;
+
+ *pitch_offset = ((pitch << 22) | /* USR1_DST_PITCH */
+ (offset << 0) | /* USR1_DST_OFFSET */
+ 0);
+}
+
+static Bool
+ATIGetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch_offset)
+{
+ CARD32 pitch, offset;
+ int bpp;
+
+ bpp = pPix->drawable.bitsPerPixel;
+
+ pitch = exaGetPixmapPitch(pPix);
+ offset = exaGetPixmapOffset(pPix);
+
+ ATIGetOffsetPitch(bpp, pitch_offset, offset, pitch);
+
+ return TRUE;
+}
+
+static Bool
+ATIMach64PrepareCopy
+(
+ PixmapPtr pSrcPixmap,
+ PixmapPtr pDstPixmap,
+ int xdir,
+ int ydir,
+ int alu,
+ Pixel planemask
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pSrcPixmap->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ CARD32 src_pitch_offset, dst_pitch_offset;
+
+ ATIDRISync(pScreenInfo);
+
+ ATIGetPixmapOffsetPitch(pSrcPixmap,&src_pitch_offset);
+ ATIGetPixmapOffsetPitch(pDstPixmap,&dst_pitch_offset);
+ ATIMach64WaitForFIFO(pATI, 5);
+ outf(DP_WRITE_MASK, planemask);
+ outf(SRC_OFF_PITCH,src_pitch_offset);
+ outf(DST_OFF_PITCH,dst_pitch_offset);
+
+ outf(DP_SRC, DP_MONO_SRC_ALLONES |
+ SetBits(SRC_BLIT, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
+ outf(DP_MIX, SetBits(ATIMach64ALU[alu], DP_FRGD_MIX));
+
+ outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
+
+ pATI->dst_cntl = 0;
+
+ if (ydir > 0)
+ pATI->dst_cntl |= DST_Y_DIR;
+ if (xdir > 0)
+ pATI->dst_cntl |= DST_X_DIR;
+
+ if (pATI->XModifier == 1)
+ outf(DST_CNTL, pATI->dst_cntl);
+ else
+ pATI->dst_cntl |= DST_24_ROT_EN;
+
+ return TRUE;
+}
+
+static void
+ATIMach64Copy
+(
+ PixmapPtr pDstPixmap,
+ int srcX,
+ int srcY,
+ int dstX,
+ int dstY,
+ int w,
+ int h
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ srcX *= pATI->XModifier;
+ dstY *= pATI->XModifier;
+ w *= pATI->XModifier;
+
+ ATIDRISync(pScreenInfo);
+
+ /* Disable clipping if it gets in the way */
+ ATIMach64ValidateClip(pATI, dstX, dstX + w - 1, dstY, dstY + h - 1);
+
+ if (!(pATI->dst_cntl & DST_X_DIR))
+ {
+ srcX += w - 1;
+ dstX += w - 1;
+ }
+
+ if (!(pATI->dst_cntl & DST_Y_DIR))
+ {
+ srcY += h - 1;
+ dstY += h - 1;
+ }
+
+ if (pATI->XModifier != 1)
+ outf(DST_CNTL, pATI->dst_cntl | SetBits((dstX / 4) % 6, DST_24_ROT));
+
+ ATIMach64WaitForFIFO(pATI, 4);
+ outf(SRC_Y_X, SetWord(srcX, 1) | SetWord(srcY, 0));
+ outf(SRC_WIDTH1, w);
+ outf(DST_Y_X, SetWord(dstX, 1) | SetWord(dstY, 0));
+ outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
+}
+
+static void
+ATIMach64DoneCopy(PixmapPtr pDstPixmap) { }
+
+static Bool
+ATIMach64PrepareSolid
+(
+ PixmapPtr pPixmap,
+ int alu,
+ Pixel planemask,
+ Pixel fg
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ CARD32 dst_pitch_offset;
+
+ ATIDRISync(pScreenInfo);
+
+ ATIGetPixmapOffsetPitch(pPixmap,&dst_pitch_offset);
+ ATIMach64WaitForFIFO(pATI, 6);
+ outf(DP_WRITE_MASK, planemask);
+ outf(DST_OFF_PITCH,dst_pitch_offset);
+ outf(DP_SRC, DP_MONO_SRC_ALLONES |
+ SetBits(SRC_FRGD, DP_FRGD_SRC) | SetBits(SRC_BKGD, DP_BKGD_SRC));
+ outf(DP_FRGD_CLR, fg);
+ outf(DP_MIX, SetBits(ATIMach64ALU[alu], DP_FRGD_MIX));
+
+ outf(CLR_CMP_CNTL, CLR_CMP_FN_FALSE);
+
+ if (pATI->XModifier == 1)
+ outf(DST_CNTL, DST_X_DIR | DST_Y_DIR);
+ return TRUE;
+}
+
+static void
+ATIMach64Solid
+(
+ PixmapPtr pPixmap,
+ int x1,
+ int y1,
+ int x2,
+ int y2
+)
+{
+ int x = x1;
+ int y = y1;
+ int w = x2-x1;
+ int h = y2-y1;
+ ScrnInfoPtr pScreenInfo = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ ATIDRISync(pScreenInfo);
+
+ if (pATI->XModifier != 1)
+ {
+ x *= pATI->XModifier;
+ w *= pATI->XModifier;
+
+ outf(DST_CNTL, SetBits((x / 4) % 6, DST_24_ROT) |
+ (DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN));
+ }
+
+ /* Disable clipping if it gets in the way */
+ ATIMach64ValidateClip(pATI, x, x + w - 1, y, y + h - 1);
+
+ ATIMach64WaitForFIFO(pATI, 2);
+ outf(DST_Y_X, SetWord(x, 1) | SetWord(y, 0));
+ outf(DST_HEIGHT_WIDTH, SetWord(w, 1) | SetWord(h, 0));
+}
+
+static void
+ATIMach64DoneSolid(PixmapPtr pPixmap) { }
+
+/* Compute log base 2 of val. */
+static __inline__ int
+ATILog2(int val)
+{
+ int bits;
+
+ for (bits = 0; val != 0; val >>= 1, ++bits)
+ ;
+ return bits - 1;
+}
+
+/*
+ * Memory layour for EXA with DRI (no local_textures):
+ * | front | back | depth | textures | pixmaps, xv | c |
+ *
+ * 1024x768@16bpp with 8 MB:
+ * | 1.5 MB | 1.5 MB | 1.5 MB | 0 | ~3.5 MB | c |
+ *
+ * 1024x768@32bpp with 8 MB:
+ * | 3.0 MB | 3.0 MB | 1.5 MB | 0 | ~0.5 MB | c |
+ *
+ * "c" is the hw cursor which occupies 1KB
+ */
+static void
+ATIMach64SetupMemEXA(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ int cpp = (pScreenInfo->bitsPerPixel + 7) / 8;
+ /* front and back buffer */
+ int bufferSize = pScreenInfo->virtualY * pScreenInfo->displayWidth * cpp;
+ /* always 16-bit z-buffer */
+ int depthSize = pScreenInfo->virtualY * pScreenInfo->displayWidth * 2;
+
+ ExaDriverPtr pExa = pATI->pExa;
+
+ pExa->memoryBase = pATI->pMemory;
+ pExa->memorySize = pScreenInfo->videoRam * 1024;
+ pExa->offScreenBase = bufferSize;
+
+#ifdef XF86DRI_DEVEL
+ if (pATI->directRenderingEnabled)
+ {
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+ Bool is_pci = pATIDRIServer->IsPCI;
+
+ int textureSize = 0;
+ int pixmapCache = 0;
+ int next = 0;
+ int err = 0x0;
+
+ /* front buffer */
+ pATIDRIServer->frontOffset = 0;
+ pATIDRIServer->frontPitch = pScreenInfo->displayWidth;
+ next += bufferSize;
+
+ /* back buffer */
+ pATIDRIServer->backOffset = next;
+ pATIDRIServer->backPitch = pScreenInfo->displayWidth;
+ next += bufferSize;
+
+ /* depth buffer */
+ pATIDRIServer->depthOffset = next;
+ pATIDRIServer->depthPitch = pScreenInfo->displayWidth;
+ next += depthSize;
+
+ /* ATIScreenInit does check for the this condition. */
+ if (next > pExa->memorySize)
+ {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "DRI static buffer allocation failed, disabling DRI --"
+ "need at least %d kB video memory\n", next / 1024 );
+ ATIDRICloseScreen(pScreen);
+ pATI->directRenderingEnabled = FALSE;
+
+ err |= 0x1;
+ }
+
+ /* local textures */
+
+ /* Reserve approx. half of offscreen memory for local textures */
+ textureSize = (pExa->memorySize - next) / 2;
+
+ /* In case DRI requires more offscreen memory than available,
+ * should not happen as ATIScreenInit would have not enabled DRI */
+ if (textureSize < 0)
+ textureSize = 0;
+
+ /* Try for enough pixmap cache for a full viewport */
+ pixmapCache = (pExa->memorySize - next) - textureSize;
+ if (pixmapCache < bufferSize)
+ textureSize = 0;
+
+ /* Don't allocate a local texture heap for AGP unless requested */
+ if ( !is_pci && !pATI->OptionLocalTextures )
+ textureSize = 0;
+
+ if (textureSize > 0)
+ {
+ int l = ATILog2(textureSize / MACH64_NR_TEX_REGIONS);
+ if (l < MACH64_LOG_TEX_GRANULARITY)
+ l = MACH64_LOG_TEX_GRANULARITY;
+ pATIDRIServer->logTextureGranularity = l;
+
+ /* Round the texture size down to the nearest whole number of
+ * texture regions.
+ */
+ textureSize = (textureSize >> l) << l;
+ }
+
+ /* Set a minimum usable local texture heap size. This will fit
+ * two 256x256 textures. We check this after any rounding of
+ * the texture area.
+ */
+ if (textureSize < 256*256 * cpp * 2)
+ textureSize = 0;
+
+ /* Disable DRI for PCI if cannot allocate a local texture heap */
+ if ( is_pci && textureSize == 0 )
+ {
+ xf86DrvMsg(pScreen->myNum, X_WARNING,
+ "Not enough memory for local textures, disabling DRI\n");
+ ATIDRICloseScreen(pScreen);
+ pATI->directRenderingEnabled = FALSE;
+
+ err |= 0x2;
+ }
+
+ if (!err)
+ {
+ pATIDRIServer->textureOffset = next;
+ pATIDRIServer->textureSize = textureSize;
+ next += textureSize;
+
+ pExa->offScreenBase = next;
+ }
+ }
+#endif /* XF86DRI_DEVEL */
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "EXA memory management initialized\n"
+ "\t base : %10p\n"
+ "\t offscreen: +%10lx\n"
+ "\t size : +%10lx\n"
+ "\t cursor : %10p\n",
+ pExa->memoryBase,
+ pExa->offScreenBase,
+ pExa->memorySize,
+ pATI->pCursorImage);
+
+ if (TRUE || xf86GetVerbosity() > 1)
+ {
+ int offscreen = pExa->memorySize - pExa->offScreenBase;
+ int viewport = bufferSize;
+ int dvdframe = 720*480*cpp; /* enough for single-buffered DVD */
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "Will use %d kB of offscreen memory for EXA\n"
+ "\t\t or %5.2f viewports (composite)\n"
+ "\t\t or %5.2f dvdframes (xvideo)\n",
+ offscreen / 1024,
+ 1.0 * offscreen / viewport,
+ 1.0 * offscreen / dvdframe);
+ }
+
+#ifdef XF86DRI_DEVEL
+ if (pATI->directRenderingEnabled)
+ {
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "Will use back buffer at offset 0x%x\n",
+ pATIDRIServer->backOffset);
+
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "Will use depth buffer at offset 0x%x\n",
+ pATIDRIServer->depthOffset);
+
+ if (pATIDRIServer->textureSize > 0) {
+ xf86DrvMsg(pScreen->myNum, X_INFO,
+ "Will use %d kB for local textures at offset 0x%x\n",
+ pATIDRIServer->textureSize/1024,
+ pATIDRIServer->textureOffset);
+ }
+ }
+#endif /* XF86DRI_DEVEL */
+
+ /* FIXME: set to 64 if that helps for hostdata blits or textures */
+ /* FIXME: must be multiple of 8 pixels; 32 is ok for 16bpp, 32bpp */
+ pExa->pixmapOffsetAlign = 64;
+ pExa->pixmapPitchAlign = 64;
+
+ pExa->flags = EXA_OFFSCREEN_PIXMAPS;
+
+ pExa->maxX = ATIMach64MaxX;
+ pExa->maxY = ATIMach64MaxY;
+}
+
+Bool ATIMach64ExaInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+ ExaDriverPtr pExa;
+
+ /* FIXME: which chips support EXA ? */
+ if (pATI->Chip < ATI_CHIP_264CT)
+ {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "EXA is not supported for ATI chips earlier than "
+ "the ATI Mach64.\n");
+ return FALSE;
+ }
+
+ pExa = exaDriverAlloc();
+ if (!pExa)
+ return FALSE;
+
+ pATI->pExa = pExa;
+
+ pExa->exa_major = 2;
+ pExa->exa_minor = 0;
+
+ ATIMach64SetupMemEXA(pScreen);
+
+ pExa->WaitMarker = ATIMach64WaitMarker;
+
+ pExa->PrepareSolid = ATIMach64PrepareSolid;
+ pExa->Solid = ATIMach64Solid;
+ pExa->DoneSolid = ATIMach64DoneSolid;
+
+ pExa->PrepareCopy = ATIMach64PrepareCopy;
+ pExa->Copy = ATIMach64Copy;
+ pExa->DoneCopy = ATIMach64DoneCopy;
+
+ return exaDriverInit(pScreen, pATI->pExa);
+}
+#endif
diff --git a/src/atimach64io.h b/src/atimach64io.h
index 9dbf244..12598fd 100644
--- a/src/atimach64io.h
+++ b/src/atimach64io.h
@@ -206,6 +206,10 @@ extern void ATIMach64PollEngineStatus(ATIPtr);
#ifdef XF86DRI_DEVEL
+/*
+ * DRI Sync and Lock definitions.
+ */
+
#define ATIDRIWaitForIdle(_pATI) \
do { \
ATIDRIServerInfoPtr pATIDRIServer = _pATI->pDRIServerInfo; \
@@ -226,6 +230,53 @@ do { \
} \
} while (0)
+/*
+ * Set upon DRISwapContext and when DRI accesses the GPU engine
+ * from within the server, see DRIInitBuffers/DRIMoveBuffers.
+ *
+ * Forces the EXA/XAA software paths to sync before accessing the FB memory.
+ */
+static __inline__ void ATIDRIMarkSyncInt(ScrnInfoPtr _pScrInfo)
+{
+ ATIPtr _pATI=ATIPTR(_pScrInfo);
+#ifdef USE_EXA
+ if (_pATI->useEXA)
+ exaMarkSync(_pScrInfo->pScreen);
+#endif
+#ifdef USE_XAA
+ if (!_pATI->useEXA)
+ SET_SYNC_FLAG(_pATI->pXAAInfo); /* NeedToSync = TRUE */
+#endif
+}
+
+/*
+ * Set upon DRISwapContext and when the server acquires the DRI lock.
+ *
+ * Forces the EXA/XAA accelerated paths to sync before accessing the GPU engine.
+ */
+static __inline__ void ATIDRIMarkSyncExt(ScrnInfoPtr _pScrInfo)
+{
+ ATIPtr _pATI=ATIPTR(_pScrInfo);
+ _pATI->NeedDRISync = TRUE;
+}
+
+static __inline__ void ATIDRISync(ScrnInfoPtr _pScrInfo)
+{
+ ATIPtr _pATI=ATIPTR(_pScrInfo);
+#ifdef USE_EXA
+ if (_pATI->directRenderingEnabled && _pATI->pExa)
+ {
+ if (_pATI->NeedDRISync) exaWaitSync(_pScrInfo->pScreen);
+ }
+#endif
+#ifdef USE_XAA
+ if (_pATI->directRenderingEnabled && _pATI->pXAAInfo)
+ {
+ if (_pATI->NeedDRISync) (*_pATI->pXAAInfo->Sync)(_pScrInfo);
+ }
+#endif
+}
+
#define ATIDRILock(_pScrInfo) \
do \
{ \
@@ -233,7 +284,7 @@ do \
if (_pATI->directRenderingEnabled) \
{ \
DRILock(_pScrInfo->pScreen, 0); \
- pATI->NeedDRISync = TRUE; \
+ ATIDRIMarkSyncExt(_pScrInfo); \
} \
} while (0)
@@ -247,16 +298,6 @@ do \
} \
} while (0)
-#define ATIDRISync(_pScrInfo) \
-do \
-{ \
- ATIPtr _pATI=ATIPTR(_pScrInfo); \
- if (_pATI->directRenderingEnabled && _pATI->pXAAInfo) \
- { \
- if (_pATI->NeedDRISync) (*_pATI->pXAAInfo->Sync)(_pScrInfo); \
- } \
-} while (0)
-
#else /* XF86DRI_DEVEL */
@@ -267,7 +308,6 @@ do
#endif /* XF86DRI_DEVEL */
-
/*
* An outf() variant to write two registers such that the second register is
* is always written whenever either is to be changed.
@@ -368,4 +408,11 @@ extern void ATIMach64AccessPLLReg(ATIPtr, const CARD8, const Bool);
#endif
+/*
+ * Return the MMIO address of register, used for HOST_DATA_X only.
+ */
+#define ATIHostDataAddr(_Register) \
+ ((CARD8 *)pATI->pBlock[GetBits(_Register, BLOCK_SELECT)] + \
+ ((_Register) & MM_IO_SELECT))
+
#endif /* ___ATIMACH64IO_H___ */
diff --git a/src/atimach64xv.c b/src/atimach64xv.c
index 670ef83..14b1cc1 100644
--- a/src/atimach64xv.c
+++ b/src/atimach64xv.c
@@ -501,6 +501,25 @@ ATIMach64GetPortAttribute
return Success;
}
+static pointer
+ATIMach64XVMemAlloc
+(
+ ScreenPtr pScreen,
+ pointer pVideo,
+ int size,
+ int *offset,
+ ATIPtr pATI
+);
+
+static void
+ATIMach64XVMemFree
+(
+ ScreenPtr pScreen,
+ pointer pVideo,
+ ATIPtr pATI
+);
+
+#ifdef USE_XAA
/*
* ATIMach64RemoveLinearCallback --
*
@@ -519,6 +538,7 @@ ATIMach64RemoveLinearCallback
pATI->pXVBuffer = NULL;
outf(OVERLAY_SCALE_CNTL, SCALE_EN);
}
+#endif /* USE_XAA */
/*
* ATIMach64StopVideo --
@@ -543,19 +563,23 @@ ATIMach64StopVideo
REGION_EMPTY(pScreen, &pATI->VideoClip);
- if (!Cleanup)
+#ifdef USE_XAA
+ if (!pATI->useEXA && !Cleanup)
{
/*
* Free offscreen buffer if/when its allocation is needed by XAA's
* pixmap cache.
*/
- if (pATI->pXVBuffer)
- pATI->pXVBuffer->RemoveLinearCallback =
+ FBLinearPtr linear = (FBLinearPtr)pATI->pXVBuffer;
+ if (linear)
+ linear->RemoveLinearCallback =
ATIMach64RemoveLinearCallback;
return;
}
+#endif /* USE_XAA */
- pATI->pXVBuffer = ATIResizeOffscreenLinear(pScreen, pATI->pXVBuffer, 0);
+ ATIMach64XVMemFree(pScreen, pATI->pXVBuffer, pATI);
+ pATI->pXVBuffer = NULL;
outf(OVERLAY_SCALE_CNTL, SCALE_EN);
}
@@ -956,6 +980,7 @@ ATIMach64PutImage
int SrcTop, SrcLeft, DstWidth, DstHeight;
int Top, Bottom, Left, Right, nLine, nPixel, Offset;
int OffsetV, OffsetU;
+ int XVOffset;
int tmp;
CARD8 *pDst;
@@ -981,11 +1006,11 @@ ATIMach64PutImage
*/
DstPitch = /* bytes */
(DstWidth + DstWidth + 15) & ~15;
- DstSize = /* pixels */
- ((DstPitch * DstHeight) + pATI->AdjustDepth - 1) / pATI->AdjustDepth;
+ DstSize = /* bytes */
+ (DstPitch * DstHeight);
- pATI->pXVBuffer = ATIResizeOffscreenLinear(pScreen, pATI->pXVBuffer,
- (pATI->DoubleBuffer + 1) * DstSize);
+ pATI->pXVBuffer = ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer,
+ (pATI->DoubleBuffer + 1) * DstSize, &XVOffset, pATI);
if (!pATI->pXVBuffer)
{
@@ -993,7 +1018,7 @@ ATIMach64PutImage
return BadAlloc;
pATI->pXVBuffer =
- ATIResizeOffscreenLinear(pScreen, pATI->pXVBuffer, DstSize);
+ ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer, DstSize, &XVOffset, pATI);
if (!pATI->pXVBuffer)
return BadAlloc;
@@ -1012,8 +1037,7 @@ ATIMach64PutImage
/* Synchronise video memory accesses */
ATIMach64Sync(pScreenInfo);
- Offset = (pATI->pXVBuffer->offset * pATI->AdjustDepth) +
- (pATI->CurrentBuffer * DstSize * pATI->AdjustDepth);
+ Offset = XVOffset + pATI->CurrentBuffer * DstSize;
pDst = pATI->pMemoryLE;
pDst += Offset;
@@ -1113,6 +1137,7 @@ ATIMach64AllocateSurface
{
ScreenPtr pScreen;
ATIPtr pATI = ATIPTR(pScreenInfo);
+ int XVOffset;
if (pATI->ActiveSurface)
return BadAlloc;
@@ -1126,13 +1151,12 @@ ATIMach64AllocateSurface
pScreen = pScreenInfo->pScreen;
- pATI->pXVBuffer = ATIResizeOffscreenLinear(pScreen, pATI->pXVBuffer,
- ((Height * pATI->SurfacePitch) + pATI->AdjustDepth - 1) /
- pATI->AdjustDepth);
+ pATI->pXVBuffer = ATIMach64XVMemAlloc(pScreen, pATI->pXVBuffer,
+ Height * pATI->SurfacePitch, &XVOffset, pATI);
if (!pATI->pXVBuffer)
return BadAlloc;
- pATI->SurfaceOffset = pATI->pXVBuffer->offset * pATI->AdjustDepth;
+ pATI->SurfaceOffset = XVOffset;
pSurface->pScrn = pScreenInfo;
pSurface->id = ImageID;
@@ -1167,8 +1191,8 @@ ATIMach64FreeSurface
return Success;
outf(OVERLAY_SCALE_CNTL, SCALE_EN);
- pATI->pXVBuffer = ATIResizeOffscreenLinear(pSurface->pScrn->pScreen,
- pATI->pXVBuffer, 0);
+ ATIMach64XVMemFree(pSurface->pScrn->pScreen, pATI->pXVBuffer, pATI);
+ pATI->pXVBuffer = NULL;
pATI->ActiveSurface = FALSE;
return Success;
@@ -1498,3 +1522,84 @@ ATIMach64CloseXVideo
REGION_UNINIT(pScreen, &pATI->VideoClip);
}
+
+static pointer
+ATIMach64XVMemAlloc
+(
+ ScreenPtr pScreen,
+ pointer pVideo,
+ int size,
+ int *offset,
+ ATIPtr pATI
+)
+{
+#ifdef USE_EXA
+ if (pATI->useEXA) {
+ ExaOffscreenArea *area = (ExaOffscreenArea *)pVideo;
+
+ if (area != NULL) {
+ if (area->size >= size) {
+ *offset = area->offset;
+ return area;
+ }
+
+ exaOffscreenFree(pScreen, area);
+ }
+
+ area = exaOffscreenAlloc(pScreen, size, 64, TRUE, NULL, NULL);
+ if (area != NULL) {
+ *offset = area->offset;
+ return area;
+ }
+ }
+#endif /* USE_EXA */
+
+#ifdef USE_XAA
+ if (!pATI->useEXA) {
+ FBLinearPtr linear = (FBLinearPtr)pVideo;
+ int cpp = pATI->AdjustDepth;
+
+ /* XAA allocates in units of pixels at the screen bpp, so adjust size
+ * appropriately.
+ */
+ size = (size + cpp - 1) / cpp;
+
+ linear = ATIResizeOffscreenLinear(pScreen, linear, size);
+ if (linear != NULL) {
+ *offset = linear->offset * cpp;
+ return linear;
+ }
+ }
+#endif /* USE_XAA */
+
+ *offset = 0;
+ return NULL;
+}
+
+static void
+ATIMach64XVMemFree
+(
+ ScreenPtr pScreen,
+ pointer pVideo,
+ ATIPtr pATI
+)
+{
+#ifdef USE_EXA
+ if (pATI->useEXA) {
+ ExaOffscreenArea *area = (ExaOffscreenArea *)pVideo;
+
+ if (area != NULL)
+ exaOffscreenFree(pScreen, area);
+ }
+#endif /* USE_EXA */
+
+#ifdef USE_XAA
+ if (!pATI->useEXA) {
+ FBLinearPtr linear = (FBLinearPtr)pVideo;
+
+ if (linear != NULL)
+ ATIResizeOffscreenLinear(pScreen, linear, 0);
+ }
+#endif /* USE_XAA */
+}
+
diff --git a/src/atioption.c b/src/atioption.c
index 16cba24..43e0b7a 100644
--- a/src/atioption.c
+++ b/src/atioption.c
@@ -216,6 +216,13 @@ const OptionInfoRec ATIPublicOptions[] =
FALSE,
},
{
+ ATI_OPTION_ACCELMETHOD,
+ "AccelMethod",
+ OPTV_STRING,
+ {0},
+ FALSE
+ },
+ {
-1,
NULL,
OPTV_NONE,
diff --git a/src/atioption.h b/src/atioption.h
index 51778a4..836e911 100644
--- a/src/atioption.h
+++ b/src/atioption.h
@@ -69,7 +69,8 @@ typedef enum
ATI_OPTION_PROBE_CLOCKS,
ATI_OPTION_REFERENCE_CLOCK,
ATI_OPTION_SHADOW_FB,
- ATI_OPTION_SWCURSOR
+ ATI_OPTION_SWCURSOR,
+ ATI_OPTION_ACCELMETHOD
} ATIPublicOptionType;
#ifdef TV_OUT
diff --git a/src/atiscreen.c b/src/atiscreen.c
index 5e324dd..f69cb59 100644
--- a/src/atiscreen.c
+++ b/src/atiscreen.c
@@ -121,6 +121,201 @@ ATIMinBits
for (bits = 0; val; val >>= 1, ++bits);
return bits;
}
+
+#ifdef USE_XAA
+#ifdef XF86DRI_DEVEL
+/*
+ * Memory layour for XAA with DRI (no local_textures):
+ * | front | pixmaps, xv | back | depth | textures | c |
+ *
+ * 1024x768@16bpp with 8 MB:
+ * | 1.5 MB | ~3.5 MB | 1.5 MB | 1.5 MB | 0 | c |
+ *
+ * 1024x768@32bpp with 8 MB:
+ * | 3.0 MB | ~0.5 MB | 3.0 MB | 1.5 MB | 0 | c |
+ *
+ * "c" is the hw cursor which occupies 1KB
+ */
+static Bool
+ATIMach64SetupMemXAA
+(
+ int iScreen,
+ ScreenPtr pScreen
+)
+{
+ ScrnInfoPtr pScreenInfo = xf86Screens[iScreen];
+ ATIPtr pATI = ATIPTR(pScreenInfo);
+
+ ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
+ int cpp = pATI->bitsPerPixel >> 3;
+ int widthBytes = pScreenInfo->displayWidth * cpp;
+ int zWidthBytes = pScreenInfo->displayWidth * 2; /* always 16-bit z-buffer */
+ int fbSize = pScreenInfo->videoRam * 1024;
+ int bufferSize = pScreenInfo->virtualY * widthBytes;
+ int zBufferSize = pScreenInfo->virtualY * zWidthBytes;
+ int offscreenBytes, total, scanlines;
+
+ pATIDRIServer->fbX = 0;
+ pATIDRIServer->fbY = 0;
+ pATIDRIServer->frontOffset = 0;
+ pATIDRIServer->frontPitch = pScreenInfo->displayWidth;
+
+ /* Calculate memory remaining for pixcache and textures after
+ * front, back, and depth buffers
+ */
+ offscreenBytes = fbSize - ( 2 * bufferSize + zBufferSize );
+
+ if ( !pATIDRIServer->IsPCI && !pATI->OptionLocalTextures ) {
+ /* Don't allocate a local texture heap for AGP unless requested */
+ pATIDRIServer->textureSize = 0;
+ } else {
+ int l, maxPixcache;
+
+#ifdef XvExtension
+
+ int xvBytes;
+
+ /* Try for enough pixmap cache for DVD and a full viewport
+ */
+ xvBytes = 720*480*cpp; /* enough for single-buffered DVD */
+ maxPixcache = xvBytes > bufferSize ? xvBytes : bufferSize;
+
+#else /* XvExtension */
+
+ /* Try for one viewport */
+ maxPixcache = bufferSize;
+
+#endif /* XvExtension */
+
+ pATIDRIServer->textureSize = offscreenBytes - maxPixcache;
+
+ /* If that gives us less than half the offscreen mem available for textures, split
+ * the available mem between textures and pixmap cache
+ */
+ if (pATIDRIServer->textureSize < (offscreenBytes/2)) {
+ pATIDRIServer->textureSize = offscreenBytes/2;
+ }
+
+ if (pATIDRIServer->textureSize <= 0)
+ pATIDRIServer->textureSize = 0;
+
+ l = ATIMinBits((pATIDRIServer->textureSize-1) / MACH64_NR_TEX_REGIONS);
+ if (l < MACH64_LOG_TEX_GRANULARITY) l = MACH64_LOG_TEX_GRANULARITY;
+
+ /* Round the texture size up to the nearest whole number of
+ * texture regions. Again, be greedy about this, don't round
+ * down.
+ */
+ pATIDRIServer->logTextureGranularity = l;
+ pATIDRIServer->textureSize =
+ (pATIDRIServer->textureSize >> l) << l;
+ }
+
+ total = fbSize - pATIDRIServer->textureSize;
+ scanlines = total / widthBytes;
+ if (scanlines > ATIMach64MaxY) scanlines = ATIMach64MaxY;
+
+ /* Recalculate the texture offset and size to accomodate any
+ * rounding to a whole number of scanlines.
+ * FIXME: Is this actually needed?
+ */
+ pATIDRIServer->textureOffset = scanlines * widthBytes;
+ pATIDRIServer->textureSize = fbSize - pATIDRIServer->textureOffset;
+
+ /* Set a minimum usable local texture heap size. This will fit
+ * two 256x256 textures. We check this after any rounding of
+ * the texture area.
+ */
+ if (pATIDRIServer->textureSize < 256*256 * cpp * 2) {
+ pATIDRIServer->textureOffset = 0;
+ pATIDRIServer->textureSize = 0;
+ scanlines = fbSize / widthBytes;
+ if (scanlines > ATIMach64MaxY) scanlines = ATIMach64MaxY;
+ }
+
+ pATIDRIServer->depthOffset = scanlines * widthBytes - zBufferSize;
+ pATIDRIServer->depthPitch = pScreenInfo->displayWidth;
+ pATIDRIServer->depthY = pATIDRIServer->depthOffset/widthBytes;
+ pATIDRIServer->depthX = (pATIDRIServer->depthOffset -
+ (pATIDRIServer->depthY * widthBytes)) / cpp;
+
+ pATIDRIServer->backOffset = pATIDRIServer->depthOffset - bufferSize;
+ pATIDRIServer->backPitch = pScreenInfo->displayWidth;
+ pATIDRIServer->backY = pATIDRIServer->backOffset/widthBytes;
+ pATIDRIServer->backX = (pATIDRIServer->backOffset -
+ (pATIDRIServer->backY * widthBytes)) / cpp;
+
+ scanlines = fbSize / widthBytes;
+ if (scanlines > ATIMach64MaxY) scanlines = ATIMach64MaxY;
+
+ if ( pATIDRIServer->IsPCI && pATIDRIServer->textureSize == 0 ) {
+ xf86DrvMsg(iScreen, X_WARNING,
+ "Not enough memory for local textures, disabling DRI\n");
+ ATIDRICloseScreen(pScreen);
+ pATI->directRenderingEnabled = FALSE;
+ } else {
+ BoxRec ScreenArea;
+
+ ScreenArea.x1 = 0;
+ ScreenArea.y1 = 0;
+ ScreenArea.x2 = pATI->displayWidth;
+ ScreenArea.y2 = scanlines;
+
+ if (!xf86InitFBManager(pScreen, &ScreenArea)) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Memory manager initialization to (%d,%d) (%d,%d) failed\n",
+ ScreenArea.x1, ScreenArea.y1,
+ ScreenArea.x2, ScreenArea.y2);
+ return FALSE;
+ } else {
+ int width, height;
+
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Memory manager initialized to (%d,%d) (%d,%d)\n",
+ ScreenArea.x1, ScreenArea.y1, ScreenArea.x2, ScreenArea.y2);
+
+ if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0)) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Largest offscreen area available: %d x %d\n",
+ width, height);
+
+ /* lines in offscreen area needed for depth buffer and textures */
+ pATI->depthTexLines = scanlines
+ - pATIDRIServer->depthOffset / widthBytes;
+ pATI->backLines = scanlines
+ - pATIDRIServer->backOffset / widthBytes
+ - pATI->depthTexLines;
+ pATI->depthTexArea = NULL;
+ pATI->backArea = NULL;
+ } else {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
+ "Unable to determine largest offscreen area available\n");
+ return FALSE;
+ }
+
+ }
+
+ xf86DrvMsg(iScreen, X_INFO, "Will use %d kB of offscreen memory for XAA\n",
+ (offscreenBytes - pATIDRIServer->textureSize)/1024);
+
+ xf86DrvMsg(iScreen, X_INFO, "Will use back buffer at offset 0x%x\n",
+ pATIDRIServer->backOffset);
+
+ xf86DrvMsg(iScreen, X_INFO, "Will use depth buffer at offset 0x%x\n",
+ pATIDRIServer->depthOffset);
+
+ if (pATIDRIServer->textureSize > 0) {
+ xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
+ "Will use %d kB for local textures at offset 0x%x\n",
+ pATIDRIServer->textureSize/1024,
+ pATIDRIServer->textureOffset);
+ }
+ }
+
+ return TRUE;
+}
+#endif /* XF86DRI_DEVEL */
+#endif /* USE_XAA */
/*
* ATIScreenInit --
@@ -140,9 +335,6 @@ ATIScreenInit
ATIPtr pATI = ATIPTR(pScreenInfo);
pointer pFB;
int VisualMask;
-#ifdef XF86DRI_DEVEL
- BoxRec ScreenArea;
-#endif
/* Set video hardware state */
if (!ATIEnterGraphics(pScreen, pScreenInfo, pATI))
@@ -301,186 +493,38 @@ ATIScreenInit
#endif /* AVOID_CPIO */
- /* Memory manager setup */
+#ifdef USE_XAA
+
+ /* Memory manager setup */
#ifdef XF86DRI_DEVEL
if (pATI->directRenderingEnabled)
{
- ATIDRIServerInfoPtr pATIDRIServer = pATI->pDRIServerInfo;
- int cpp = pATI->bitsPerPixel >> 3;
- int widthBytes = pScreenInfo->displayWidth * cpp;
- int zWidthBytes = pScreenInfo->displayWidth * 2; /* always 16-bit z-buffer */
- int fbSize = pScreenInfo->videoRam * 1024;
- int bufferSize = pScreenInfo->virtualY * widthBytes;
- int zBufferSize = pScreenInfo->virtualY * zWidthBytes;
- int offscreenBytes, total, scanlines;
-
- pATIDRIServer->fbX = 0;
- pATIDRIServer->fbY = 0;
- pATIDRIServer->frontOffset = 0;
- pATIDRIServer->frontPitch = pScreenInfo->displayWidth;
-
- /* Calculate memory remaining for pixcache and textures after
- * front, back, and depth buffers
- */
- offscreenBytes = fbSize - ( 2 * bufferSize + zBufferSize );
-
- if ( !pATIDRIServer->IsPCI && !pATI->OptionLocalTextures ) {
- /* Don't allocate a local texture heap for AGP unless requested */
- pATIDRIServer->textureSize = 0;
- } else {
- int l, maxPixcache;
-
-#ifdef XvExtension
-
- int xvBytes;
-
- /* Try for enough pixmap cache for DVD and a full viewport
- */
- xvBytes = 720*480*cpp; /* enough for single-buffered DVD */
- maxPixcache = xvBytes > bufferSize ? xvBytes : bufferSize;
-
-#else /* XvExtension */
-
- /* Try for one viewport */
- maxPixcache = bufferSize;
-
-#endif /* XvExtension */
-
- pATIDRIServer->textureSize = offscreenBytes - maxPixcache;
-
- /* If that gives us less than half the offscreen mem available for textures, split
- * the available mem between textures and pixmap cache
- */
- if (pATIDRIServer->textureSize < (offscreenBytes/2)) {
- pATIDRIServer->textureSize = offscreenBytes/2;
- }
-
- if (pATIDRIServer->textureSize <= 0)
- pATIDRIServer->textureSize = 0;
-
- l = ATIMinBits((pATIDRIServer->textureSize-1) / MACH64_NR_TEX_REGIONS);
- if (l < MACH64_LOG_TEX_GRANULARITY) l = MACH64_LOG_TEX_GRANULARITY;
-
- /* Round the texture size up to the nearest whole number of
- * texture regions. Again, be greedy about this, don't round
- * down.
- */
- pATIDRIServer->logTextureGranularity = l;
- pATIDRIServer->textureSize =
- (pATIDRIServer->textureSize >> l) << l;
- }
-
- total = fbSize - pATIDRIServer->textureSize;
- scanlines = total / widthBytes;
- if (scanlines > ATIMach64MaxY) scanlines = ATIMach64MaxY;
-
- /* Recalculate the texture offset and size to accomodate any
- * rounding to a whole number of scanlines.
- * FIXME: Is this actually needed?
- */
- pATIDRIServer->textureOffset = scanlines * widthBytes;
- pATIDRIServer->textureSize = fbSize - pATIDRIServer->textureOffset;
-
- /* Set a minimum usable local texture heap size. This will fit
- * two 256x256 textures. We check this after any rounding of
- * the texture area.
- */
- if (pATIDRIServer->textureSize < 256*256 * cpp * 2) {
- pATIDRIServer->textureOffset = 0;
- pATIDRIServer->textureSize = 0;
- scanlines = fbSize / widthBytes;
- if (scanlines > ATIMach64MaxY) scanlines = ATIMach64MaxY;
- }
-
- pATIDRIServer->depthOffset = scanlines * widthBytes - zBufferSize;
- pATIDRIServer->depthPitch = pScreenInfo->displayWidth;
- pATIDRIServer->depthY = pATIDRIServer->depthOffset/widthBytes;
- pATIDRIServer->depthX = (pATIDRIServer->depthOffset -
- (pATIDRIServer->depthY * widthBytes)) / cpp;
-
- pATIDRIServer->backOffset = pATIDRIServer->depthOffset - bufferSize;
- pATIDRIServer->backPitch = pScreenInfo->displayWidth;
- pATIDRIServer->backY = pATIDRIServer->backOffset/widthBytes;
- pATIDRIServer->backX = (pATIDRIServer->backOffset -
- (pATIDRIServer->backY * widthBytes)) / cpp;
-
- scanlines = fbSize / widthBytes;
- if (scanlines > ATIMach64MaxY) scanlines = ATIMach64MaxY;
-
- if ( pATIDRIServer->IsPCI && pATIDRIServer->textureSize == 0 ) {
- xf86DrvMsg(iScreen, X_WARNING,
- "Not enough memory for local textures, disabling DRI\n");
- ATIDRICloseScreen(pScreen);
- pATI->directRenderingEnabled = FALSE;
- } else {
-
- ScreenArea.x1 = 0;
- ScreenArea.y1 = 0;
- ScreenArea.x2 = pATI->displayWidth;
- ScreenArea.y2 = scanlines;
-
- if (!xf86InitFBManager(pScreen, &ScreenArea)) {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
- "Memory manager initialization to (%d,%d) (%d,%d) failed\n",
- ScreenArea.x1, ScreenArea.y1,
- ScreenArea.x2, ScreenArea.y2);
- return FALSE;
- } else {
- int width, height;
-
- xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
- "Memory manager initialized to (%d,%d) (%d,%d)\n",
- ScreenArea.x1, ScreenArea.y1, ScreenArea.x2, ScreenArea.y2);
-
- if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0)) {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
- "Largest offscreen area available: %d x %d\n",
- width, height);
-
- /* lines in offscreen area needed for depth buffer and textures */
- pATI->depthTexLines = scanlines
- - pATIDRIServer->depthOffset / widthBytes;
- pATI->backLines = scanlines
- - pATIDRIServer->backOffset / widthBytes
- - pATI->depthTexLines;
- pATI->depthTexArea = NULL;
- pATI->backArea = NULL;
- } else {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_ERROR,
- "Unable to determine largest offscreen area available\n");
- return FALSE;
- }
-
- }
-
- xf86DrvMsg(iScreen, X_INFO, "Will use %d kB of offscreen memory for XAA\n",
- (offscreenBytes - pATIDRIServer->textureSize)/1024);
-
- xf86DrvMsg(iScreen, X_INFO, "Will use back buffer at offset 0x%x\n",
- pATIDRIServer->backOffset);
-
- xf86DrvMsg(iScreen, X_INFO, "Will use depth buffer at offset 0x%x\n",
- pATIDRIServer->depthOffset);
-
- if (pATIDRIServer->textureSize > 0) {
- xf86DrvMsg(pScreenInfo->scrnIndex, X_INFO,
- "Will use %d kB for local textures at offset 0x%x\n",
- pATIDRIServer->textureSize/1024,
- pATIDRIServer->textureOffset);
- }
- }
+ if (!pATI->useEXA && !ATIMach64SetupMemXAA(iScreen, pScreen))
+ return FALSE;
}
#endif /* XF86DRI_DEVEL */
/* Setup acceleration */
+
/* If direct rendering is not enabled, the framebuffer memory
* manager is initialized by this function call */
- if (!ATIInitializeAcceleration(pScreen, pScreenInfo, pATI))
+ if (!pATI->useEXA && !ATIInitializeAcceleration(pScreen, pScreenInfo, pATI))
+ return FALSE;
+
+#endif /* USE_XAA */
+
+#ifdef USE_EXA
+
+ /* EXA initializes both memory manager and acceleration here */
+
+ if (pATI->useEXA && !ATIMach64ExaInit(pScreen))
return FALSE;
+#endif /* USE_EXA */
+
#ifndef AVOID_DGA
/* Initialise DGA support */
@@ -593,11 +637,21 @@ ATICloseScreen
ATICloseXVideo(pScreen, pScreenInfo, pATI);
+#ifdef USE_EXA
+ if (pATI->pExa)
+ {
+ exaDriverFini(pScreen);
+ xfree(pATI->pExa);
+ pATI->pExa = NULL;
+ }
+#endif
+#ifdef USE_XAA
if (pATI->pXAAInfo)
{
XAADestroyInfoRec(pATI->pXAAInfo);
pATI->pXAAInfo = NULL;
}
+#endif
if ((pScreen->CloseScreen = pATI->CloseScreen))
{
@@ -615,9 +669,14 @@ ATICloseScreen
ATILeaveGraphics(pScreenInfo, pATI);
- xfree(pATI->ExpansionBitmapScanlinePtr[1]);
- pATI->ExpansionBitmapScanlinePtr[0] =
+#ifdef USE_XAA
+ if (!pATI->useEXA)
+ {
+ xfree(pATI->ExpansionBitmapScanlinePtr[1]);
+ pATI->ExpansionBitmapScanlinePtr[0] = NULL;
pATI->ExpansionBitmapScanlinePtr[1] = NULL;
+ }
+#endif
xfree(pATI->pShadow);
pATI->pShadow = NULL;
diff --git a/src/atistruct.h b/src/atistruct.h
index 44aec36..08bbb0e 100644
--- a/src/atistruct.h
+++ b/src/atistruct.h
@@ -52,7 +52,12 @@
#endif /* TV_OUT */
+#ifdef USE_EXA
+#include "exa.h"
+#endif
+#ifdef USE_XAA
#include "xaa.h"
+#endif
#include "xf86Cursor.h"
#include "xf86Pci.h"
#include "xf86Resources.h"
@@ -268,15 +273,23 @@ typedef struct _ATIRec
/*
* XAA interface.
*/
+ Bool useEXA;
+#ifdef USE_EXA
+ ExaDriverPtr pExa;
+#endif
+#ifdef USE_XAA
XAAInfoRecPtr pXAAInfo;
+#endif
int nAvailableFIFOEntries, nFIFOEntries, nHostFIFOEntries;
CARD8 EngineIsBusy, EngineIsLocked, XModifier;
CARD32 dst_cntl; /* For SetupFor/Subsequent communication */
CARD32 sc_left_right, sc_top_bottom;
CARD16 sc_left, sc_right, sc_top, sc_bottom; /* Current scissors */
pointer pHOST_DATA; /* Current HOST_DATA_* transfer window address */
+#ifdef USE_XAA
CARD32 *ExpansionBitmapScanlinePtr[2];
int ExpansionBitmapWidth;
+#endif
/*
* Cursor-related definitions.
@@ -354,7 +367,7 @@ typedef struct _ATIRec
* XVideo-related data.
*/
DevUnion XVPortPrivate[1];
- FBLinearPtr pXVBuffer;
+ pointer pXVBuffer; /* USE_EXA: ExaOffscreenArea*, USE_XAA: FBLinearPtr */
RegionRec VideoClip;
int SurfacePitch, SurfaceOffset;
CARD8 AutoPaint, DoubleBuffer, CurrentBuffer, ActiveSurface;
@@ -457,10 +470,12 @@ typedef struct _ATIRec
Bool have3DWindows;
/* offscreen memory management */
+#ifdef USE_XAA
int backLines;
FBAreaPtr backArea;
int depthTexLines;
FBAreaPtr depthTexArea;
+#endif
CARD8 OptionIsPCI; /* Force PCI mode */
CARD8 OptionDMAMode; /* async, sync, mmio */
CARD8 OptionAGPMode; /* AGP mode */