Hi, this is referring to the a very reproducable lockup that occurred with glaxium on r100 hardware. Several months ago I tracked it down to emission of state changes and introduced a workaround that waits for 3D idle before state changes. Now I had a new idea about a possible cause of trouble: the order in which state atoms are emitted. And it appears I was right. :) I made a small hack that forces state attoms to be emitted in a fixed order and dropped the wait for 3D idle. The lockups are still gone and frame rates have increased significantly.
A patch is attached. The order in which state atoms are emitted now is pretty arbitrary. It may be worth finding out exactly which permutations of state changes trigger the lockup. In the interest of security we could detect them in the DRM driver and emit a 3D idle to prevent an engine lockup. Finding all these permutations would take a lot of time (and reboots) though and it may even be too late to prevent a lockup when such a condition is detected. But maybe someone with hardware docs has a good guess, like dependencies of different state change commands that could cause inconsistencies if certain pairs of them are emitted in the wrong order. On the other hand we may just clean up my hack and be content with it. How do people feel about this? Regards, Felix ------------ __\|/__ ___ ___ ------------------------- Felix ___\_e -_/___/ __\___/ __\_____ You can do anything, Kühling (_____\Ä/____/ /_____/ /________) just not everything [EMAIL PROTECTED] \___/ \___/ U at the same time.
--- ./radeon_context.h.~1.6.~ 2003-12-08 00:53:32.000000000 +0100 +++ ./radeon_context.h 2004-01-03 02:55:42.000000000 +0100 @@ -185,7 +185,8 @@ GLuint is_tcl; int *cmd; /* one or more cmd's */ int *lastcmd; /* one or more cmd's */ + GLboolean dirty; GLboolean (*check)( GLcontext * ); /* is this state active? */ }; --- ./radeon_ioctl.c.~1.4.~ 2003-12-26 18:51:12.000000000 +0100 +++ ./radeon_ioctl.c 2004-01-03 03:15:50.000000000 +0100 @@ -80,6 +80,7 @@ { struct radeon_state_atom *state, *tmp; char *dest; + int i; /* From Felix Kuhling: similar to some other lockups, glaxium will * lock with what we believe to be a normal command stream, but @@ -92,7 +93,7 @@ * so let's just put the wait in always (unless Felix wants to * narrow it down further...) */ - if (1) { + if (0) { drmRadeonCmdHeader *cmd; cmd = (drmRadeonCmdHeader *)radeonAllocCmdBuf( rmesa, sizeof(*cmd), __FUNCTION__ ); @@ -102,8 +103,9 @@ foreach_s( state, tmp, list ) { if (state->check( rmesa->glCtx )) { - dest = radeonAllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__); - memcpy( dest, state->cmd, state->cmd_size * 4); + /*dest = radeonAllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__); + memcpy( dest, state->cmd, state->cmd_size * 4);*/ + state->dirty = GL_TRUE; move_to_head( &(rmesa->hw.clean), state ); if (RADEON_DEBUG & DEBUG_STATE) print_state_atom( state ); @@ -111,6 +113,40 @@ else if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "skip state %s\n", state->name); } + +#define EMIT_ATOM(ATOM) \ +do { \ + if (rmesa->hw.ATOM.dirty) { \ + rmesa->hw.ATOM.dirty = GL_FALSE; \ + dest = radeonAllocCmdBuf( rmesa, rmesa->hw.ATOM.cmd_size * 4, __FUNCTION__); \ + memcpy( dest, rmesa->hw.ATOM.cmd, rmesa->hw.ATOM.cmd_size * 4); \ + } \ +} while (0) + + /* emit state in a fixed order */ + EMIT_ATOM (ctx); + EMIT_ATOM (set); + EMIT_ATOM (lin); + EMIT_ATOM (msk); + EMIT_ATOM (vpt); + EMIT_ATOM (tcl); + EMIT_ATOM (msc); + EMIT_ATOM (tex[0]); + EMIT_ATOM (tex[1]); + EMIT_ATOM (zbs); + EMIT_ATOM (mtl); + for (i = 0; i < 5; ++i) + EMIT_ATOM (mat[i]); + for (i = 0; i < 8; ++i) + EMIT_ATOM (lit[i]); + for (i = 0; i < 6; ++i) + EMIT_ATOM (ucp[i]); + EMIT_ATOM (eye); + EMIT_ATOM (grd); + EMIT_ATOM (fog); + EMIT_ATOM (glt); + EMIT_ATOM (txr[0]); + EMIT_ATOM (txr[1]); }