summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/radeon/radeon_ioctl.c
diff options
context:
space:
mode:
authorEric Anholt <anholt@FreeBSD.org>2004-09-30 00:08:05 +0000
committerEric Anholt <anholt@FreeBSD.org>2004-09-30 00:08:05 +0000
commit7a086dc05e665a78f7e9d069aa4fc70e844b8988 (patch)
treef7ef0c3e7354f494cea48f10ae86810dd442c63f /src/mesa/drivers/dri/radeon/radeon_ioctl.c
parentfa569c0a73576d3cca7cd1d0363064be099a6a22 (diff)
OK, one more time. Simplify the state-backup system by just storing the full
state in a ready-to-emit cmdbuf, which avoids the issue Nicolai Haehnle reported where the check() could return differently during backup-and-emit than it should have if it were called at the right time. Move the lit emission before most of the TCL state emission on r200, which fixes neverball issues. Tested with: r100/r200 with neverball, tuxracer, chromium, quake3, ipers
Diffstat (limited to 'src/mesa/drivers/dri/radeon/radeon_ioctl.c')
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.c74
1 files changed, 36 insertions, 38 deletions
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
index 5ef14e34bb..50d5154016 100644
--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
@@ -62,59 +62,52 @@ static void radeonWaitForIdle( radeonContextPtr rmesa );
static int radeonFlushCmdBufLocked( radeonContextPtr rmesa,
const char * caller );
-void radeonSaveHwState( radeonContextPtr rmesa )
+static void radeonSaveHwState( radeonContextPtr rmesa )
{
struct radeon_state_atom *atom;
+ char * dest = rmesa->backup_store.cmd_buf;
- foreach(atom, &rmesa->hw.atomlist)
- memcpy(atom->savedcmd, atom->cmd, atom->cmd_size * 4);
-}
-
-static void radeonSwapHwState( radeonContextPtr rmesa )
-{
- int *temp;
- struct radeon_state_atom *atom;
+ rmesa->backup_store.cmd_used = 0;
- foreach(atom, &rmesa->hw.atomlist) {
- temp = atom->cmd;
- atom->cmd = atom->savedcmd;
- atom->savedcmd = temp;
+ foreach( atom, &rmesa->hw.atomlist ) {
+ if ( atom->check( rmesa->glCtx ) ) {
+ int size = atom->cmd_size * 4;
+ memcpy( dest, atom->cmd, size);
+ dest += size;
+ rmesa->backup_store.cmd_used += size;
+ }
}
+
+ assert( rmesa->backup_store.cmd_used <= RADEON_CMD_BUF_SZ );
}
/* At this point we were in FlushCmdBufLocked but we had lost our context, so
- * we need to unwire our current cmdbuf and hook a new one in, emit that, then
- * wire the old cmdbuf back in so that FlushCmdBufLocked can continue and the
- * buffer can depend on the state not being lost across lock/unlock.
+ * we need to unwire our current cmdbuf, hook the one with the saved state in
+ * it, flush it, and then put the current one back. This is so commands at the
+ * start of a cmdbuf can rely on the state being kept from the previous one.
*/
static void radeonBackUpAndEmitLostStateLocked( radeonContextPtr rmesa )
{
- GLuint nr_released_bufs;
- struct radeon_store store;
+ GLuint nr_released_bufs, saved_cmd_used;
+ struct radeon_store saved_store;
+
+ if (rmesa->backup_store.cmd_used == 0)
+ return;
+
+ if (RADEON_DEBUG & DEBUG_STATE)
+ fprintf(stderr, "Emitting backup state on lost context\n");
rmesa->lost_context = GL_FALSE;
nr_released_bufs = rmesa->dma.nr_released_bufs;
- store = rmesa->store;
- rmesa->store.statenr = 0;
- rmesa->store.primnr = 0;
- rmesa->store.cmd_used = 0;
- rmesa->store.elts_start = 0;
- rmesa->hw.all_dirty = GL_TRUE;
- radeonSwapHwState( rmesa );
- /* In this case it's okay to EmitState while locked because we won't exhaust
- * our (empty) cmdbuf.
- */
- radeonEmitState(rmesa);
- radeonFlushCmdBufLocked(rmesa, __FUNCTION__);
-
- radeonSwapHwState(rmesa);
- /* We've just cleared out the dirty flags, so we don't remember what
- * actually needed to be emitted for the next state emit.
- */
- rmesa->hw.all_dirty = GL_TRUE;
+ saved_store = rmesa->store;
+ rmesa->dma.nr_released_bufs = 0;
+ rmesa->store = rmesa->backup_store;
+ saved_cmd_used = rmesa->backup_store.cmd_used;
+ radeonFlushCmdBufLocked( rmesa, __FUNCTION__ );
+ rmesa->backup_store.cmd_used = saved_cmd_used;
rmesa->dma.nr_released_bufs = nr_released_bufs;
- rmesa->store = store;
+ rmesa->store = saved_store;
}
/* =============================================================
@@ -176,6 +169,11 @@ void radeonEmitState( radeonContextPtr rmesa )
if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
fprintf(stderr, "%s\n", __FUNCTION__);
+ if (rmesa->save_on_next_emit) {
+ radeonSaveHwState(rmesa);
+ rmesa->save_on_next_emit = GL_FALSE;
+ }
+
if (!rmesa->hw.is_dirty && !rmesa->hw.all_dirty)
return;
@@ -582,7 +580,7 @@ static int radeonFlushCmdBufLocked( radeonContextPtr rmesa,
rmesa->store.statenr = 0;
rmesa->store.cmd_used = 0;
rmesa->dma.nr_released_bufs = 0;
- rmesa->save_on_next_unlock = 1;
+ rmesa->save_on_next_emit = 1;
return ret;
}