summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/radeon_accel.c42
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;