summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r200/r200_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/r200/r200_state.c')
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.c79
1 files changed, 78 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index 41c7607b61..d266e78910 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -54,6 +54,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_tex.h"
#include "r200_swtcl.h"
#include "r200_vtxfmt.h"
+#include "r200_vertprog.h"
#include "drirenderbuffer.h"
@@ -2100,7 +2101,71 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state )
break;
case GL_VERTEX_PROGRAM_ARB:
- TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_VERTEX_PROGRAM, state);
+ if (!state) {
+ GLuint i;
+ R200_STATECHANGE( rmesa, vap );
+ rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_PROG_VTX_SHADER_ENABLE;
+ /* mark all tcl atoms (tcl vector state got overwritten) dirty
+ not sure about tcl scalar state - we need at least grd
+ with vert progs too.
+ ucp looks like it doesn't get overwritten (may even work
+ with vp for pos-invariant progs if we're lucky) */
+ R200_STATECHANGE( rmesa, mtl[0] );
+ R200_STATECHANGE( rmesa, mtl[1] );
+ R200_STATECHANGE( rmesa, fog );
+ R200_STATECHANGE( rmesa, glt );
+ R200_STATECHANGE( rmesa, eye );
+ for (i = R200_MTX_MV; i <= R200_MTX_TEX5; i++) {
+ R200_STATECHANGE( rmesa, mat[i] );
+ }
+ for (i = 0 ; i < 8; i++) {
+ R200_STATECHANGE( rmesa, lit[i] );
+ }
+ R200_STATECHANGE( rmesa, tcl );
+ for (i = 0; i <= ctx->Const.MaxClipPlanes; i++) {
+ if (ctx->Transform.ClipPlanesEnabled & (1 << i)) {
+ rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (R200_UCP_ENABLE_0 << i);
+ }
+/* else {
+ rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(R200_UCP_ENABLE_0 << i);
+ }*/
+ }
+ /* FIXME: ugly as hell. need to call everything which might change tcl_output_vtxfmt0/1 and compsel */
+ r200UpdateSpecular( ctx );
+ r200Fogfv( ctx, GL_FOG_COORD_SRC, NULL );
+ /* shouldn't be necessary, as it's picked up anyway in r200ValidateState (_NEW_PROGRAM),
+ but without it doom3 locks up at always the same places. Why? */
+ r200UpdateTextureState( ctx );
+ /* if we call r200UpdateTextureState we need the code below because we are calling it with
+ non-current derived enabled values which may revert the state atoms for frag progs even when
+ they already got disabled... ugh
+ Should really figure out why we need to call r200UpdateTextureState in the first place */
+ GLuint unit;
+ for (unit = 0; unit < R200_MAX_TEXTURE_UNITS; unit++) {
+ R200_STATECHANGE( rmesa, pix[unit] );
+ R200_STATECHANGE( rmesa, tex[unit] );
+ rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &=
+ ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
+ rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT;
+ /* need to guard this with drmSupportsFragmentShader? Should never get here if
+ we don't announce ATI_fs, right? */
+ rmesa->hw.tex[unit].cmd[TEX_PP_TXMULTI_CTL] = 0;
+ }
+ R200_STATECHANGE( rmesa, cst );
+ R200_STATECHANGE( rmesa, tf );
+ rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0;
+ }
+ else {
+ R200_STATECHANGE( rmesa, vap );
+ if (!rmesa->TclFallback) {
+ /* FIXME: fglrx sets R200_VAP_SINGLE_BUF_STATE_ENABLE too. Do we need it? */
+ rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] |= R200_VAP_PROG_VTX_SHADER_ENABLE /*| R200_VAP_SINGLE_BUF_STATE_ENABLE*/;
+ }
+ R200_STATECHANGE( rmesa, vpi[0] );
+ R200_STATECHANGE( rmesa, vpi[1] );
+ R200_STATECHANGE( rmesa, vpp[0] );
+ R200_STATECHANGE( rmesa, vpp[1] );
+ }
break;
case GL_FRAGMENT_SHADER_ATI:
@@ -2310,6 +2375,8 @@ void r200ValidateState( GLcontext *ctx )
r200UpdateLocalViewer( ctx );
}
+/* FIXME: don't really need most of these when vertex progs are enabled */
+
/* Need an event driven matrix update?
*/
if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
@@ -2340,6 +2407,16 @@ void r200ValidateState( GLcontext *ctx )
r200UpdateClipPlanes( ctx );
}
+ if (new_state & (_NEW_PROGRAM|
+ /* need to test for pretty much anything due to possible parameter bindings */
+ _NEW_MODELVIEW|_NEW_PROJECTION|_NEW_TRANSFORM|
+ _NEW_LIGHT|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX|
+ _NEW_FOG|_NEW_POINT|_NEW_TRACK_MATRIX)) {
+ if (ctx->VertexProgram._Enabled) {
+ r200SetupVertexProg( ctx );
+ }
+ else TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, 0);
+ }
rmesa->NewGLState = 0;
}