summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/r200
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2004-09-30 00:08:05 +0000
committerEric Anholt <[email protected]>2004-09-30 00:08:05 +0000
commit7a086dc05e665a78f7e9d069aa4fc70e844b8988 (patch)
treef7ef0c3e7354f494cea48f10ae86810dd442c63f /src/mesa/drivers/dri/r200
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/r200')
-rw-r--r--src/mesa/drivers/dri/r200/r200_cmdbuf.c33
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c2
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.h9
-rw-r--r--src/mesa/drivers/dri/r200/r200_ioctl.c61
-rw-r--r--src/mesa/drivers/dri/r200/r200_ioctl.h1
-rw-r--r--src/mesa/drivers/dri/r200/r200_lock.h4
-rw-r--r--src/mesa/drivers/dri/r200/r200_state_init.c2
7 files changed, 53 insertions, 59 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c
index 384c1634ea0..5cdb3657f98 100644
--- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c
+++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c
@@ -92,18 +92,38 @@ void r200SetUpAtomList( r200ContextPtr rmesa )
insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.tex[i] );
for (i = 0; i < mtu; ++i)
insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.cube[i] );
+ for (i = 0; i < 6; ++i)
+ insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.pix[i] );
+
+ for (i = 0; i < 8; ++i)
+ insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.lit[i] );
for (i = 0; i < 3 + mtu; ++i)
insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.mat[i] );
insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.eye );
insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.glt );
for (i = 0; i < 2; ++i)
insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.mtl[i] );
- for (i = 0; i < 8; ++i)
- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.lit[i] );
for (i = 0; i < 6; ++i)
insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.ucp[i] );
- for (i = 0; i < 6; ++i)
- insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.pix[i] );
+}
+
+static void r200SaveHwState( r200ContextPtr rmesa )
+{
+ struct r200_state_atom *atom;
+ char * dest = rmesa->backup_store.cmd_buf;
+
+ rmesa->backup_store.cmd_used = 0;
+
+ foreach( atom, &rmesa->hw.atomlist ) {
+ if ( atom->check( rmesa->glCtx, atom->idx ) ) {
+ 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 <= R200_CMD_BUF_SZ );
}
void r200EmitState( r200ContextPtr rmesa )
@@ -115,6 +135,11 @@ void r200EmitState( r200ContextPtr rmesa )
if (R200_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
fprintf(stderr, "%s\n", __FUNCTION__);
+ if (rmesa->save_on_next_emit) {
+ r200SaveHwState(rmesa);
+ rmesa->save_on_next_emit = GL_FALSE;
+ }
+
if (!rmesa->hw.is_dirty && !rmesa->hw.all_dirty)
return;
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index 3b8394f794f..d5ca2f9b3a6 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -62,7 +62,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_vtxfmt.h"
#include "r200_maos.h"
-#define DRIVER_DATE "20040924"
+#define DRIVER_DATE "20040929"
#include "vblank.h"
#include "utils.h"
diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h
index 25faec955c5..140902c356b 100644
--- a/src/mesa/drivers/dri/r200/r200_context.h
+++ b/src/mesa/drivers/dri/r200/r200_context.h
@@ -191,7 +191,6 @@ struct r200_state_atom {
GLuint idx;
int *cmd; /* one or more cmd's */
int *lastcmd; /* one or more cmd's */
- int *savedcmd; /* one or more cmd's */
GLboolean dirty;
GLboolean (*check)( GLcontext *, int ); /* is this state active? */
};
@@ -825,8 +824,6 @@ struct r200_vbinfo {
};
-
-
struct r200_context {
GLcontext *glCtx; /* Mesa context */
@@ -854,6 +851,10 @@ struct r200_context {
struct r200_ioctl ioctl;
struct r200_dma dma;
struct r200_store store;
+ /* A full state emit as of the first state emit in the main store, in case
+ * the context is lost.
+ */
+ struct r200_store backup_store;
/* Page flipping
*/
@@ -876,7 +877,7 @@ struct r200_context {
drm_clip_rect_t *pClipRects;
unsigned int lastStamp;
GLboolean lost_context;
- GLboolean save_on_next_unlock;
+ GLboolean save_on_next_emit;
r200ScreenPtr r200Screen; /* Screen private DRI data */
drm_radeon_sarea_t *sarea; /* Private SAREA data */
diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c
index 74dd7d38eb9..d2fde39a1cd 100644
--- a/src/mesa/drivers/dri/r200/r200_ioctl.c
+++ b/src/mesa/drivers/dri/r200/r200_ioctl.c
@@ -58,59 +58,34 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
static void r200WaitForIdle( r200ContextPtr rmesa );
-void r200SaveHwState( r200ContextPtr rmesa )
-{
- struct r200_state_atom *atom;
-
- foreach( atom, &rmesa->hw.atomlist )
- memcpy(atom->savedcmd, atom->cmd, atom->cmd_size * 4);
-}
-
-static void r200SwapHwState( r200ContextPtr rmesa )
-{
- int *temp;
- struct r200_state_atom *atom;
-
- foreach( atom, &rmesa->hw.atomlist ) {
- temp = atom->cmd;
- atom->cmd = atom->savedcmd;
- atom->savedcmd = temp;
- }
-}
/* 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 r200BackUpAndEmitLostStateLocked( r200ContextPtr rmesa )
{
- GLuint nr_released_bufs;
- struct r200_store store;
+ GLuint nr_released_bufs, saved_cmd_used;
+ struct r200_store saved_store;
+
+ if (rmesa->backup_store.cmd_used == 0)
+ return;
+
+ if (R200_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;
- r200SwapHwState( rmesa );
- /* In this case it's okay to EmitState while locked because we won't exhaust
- * our (empty) cmdbuf.
- */
- r200EmitState( rmesa );
+ saved_store = rmesa->store;
+ rmesa->dma.nr_released_bufs = 0;
+ rmesa->store = rmesa->backup_store;
+ saved_cmd_used = rmesa->backup_store.cmd_used;
r200FlushCmdBufLocked( rmesa, __FUNCTION__ );
-
- r200SwapHwState( 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;
+ rmesa->backup_store.cmd_used = saved_cmd_used;
rmesa->dma.nr_released_bufs = nr_released_bufs;
- rmesa->store = store;
+ rmesa->store = saved_store;
}
int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller )
@@ -189,7 +164,7 @@ int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller )
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;
}
diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.h b/src/mesa/drivers/dri/r200/r200_ioctl.h
index 57474d7a052..939dab36853 100644
--- a/src/mesa/drivers/dri/r200/r200_ioctl.h
+++ b/src/mesa/drivers/dri/r200/r200_ioctl.h
@@ -117,7 +117,6 @@ extern GLboolean r200IsGartMemory( r200ContextPtr rmesa, const GLvoid *pointer,
extern GLuint r200GartOffsetFromVirtual( r200ContextPtr rmesa,
const GLvoid *pointer );
-void r200SaveHwState( r200ContextPtr rmesa );
void r200SetUpAtomList( r200ContextPtr rmesa );
/* ================================================================
diff --git a/src/mesa/drivers/dri/r200/r200_lock.h b/src/mesa/drivers/dri/r200/r200_lock.h
index 908052659c1..587e4fe5ccd 100644
--- a/src/mesa/drivers/dri/r200/r200_lock.h
+++ b/src/mesa/drivers/dri/r200/r200_lock.h
@@ -104,10 +104,6 @@ extern int prevLockLine;
rmesa->dri.hwLock, \
rmesa->dri.hwContext ); \
DEBUG_RESET(); \
- if (rmesa->save_on_next_unlock) { \
- r200SaveHwState( rmesa ); \
- rmesa->save_on_next_unlock = GL_FALSE; \
- } \
} while (0)
#endif
diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c
index e97a2f4d995..049820b3cb7 100644
--- a/src/mesa/drivers/dri/r200/r200_state_init.c
+++ b/src/mesa/drivers/dri/r200/r200_state_init.c
@@ -208,7 +208,6 @@ void r200InitState( r200ContextPtr rmesa )
rmesa->hw.ATOM.cmd_size = SZ; \
rmesa->hw.ATOM.cmd = (int *)CALLOC(SZ * sizeof(int)); \
rmesa->hw.ATOM.lastcmd = (int *)CALLOC(SZ * sizeof(int)); \
- rmesa->hw.ATOM.savedcmd = (int *)CALLOC(SZ * sizeof(int)); \
rmesa->hw.ATOM.name = NM; \
rmesa->hw.ATOM.idx = IDX; \
rmesa->hw.ATOM.check = check_##CHK; \
@@ -770,6 +769,5 @@ void r200InitState( r200ContextPtr rmesa )
r200LightingSpaceChange( ctx );
- r200SaveHwState( rmesa );
rmesa->hw.all_dirty = GL_TRUE;
}