Based on the idea of Felix Kühling that the order in which state atoms are emitted might be important on the radeon, I thought maybe it might be important on the r200 as well, even though there are no lockups.
With the attached patch indeed the random color flashings seem to be gone (at least in specviewperf 7.1 and nwn - note that the lighting in nwn is still hosed in some areas completely, but it no longer flickers).


The emit order of the atoms in this patch is just a guess. I've just tried to figure out an order which looked somehow logical, i.e. the stuff which MIGHT need some other state applied first is submitted last, not sure if it really makes sense - but it worked on the second try (as first try I have just used the order the state atoms are defined in r200_context.h, this only changed the flickering but didn't eliminate it).

I've also disabled the isosurf workaround, this likely wouldn't do anything useful now. Though I'm not sure what exactly this did correct, isosurf looked just the same with or without that workaround here. (btw isosurf still looks wrong, in POLYGON_MODE_FILL and REFLECT the reflection has a completely wrong color pattern - it looks almost as it is reversed if you compare it with software mesa (I've just used LIBGL_ALWAYS_INDIRECT=1), though interestingly in POLYGON_MODE_LINE the reflection color pattern looks ok. But it's the same with or without this patch.)

I've no idea if the order is really important or if this just hides another problem, maybe someone with databooks could answer that.

Roland
Index: r200_cmdbuf.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_cmdbuf.c,v
retrieving revision 1.3
diff -u -r1.3 r200_cmdbuf.c
--- r200_cmdbuf.c       21 Oct 2003 06:05:46 -0000      1.3
+++ r200_cmdbuf.c       9 Jan 2004 00:13:00 -0000
@@ -63,11 +63,15 @@
 {
    struct r200_state_atom *state, *tmp;
    char *dest;
+   int i, size;
 
+   size = 0;
    foreach_s( state, tmp, list ) {
       if (state->check( rmesa->glCtx, state->idx )) {
-        dest = r200AllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__);
-        memcpy( dest, state->cmd, state->cmd_size * 4);
+/*      dest = r200AllocCmdBuf( rmesa, state->cmd_size * 4, __FUNCTION__);
+        memcpy( dest, state->cmd, state->cmd_size * 4);*/
+         size += state->cmd_size;
+         state->dirty = GL_TRUE;
         move_to_head( &(rmesa->hw.clean), state );
         if (R200_DEBUG & DEBUG_STATE) 
            print_state_atom( state );
@@ -75,6 +79,61 @@
       else if (R200_DEBUG & DEBUG_STATE)
         fprintf(stderr, "skip state %s\n", state->name);
    }
+
+   if (!size)
+      return;
+
+   dest = r200AllocCmdBuf( rmesa, size * 4, __FUNCTION__);
+
+#define EMIT_ATOM(ATOM) \
+do { \
+   if (rmesa->hw.ATOM.dirty) { \
+      rmesa->hw.ATOM.dirty = GL_FALSE; \
+      memcpy( dest, rmesa->hw.ATOM.cmd, rmesa->hw.ATOM.cmd_size * 4); \
+      dest += rmesa->hw.ATOM.cmd_size * 4; \
+   } \
+} while (0)
+
+   EMIT_ATOM (ctx);
+   EMIT_ATOM (set);
+   EMIT_ATOM (lin);
+   EMIT_ATOM (msk);
+   EMIT_ATOM (vpt);
+   EMIT_ATOM (vtx);
+   EMIT_ATOM (vap);
+   EMIT_ATOM (vte);
+   EMIT_ATOM (msc);
+   EMIT_ATOM (cst);
+   EMIT_ATOM (zbs);
+   EMIT_ATOM (tcl);
+   EMIT_ATOM (msl);
+   EMIT_ATOM (tcg);
+   EMIT_ATOM (grd);
+   EMIT_ATOM (fog);
+   EMIT_ATOM (tam);
+   EMIT_ATOM (tf);
+   for (i = 0; i < 2; ++i) {
+       EMIT_ATOM (tex[i]);
+   }
+   for (i = 0; i < 2; ++i) {
+       EMIT_ATOM (cube[i]);
+   }
+   for (i = 0; i < 5; ++i)
+       EMIT_ATOM (mat[i]);
+   EMIT_ATOM (eye);
+   EMIT_ATOM (glt);
+   for (i = 0; i < 2; ++i) {
+      EMIT_ATOM (mtl[i]);
+   }
+   for (i = 0; i < 8; ++i)
+       EMIT_ATOM (lit[i]);
+   for (i = 0; i < 6; ++i)
+       EMIT_ATOM (ucp[i]);
+   for (i = 0; i < 6; ++i)
+       EMIT_ATOM (pix[i]);
+
+#undef EMIT_ATOM
+
 }
 
 
@@ -96,10 +155,10 @@
 
       rmesa->lost_context = 0;
    }
-   else {
-      move_to_tail( &rmesa->hw.dirty, &rmesa->hw.mtl[0] ); 
+/*   else {
+      move_to_tail( &rmesa->hw.dirty, &rmesa->hw.mtl[0] );*/
       /* odd bug? -- isosurf, cycle between reflect & lit */
-   }
+/*   }*/
 
    r200_emit_state_list( rmesa, &rmesa->hw.dirty );
 }
Index: r200_context.h
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_context.h,v
retrieving revision 1.7
diff -u -r1.7 r200_context.h
--- r200_context.h      11 Dec 2003 16:25:37 -0000      1.7
+++ r200_context.h      9 Jan 2004 00:13:06 -0000
@@ -186,6 +187,7 @@
    GLuint idx;
    int *cmd;                            /* one or more cmd's */
    int *lastcmd;                        /* one or more cmd's */
+   GLboolean dirty;
    GLboolean (*check)( GLcontext *, int );    /* is this state active? */
 };
 

Reply via email to