I'm trying to narrow down texturing issues with my Radeon Mobility 9100 IGP, which uses the r200 driver. Going through the Mesa demos, I found a couple that exhibited problems. The "ray" demo seems to show a problem that resembles what I see elsewhere. The textures on the sphere and in both of the map windows flicker badly. R200_NO_TCL=1 has no effect. It looks fine with software rendering. I'm running current git of Mesa and DRI.
I suspect there's some missing synchronization of the TexSubImage. I could try debugging the code, but do you have any hints for where to start looking?
So far, I've determined that it's probably not the glTexSubImage2D. Rather, the glDisable(GL_TEXTURE_2D) seems to have a lot to do with it. The texture state isn't emitted if texturing is disabled before a flush is provoked, or something. I'll keep looking...
Your chip doesn't support TCL to begin with hence disabling it won't do anything for you. Interestingly, ray works for me when tcl is enabled, but indeed flickers when it's disabled. The textures don't just flicker it looks like somehow the wrong texture is being used (so the sphere map texture displayed kinda toggles between being sphere map and plane map, same for the other textures). Rather strange considering it works with hw tcl... Maybe the sw tcl path somehow misses that another texture is used but I can't see how that could happen.
Well, I think I have some idea what might be going on.
With SW TCL, the vertices aren't processed before flush_last_swtcl_prim is called. It calls r200EmitVbufPrim, which calls r200EmitState. r200EmitState goes through the list of dirty states, one of which should be tex. Before putting its state into the cmd buffer, though, it calls check_tex (from r200_state_init.c: CHECK( tex, rmesa->state.texture.unit[idx].unitneeded )) to see whether it's really necessary. Since unitneeded has already been set to zero, it decides not to.
Seems to me r200UpdateAllTexEnv would clear unitneeded, and the R200_STATE_CHANGE (that calls flush_last_swtcl_prim if needed) is done afterwards, resulting in a missing texture state update prior to rendering the vertices waiting for SW-TCL processing. (I could also be wrong, though, I might have to study this stuff deeper.)
Not entirely sure how best to fix. Putting a R200_NEWPRIM(rmesa) at the top of r200UpdateAllTexEnv solves the problem, but is probably not optimal?
Your analysis looks right. I think it's not a problem for tcl because it does the dma flush anyway for each primitive.
In any case, I've pushed your suggested fix (though I've moved it up one function as it could be problematic there too). I don't think there should be any performance issue with this, since if there are _any_ state changes R200_NEWPRIM (and hence the dma flush) would be called anyway - only in case of all state being equal would it make a difference, but this probably shouldn't happen too often (it should only happen if an app sets some state, then reverting the state to the previous value without drawing anything in-between, or setting irrelevant state). The alternative would be to use some interim values, then checking those against the rmesa->state.x values to decide if the R200_NEWPRIM is needed before setting the rmesa->state.x values, but it doesn't seem worth the trouble (the state handling is probably no longer really optimally efficient anyway).
Mass version move, cvs -> git