diff options
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | src/radeon.h | 18 | ||||
-rw-r--r-- | src/radeon_dri.c | 170 | ||||
-rw-r--r-- | src/radeon_driver.c | 50 | ||||
-rw-r--r-- | src/radeon_exa.c | 4 | ||||
-rw-r--r-- | src/radeon_exa_funcs.c | 53 |
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, |