diff --git a/src/radeon.h b/src/radeon.h index 66b2330..633385f 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -893,6 +893,7 @@ extern void RADEONEngineFlush(ScrnInfoPtr pScrn); extern void RADEONEngineInit(ScrnInfoPtr pScrn); extern void RADEONEngineReset(ScrnInfoPtr pScrn); extern void RADEONEngineRestore(ScrnInfoPtr pScrn); +extern Bool RADEONWaitforIdlePoll(ScrnInfoPtr pScrn); extern uint8_t *RADEONHostDataBlit(ScrnInfoPtr pScrn, unsigned int cpp, unsigned int w, uint32_t dstPitchOff, uint32_t *bufPitch, int x, int *y, diff --git a/src/radeon_accel.c b/src/radeon_accel.c index 96570e8..d2ae2e6 100644 --- a/src/radeon_accel.c +++ b/src/radeon_accel.c @@ -472,6 +472,23 @@ void RADEONEngineInit(ScrnInfoPtr pScrn) RADEONEngineRestore(pScrn); } +/* really would be better to wait on a timestamp shadowed in memory, + * but this will do for now. + */ +Bool +RADEONWaitforIdlePoll(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + uint32_t i; + + for (i = 0; i < 1000000; i++) { + if ((INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE) == 0) + return TRUE; + } + return FALSE; +} + #define ACCEL_MMIO #define ACCEL_PREAMBLE() unsigned char *RADEONMMIO = info->MMIO @@ -872,6 +889,8 @@ RADEONHostDataBlitCopyPass( /* RADEONHostDataBlitCopy can return NULL ! */ if( (dst==NULL) || (src==NULL)) return; + RADEONWaitforIdlePoll(pScrn); + if ( dstPitch == srcPitch ) { #if X_BYTE_ORDER == X_BIG_ENDIAN diff --git a/src/radeon_exa.c b/src/radeon_exa.c index c4bc1bb..ebe65d1 100644 --- a/src/radeon_exa.c +++ b/src/radeon_exa.c @@ -220,17 +220,22 @@ int RADEONBiggerCrtcArea(PixmapPtr pPix) } #if X_BYTE_ORDER == X_BIG_ENDIAN - static unsigned long swapper_surfaces[3]; +#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ static Bool RADEONPrepareAccess(PixmapPtr pPix, int index) { RINFO_FROM_SCREEN(pPix->drawable.pScreen); +#if X_BYTE_ORDER == X_BIG_ENDIAN unsigned char *RADEONMMIO = info->MMIO; uint32_t offset = exaGetPixmapOffset(pPix); int bpp, soff; uint32_t size, flags; +#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ + + RADEONWaitforIdlePoll(pScrn); +#if X_BYTE_ORDER == X_BIG_ENDIAN /* Front buffer is always set with proper swappers */ if (offset == 0) return TRUE; @@ -286,11 +291,13 @@ static Bool RADEONPrepareAccess(PixmapPtr pPix, int index) OUTREG(RADEON_SURFACE0_LOWER_BOUND + soff, offset); OUTREG(RADEON_SURFACE0_UPPER_BOUND + soff, offset + size - 1); swapper_surfaces[index] = offset; +#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ return TRUE; } static void RADEONFinishAccess(PixmapPtr pPix, int index) { +#if X_BYTE_ORDER == X_BIG_ENDIAN RINFO_FROM_SCREEN(pPix->drawable.pScreen); unsigned char *RADEONMMIO = info->MMIO; uint32_t offset = exaGetPixmapOffset(pPix); @@ -318,9 +325,9 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index) OUTREG(RADEON_SURFACE0_LOWER_BOUND + soff, 0); OUTREG(RADEON_SURFACE0_UPPER_BOUND + soff, 0); swapper_surfaces[index] = 0; +#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ } -#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ #define ENTER_DRAW(x) TRACE #define LEAVE_DRAW(x) TRACE diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c index cd97cc6..eb714ab 100644 --- a/src/radeon_exa_funcs.c +++ b/src/radeon_exa_funcs.c @@ -408,6 +408,8 @@ RADEONDownloadFromScreenCP(PixmapPtr pSrc, int x, int y, int w, int h, while ((drmCommandNone(info->dri->drmFD, DRM_RADEON_CP_IDLE) == -EBUSY) && (i++ < RADEON_TIMEOUT)) ; + /* make sure the engine is idle */ + RADEONWaitforIdlePoll(pScrn); /* Kick next blit */ if (hpass) @@ -470,10 +472,8 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen) info->accel_state->exa->DownloadFromScreen = RADEONDownloadFromScreenCP; #endif -#if X_BYTE_ORDER == X_BIG_ENDIAN info->accel_state->exa->PrepareAccess = RADEONPrepareAccess; info->accel_state->exa->FinishAccess = RADEONFinishAccess; -#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ info->accel_state->exa->flags = EXA_OFFSCREEN_PIXMAPS; info->accel_state->exa->pixmapOffsetAlign = RADEON_BUFFER_ALIGN + 1;