diff options
-rw-r--r-- | src/radeon_accel.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/radeon_accel.c b/src/radeon_accel.c index ac422571..3e14217f 100644 --- a/src/radeon_accel.c +++ b/src/radeon_accel.c @@ -556,6 +556,44 @@ void RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard) buffer->idx); } + /* TODO: Fix this more elegantly. + * Sometimes (especially with multiple DRI clients), this code + * runs immediately after a DRI client issues a rendering command. + * + * The accel code regularly inserts WAIT_UNTIL_IDLE into the + * command buffer that is sent with the indirect buffer below. + * The accel code fails to set the 3D cache flush registers for + * the R300 before sending WAIT_UNTIL_IDLE. Sending a cache flush + * on these new registers is not necessary for pure 2D functionality, + * but it *is* necessary after 3D operations. + * Without the cache flushes before WAIT_UNTIL_IDLE, the R300 locks up. + * + * The CP_IDLE call into the DRM indirectly flushes all caches and + * thus avoids the lockup problem, but the solution is far from ideal. + * Better solutions could be: + * - always flush caches when entering the X server + * - track the type of rendering commands somewhere and issue + * cache flushes when they change + * However, I don't feel confident enough with the control flow + * inside the X server to implement either fix. -- nh + */ + + /* On my computer (Radeon Mobility M10) + The fix below results in x11perf -shmput500 rate of 225.0/sec + which is lower than 264.0/sec I get without it. + + On the other hand, not using CP acceleration at all benchmarks + at 144.0/sec. + + For now let us accept this as a lesser evil, especially as the + DRM driver for R300 is still in flux. + + Once the code is more stable this should probably be moved into DRM driver. + */ + + if (info->ChipFamily>=CHIP_FAMILY_R300) + drmCommandNone(info->drmFD, DRM_RADEON_CP_IDLE); + indirect.idx = buffer->idx; indirect.start = start; indirect.end = buffer->used; @@ -595,6 +633,10 @@ void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn) buffer->idx); } + /* Hack for the R300 (see RADEONCPFlushIndirect for explanation) */ + if (info->ChipFamily>=CHIP_FAMILY_R300) + drmCommandNone(info->drmFD, DRM_RADEON_CP_IDLE); + indirect.idx = buffer->idx; indirect.start = start; indirect.end = buffer->used; |