aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/radeon/radeon_tcl.c
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2004-08-17 01:41:29 +0000
committerEric Anholt <[email protected]>2004-08-17 01:41:29 +0000
commit6f3cc6a5226fd4b5d44cca91e2f76216ecaff831 (patch)
tree958ff79f2f928f34a522f4e4f16303ea2e215d6a /src/mesa/drivers/dri/radeon/radeon_tcl.c
parent7e27ab4c6ae528daa0f64b9ce79231ff39a58b79 (diff)
Close some races with locking on R100 and R200 which could manifest as rendering
errors on r100 and rendering errors and hangs on r200 (same for R100 without OLD_PACKETS). If a command buffer filled after some state (EmitState or a VBPNTR write) was emitted, the lock was grabbed, the buffer flushed, a new buffer prepared, and the lock dropped. Another client could come in, set its own state as part of rendering, and when the first client flushed the rendering commands depending on the previous state, it got the 2nd client's state. This is fixed by checking for enough space before beginning a set of state emits and rendering, and flushing the buffer first if so. This guarantees that the buffer won't wrap. Also, move the "lost_context = 1" from the end of cmdbuf flushing to UNLOCK_HARDWARE for clarity (at a minimum) that any time the lock is dropped, state may get overwritten. We don't have enough information at the point of the LOCK_HARDWARE to reset our state to the last UNLOCK_HARDWARE point in the case that we did lose our context, but saving the information to rebuild that state may be a useful optimization (ipers data suggests up to 5%).
Diffstat (limited to 'src/mesa/drivers/dri/radeon/radeon_tcl.c')
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_tcl.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c
index 9aec22b1a52..6e294d2395c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_tcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c
@@ -149,6 +149,9 @@ static GLushort *radeonAllocElts( radeonContextPtr rmesa, GLuint nr )
if (rmesa->dma.flush)
rmesa->dma.flush( rmesa );
+ radeonEnsureCmdBufSpace(rmesa, AOS_BUFSZ(rmesa->tcl.nr_aos_components) +
+ rmesa->hw.max_state_size + ELTS_BUFSZ(nr));
+
radeonEmitAOS( rmesa,
rmesa->tcl.aos_components,
rmesa->tcl.nr_aos_components, 0 );
@@ -175,6 +178,9 @@ static void EMIT_PRIM( GLcontext *ctx,
radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
radeonTclPrimitive( ctx, prim, hwprim );
+ radeonEnsureCmdBufSpace( rmesa, AOS_BUFSZ(rmesa->tcl.nr_aos_components) +
+ rmesa->hw.max_state_size + VBUF_BUFSZ );
+
radeonEmitAOS( rmesa,
rmesa->tcl.aos_components,
rmesa->tcl.nr_aos_components,