summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac5
-rw-r--r--src/radeon.h18
-rw-r--r--src/radeon_dri.c170
-rw-r--r--src/radeon_driver.c50
-rw-r--r--src/radeon_exa.c4
-rw-r--r--src/radeon_exa_funcs.c53
6 files changed, 174 insertions, 126 deletions
diff --git a/configure.ac b/configure.ac
index a7cdd10f..73ea79de 100644
--- a/configure.ac
+++ b/configure.ac
@@ -91,6 +91,8 @@ if test "$DRI" != no; then
[have_sarea_h="yes"], [have_sarea_h="no"])
AC_CHECK_FILE([${sdkdir}/dristruct.h],
[have_dristruct_h="yes"], [have_dristruct_h="no"])
+ AC_CHECK_FILE([${sdkdir}/damage.h],
+ [have_damage_h="yes"], [have_damage_h="no"])
fi
AC_MSG_CHECKING([whether to include DRI support])
@@ -110,6 +112,9 @@ if test "$DRI" = yes; then
PKG_CHECK_MODULES(DRI, [libdrm >= 2.0 xf86driproto])
AC_DEFINE(XF86DRI,1,[Enable DRI driver support])
AC_DEFINE(XF86DRI_DEVEL,1,[Enable developmental DRI driver support])
+ if test "$have_damage_h" = yes; then
+ AC_DEFINE(DAMAGE,1,[Use Damage extension])
+ fi
fi
# Note that this is sort of inverted from drivers/ati/Imakefile in
diff --git a/src/radeon.h b/src/radeon.h
index 73b3538d..8068cd9a 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -71,6 +71,10 @@
#include "radeon_dripriv.h"
#include "dri.h"
#include "GL/glxint.h"
+#ifdef DAMAGE
+#include "damage.h"
+#include "globals.h"
+#endif
#endif
/* Render support */
@@ -599,6 +603,9 @@ typedef struct {
Bool depthMoves; /* Enable depth moves -- slow! */
Bool allowPageFlip; /* Enable 3d page flipping */
+#ifdef DAMAGE
+ DamagePtr pDamage;
+#endif
Bool have3DWindows; /* Are there any 3d clients? */
drmSize gartSize;
@@ -847,7 +854,17 @@ extern Bool RADEONAccelInit(ScreenPtr pScreen);
extern Bool RADEONSetupMemEXA (ScreenPtr pScreen);
extern Bool RADEONDrawInitMMIO(ScreenPtr pScreen);
#ifdef XF86DRI
+extern Bool RADEONGetDatatypeBpp(int bpp, CARD32 *type);
+extern Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
+ CARD32 *pitch_offset);
extern Bool RADEONDrawInitCP(ScreenPtr pScreen);
+extern void RADEONDoPrepareCopyCP(ScrnInfoPtr pScrn,
+ CARD32 src_pitch_offset,
+ CARD32 dst_pitch_offset,
+ CARD32 datatype, int rop,
+ Pixel planemask);
+extern void RADEONCopyCP(PixmapPtr pDst, int srcX, int srcY, int dstX,
+ int dstY, int w, int h);
#endif
#endif
#ifdef USE_XAA
@@ -898,7 +915,6 @@ extern void RADEONDRICloseScreen(ScreenPtr pScreen);
extern void RADEONDRIResume(ScreenPtr pScreen);
extern Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen);
extern void RADEONDRIAllocatePCIGARTTable(ScreenPtr pScreen);
-extern void RADEONDRIInitPageFlip(ScreenPtr pScreen);
extern void RADEONDRIStop(ScreenPtr pScreen);
extern drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn);
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index ca70e561..c50ebcb1 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -54,8 +54,6 @@
#include "xf86PciInfo.h"
#include "windowstr.h"
-
-#include "shadowfb.h"
/* GLX/DRI/DRM definitions */
#define _XF86DRI_SERVER_
#include "GL/glxtokens.h"
@@ -70,7 +68,7 @@ static void RADEONDRITransitionTo3d(ScreenPtr pScreen);
static void RADEONDRITransitionMultiToSingle3d(ScreenPtr pScreen);
static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen);
-#ifdef USE_XAA
+#ifdef DAMAGE
static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
#endif
@@ -420,6 +418,19 @@ static void RADEONLeaveServer(ScreenPtr pScreen)
RADEONInfoPtr info = RADEONPTR(pScrn);
RING_LOCALS;
+#ifdef DAMAGE
+ if (info->pDamage) {
+ RegionPtr pDamageReg = DamageRegion(info->pDamage);
+
+ if (pDamageReg) {
+ RADEONDRIRefreshArea(pScrn, REGION_NUM_RECTS(pDamageReg),
+ REGION_RECTS(pDamageReg));
+
+ DamageEmpty(info->pDamage);
+ }
+ }
+#endif
+
/* The CP is always running, but if we've generated any CP commands
* we must flush them to the kernel module now.
*/
@@ -1624,30 +1635,6 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen)
return TRUE;
}
-void RADEONDRIInitPageFlip(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
-#ifdef USE_XAA
- /* Have shadowfb run only while there is 3d active. This must happen late,
- * after XAAInit has been called
- */
- if (!info->useEXA) {
- if (!ShadowFBInit( pScreen, RADEONDRIRefreshArea )) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ShadowFB init failed, Page Flipping disabled\n");
- info->allowPageFlip = 0;
- } else
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "ShadowFB initialized for Page Flipping\n");
- } else
-#endif /* USE_XAA */
- {
- info->allowPageFlip = 0;
- }
-}
-
/**
* This function will attempt to get the Radeon hardware back into shape
* after a resume from disc.
@@ -1798,8 +1785,6 @@ void RADEONDRICloseScreen(ScreenPtr pScreen)
}
}
-#ifdef USE_XAA
-
/* Use callbacks from dri.c to support pageflipping mode for a single
* 3d context without need for any specific full-screen extension.
*
@@ -1808,12 +1793,12 @@ void RADEONDRICloseScreen(ScreenPtr pScreen)
*/
-/* Use the shadowfb module to maintain a list of dirty rectangles.
+#ifdef DAMAGE
+
+/* Use the damage layer to maintain a list of dirty rectangles.
* These are blitted to the back buffer to keep both buffers clean
* during page-flipping when the 3d application isn't fullscreen.
*
- * Unlike most use of the shadowfb code, both buffers are in video memory.
- *
* An alternative to this would be to organize for all on-screen drawing
* operations to be duplicated for the two buffers. That might be
* faster, but seems like a lot more work...
@@ -1824,7 +1809,11 @@ static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
int i;
- RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+ ScreenPtr pScreen = pScrn->pScreen;
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+#ifdef USE_EXA
+ PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
+#endif
if (!info->directRenderingInited)
return;
@@ -1835,64 +1824,98 @@ static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
if (!pSAREAPriv->pfAllowPageFlip && pSAREAPriv->pfCurrentPage == 0)
return;
- /* XXX: implement for EXA */
/* pretty much a hack. */
- /* Make sure accel has been properly inited */
- if (info->accel == NULL || info->accel->SetupForScreenToScreenCopy == NULL)
- return;
- if (info->tilingEnabled)
- info->dst_pitch_offset |= RADEON_DST_TILE_MACRO;
- (*info->accel->SetupForScreenToScreenCopy)(pScrn,
- 1, 1, GXcopy,
- (CARD32)(-1), -1);
+#ifdef USE_EXA
+ if (info->useEXA) {
+ CARD32 src_pitch_offset, dst_pitch_offset, datatype;
+
+ RADEONGetPixmapOffsetPitch(pPix, &src_pitch_offset);
+ dst_pitch_offset = src_pitch_offset + (info->backOffset >> 10);
+ RADEONGetDatatypeBpp(pScrn->bitsPerPixel, &datatype);
+ info->xdir = info->ydir = 1;
+
+ RADEONDoPrepareCopyCP(pScrn, src_pitch_offset, dst_pitch_offset, datatype,
+ GXcopy, ~0);
+ }
+#endif
+
+#ifdef USE_XAA
+ if (!info->useEXA) {
+ /* Make sure accel has been properly inited */
+ if (info->accel == NULL || info->accel->SetupForScreenToScreenCopy == NULL)
+ return;
+ if (info->tilingEnabled)
+ info->dst_pitch_offset |= RADEON_DST_TILE_MACRO;
+ (*info->accel->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, GXcopy,
+ (CARD32)(-1), -1);
+ }
+#endif
for (i = 0 ; i < num ; i++, pbox++) {
int xa = max(pbox->x1, 0), xb = min(pbox->x2, pScrn->virtualX-1);
int ya = max(pbox->y1, 0), yb = min(pbox->y2, pScrn->virtualY-1);
if (xa <= xb && ya <= yb) {
- (*info->accel->SubsequentScreenToScreenCopy)(pScrn, xa, ya,
- xa + info->backX,
- ya + info->backY,
- xb - xa + 1,
- yb - ya + 1);
+#ifdef USE_EXA
+ if (info->useEXA) {
+ RADEONCopyCP(pPix, xa, ya, xa, ya, xb - xa + 1, yb - ya + 1);
+ }
+#endif
+
+#ifdef USE_XAA
+ if (!info->useEXA) {
+ (*info->accel->SubsequentScreenToScreenCopy)(pScrn, xa, ya,
+ xa + info->backX,
+ ya + info->backY,
+ xb - xa + 1,
+ yb - ya + 1);
+ }
+#endif
}
}
+
+#ifdef USE_XAA
info->dst_pitch_offset &= ~RADEON_DST_TILE_MACRO;
+#endif
}
-#endif /* USE_XAA */
+#endif /* DAMAGE */
static void RADEONEnablePageFlip(ScreenPtr pScreen)
{
-#ifdef USE_XAA
+#ifdef DAMAGE
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
- /* XXX: Fix in EXA case */
if (info->allowPageFlip) {
- /* pretty much a hack. */
- if (info->tilingEnabled)
- info->dst_pitch_offset |= RADEON_DST_TILE_MACRO;
- /* Duplicate the frontbuffer to the backbuffer */
- (*info->accel->SetupForScreenToScreenCopy)(pScrn,
- 1, 1, GXcopy,
- (CARD32)(-1), -1);
+ BoxRec box = { .x1 = 0, .y1 = 0, .x2 = pScrn->virtualX - 1,
+ .y2 = pScrn->virtualY - 1 };
+ RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+
+ if (!info->pDamage) {
+ PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
+
+ /* Have damage run only while there is 3d active.
+ */
+ info->pDamage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
+ pScreen, pPix);
+
+ if (info->pDamage == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No screen damage record, page flipping disabled\n");
+ info->allowPageFlip = 0;
+ return;
+ }
+
+ DamageRegister(&pPix->drawable, info->pDamage);
+ }
- (*info->accel->SubsequentScreenToScreenCopy)(pScrn,
- 0,
- 0,
- info->backX,
- info->backY,
- pScrn->virtualX,
- pScrn->virtualY);
-
- info->dst_pitch_offset &= ~RADEON_DST_TILE_MACRO;
pSAREAPriv->pfAllowPageFlip = 1;
+ RADEONDRIRefreshArea(pScrn, 1, &box);
}
-#endif /* USE_XAA */
+#endif
}
static void RADEONDisablePageFlip(ScreenPtr pScreen)
@@ -1902,6 +1925,17 @@ static void RADEONDisablePageFlip(ScreenPtr pScreen)
* -- DRM needs to cope with Front-to-Back swapbuffers.
*/
RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+#ifdef DAMAGE
+ RADEONInfoPtr info = RADEONPTR(xf86Screens[pScreen->myNum]);
+
+ if (info->pDamage) {
+ PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
+
+ DamageUnregister(&pPix->drawable, info->pDamage);
+ DamageDestroy(info->pDamage);
+ info->pDamage = NULL;
+ }
+#endif
pSAREAPriv->pfAllowPageFlip = 0;
}
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 60725da5..bb1e070c 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -55,7 +55,7 @@
* This server does not yet support these XFree86 4.0 features:
* !!!! FIXME !!!!
* DDC1 & DDC2
- * shadowfb (Note: dri uses shadowfb for another purpose in radeon_dri.c)
+ * shadowfb
* overlay planes
*
* Modified by Marc Aurele La France (tsi@xfree86.org) for ATI driver merge.
@@ -360,11 +360,6 @@ static const char *driSymbols[] = {
"DRICreatePCIBusID",
NULL
};
-
-static const char *driShadowFBSymbols[] = {
- "ShadowFBInit",
- NULL
-};
#endif
static const char *vbeSymbols[] = {
@@ -411,7 +406,6 @@ void RADEONLoaderRefSymLists(void)
#ifdef XF86DRI
drmSymbols,
driSymbols,
- driShadowFBSymbols,
#endif
fbdevHWSymbols,
vbeSymbols,
@@ -3214,6 +3208,7 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
MessageType from;
+ char *reason;
info->directRenderingEnabled = FALSE;
info->directRenderingInited = FALSE;
@@ -3389,30 +3384,25 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn)
OPTION_NO_BACKBUFFER,
FALSE);
-#ifdef XF86DRI
+ info->allowPageFlip = 0;
+
+#ifdef DAMAGE
if (info->noBackBuffer) {
- info->allowPageFlip = 0;
- } else if (!xf86LoadSubModule(pScrn, "shadowfb")) {
- info->allowPageFlip = 0;
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Couldn't load shadowfb module:\n");
+ from = X_DEFAULT;
+ reason = " because back buffer disabled";
} else {
- xf86LoaderReqSymLists(driShadowFBSymbols, NULL);
-
- info->allowPageFlip = xf86ReturnOptValBool(info->Options,
- OPTION_PAGE_FLIP,
- FALSE);
- if (info->allowPageFlip && info->useEXA) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Page flipping not allowed with EXA, disabling.\n");
- info->allowPageFlip = FALSE;
- }
+ from = xf86GetOptValBool(info->Options, OPTION_PAGE_FLIP,
+ &info->allowPageFlip) ? X_CONFIG : X_DEFAULT;
+ reason = "";
}
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Page flipping %sabled\n",
- info->allowPageFlip ? "en" : "dis");
+#else
+ from = X_DEFAULT;
+ reason = " because Damage layer not available at build time";
#endif
+ xf86DrvMsg(pScrn->scrnIndex, from, "Page Flipping %sabled%s\n",
+ info->allowPageFlip ? "en" : "dis", reason);
+
info->DMAForXv = TRUE;
from = xf86GetOptValBool(info->Options, OPTION_XV_DMA, &info->DMAForXv)
? X_CONFIG : X_INFO;
@@ -4835,14 +4825,6 @@ _X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
info->accelOn = FALSE;
}
-#ifdef XF86DRI
- /* Init page flipping if enabled now */
- if (info->allowPageFlip) {
- RADEONTRACE(("Initializing Page Flipping\n"));
- RADEONDRIInitPageFlip(pScreen);
- }
-#endif
-
/* Init DPMS */
RADEONTRACE(("Initializing DPMS\n"));
xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0);
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index 9ef74e99..7e57fe76 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -118,7 +118,7 @@ static __inline__ CARD32 F_TO_DW(float val)
/* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we
* require src and dest datatypes to be equal.
*/
-static Bool RADEONGetDatatypeBpp(int bpp, CARD32 *type)
+Bool RADEONGetDatatypeBpp(int bpp, CARD32 *type)
{
switch (bpp) {
case 8:
@@ -172,7 +172,7 @@ static Bool RADEONGetOffsetPitch(PixmapPtr pPix, int bpp, CARD32 *pitch_offset,
return TRUE;
}
-static Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch_offset)
+Bool RADEONGetPixmapOffsetPitch(PixmapPtr pPix, CARD32 *pitch_offset)
{
RINFO_FROM_SCREEN(pPix->drawable.pScreen);
CARD32 pitch, offset;
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index c0bdf6e7..f018e552 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -127,6 +127,35 @@ FUNC_NAME(RADEONDoneSolid)(PixmapPtr pPix)
TRACE;
}
+void
+FUNC_NAME(RADEONDoPrepareCopy)(ScrnInfoPtr pScrn, CARD32 src_pitch_offset,
+ CARD32 dst_pitch_offset, CARD32 datatype, int rop,
+ Pixel planemask)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ ACCEL_PREAMBLE();
+
+ RADEON_SWITCH_TO_2D();
+
+ BEGIN_ACCEL(5);
+ OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL,
+ RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
+ RADEON_GMC_BRUSH_NONE |
+ (datatype << 8) |
+ RADEON_GMC_SRC_DATATYPE_COLOR |
+ RADEON_ROP[rop].rop |
+ RADEON_DP_SRC_SOURCE_MEMORY |
+ RADEON_GMC_CLR_CMP_CNTL_DIS);
+ OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask);
+ OUT_ACCEL_REG(RADEON_DP_CNTL,
+ ((info->xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) |
+ (info->ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)));
+ OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset);
+ OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset);
+ FINISH_ACCEL();
+}
+
static Bool
FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst,
int xdir, int ydir,
@@ -135,7 +164,6 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst,
{
RINFO_FROM_SCREEN(pDst->drawable.pScreen);
CARD32 datatype, src_pitch_offset, dst_pitch_offset;
- ACCEL_PREAMBLE();
TRACE;
@@ -151,30 +179,13 @@ FUNC_NAME(RADEONPrepareCopy)(PixmapPtr pSrc, PixmapPtr pDst,
if (!RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_offset))
RADEON_FALLBACK(("RADEONGetPixmapOffsetPitch dest failed\n"));
- RADEON_SWITCH_TO_2D();
-
- BEGIN_ACCEL(5);
- OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL,
- RADEON_GMC_DST_PITCH_OFFSET_CNTL |
- RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
- RADEON_GMC_BRUSH_NONE |
- (datatype << 8) |
- RADEON_GMC_SRC_DATATYPE_COLOR |
- RADEON_ROP[rop].rop |
- RADEON_DP_SRC_SOURCE_MEMORY |
- RADEON_GMC_CLR_CMP_CNTL_DIS);
- OUT_ACCEL_REG(RADEON_DP_WRITE_MASK, planemask);
- OUT_ACCEL_REG(RADEON_DP_CNTL,
- ((xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) |
- (ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)));
- OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset);
- OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset);
- FINISH_ACCEL();
+ FUNC_NAME(RADEONDoPrepareCopy)(pScrn, src_pitch_offset, dst_pitch_offset,
+ datatype, rop, planemask);
return TRUE;
}
-static void
+void
FUNC_NAME(RADEONCopy)(PixmapPtr pDst,
int srcX, int srcY,
int dstX, int dstY,