diff options
author | Eric Anholt <anholt@FreeBSD.org> | 2004-08-17 20:10:29 +0000 |
---|---|---|
committer | Eric Anholt <anholt@FreeBSD.org> | 2004-08-17 20:10:29 +0000 |
commit | 626f825bcc91a3068e2e1c68e7467b42826c51ea (patch) | |
tree | f9fde8dc1d3f487b1a82749a114e64b1e2f40279 /src/mesa/drivers | |
parent | ffdea1ae80a1405fe805cd197c7650d9c5157e2e (diff) |
Revert the move of lost_context setting to UNLOCK_HARDWARE that was done in the
last commit. I've been convinced by keithw that it's sufficient, and put a note
in the code about it.
Close another race for state in the Clear functions. I made the situation worse
in my last commit, but this should fix things. Might be a slight performance
hit, which could be regained by splitting the R*_FIREVERTICES calls in r*Clear
up so that the EmitState doesn't happen in a separate new cmdbuf.
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_ioctl.c | 25 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_lock.h | 11 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_ioctl.c | 26 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_lock.h | 11 |
4 files changed, 45 insertions, 28 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index 5d084baf3e..fb462e0850 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -132,6 +132,19 @@ int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller ) rmesa->store.statenr = 0; rmesa->store.cmd_used = 0; rmesa->dma.nr_released_bufs = 0; + /* Set lost_context so that the first state emit on the new buffer is a full + * one. This is because the context might get lost while preparing the next + * buffer, and when we lock and find out, we don't have the information to + * recreate the state. This function should always be called before the new + * buffer is begun, so it's sufficient to just set lost_context here. + * + * The alternative to this would be to copy out the state on unlock + * (approximately) and if we did lose the context, dispatch a cmdbuf to reset + * the state to that old copy before continuing with the accumulated command + * buffer. + */ + rmesa->lost_context = 1; + return ret; } @@ -563,9 +576,6 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, return; } - /* Need to cope with lostcontext here as kernel relies on - * some residual state: - */ R200_FIREVERTICES( rmesa ); if ( mask & DD_FRONT_LEFT_BIT ) { @@ -603,6 +613,13 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, cx += dPriv->x; cy = dPriv->y + dPriv->h - cy - ch; + /* We have to emit state along with the clear, since the kernel relies on + * some of it. The EmitState that was above R200_FIREVERTICES was an + * attempt to do that, except that another context may come in and cause us + * to lose our context while we're unlocked. + */ + r200EmitState( rmesa ); + LOCK_HARDWARE( rmesa ); /* Throttle the number of clear ioctls we do. @@ -635,6 +652,8 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, } } + /* Send current state to the hardware */ + r200FlushCmdBufLocked( rmesa, __FUNCTION__ ); for ( i = 0 ; i < dPriv->numClipRects ; ) { GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects ); diff --git a/src/mesa/drivers/dri/r200/r200_lock.h b/src/mesa/drivers/dri/r200/r200_lock.h index c913bd5f62..587e4fe5cc 100644 --- a/src/mesa/drivers/dri/r200/r200_lock.h +++ b/src/mesa/drivers/dri/r200/r200_lock.h @@ -98,23 +98,12 @@ extern int prevLockLine; DEBUG_LOCK(); \ } while (0) -/* Unlock the hardware. We must assume that state has been lost when we unlock, - * because when we next grab the lock (to emit an accumulated cmdbuf), we don't - * have the information to recreate the context state as of the last unlock in - * in the case that we did lose the context state. - * - * The alternative to this would be to copy out the state on unlock - * (approximately) and if we did lose the context, dispatch a cmdbuf to reset - * the state to that old copy before continuing with the accumulated command - * buffer. - */ #define UNLOCK_HARDWARE( rmesa ) \ do { \ DRM_UNLOCK( rmesa->dri.fd, \ rmesa->dri.hwLock, \ rmesa->dri.hwContext ); \ DEBUG_RESET(); \ - rmesa->lost_context = GL_TRUE; \ } while (0) #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 3cb7dca215..999176e0e9 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -544,6 +544,19 @@ static int radeonFlushCmdBufLocked( radeonContextPtr rmesa, rmesa->store.statenr = 0; rmesa->store.cmd_used = 0; rmesa->dma.nr_released_bufs = 0; + /* Set lost_context so that the first state emit on the new buffer is a full + * one. This is because the context might get lost while preparing the next + * buffer, and when we lock and find out, we don't have the information to + * recreate the state. This function should always be called before the new + * buffer is begun, so it's sufficient to just set lost_context here. + * + * The alternative to this would be to copy out the state on unlock + * (approximately) and if we did lose the context, dispatch a cmdbuf to reset + * the state to that old copy before continuing with the accumulated command + * buffer. + */ + rmesa->lost_context = 1; + return ret; } @@ -977,9 +990,6 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all, __FUNCTION__, all, cx, cy, cw, ch ); } - /* Need to cope with lostcontext here as kernel relies on - * some residual state: - */ RADEON_FIREVERTICES( rmesa ); if ( mask & DD_FRONT_LEFT_BIT ) { @@ -1018,6 +1028,13 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all, cx += dPriv->x; cy = dPriv->y + dPriv->h - cy - ch; + /* We have to emit state along with the clear, since the kernel relies on + * some of it. The EmitState that was above RADEON_FIREVERTICES was an + * attempt to do that, except that another context may come in and cause us + * to lose our context while we're unlocked. + */ + radeonEmitState( rmesa ); + LOCK_HARDWARE( rmesa ); /* Throttle the number of clear ioctls we do. @@ -1059,6 +1076,9 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask, GLboolean all, } } + /* Send current state to the hardware */ + radeonFlushCmdBufLocked( rmesa, __FUNCTION__ ); + for ( i = 0 ; i < dPriv->numClipRects ; ) { GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects ); drm_clip_rect_t *box = dPriv->pClipRects; diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h index e18a642088..c2e0c3706b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.h +++ b/src/mesa/drivers/dri/radeon/radeon_lock.h @@ -99,23 +99,12 @@ extern int prevLockLine; DEBUG_LOCK(); \ } while (0) -/* Unlock the hardware. We must assume that state has been lost when we unlock, - * because when we next grab the lock (to emit an accumulated cmdbuf), we don't - * have the information to recreate the context state as of the last unlock in - * in the case that we did lose the context state. - * - * The alternative to this would be to copy out the state on unlock - * (approximately) and if we did lose the context, dispatch a cmdbuf to reset - * the state to that old copy before continuing with the accumulated command - * buffer. - */ #define UNLOCK_HARDWARE( rmesa ) \ do { \ DRM_UNLOCK( rmesa->dri.fd, \ rmesa->dri.hwLock, \ rmesa->dri.hwContext ); \ DEBUG_RESET(); \ - rmesa->lost_context = GL_TRUE; \ } while (0) #endif |