diff options
author | Eric Anholt <anholt@FreeBSD.org> | 2004-08-17 01:41:29 +0000 |
---|---|---|
committer | Eric Anholt <anholt@FreeBSD.org> | 2004-08-17 01:41:29 +0000 |
commit | 6f3cc6a5226fd4b5d44cca91e2f76216ecaff831 (patch) | |
tree | 958ff79f2f928f34a522f4e4f16303ea2e215d6a /src/mesa/drivers/dri/radeon/radeon_ioctl.c | |
parent | 7e27ab4c6ae528daa0f64b9ce79231ff39a58b79 (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_ioctl.c')
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_ioctl.c | 27 |
1 files changed, 10 insertions, 17 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index c5707a0280..3cb7dca215 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -204,9 +204,10 @@ extern void radeonEmitVbufPrim( radeonContextPtr rmesa, fprintf(stderr, "%s cmd_used/4: %d\n", __FUNCTION__, rmesa->store.cmd_used/4); + cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, VBUF_BUFSZ, + __FUNCTION__ ); #if RADEON_OLD_PACKETS - cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 6 * sizeof(*cmd), - __FUNCTION__ ); + cmd[0].i = 0; cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM | (3 << 16); cmd[2].i = rmesa->ioctl.vertex_offset; @@ -223,8 +224,6 @@ extern void radeonEmitVbufPrim( radeonContextPtr rmesa, __FUNCTION__, cmd[1].i, cmd[2].i, cmd[4].i, cmd[5].i); #else - cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 4 * sizeof(*cmd), - __FUNCTION__ ); cmd[0].i = 0; cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_VBUF | (1 << 16); @@ -291,10 +290,10 @@ GLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa, radeonEmitState( rmesa ); + cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, + ELTS_BUFSZ(min_nr), + __FUNCTION__ ); #if RADEON_OLD_PACKETS - cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, - 24 + min_nr*2, - __FUNCTION__ ); cmd[0].i = 0; cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; cmd[1].i = RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM; @@ -308,9 +307,6 @@ GLushort *radeonAllocEltsOpenEnded( radeonContextPtr rmesa, retval = (GLushort *)(cmd+6); #else - cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, - 16 + min_nr*2, - __FUNCTION__ ); cmd[0].i = 0; cmd[0].header.cmd_type = RADEON_CMD_PACKET3_CLIP; cmd[1].i = RADEON_CP_PACKET3_3D_DRAW_INDX; @@ -354,7 +350,7 @@ void radeonEmitVertexAOS( radeonContextPtr rmesa, fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n", __FUNCTION__, vertex_size, offset); - cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, 5 * sizeof(int), + cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, VERT_AOS_BUFSZ, __FUNCTION__ ); cmd[0].i = 0; @@ -380,7 +376,7 @@ void radeonEmitAOS( radeonContextPtr rmesa, (component[0]->aos_start + offset * component[0]->aos_stride * 4); #else drm_radeon_cmd_header_t *cmd; - int sz = 3 + (nr/2 * 3) + (nr & 1) * 2; + int sz = AOS_BUFSZ; int i; int *tmp; @@ -388,11 +384,11 @@ void radeonEmitAOS( radeonContextPtr rmesa, fprintf(stderr, "%s\n", __FUNCTION__); - cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, sz * sizeof(int), + cmd = (drm_radeon_cmd_header_t *)radeonAllocCmdBuf( rmesa, sz, __FUNCTION__ ); cmd[0].i = 0; cmd[0].header.cmd_type = RADEON_CMD_PACKET3; - cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | ((sz-3) << 16); + cmd[1].i = RADEON_CP_PACKET3_3D_LOAD_VBPNTR | (((sz / sizeof(int))-3) << 16); cmd[2].i = nr; tmp = &cmd[0].i; cmd += 3; @@ -548,7 +544,6 @@ static int radeonFlushCmdBufLocked( radeonContextPtr rmesa, rmesa->store.statenr = 0; rmesa->store.cmd_used = 0; rmesa->dma.nr_released_bufs = 0; - rmesa->lost_context = 1; return ret; } @@ -982,8 +977,6 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all, __FUNCTION__, all, cx, cy, cw, ch ); } - radeonEmitState( rmesa ); - /* Need to cope with lostcontext here as kernel relies on * some residual state: */ |