Home | History | Annotate | Download | only in r200
      1 /**************************************************************************
      2 
      3 Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
      4 
      5 The Weather Channel (TM) funded Tungsten Graphics to develop the
      6 initial release of the Radeon 8500 driver under the XFree86 license.
      7 This notice must be preserved.
      8 
      9 Permission is hereby granted, free of charge, to any person obtaining
     10 a copy of this software and associated documentation files (the
     11 "Software"), to deal in the Software without restriction, including
     12 without limitation the rights to use, copy, modify, merge, publish,
     13 distribute, sublicense, and/or sell copies of the Software, and to
     14 permit persons to whom the Software is furnished to do so, subject to
     15 the following conditions:
     16 
     17 The above copyright notice and this permission notice (including the
     18 next paragraph) shall be included in all copies or substantial
     19 portions of the Software.
     20 
     21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     22 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     24 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     25 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     26 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     27 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     28 
     29 **************************************************************************/
     30 
     31 /*
     32  * Authors:
     33  *   Keith Whitwell <keith (at) tungstengraphics.com>
     34  */
     35 
     36 #include "main/glheader.h"
     37 #include "main/imports.h"
     38 #include "main/api_arrayelt.h"
     39 #include "main/enums.h"
     40 #include "main/colormac.h"
     41 #include "main/light.h"
     42 #include "main/framebuffer.h"
     43 #include "main/fbobject.h"
     44 
     45 #include "swrast/swrast.h"
     46 #include "vbo/vbo.h"
     47 #include "tnl/tnl.h"
     48 #include "tnl/t_pipeline.h"
     49 #include "swrast_setup/swrast_setup.h"
     50 #include "drivers/common/meta.h"
     51 
     52 #include "radeon_common.h"
     53 #include "radeon_mipmap_tree.h"
     54 #include "r200_context.h"
     55 #include "r200_ioctl.h"
     56 #include "r200_state.h"
     57 #include "r200_tcl.h"
     58 #include "r200_tex.h"
     59 #include "r200_swtcl.h"
     60 #include "r200_vertprog.h"
     61 
     62 
     63 /* =============================================================
     64  * Alpha blending
     65  */
     66 
     67 static void r200AlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref )
     68 {
     69    r200ContextPtr rmesa = R200_CONTEXT(ctx);
     70    int pp_misc = rmesa->hw.ctx.cmd[CTX_PP_MISC];
     71    GLubyte refByte;
     72 
     73    CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
     74 
     75    R200_STATECHANGE( rmesa, ctx );
     76 
     77    pp_misc &= ~(R200_ALPHA_TEST_OP_MASK | R200_REF_ALPHA_MASK);
     78    pp_misc |= (refByte & R200_REF_ALPHA_MASK);
     79 
     80    switch ( func ) {
     81    case GL_NEVER:
     82       pp_misc |= R200_ALPHA_TEST_FAIL;
     83       break;
     84    case GL_LESS:
     85       pp_misc |= R200_ALPHA_TEST_LESS;
     86       break;
     87    case GL_EQUAL:
     88       pp_misc |= R200_ALPHA_TEST_EQUAL;
     89       break;
     90    case GL_LEQUAL:
     91       pp_misc |= R200_ALPHA_TEST_LEQUAL;
     92       break;
     93    case GL_GREATER:
     94       pp_misc |= R200_ALPHA_TEST_GREATER;
     95       break;
     96    case GL_NOTEQUAL:
     97       pp_misc |= R200_ALPHA_TEST_NEQUAL;
     98       break;
     99    case GL_GEQUAL:
    100       pp_misc |= R200_ALPHA_TEST_GEQUAL;
    101       break;
    102    case GL_ALWAYS:
    103       pp_misc |= R200_ALPHA_TEST_PASS;
    104       break;
    105    }
    106 
    107    rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
    108 }
    109 
    110 static void r200BlendColor( struct gl_context *ctx, const GLfloat cf[4] )
    111 {
    112    GLubyte color[4];
    113    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    114    R200_STATECHANGE( rmesa, ctx );
    115    CLAMPED_FLOAT_TO_UBYTE(color[0], cf[0]);
    116    CLAMPED_FLOAT_TO_UBYTE(color[1], cf[1]);
    117    CLAMPED_FLOAT_TO_UBYTE(color[2], cf[2]);
    118    CLAMPED_FLOAT_TO_UBYTE(color[3], cf[3]);
    119    rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] = radeonPackColor( 4, color[0], color[1], color[2], color[3] );
    120 }
    121 
    122 /**
    123  * Calculate the hardware blend factor setting.  This same function is used
    124  * for source and destination of both alpha and RGB.
    125  *
    126  * \returns
    127  * The hardware register value for the specified blend factor.  This value
    128  * will need to be shifted into the correct position for either source or
    129  * destination factor.
    130  *
    131  * \todo
    132  * Since the two cases where source and destination are handled differently
    133  * are essentially error cases, they should never happen.  Determine if these
    134  * cases can be removed.
    135  */
    136 static int blend_factor( GLenum factor, GLboolean is_src )
    137 {
    138    int func;
    139 
    140    switch ( factor ) {
    141    case GL_ZERO:
    142       func = R200_BLEND_GL_ZERO;
    143       break;
    144    case GL_ONE:
    145       func = R200_BLEND_GL_ONE;
    146       break;
    147    case GL_DST_COLOR:
    148       func = R200_BLEND_GL_DST_COLOR;
    149       break;
    150    case GL_ONE_MINUS_DST_COLOR:
    151       func = R200_BLEND_GL_ONE_MINUS_DST_COLOR;
    152       break;
    153    case GL_SRC_COLOR:
    154       func = R200_BLEND_GL_SRC_COLOR;
    155       break;
    156    case GL_ONE_MINUS_SRC_COLOR:
    157       func = R200_BLEND_GL_ONE_MINUS_SRC_COLOR;
    158       break;
    159    case GL_SRC_ALPHA:
    160       func = R200_BLEND_GL_SRC_ALPHA;
    161       break;
    162    case GL_ONE_MINUS_SRC_ALPHA:
    163       func = R200_BLEND_GL_ONE_MINUS_SRC_ALPHA;
    164       break;
    165    case GL_DST_ALPHA:
    166       func = R200_BLEND_GL_DST_ALPHA;
    167       break;
    168    case GL_ONE_MINUS_DST_ALPHA:
    169       func = R200_BLEND_GL_ONE_MINUS_DST_ALPHA;
    170       break;
    171    case GL_SRC_ALPHA_SATURATE:
    172       func = (is_src) ? R200_BLEND_GL_SRC_ALPHA_SATURATE : R200_BLEND_GL_ZERO;
    173       break;
    174    case GL_CONSTANT_COLOR:
    175       func = R200_BLEND_GL_CONST_COLOR;
    176       break;
    177    case GL_ONE_MINUS_CONSTANT_COLOR:
    178       func = R200_BLEND_GL_ONE_MINUS_CONST_COLOR;
    179       break;
    180    case GL_CONSTANT_ALPHA:
    181       func = R200_BLEND_GL_CONST_ALPHA;
    182       break;
    183    case GL_ONE_MINUS_CONSTANT_ALPHA:
    184       func = R200_BLEND_GL_ONE_MINUS_CONST_ALPHA;
    185       break;
    186    default:
    187       func = (is_src) ? R200_BLEND_GL_ONE : R200_BLEND_GL_ZERO;
    188    }
    189    return func;
    190 }
    191 
    192 /**
    193  * Sets both the blend equation and the blend function.
    194  * This is done in a single
    195  * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
    196  * change the interpretation of the blend function.
    197  * Also, make sure that blend function and blend equation are set to their default
    198  * value if color blending is not enabled, since at least blend equations GL_MIN
    199  * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for
    200  * unknown reasons.
    201  */
    202 static void r200_set_blend_state( struct gl_context * ctx )
    203 {
    204    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    205    GLuint cntl = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &
    206       ~(R200_ROP_ENABLE | R200_ALPHA_BLEND_ENABLE | R200_SEPARATE_ALPHA_ENABLE);
    207 
    208    int func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
    209       (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
    210    int eqn = R200_COMB_FCN_ADD_CLAMP;
    211    int funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
    212       (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
    213    int eqnA = R200_COMB_FCN_ADD_CLAMP;
    214 
    215    R200_STATECHANGE( rmesa, ctx );
    216 
    217    if (ctx->Color.ColorLogicOpEnabled) {
    218       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =  cntl | R200_ROP_ENABLE;
    219       rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqn | func;
    220       rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
    221       return;
    222    } else if (ctx->Color.BlendEnabled) {
    223       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =  cntl | R200_ALPHA_BLEND_ENABLE | R200_SEPARATE_ALPHA_ENABLE;
    224    }
    225    else {
    226       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
    227       rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqn | func;
    228       rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
    229       return;
    230    }
    231 
    232    func = (blend_factor( ctx->Color.Blend[0].SrcRGB, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
    233       (blend_factor( ctx->Color.Blend[0].DstRGB, GL_FALSE ) << R200_DST_BLEND_SHIFT);
    234 
    235    switch(ctx->Color.Blend[0].EquationRGB) {
    236    case GL_FUNC_ADD:
    237       eqn = R200_COMB_FCN_ADD_CLAMP;
    238       break;
    239 
    240    case GL_FUNC_SUBTRACT:
    241       eqn = R200_COMB_FCN_SUB_CLAMP;
    242       break;
    243 
    244    case GL_FUNC_REVERSE_SUBTRACT:
    245       eqn = R200_COMB_FCN_RSUB_CLAMP;
    246       break;
    247 
    248    case GL_MIN:
    249       eqn = R200_COMB_FCN_MIN;
    250       func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
    251          (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
    252       break;
    253 
    254    case GL_MAX:
    255       eqn = R200_COMB_FCN_MAX;
    256       func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
    257          (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
    258       break;
    259 
    260    default:
    261       fprintf( stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
    262          __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationRGB );
    263       return;
    264    }
    265 
    266    funcA = (blend_factor( ctx->Color.Blend[0].SrcA, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
    267       (blend_factor( ctx->Color.Blend[0].DstA, GL_FALSE ) << R200_DST_BLEND_SHIFT);
    268 
    269    switch(ctx->Color.Blend[0].EquationA) {
    270    case GL_FUNC_ADD:
    271       eqnA = R200_COMB_FCN_ADD_CLAMP;
    272       break;
    273 
    274    case GL_FUNC_SUBTRACT:
    275       eqnA = R200_COMB_FCN_SUB_CLAMP;
    276       break;
    277 
    278    case GL_FUNC_REVERSE_SUBTRACT:
    279       eqnA = R200_COMB_FCN_RSUB_CLAMP;
    280       break;
    281 
    282    case GL_MIN:
    283       eqnA = R200_COMB_FCN_MIN;
    284       funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
    285          (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
    286       break;
    287 
    288    case GL_MAX:
    289       eqnA = R200_COMB_FCN_MAX;
    290       funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
    291          (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
    292       break;
    293 
    294    default:
    295       fprintf( stderr, "[%s:%u] Invalid A blend equation (0x%04x).\n",
    296          __FUNCTION__, __LINE__, ctx->Color.Blend[0].EquationA );
    297       return;
    298    }
    299 
    300    rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqnA | funcA;
    301    rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
    302 
    303 }
    304 
    305 static void r200BlendEquationSeparate( struct gl_context *ctx,
    306 				       GLenum modeRGB, GLenum modeA )
    307 {
    308       r200_set_blend_state( ctx );
    309 }
    310 
    311 static void r200BlendFuncSeparate( struct gl_context *ctx,
    312 				     GLenum sfactorRGB, GLenum dfactorRGB,
    313 				     GLenum sfactorA, GLenum dfactorA )
    314 {
    315       r200_set_blend_state( ctx );
    316 }
    317 
    318 
    319 /* =============================================================
    320  * Depth testing
    321  */
    322 
    323 static void r200DepthFunc( struct gl_context *ctx, GLenum func )
    324 {
    325    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    326 
    327    R200_STATECHANGE( rmesa, ctx );
    328    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_Z_TEST_MASK;
    329 
    330    switch ( ctx->Depth.Func ) {
    331    case GL_NEVER:
    332       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_NEVER;
    333       break;
    334    case GL_LESS:
    335       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_LESS;
    336       break;
    337    case GL_EQUAL:
    338       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_EQUAL;
    339       break;
    340    case GL_LEQUAL:
    341       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_LEQUAL;
    342       break;
    343    case GL_GREATER:
    344       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_GREATER;
    345       break;
    346    case GL_NOTEQUAL:
    347       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_NEQUAL;
    348       break;
    349    case GL_GEQUAL:
    350       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_GEQUAL;
    351       break;
    352    case GL_ALWAYS:
    353       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_ALWAYS;
    354       break;
    355    }
    356 }
    357 
    358 static void r200DepthMask( struct gl_context *ctx, GLboolean flag )
    359 {
    360    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    361    R200_STATECHANGE( rmesa, ctx );
    362 
    363    if ( ctx->Depth.Mask ) {
    364       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |=  R200_Z_WRITE_ENABLE;
    365    } else {
    366       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_Z_WRITE_ENABLE;
    367    }
    368 }
    369 
    370 
    371 /* =============================================================
    372  * Fog
    373  */
    374 
    375 
    376 static void r200Fogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param )
    377 {
    378    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    379    union { int i; float f; } c, d;
    380    GLubyte col[4];
    381    GLuint i;
    382 
    383    c.i = rmesa->hw.fog.cmd[FOG_C];
    384    d.i = rmesa->hw.fog.cmd[FOG_D];
    385 
    386    switch (pname) {
    387    case GL_FOG_MODE:
    388       if (!ctx->Fog.Enabled)
    389 	 return;
    390       R200_STATECHANGE(rmesa, tcl);
    391       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_TCL_FOG_MASK;
    392       switch (ctx->Fog.Mode) {
    393       case GL_LINEAR:
    394 	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_LINEAR;
    395 	 if (ctx->Fog.Start == ctx->Fog.End) {
    396 	    c.f = 1.0F;
    397 	    d.f = 1.0F;
    398 	 }
    399 	 else {
    400 	    c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
    401 	    d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
    402 	 }
    403 	 break;
    404       case GL_EXP:
    405 	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_EXP;
    406 	 c.f = 0.0;
    407 	 d.f = -ctx->Fog.Density;
    408 	 break;
    409       case GL_EXP2:
    410 	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_EXP2;
    411 	 c.f = 0.0;
    412 	 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
    413 	 break;
    414       default:
    415 	 return;
    416       }
    417       break;
    418    case GL_FOG_DENSITY:
    419       switch (ctx->Fog.Mode) {
    420       case GL_EXP:
    421 	 c.f = 0.0;
    422 	 d.f = -ctx->Fog.Density;
    423 	 break;
    424       case GL_EXP2:
    425 	 c.f = 0.0;
    426 	 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
    427 	 break;
    428       default:
    429 	 break;
    430       }
    431       break;
    432    case GL_FOG_START:
    433    case GL_FOG_END:
    434       if (ctx->Fog.Mode == GL_LINEAR) {
    435 	 if (ctx->Fog.Start == ctx->Fog.End) {
    436 	    c.f = 1.0F;
    437 	    d.f = 1.0F;
    438 	 } else {
    439 	    c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
    440 	    d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
    441 	 }
    442       }
    443       break;
    444    case GL_FOG_COLOR:
    445       R200_STATECHANGE( rmesa, ctx );
    446       _mesa_unclamped_float_rgba_to_ubyte(col, ctx->Fog.Color );
    447       i = radeonPackColor( 4, col[0], col[1], col[2], 0 );
    448       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_COLOR_MASK;
    449       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= i;
    450       break;
    451    case GL_FOG_COORD_SRC: {
    452       GLuint out_0 = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0];
    453       GLuint fog   = rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR];
    454 
    455       fog &= ~R200_FOG_USE_MASK;
    456       if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD || ctx->VertexProgram.Enabled) {
    457 	 fog   |= R200_FOG_USE_VTX_FOG;
    458 	 out_0 |= R200_VTX_DISCRETE_FOG;
    459       }
    460       else {
    461 	 fog   |=  R200_FOG_USE_SPEC_ALPHA;
    462 	 out_0 &= ~R200_VTX_DISCRETE_FOG;
    463       }
    464 
    465       if ( fog != rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] ) {
    466 	 R200_STATECHANGE( rmesa, ctx );
    467 	 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = fog;
    468       }
    469 
    470       if (out_0 != rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0]) {
    471 	 R200_STATECHANGE( rmesa, vtx );
    472 	 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] = out_0;
    473       }
    474 
    475       break;
    476    }
    477    default:
    478       return;
    479    }
    480 
    481    if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
    482       R200_STATECHANGE( rmesa, fog );
    483       rmesa->hw.fog.cmd[FOG_C] = c.i;
    484       rmesa->hw.fog.cmd[FOG_D] = d.i;
    485    }
    486 }
    487 
    488 /* =============================================================
    489  * Culling
    490  */
    491 
    492 static void r200CullFace( struct gl_context *ctx, GLenum unused )
    493 {
    494    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    495    GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
    496    GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL];
    497 
    498    s |= R200_FFACE_SOLID | R200_BFACE_SOLID;
    499    t &= ~(R200_CULL_FRONT | R200_CULL_BACK);
    500 
    501    if ( ctx->Polygon.CullFlag ) {
    502       switch ( ctx->Polygon.CullFaceMode ) {
    503       case GL_FRONT:
    504 	 s &= ~R200_FFACE_SOLID;
    505 	 t |= R200_CULL_FRONT;
    506 	 break;
    507       case GL_BACK:
    508 	 s &= ~R200_BFACE_SOLID;
    509 	 t |= R200_CULL_BACK;
    510 	 break;
    511       case GL_FRONT_AND_BACK:
    512 	 s &= ~(R200_FFACE_SOLID | R200_BFACE_SOLID);
    513 	 t |= (R200_CULL_FRONT | R200_CULL_BACK);
    514 	 break;
    515       }
    516    }
    517 
    518    if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
    519       R200_STATECHANGE(rmesa, set );
    520       rmesa->hw.set.cmd[SET_SE_CNTL] = s;
    521    }
    522 
    523    if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) {
    524       R200_STATECHANGE(rmesa, tcl );
    525       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t;
    526    }
    527 }
    528 
    529 static void r200FrontFace( struct gl_context *ctx, GLenum mode )
    530 {
    531    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    532    int cull_face = (mode == GL_CW) ? R200_FFACE_CULL_CW : R200_FFACE_CULL_CCW;
    533 
    534    R200_STATECHANGE( rmesa, set );
    535    rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_FFACE_CULL_DIR_MASK;
    536 
    537    R200_STATECHANGE( rmesa, tcl );
    538    rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_CULL_FRONT_IS_CCW;
    539 
    540    /* Winding is inverted when rendering to FBO */
    541    if (ctx->DrawBuffer && _mesa_is_user_fbo(ctx->DrawBuffer))
    542       cull_face = (mode == GL_CCW) ? R200_FFACE_CULL_CW : R200_FFACE_CULL_CCW;
    543    rmesa->hw.set.cmd[SET_SE_CNTL] |= cull_face;
    544 
    545    if ( mode == GL_CCW )
    546       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_CULL_FRONT_IS_CCW;
    547 }
    548 
    549 /* =============================================================
    550  * Point state
    551  */
    552 static void r200PointSize( struct gl_context *ctx, GLfloat size )
    553 {
    554    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    555    GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
    556 
    557    radeon_print(RADEON_STATE, RADEON_TRACE,
    558        "%s(%p) size: %f, fixed point result: %d.%d (%d/16)\n",
    559        __func__, ctx, size,
    560        ((GLuint)(ctx->Point.Size * 16.0))/16,
    561        (((GLuint)(ctx->Point.Size * 16.0))&15)*100/16,
    562        ((GLuint)(ctx->Point.Size * 16.0))&15);
    563 
    564    R200_STATECHANGE( rmesa, cst );
    565    R200_STATECHANGE( rmesa, ptp );
    566    rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= ~0xffff;
    567    rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= ((GLuint)(ctx->Point.Size * 16.0));
    568 /* this is the size param of the point size calculation (point size reg value
    569    is not used when calculation is active). */
    570    fcmd[PTP_VPORT_SCALE_PTSIZE] = ctx->Point.Size;
    571 }
    572 
    573 static void r200PointParameter( struct gl_context *ctx, GLenum pname, const GLfloat *params)
    574 {
    575    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    576    GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
    577 
    578    switch (pname) {
    579    case GL_POINT_SIZE_MIN:
    580    /* Can clamp both in tcl and setup - just set both (as does fglrx) */
    581       R200_STATECHANGE( rmesa, lin );
    582       R200_STATECHANGE( rmesa, ptp );
    583       rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= 0xffff;
    584       rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)(ctx->Point.MinSize * 16.0) << 16;
    585       fcmd[PTP_CLAMP_MIN] = ctx->Point.MinSize;
    586       break;
    587    case GL_POINT_SIZE_MAX:
    588       R200_STATECHANGE( rmesa, cst );
    589       R200_STATECHANGE( rmesa, ptp );
    590       rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= 0xffff;
    591       rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= (GLuint)(ctx->Point.MaxSize * 16.0) << 16;
    592       fcmd[PTP_CLAMP_MAX] = ctx->Point.MaxSize;
    593       break;
    594    case GL_POINT_DISTANCE_ATTENUATION:
    595       R200_STATECHANGE( rmesa, vtx );
    596       R200_STATECHANGE( rmesa, spr );
    597       R200_STATECHANGE( rmesa, ptp );
    598       GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
    599       rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &=
    600 	 ~(R200_PS_MULT_MASK | R200_PS_LIN_ATT_ZERO | R200_PS_SE_SEL_STATE);
    601       /* can't rely on ctx->Point._Attenuated here and test for NEW_POINT in
    602 	 r200ValidateState looks like overkill */
    603       if (ctx->Point.Params[0] != 1.0 ||
    604 	  ctx->Point.Params[1] != 0.0 ||
    605 	  ctx->Point.Params[2] != 0.0 ||
    606 	  (ctx->VertexProgram.Enabled && ctx->VertexProgram.PointSizeEnabled)) {
    607 	 /* all we care for vp would be the ps_se_sel_state setting */
    608 	 fcmd[PTP_ATT_CONST_QUAD] = ctx->Point.Params[2];
    609 	 fcmd[PTP_ATT_CONST_LIN] = ctx->Point.Params[1];
    610 	 fcmd[PTP_ATT_CONST_CON] = ctx->Point.Params[0];
    611 	 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_MULT_ATTENCONST;
    612 	 if (ctx->Point.Params[1] == 0.0)
    613 	    rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_LIN_ATT_ZERO;
    614 /* FIXME: setting this here doesn't look quite ok - we only want to do
    615           that if we're actually drawing points probably */
    616 	 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_PT_SIZE;
    617 	 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= R200_VTX_POINT_SIZE;
    618       }
    619       else {
    620 	 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |=
    621 	    R200_PS_SE_SEL_STATE | R200_PS_MULT_CONST;
    622 	 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_PT_SIZE;
    623 	 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~R200_VTX_POINT_SIZE;
    624       }
    625       break;
    626    case GL_POINT_FADE_THRESHOLD_SIZE:
    627       /* don't support multisampling, so doesn't matter. */
    628       break;
    629    /* can't do these but don't need them.
    630    case GL_POINT_SPRITE_R_MODE_NV:
    631    case GL_POINT_SPRITE_COORD_ORIGIN: */
    632    default:
    633       fprintf(stderr, "bad pname parameter in r200PointParameter\n");
    634       return;
    635    }
    636 }
    637 
    638 /* =============================================================
    639  * Line state
    640  */
    641 static void r200LineWidth( struct gl_context *ctx, GLfloat widthf )
    642 {
    643    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    644 
    645    R200_STATECHANGE( rmesa, lin );
    646    R200_STATECHANGE( rmesa, set );
    647 
    648    /* Line width is stored in U6.4 format.
    649     * Same min/max limits for AA, non-AA lines.
    650     */
    651    rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= ~0xffff;
    652    rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)
    653       (CLAMP(widthf, ctx->Const.MinLineWidth, ctx->Const.MaxLineWidth) * 16.0);
    654 
    655    if ( widthf > 1.0 ) {
    656       rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_WIDELINE_ENABLE;
    657    } else {
    658       rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_WIDELINE_ENABLE;
    659    }
    660 }
    661 
    662 static void r200LineStipple( struct gl_context *ctx, GLint factor, GLushort pattern )
    663 {
    664    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    665 
    666    R200_STATECHANGE( rmesa, lin );
    667    rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
    668       ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
    669 }
    670 
    671 
    672 /* =============================================================
    673  * Masks
    674  */
    675 static void r200ColorMask( struct gl_context *ctx,
    676 			   GLboolean r, GLboolean g,
    677 			   GLboolean b, GLboolean a )
    678 {
    679    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    680    GLuint mask;
    681    struct radeon_renderbuffer *rrb;
    682    GLuint flag = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] & ~R200_PLANE_MASK_ENABLE;
    683 
    684    rrb = radeon_get_colorbuffer(&rmesa->radeon);
    685    if (!rrb)
    686      return;
    687    mask = radeonPackColor( rrb->cpp,
    688 			   ctx->Color.ColorMask[0][RCOMP],
    689 			   ctx->Color.ColorMask[0][GCOMP],
    690 			   ctx->Color.ColorMask[0][BCOMP],
    691 			   ctx->Color.ColorMask[0][ACOMP] );
    692 
    693 
    694    if (!(r && g && b && a))
    695       flag |= R200_PLANE_MASK_ENABLE;
    696 
    697    if ( rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] != flag ) {
    698       R200_STATECHANGE( rmesa, ctx );
    699       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = flag;
    700    }
    701 
    702    if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
    703       R200_STATECHANGE( rmesa, msk );
    704       rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;
    705    }
    706 }
    707 
    708 
    709 /* =============================================================
    710  * Polygon state
    711  */
    712 
    713 static void r200PolygonOffset( struct gl_context *ctx,
    714 			       GLfloat factor, GLfloat units )
    715 {
    716    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    717    const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
    718    float_ui32_type constant =  { units * depthScale };
    719    float_ui32_type factoru = { factor };
    720 
    721 /*    factor *= 2; */
    722 /*    constant *= 2; */
    723 
    724 /*    fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
    725 
    726    R200_STATECHANGE( rmesa, zbs );
    727    rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR]   = factoru.ui32;
    728    rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
    729 }
    730 
    731 static void r200PolygonMode( struct gl_context *ctx, GLenum face, GLenum mode )
    732 {
    733    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    734    GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0;
    735 
    736    /* Can't generally do unfilled via tcl, but some good special
    737     * cases work.
    738     */
    739    TCL_FALLBACK( ctx, R200_TCL_FALLBACK_UNFILLED, flag);
    740    if (rmesa->radeon.TclFallback) {
    741       r200ChooseRenderState( ctx );
    742       r200ChooseVertexState( ctx );
    743    }
    744 }
    745 
    746 
    747 /* =============================================================
    748  * Rendering attributes
    749  *
    750  * We really don't want to recalculate all this every time we bind a
    751  * texture.  These things shouldn't change all that often, so it makes
    752  * sense to break them out of the core texture state update routines.
    753  */
    754 
    755 /* Examine lighting and texture state to determine if separate specular
    756  * should be enabled.
    757  */
    758 static void r200UpdateSpecular( struct gl_context *ctx )
    759 {
    760    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    761    uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
    762 
    763    R200_STATECHANGE( rmesa, tcl );
    764    R200_STATECHANGE( rmesa, vtx );
    765 
    766    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_0_SHIFT);
    767    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_1_SHIFT);
    768    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_0;
    769    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_1;
    770    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LIGHTING_ENABLE;
    771 
    772    p &= ~R200_SPECULAR_ENABLE;
    773 
    774    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_DIFFUSE_SPECULAR_COMBINE;
    775 
    776 
    777    if (ctx->Light.Enabled &&
    778        ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
    779       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
    780 	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) |
    781 	  (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
    782       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0;
    783       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1;
    784       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE;
    785       p |=  R200_SPECULAR_ENABLE;
    786       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &=
    787 	 ~R200_DIFFUSE_SPECULAR_COMBINE;
    788    }
    789    else if (ctx->Light.Enabled) {
    790       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
    791 	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT));
    792       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0;
    793       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE;
    794    } else if (ctx->Fog.ColorSumEnabled ) {
    795       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
    796 	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) |
    797 	  (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
    798       p |=  R200_SPECULAR_ENABLE;
    799    } else {
    800       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
    801 	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT));
    802    }
    803 
    804    if (ctx->Fog.Enabled) {
    805       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
    806 	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
    807       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1;
    808    }
    809 
    810    if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
    811       R200_STATECHANGE( rmesa, ctx );
    812       rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
    813    }
    814 
    815    /* Update vertex/render formats
    816     */
    817    if (rmesa->radeon.TclFallback) {
    818       r200ChooseRenderState( ctx );
    819       r200ChooseVertexState( ctx );
    820    }
    821 }
    822 
    823 
    824 /* =============================================================
    825  * Materials
    826  */
    827 
    828 
    829 /* Update on colormaterial, material emmissive/ambient,
    830  * lightmodel.globalambient
    831  */
    832 static void update_global_ambient( struct gl_context *ctx )
    833 {
    834    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    835    float *fcmd = (float *)R200_DB_STATE( glt );
    836 
    837    /* Need to do more if both emmissive & ambient are PREMULT:
    838     * I believe this is not nessary when using source_material. This condition thus
    839     * will never happen currently, and the function has no dependencies on materials now
    840     */
    841    if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] &
    842        ((3 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
    843 	(3 << R200_FRONT_AMBIENT_SOURCE_SHIFT))) == 0)
    844    {
    845       COPY_3V( &fcmd[GLT_RED],
    846 	       ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
    847       ACC_SCALE_3V( &fcmd[GLT_RED],
    848 		   ctx->Light.Model.Ambient,
    849 		   ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
    850    }
    851    else
    852    {
    853       COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
    854    }
    855 
    856    R200_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
    857 }
    858 
    859 /* Update on change to
    860  *    - light[p].colors
    861  *    - light[p].enabled
    862  */
    863 static void update_light_colors( struct gl_context *ctx, GLuint p )
    864 {
    865    struct gl_light *l = &ctx->Light.Light[p];
    866 
    867 /*     fprintf(stderr, "%s\n", __FUNCTION__); */
    868 
    869    if (l->Enabled) {
    870       r200ContextPtr rmesa = R200_CONTEXT(ctx);
    871       float *fcmd = (float *)R200_DB_STATE( lit[p] );
    872 
    873       COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
    874       COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
    875       COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
    876 
    877       R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
    878    }
    879 }
    880 
    881 static void r200ColorMaterial( struct gl_context *ctx, GLenum face, GLenum mode )
    882 {
    883       r200ContextPtr rmesa = R200_CONTEXT(ctx);
    884       GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1];
    885       light_model_ctl1 &= ~((0xf << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
    886 			   (0xf << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
    887 			   (0xf << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
    888 		   (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
    889 		   (0xf << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
    890 		   (0xf << R200_BACK_AMBIENT_SOURCE_SHIFT) |
    891 		   (0xf << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
    892 		   (0xf << R200_BACK_SPECULAR_SOURCE_SHIFT));
    893 
    894    if (ctx->Light.ColorMaterialEnabled) {
    895       GLuint mask = ctx->Light._ColorMaterialBitmask;
    896 
    897       if (mask & MAT_BIT_FRONT_EMISSION) {
    898 	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
    899 			     R200_FRONT_EMISSIVE_SOURCE_SHIFT);
    900       }
    901       else
    902 	 light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
    903 			     R200_FRONT_EMISSIVE_SOURCE_SHIFT);
    904 
    905       if (mask & MAT_BIT_FRONT_AMBIENT) {
    906 	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
    907 			     R200_FRONT_AMBIENT_SOURCE_SHIFT);
    908       }
    909       else
    910          light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
    911 			     R200_FRONT_AMBIENT_SOURCE_SHIFT);
    912 
    913       if (mask & MAT_BIT_FRONT_DIFFUSE) {
    914 	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
    915 			     R200_FRONT_DIFFUSE_SOURCE_SHIFT);
    916       }
    917       else
    918          light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
    919 			     R200_FRONT_DIFFUSE_SOURCE_SHIFT);
    920 
    921       if (mask & MAT_BIT_FRONT_SPECULAR) {
    922 	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
    923 			     R200_FRONT_SPECULAR_SOURCE_SHIFT);
    924       }
    925       else {
    926          light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
    927 			     R200_FRONT_SPECULAR_SOURCE_SHIFT);
    928       }
    929 
    930       if (mask & MAT_BIT_BACK_EMISSION) {
    931 	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
    932 			     R200_BACK_EMISSIVE_SOURCE_SHIFT);
    933       }
    934 
    935       else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
    936 			     R200_BACK_EMISSIVE_SOURCE_SHIFT);
    937 
    938       if (mask & MAT_BIT_BACK_AMBIENT) {
    939 	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
    940 			     R200_BACK_AMBIENT_SOURCE_SHIFT);
    941       }
    942       else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
    943 			     R200_BACK_AMBIENT_SOURCE_SHIFT);
    944 
    945       if (mask & MAT_BIT_BACK_DIFFUSE) {
    946 	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
    947 			     R200_BACK_DIFFUSE_SOURCE_SHIFT);
    948    }
    949       else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
    950 			     R200_BACK_DIFFUSE_SOURCE_SHIFT);
    951 
    952       if (mask & MAT_BIT_BACK_SPECULAR) {
    953 	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
    954 			     R200_BACK_SPECULAR_SOURCE_SHIFT);
    955       }
    956       else {
    957          light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
    958 			     R200_BACK_SPECULAR_SOURCE_SHIFT);
    959       }
    960       }
    961    else {
    962        /* Default to SOURCE_MATERIAL:
    963         */
    964      light_model_ctl1 |=
    965         (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
    966         (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
    967         (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
    968         (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
    969         (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
    970         (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_AMBIENT_SOURCE_SHIFT) |
    971         (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
    972         (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_SPECULAR_SOURCE_SHIFT);
    973    }
    974 
    975    if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]) {
    976       R200_STATECHANGE( rmesa, tcl );
    977       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] = light_model_ctl1;
    978    }
    979 
    980 
    981 }
    982 
    983 void r200UpdateMaterial( struct gl_context *ctx )
    984 {
    985    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    986    GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
    987    GLfloat *fcmd = (GLfloat *)R200_DB_STATE( mtl[0] );
    988    GLfloat *fcmd2 = (GLfloat *)R200_DB_STATE( mtl[1] );
    989    GLuint mask = ~0;
    990 
    991    /* Might be possible and faster to update everything unconditionally? */
    992    if (ctx->Light.ColorMaterialEnabled)
    993       mask &= ~ctx->Light._ColorMaterialBitmask;
    994 
    995    if (R200_DEBUG & RADEON_STATE)
    996       fprintf(stderr, "%s\n", __FUNCTION__);
    997 
    998    if (mask & MAT_BIT_FRONT_EMISSION) {
    999       fcmd[MTL_EMMISSIVE_RED]   = mat[MAT_ATTRIB_FRONT_EMISSION][0];
   1000       fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
   1001       fcmd[MTL_EMMISSIVE_BLUE]  = mat[MAT_ATTRIB_FRONT_EMISSION][2];
   1002       fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
   1003    }
   1004    if (mask & MAT_BIT_FRONT_AMBIENT) {
   1005       fcmd[MTL_AMBIENT_RED]     = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
   1006       fcmd[MTL_AMBIENT_GREEN]   = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
   1007       fcmd[MTL_AMBIENT_BLUE]    = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
   1008       fcmd[MTL_AMBIENT_ALPHA]   = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
   1009    }
   1010    if (mask & MAT_BIT_FRONT_DIFFUSE) {
   1011       fcmd[MTL_DIFFUSE_RED]     = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
   1012       fcmd[MTL_DIFFUSE_GREEN]   = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
   1013       fcmd[MTL_DIFFUSE_BLUE]    = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
   1014       fcmd[MTL_DIFFUSE_ALPHA]   = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
   1015    }
   1016    if (mask & MAT_BIT_FRONT_SPECULAR) {
   1017       fcmd[MTL_SPECULAR_RED]    = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
   1018       fcmd[MTL_SPECULAR_GREEN]  = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
   1019       fcmd[MTL_SPECULAR_BLUE]   = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
   1020       fcmd[MTL_SPECULAR_ALPHA]  = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
   1021    }
   1022    if (mask & MAT_BIT_FRONT_SHININESS) {
   1023       fcmd[MTL_SHININESS]       = mat[MAT_ATTRIB_FRONT_SHININESS][0];
   1024    }
   1025 
   1026    if (mask & MAT_BIT_BACK_EMISSION) {
   1027       fcmd2[MTL_EMMISSIVE_RED]   = mat[MAT_ATTRIB_BACK_EMISSION][0];
   1028       fcmd2[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_BACK_EMISSION][1];
   1029       fcmd2[MTL_EMMISSIVE_BLUE]  = mat[MAT_ATTRIB_BACK_EMISSION][2];
   1030       fcmd2[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_BACK_EMISSION][3];
   1031    }
   1032    if (mask & MAT_BIT_BACK_AMBIENT) {
   1033       fcmd2[MTL_AMBIENT_RED]     = mat[MAT_ATTRIB_BACK_AMBIENT][0];
   1034       fcmd2[MTL_AMBIENT_GREEN]   = mat[MAT_ATTRIB_BACK_AMBIENT][1];
   1035       fcmd2[MTL_AMBIENT_BLUE]    = mat[MAT_ATTRIB_BACK_AMBIENT][2];
   1036       fcmd2[MTL_AMBIENT_ALPHA]   = mat[MAT_ATTRIB_BACK_AMBIENT][3];
   1037    }
   1038    if (mask & MAT_BIT_BACK_DIFFUSE) {
   1039       fcmd2[MTL_DIFFUSE_RED]     = mat[MAT_ATTRIB_BACK_DIFFUSE][0];
   1040       fcmd2[MTL_DIFFUSE_GREEN]   = mat[MAT_ATTRIB_BACK_DIFFUSE][1];
   1041       fcmd2[MTL_DIFFUSE_BLUE]    = mat[MAT_ATTRIB_BACK_DIFFUSE][2];
   1042       fcmd2[MTL_DIFFUSE_ALPHA]   = mat[MAT_ATTRIB_BACK_DIFFUSE][3];
   1043    }
   1044    if (mask & MAT_BIT_BACK_SPECULAR) {
   1045       fcmd2[MTL_SPECULAR_RED]    = mat[MAT_ATTRIB_BACK_SPECULAR][0];
   1046       fcmd2[MTL_SPECULAR_GREEN]  = mat[MAT_ATTRIB_BACK_SPECULAR][1];
   1047       fcmd2[MTL_SPECULAR_BLUE]   = mat[MAT_ATTRIB_BACK_SPECULAR][2];
   1048       fcmd2[MTL_SPECULAR_ALPHA]  = mat[MAT_ATTRIB_BACK_SPECULAR][3];
   1049    }
   1050    if (mask & MAT_BIT_BACK_SHININESS) {
   1051       fcmd2[MTL_SHININESS]       = mat[MAT_ATTRIB_BACK_SHININESS][0];
   1052    }
   1053 
   1054    R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[0] );
   1055    R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[1] );
   1056 
   1057    /* currently material changes cannot trigger a global ambient change, I believe this is correct
   1058     update_global_ambient( ctx ); */
   1059 }
   1060 
   1061 /* _NEW_LIGHT
   1062  * _NEW_MODELVIEW
   1063  * _MESA_NEW_NEED_EYE_COORDS
   1064  *
   1065  * Uses derived state from mesa:
   1066  *       _VP_inf_norm
   1067  *       _h_inf_norm
   1068  *       _Position
   1069  *       _NormSpotDirection
   1070  *       _ModelViewInvScale
   1071  *       _NeedEyeCoords
   1072  *       _EyeZDir
   1073  *
   1074  * which are calculated in light.c and are correct for the current
   1075  * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
   1076  * and _MESA_NEW_NEED_EYE_COORDS.
   1077  */
   1078 static void update_light( struct gl_context *ctx )
   1079 {
   1080    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1081 
   1082    /* Have to check these, or have an automatic shortcircuit mechanism
   1083     * to remove noop statechanges. (Or just do a better job on the
   1084     * front end).
   1085     */
   1086    {
   1087       GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0];
   1088 
   1089       if (ctx->_NeedEyeCoords)
   1090 	 tmp &= ~R200_LIGHT_IN_MODELSPACE;
   1091       else
   1092 	 tmp |= R200_LIGHT_IN_MODELSPACE;
   1093 
   1094       if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0])
   1095       {
   1096 	 R200_STATECHANGE( rmesa, tcl );
   1097 	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] = tmp;
   1098       }
   1099    }
   1100 
   1101    {
   1102       GLfloat *fcmd = (GLfloat *)R200_DB_STATE( eye );
   1103       fcmd[EYE_X] = ctx->_EyeZDir[0];
   1104       fcmd[EYE_Y] = ctx->_EyeZDir[1];
   1105       fcmd[EYE_Z] = - ctx->_EyeZDir[2];
   1106       fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
   1107       R200_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
   1108    }
   1109 
   1110 
   1111 
   1112    if (ctx->Light.Enabled) {
   1113       GLint p;
   1114       for (p = 0 ; p < MAX_LIGHTS; p++) {
   1115 	 if (ctx->Light.Light[p].Enabled) {
   1116 	    struct gl_light *l = &ctx->Light.Light[p];
   1117 	    GLfloat *fcmd = (GLfloat *)R200_DB_STATE( lit[p] );
   1118 
   1119 	    if (l->EyePosition[3] == 0.0) {
   1120 	       COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
   1121 	       COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
   1122 	       fcmd[LIT_POSITION_W] = 0;
   1123 	       fcmd[LIT_DIRECTION_W] = 0;
   1124 	    } else {
   1125 	       COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
   1126 	       fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
   1127 	       fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
   1128 	       fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
   1129 	       fcmd[LIT_DIRECTION_W] = 0;
   1130 	    }
   1131 
   1132 	    R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
   1133 	 }
   1134       }
   1135    }
   1136 }
   1137 
   1138 static void r200Lightfv( struct gl_context *ctx, GLenum light,
   1139 			   GLenum pname, const GLfloat *params )
   1140 {
   1141    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1142    GLint p = light - GL_LIGHT0;
   1143    struct gl_light *l = &ctx->Light.Light[p];
   1144    GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
   1145 
   1146 
   1147    switch (pname) {
   1148    case GL_AMBIENT:
   1149    case GL_DIFFUSE:
   1150    case GL_SPECULAR:
   1151       update_light_colors( ctx, p );
   1152       break;
   1153 
   1154    case GL_SPOT_DIRECTION:
   1155       /* picked up in update_light */
   1156       break;
   1157 
   1158    case GL_POSITION: {
   1159       /* positions picked up in update_light, but can do flag here */
   1160       GLuint flag = (p&1)? R200_LIGHT_1_IS_LOCAL : R200_LIGHT_0_IS_LOCAL;
   1161       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
   1162 
   1163       R200_STATECHANGE(rmesa, tcl);
   1164       if (l->EyePosition[3] != 0.0F)
   1165 	 rmesa->hw.tcl.cmd[idx] |= flag;
   1166       else
   1167 	 rmesa->hw.tcl.cmd[idx] &= ~flag;
   1168       break;
   1169    }
   1170 
   1171    case GL_SPOT_EXPONENT:
   1172       R200_STATECHANGE(rmesa, lit[p]);
   1173       fcmd[LIT_SPOT_EXPONENT] = params[0];
   1174       break;
   1175 
   1176    case GL_SPOT_CUTOFF: {
   1177       GLuint flag = (p&1) ? R200_LIGHT_1_IS_SPOT : R200_LIGHT_0_IS_SPOT;
   1178       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
   1179 
   1180       R200_STATECHANGE(rmesa, lit[p]);
   1181       fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
   1182 
   1183       R200_STATECHANGE(rmesa, tcl);
   1184       if (l->SpotCutoff != 180.0F)
   1185 	 rmesa->hw.tcl.cmd[idx] |= flag;
   1186       else
   1187 	 rmesa->hw.tcl.cmd[idx] &= ~flag;
   1188 
   1189       break;
   1190    }
   1191 
   1192    case GL_CONSTANT_ATTENUATION:
   1193       R200_STATECHANGE(rmesa, lit[p]);
   1194       fcmd[LIT_ATTEN_CONST] = params[0];
   1195       if ( params[0] == 0.0 )
   1196 	 fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
   1197       else
   1198 	 fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
   1199       break;
   1200    case GL_LINEAR_ATTENUATION:
   1201       R200_STATECHANGE(rmesa, lit[p]);
   1202       fcmd[LIT_ATTEN_LINEAR] = params[0];
   1203       break;
   1204    case GL_QUADRATIC_ATTENUATION:
   1205       R200_STATECHANGE(rmesa, lit[p]);
   1206       fcmd[LIT_ATTEN_QUADRATIC] = params[0];
   1207       break;
   1208    default:
   1209       return;
   1210    }
   1211 
   1212    /* Set RANGE_ATTEN only when needed */
   1213    switch (pname) {
   1214    case GL_POSITION:
   1215    case GL_CONSTANT_ATTENUATION:
   1216    case GL_LINEAR_ATTENUATION:
   1217    case GL_QUADRATIC_ATTENUATION: {
   1218       GLuint *icmd = (GLuint *)R200_DB_STATE( tcl );
   1219       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
   1220       GLuint atten_flag = ( p&1 ) ? R200_LIGHT_1_ENABLE_RANGE_ATTEN
   1221 				  : R200_LIGHT_0_ENABLE_RANGE_ATTEN;
   1222       GLuint atten_const_flag = ( p&1 ) ? R200_LIGHT_1_CONSTANT_RANGE_ATTEN
   1223 				  : R200_LIGHT_0_CONSTANT_RANGE_ATTEN;
   1224 
   1225       if ( l->EyePosition[3] == 0.0F ||
   1226 	   ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
   1227 	     fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
   1228 	 /* Disable attenuation */
   1229 	 icmd[idx] &= ~atten_flag;
   1230       } else {
   1231 	 if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
   1232 	    /* Enable only constant portion of attenuation calculation */
   1233 	    icmd[idx] |= ( atten_flag | atten_const_flag );
   1234 	 } else {
   1235 	    /* Enable full attenuation calculation */
   1236 	    icmd[idx] &= ~atten_const_flag;
   1237 	    icmd[idx] |= atten_flag;
   1238 	 }
   1239       }
   1240 
   1241       R200_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
   1242       break;
   1243    }
   1244    default:
   1245      break;
   1246    }
   1247 }
   1248 
   1249 static void r200UpdateLocalViewer ( struct gl_context *ctx )
   1250 {
   1251 /* It looks like for the texgen modes GL_SPHERE_MAP, GL_NORMAL_MAP and
   1252    GL_REFLECTION_MAP we need R200_LOCAL_VIEWER set (fglrx does exactly that
   1253    for these and only these modes). This means specular highlights may turn out
   1254    wrong in some cases when lighting is enabled but GL_LIGHT_MODEL_LOCAL_VIEWER
   1255    is not set, though it seems to happen rarely and the effect seems quite
   1256    subtle. May need TCL fallback to fix it completely, though I'm not sure
   1257    how you'd identify the cases where the specular highlights indeed will
   1258    be wrong. Don't know if fglrx does something special in that case.
   1259 */
   1260    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1261    R200_STATECHANGE( rmesa, tcl );
   1262    if (ctx->Light.Model.LocalViewer ||
   1263        ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS)
   1264       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LOCAL_VIEWER;
   1265    else
   1266       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LOCAL_VIEWER;
   1267 }
   1268 
   1269 static void r200LightModelfv( struct gl_context *ctx, GLenum pname,
   1270 				const GLfloat *param )
   1271 {
   1272    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1273 
   1274    switch (pname) {
   1275       case GL_LIGHT_MODEL_AMBIENT:
   1276 	 update_global_ambient( ctx );
   1277 	 break;
   1278 
   1279       case GL_LIGHT_MODEL_LOCAL_VIEWER:
   1280 	 r200UpdateLocalViewer( ctx );
   1281          break;
   1282 
   1283       case GL_LIGHT_MODEL_TWO_SIDE:
   1284 	 R200_STATECHANGE( rmesa, tcl );
   1285 	 if (ctx->Light.Model.TwoSide)
   1286 	    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHT_TWOSIDE;
   1287 	 else
   1288 	    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~(R200_LIGHT_TWOSIDE);
   1289 	 if (rmesa->radeon.TclFallback) {
   1290 	    r200ChooseRenderState( ctx );
   1291 	    r200ChooseVertexState( ctx );
   1292 	 }
   1293          break;
   1294 
   1295       case GL_LIGHT_MODEL_COLOR_CONTROL:
   1296 	 r200UpdateSpecular(ctx);
   1297          break;
   1298 
   1299       default:
   1300          break;
   1301    }
   1302 }
   1303 
   1304 static void r200ShadeModel( struct gl_context *ctx, GLenum mode )
   1305 {
   1306    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1307    GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
   1308 
   1309    s &= ~(R200_DIFFUSE_SHADE_MASK |
   1310 	  R200_ALPHA_SHADE_MASK |
   1311 	  R200_SPECULAR_SHADE_MASK |
   1312 	  R200_FOG_SHADE_MASK |
   1313 	  R200_DISC_FOG_SHADE_MASK);
   1314 
   1315    switch ( mode ) {
   1316    case GL_FLAT:
   1317       s |= (R200_DIFFUSE_SHADE_FLAT |
   1318 	    R200_ALPHA_SHADE_FLAT |
   1319 	    R200_SPECULAR_SHADE_FLAT |
   1320 	    R200_FOG_SHADE_FLAT |
   1321 	    R200_DISC_FOG_SHADE_FLAT);
   1322       break;
   1323    case GL_SMOOTH:
   1324       s |= (R200_DIFFUSE_SHADE_GOURAUD |
   1325 	    R200_ALPHA_SHADE_GOURAUD |
   1326 	    R200_SPECULAR_SHADE_GOURAUD |
   1327 	    R200_FOG_SHADE_GOURAUD |
   1328 	    R200_DISC_FOG_SHADE_GOURAUD);
   1329       break;
   1330    default:
   1331       return;
   1332    }
   1333 
   1334    if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
   1335       R200_STATECHANGE( rmesa, set );
   1336       rmesa->hw.set.cmd[SET_SE_CNTL] = s;
   1337    }
   1338 }
   1339 
   1340 
   1341 /* =============================================================
   1342  * User clip planes
   1343  */
   1344 
   1345 static void r200ClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq )
   1346 {
   1347    GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
   1348    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1349    GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
   1350 
   1351    R200_STATECHANGE( rmesa, ucp[p] );
   1352    rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
   1353    rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
   1354    rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
   1355    rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
   1356 }
   1357 
   1358 static void r200UpdateClipPlanes( struct gl_context *ctx )
   1359 {
   1360    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1361    GLuint p;
   1362 
   1363    for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
   1364       if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
   1365 	 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
   1366 
   1367 	 R200_STATECHANGE( rmesa, ucp[p] );
   1368 	 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
   1369 	 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
   1370 	 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
   1371 	 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
   1372       }
   1373    }
   1374 }
   1375 
   1376 
   1377 /* =============================================================
   1378  * Stencil
   1379  */
   1380 
   1381 static void
   1382 r200StencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
   1383                          GLint ref, GLuint mask )
   1384 {
   1385    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1386    GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << R200_STENCIL_REF_SHIFT) |
   1387 		     ((ctx->Stencil.ValueMask[0] & 0xff) << R200_STENCIL_MASK_SHIFT));
   1388 
   1389    R200_STATECHANGE( rmesa, ctx );
   1390    R200_STATECHANGE( rmesa, msk );
   1391 
   1392    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_STENCIL_TEST_MASK;
   1393    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(R200_STENCIL_REF_MASK|
   1394 						   R200_STENCIL_VALUE_MASK);
   1395 
   1396    switch ( ctx->Stencil.Function[0] ) {
   1397    case GL_NEVER:
   1398       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_NEVER;
   1399       break;
   1400    case GL_LESS:
   1401       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_LESS;
   1402       break;
   1403    case GL_EQUAL:
   1404       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_EQUAL;
   1405       break;
   1406    case GL_LEQUAL:
   1407       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_LEQUAL;
   1408       break;
   1409    case GL_GREATER:
   1410       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_GREATER;
   1411       break;
   1412    case GL_NOTEQUAL:
   1413       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_NEQUAL;
   1414       break;
   1415    case GL_GEQUAL:
   1416       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_GEQUAL;
   1417       break;
   1418    case GL_ALWAYS:
   1419       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_ALWAYS;
   1420       break;
   1421    }
   1422 
   1423    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
   1424 }
   1425 
   1426 static void
   1427 r200StencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
   1428 {
   1429    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1430 
   1431    R200_STATECHANGE( rmesa, msk );
   1432    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~R200_STENCIL_WRITE_MASK;
   1433    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
   1434       ((ctx->Stencil.WriteMask[0] & 0xff) << R200_STENCIL_WRITEMASK_SHIFT);
   1435 }
   1436 
   1437 static void
   1438 r200StencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
   1439                        GLenum zfail, GLenum zpass )
   1440 {
   1441    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1442 
   1443    R200_STATECHANGE( rmesa, ctx );
   1444    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(R200_STENCIL_FAIL_MASK |
   1445 					       R200_STENCIL_ZFAIL_MASK |
   1446 					       R200_STENCIL_ZPASS_MASK);
   1447 
   1448    switch ( ctx->Stencil.FailFunc[0] ) {
   1449    case GL_KEEP:
   1450       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_KEEP;
   1451       break;
   1452    case GL_ZERO:
   1453       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_ZERO;
   1454       break;
   1455    case GL_REPLACE:
   1456       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_REPLACE;
   1457       break;
   1458    case GL_INCR:
   1459       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INC;
   1460       break;
   1461    case GL_DECR:
   1462       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_DEC;
   1463       break;
   1464    case GL_INCR_WRAP_EXT:
   1465       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INC_WRAP;
   1466       break;
   1467    case GL_DECR_WRAP_EXT:
   1468       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_DEC_WRAP;
   1469       break;
   1470    case GL_INVERT:
   1471       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INVERT;
   1472       break;
   1473    }
   1474 
   1475    switch ( ctx->Stencil.ZFailFunc[0] ) {
   1476    case GL_KEEP:
   1477       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_KEEP;
   1478       break;
   1479    case GL_ZERO:
   1480       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_ZERO;
   1481       break;
   1482    case GL_REPLACE:
   1483       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_REPLACE;
   1484       break;
   1485    case GL_INCR:
   1486       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INC;
   1487       break;
   1488    case GL_DECR:
   1489       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_DEC;
   1490       break;
   1491    case GL_INCR_WRAP_EXT:
   1492       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INC_WRAP;
   1493       break;
   1494    case GL_DECR_WRAP_EXT:
   1495       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_DEC_WRAP;
   1496       break;
   1497    case GL_INVERT:
   1498       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INVERT;
   1499       break;
   1500    }
   1501 
   1502    switch ( ctx->Stencil.ZPassFunc[0] ) {
   1503    case GL_KEEP:
   1504       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_KEEP;
   1505       break;
   1506    case GL_ZERO:
   1507       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_ZERO;
   1508       break;
   1509    case GL_REPLACE:
   1510       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_REPLACE;
   1511       break;
   1512    case GL_INCR:
   1513       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INC;
   1514       break;
   1515    case GL_DECR:
   1516       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_DEC;
   1517       break;
   1518    case GL_INCR_WRAP_EXT:
   1519       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INC_WRAP;
   1520       break;
   1521    case GL_DECR_WRAP_EXT:
   1522       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_DEC_WRAP;
   1523       break;
   1524    case GL_INVERT:
   1525       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INVERT;
   1526       break;
   1527    }
   1528 }
   1529 
   1530 
   1531 /* =============================================================
   1532  * Window position and viewport transformation
   1533  */
   1534 
   1535 /**
   1536  * Called when window size or position changes or viewport or depth range
   1537  * state is changed.  We update the hardware viewport state here.
   1538  */
   1539 void r200UpdateWindow( struct gl_context *ctx )
   1540 {
   1541    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1542    __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
   1543    GLfloat xoffset = 0;
   1544    GLfloat yoffset = dPriv ? (GLfloat) dPriv->h : 0;
   1545    const GLfloat *v = ctx->Viewport._WindowMap.m;
   1546    const GLboolean render_to_fbo = (ctx->DrawBuffer ? _mesa_is_user_fbo(ctx->DrawBuffer) : 0);
   1547    const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
   1548    GLfloat y_scale, y_bias;
   1549 
   1550    if (render_to_fbo) {
   1551       y_scale = 1.0;
   1552       y_bias = 0;
   1553    } else {
   1554       y_scale = -1.0;
   1555       y_bias = yoffset;
   1556    }
   1557 
   1558    float_ui32_type sx = { v[MAT_SX] };
   1559    float_ui32_type tx = { v[MAT_TX] + xoffset };
   1560    float_ui32_type sy = { v[MAT_SY] * y_scale };
   1561    float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias };
   1562    float_ui32_type sz = { v[MAT_SZ] * depthScale };
   1563    float_ui32_type tz = { v[MAT_TZ] * depthScale };
   1564 
   1565    R200_STATECHANGE( rmesa, vpt );
   1566 
   1567    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE]  = sx.ui32;
   1568    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
   1569    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE]  = sy.ui32;
   1570    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
   1571    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE]  = sz.ui32;
   1572    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
   1573 }
   1574 
   1575 void r200_vtbl_update_scissor( struct gl_context *ctx )
   1576 {
   1577    r200ContextPtr r200 = R200_CONTEXT(ctx);
   1578    unsigned x1, y1, x2, y2;
   1579    struct radeon_renderbuffer *rrb;
   1580 
   1581    R200_SET_STATE(r200, set, SET_RE_CNTL, R200_SCISSOR_ENABLE | r200->hw.set.cmd[SET_RE_CNTL]);
   1582 
   1583    if (r200->radeon.state.scissor.enabled) {
   1584       x1 = r200->radeon.state.scissor.rect.x1;
   1585       y1 = r200->radeon.state.scissor.rect.y1;
   1586       x2 = r200->radeon.state.scissor.rect.x2;
   1587       y2 = r200->radeon.state.scissor.rect.y2;
   1588    } else {
   1589       rrb = radeon_get_colorbuffer(&r200->radeon);
   1590       x1 = 0;
   1591       y1 = 0;
   1592       x2 = rrb->base.Base.Width - 1;
   1593       y2 = rrb->base.Base.Height - 1;
   1594    }
   1595 
   1596    R200_SET_STATE(r200, sci, SCI_XY_1, x1 | (y1 << 16));
   1597    R200_SET_STATE(r200, sci, SCI_XY_2, x2 | (y2 << 16));
   1598 }
   1599 
   1600 
   1601 static void r200Viewport( struct gl_context *ctx, GLint x, GLint y,
   1602 			    GLsizei width, GLsizei height )
   1603 {
   1604    /* Don't pipeline viewport changes, conflict with window offset
   1605     * setting below.  Could apply deltas to rescue pipelined viewport
   1606     * values, or keep the originals hanging around.
   1607     */
   1608    r200UpdateWindow( ctx );
   1609 
   1610    radeon_viewport(ctx, x, y, width, height);
   1611 }
   1612 
   1613 static void r200DepthRange( struct gl_context *ctx, GLclampd nearval,
   1614 			      GLclampd farval )
   1615 {
   1616    r200UpdateWindow( ctx );
   1617 }
   1618 
   1619 void r200UpdateViewportOffset( struct gl_context *ctx )
   1620 {
   1621    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1622    __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
   1623    GLfloat xoffset = (GLfloat)0;
   1624    GLfloat yoffset = (GLfloat)dPriv->h;
   1625    const GLfloat *v = ctx->Viewport._WindowMap.m;
   1626 
   1627    float_ui32_type tx;
   1628    float_ui32_type ty;
   1629 
   1630    tx.f = v[MAT_TX] + xoffset;
   1631    ty.f = (- v[MAT_TY]) + yoffset;
   1632 
   1633    if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 ||
   1634 	rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 )
   1635    {
   1636       /* Note: this should also modify whatever data the context reset
   1637        * code uses...
   1638        */
   1639       R200_STATECHANGE( rmesa, vpt );
   1640       rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
   1641       rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
   1642 
   1643       /* update polygon stipple x/y screen offset */
   1644       {
   1645          GLuint stx, sty;
   1646          GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
   1647 
   1648          m &= ~(R200_STIPPLE_X_OFFSET_MASK |
   1649                 R200_STIPPLE_Y_OFFSET_MASK);
   1650 
   1651          /* add magic offsets, then invert */
   1652          stx = 31 - ((-1) & R200_STIPPLE_COORD_MASK);
   1653          sty = 31 - ((dPriv->h - 1)
   1654                      & R200_STIPPLE_COORD_MASK);
   1655 
   1656          m |= ((stx << R200_STIPPLE_X_OFFSET_SHIFT) |
   1657                (sty << R200_STIPPLE_Y_OFFSET_SHIFT));
   1658 
   1659          if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
   1660             R200_STATECHANGE( rmesa, msc );
   1661 	    rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
   1662          }
   1663       }
   1664    }
   1665 
   1666    radeonUpdateScissor( ctx );
   1667 }
   1668 
   1669 
   1670 
   1671 /* =============================================================
   1672  * Miscellaneous
   1673  */
   1674 
   1675 static void r200RenderMode( struct gl_context *ctx, GLenum mode )
   1676 {
   1677    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1678    FALLBACK( rmesa, R200_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
   1679 }
   1680 
   1681 
   1682 static GLuint r200_rop_tab[] = {
   1683    R200_ROP_CLEAR,
   1684    R200_ROP_AND,
   1685    R200_ROP_AND_REVERSE,
   1686    R200_ROP_COPY,
   1687    R200_ROP_AND_INVERTED,
   1688    R200_ROP_NOOP,
   1689    R200_ROP_XOR,
   1690    R200_ROP_OR,
   1691    R200_ROP_NOR,
   1692    R200_ROP_EQUIV,
   1693    R200_ROP_INVERT,
   1694    R200_ROP_OR_REVERSE,
   1695    R200_ROP_COPY_INVERTED,
   1696    R200_ROP_OR_INVERTED,
   1697    R200_ROP_NAND,
   1698    R200_ROP_SET,
   1699 };
   1700 
   1701 static void r200LogicOpCode( struct gl_context *ctx, GLenum opcode )
   1702 {
   1703    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1704    GLuint rop = (GLuint)opcode - GL_CLEAR;
   1705 
   1706    ASSERT( rop < 16 );
   1707 
   1708    R200_STATECHANGE( rmesa, msk );
   1709    rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = r200_rop_tab[rop];
   1710 }
   1711 
   1712 /* =============================================================
   1713  * State enable/disable
   1714  */
   1715 
   1716 static void r200Enable( struct gl_context *ctx, GLenum cap, GLboolean state )
   1717 {
   1718    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1719    GLuint p, flag;
   1720 
   1721    if ( R200_DEBUG & RADEON_STATE )
   1722       fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
   1723 	       _mesa_lookup_enum_by_nr( cap ),
   1724 	       state ? "GL_TRUE" : "GL_FALSE" );
   1725 
   1726    switch ( cap ) {
   1727       /* Fast track this one...
   1728        */
   1729    case GL_TEXTURE_1D:
   1730    case GL_TEXTURE_2D:
   1731    case GL_TEXTURE_3D:
   1732       break;
   1733 
   1734    case GL_ALPHA_TEST:
   1735       R200_STATECHANGE( rmesa, ctx );
   1736       if (state) {
   1737 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_ALPHA_TEST_ENABLE;
   1738       } else {
   1739 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ALPHA_TEST_ENABLE;
   1740       }
   1741       break;
   1742 
   1743    case GL_BLEND:
   1744    case GL_COLOR_LOGIC_OP:
   1745       r200_set_blend_state( ctx );
   1746       break;
   1747 
   1748    case GL_CLIP_PLANE0:
   1749    case GL_CLIP_PLANE1:
   1750    case GL_CLIP_PLANE2:
   1751    case GL_CLIP_PLANE3:
   1752    case GL_CLIP_PLANE4:
   1753    case GL_CLIP_PLANE5:
   1754       p = cap-GL_CLIP_PLANE0;
   1755       R200_STATECHANGE( rmesa, tcl );
   1756       if (state) {
   1757 	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (R200_UCP_ENABLE_0<<p);
   1758 	 r200ClipPlane( ctx, cap, NULL );
   1759       }
   1760       else {
   1761 	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(R200_UCP_ENABLE_0<<p);
   1762       }
   1763       break;
   1764 
   1765    case GL_COLOR_MATERIAL:
   1766       r200ColorMaterial( ctx, 0, 0 );
   1767       r200UpdateMaterial( ctx );
   1768       break;
   1769 
   1770    case GL_CULL_FACE:
   1771       r200CullFace( ctx, 0 );
   1772       break;
   1773 
   1774    case GL_DEPTH_TEST:
   1775       R200_STATECHANGE(rmesa, ctx );
   1776       if ( state ) {
   1777 	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_Z_ENABLE;
   1778       } else {
   1779 	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_Z_ENABLE;
   1780       }
   1781       break;
   1782 
   1783    case GL_DITHER:
   1784       R200_STATECHANGE(rmesa, ctx );
   1785       if ( state ) {
   1786 	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_DITHER_ENABLE;
   1787 	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
   1788       } else {
   1789 	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_DITHER_ENABLE;
   1790 	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  rmesa->radeon.state.color.roundEnable;
   1791       }
   1792       break;
   1793 
   1794    case GL_FOG:
   1795       R200_STATECHANGE(rmesa, ctx );
   1796       if ( state ) {
   1797 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_FOG_ENABLE;
   1798 	 r200Fogfv( ctx, GL_FOG_MODE, NULL );
   1799       } else {
   1800 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_FOG_ENABLE;
   1801 	 R200_STATECHANGE(rmesa, tcl);
   1802 	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_TCL_FOG_MASK;
   1803       }
   1804       r200UpdateSpecular( ctx ); /* for PK_SPEC */
   1805       if (rmesa->radeon.TclFallback)
   1806 	 r200ChooseVertexState( ctx );
   1807       _mesa_allow_light_in_model( ctx, !state );
   1808       break;
   1809 
   1810    case GL_LIGHT0:
   1811    case GL_LIGHT1:
   1812    case GL_LIGHT2:
   1813    case GL_LIGHT3:
   1814    case GL_LIGHT4:
   1815    case GL_LIGHT5:
   1816    case GL_LIGHT6:
   1817    case GL_LIGHT7:
   1818       R200_STATECHANGE(rmesa, tcl);
   1819       p = cap - GL_LIGHT0;
   1820       if (p&1)
   1821 	 flag = (R200_LIGHT_1_ENABLE |
   1822 		 R200_LIGHT_1_ENABLE_AMBIENT |
   1823 		 R200_LIGHT_1_ENABLE_SPECULAR);
   1824       else
   1825 	 flag = (R200_LIGHT_0_ENABLE |
   1826 		 R200_LIGHT_0_ENABLE_AMBIENT |
   1827 		 R200_LIGHT_0_ENABLE_SPECULAR);
   1828 
   1829       if (state)
   1830 	 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
   1831       else
   1832 	 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
   1833 
   1834       /*
   1835        */
   1836       update_light_colors( ctx, p );
   1837       break;
   1838 
   1839    case GL_LIGHTING:
   1840       r200UpdateSpecular(ctx);
   1841       /* for reflection map fixup - might set recheck_texgen for all units too */
   1842       rmesa->radeon.NewGLState |= _NEW_TEXTURE;
   1843       break;
   1844 
   1845    case GL_LINE_SMOOTH:
   1846       R200_STATECHANGE( rmesa, ctx );
   1847       if ( state ) {
   1848 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  R200_ANTI_ALIAS_LINE;
   1849       } else {
   1850 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ANTI_ALIAS_LINE;
   1851       }
   1852       break;
   1853 
   1854    case GL_LINE_STIPPLE:
   1855       R200_STATECHANGE( rmesa, set );
   1856       if ( state ) {
   1857 	 rmesa->hw.set.cmd[SET_RE_CNTL] |=  R200_PATTERN_ENABLE;
   1858       } else {
   1859 	 rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PATTERN_ENABLE;
   1860       }
   1861       break;
   1862 
   1863    case GL_NORMALIZE:
   1864       R200_STATECHANGE( rmesa, tcl );
   1865       if ( state ) {
   1866 	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |=  R200_NORMALIZE_NORMALS;
   1867       } else {
   1868 	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_NORMALIZE_NORMALS;
   1869       }
   1870       break;
   1871 
   1872       /* Pointsize registers on r200 only work for point sprites, and point smooth
   1873        * doesn't work for point sprites (and isn't needed for 1.0 sized aa points).
   1874        * In any case, setting pointmin == pointsizemax == 1.0 for aa points
   1875        * is enough to satisfy conform.
   1876        */
   1877    case GL_POINT_SMOOTH:
   1878       break;
   1879 
   1880       /* These don't really do anything, as we don't use the 3vtx
   1881        * primitives yet.
   1882        */
   1883 #if 0
   1884    case GL_POLYGON_OFFSET_POINT:
   1885       R200_STATECHANGE( rmesa, set );
   1886       if ( state ) {
   1887 	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_ZBIAS_ENABLE_POINT;
   1888       } else {
   1889 	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_POINT;
   1890       }
   1891       break;
   1892 
   1893    case GL_POLYGON_OFFSET_LINE:
   1894       R200_STATECHANGE( rmesa, set );
   1895       if ( state ) {
   1896 	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_ZBIAS_ENABLE_LINE;
   1897       } else {
   1898 	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_LINE;
   1899       }
   1900       break;
   1901 #endif
   1902 
   1903    case GL_POINT_SPRITE_ARB:
   1904       R200_STATECHANGE( rmesa, spr );
   1905       if ( state ) {
   1906 	 int i;
   1907 	 for (i = 0; i < 6; i++) {
   1908 	    rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |=
   1909 		ctx->Point.CoordReplace[i] << (R200_PS_GEN_TEX_0_SHIFT + i);
   1910 	 }
   1911       } else {
   1912 	 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &= ~R200_PS_GEN_TEX_MASK;
   1913       }
   1914       break;
   1915 
   1916    case GL_POLYGON_OFFSET_FILL:
   1917       R200_STATECHANGE( rmesa, set );
   1918       if ( state ) {
   1919 	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_ZBIAS_ENABLE_TRI;
   1920       } else {
   1921 	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_TRI;
   1922       }
   1923       break;
   1924 
   1925    case GL_POLYGON_SMOOTH:
   1926       R200_STATECHANGE( rmesa, ctx );
   1927       if ( state ) {
   1928 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  R200_ANTI_ALIAS_POLY;
   1929       } else {
   1930 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ANTI_ALIAS_POLY;
   1931       }
   1932       break;
   1933 
   1934    case GL_POLYGON_STIPPLE:
   1935       R200_STATECHANGE(rmesa, set );
   1936       if ( state ) {
   1937 	 rmesa->hw.set.cmd[SET_RE_CNTL] |=  R200_STIPPLE_ENABLE;
   1938       } else {
   1939 	 rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_STIPPLE_ENABLE;
   1940       }
   1941       break;
   1942 
   1943    case GL_RESCALE_NORMAL_EXT: {
   1944       GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
   1945       R200_STATECHANGE( rmesa, tcl );
   1946       if ( tmp ) {
   1947 	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |=  R200_RESCALE_NORMALS;
   1948       } else {
   1949 	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS;
   1950       }
   1951       break;
   1952    }
   1953 
   1954    case GL_SCISSOR_TEST:
   1955       radeon_firevertices(&rmesa->radeon);
   1956       rmesa->radeon.state.scissor.enabled = state;
   1957       radeonUpdateScissor( ctx );
   1958       break;
   1959 
   1960    case GL_STENCIL_TEST:
   1961       {
   1962 	 GLboolean hw_stencil = GL_FALSE;
   1963 	 if (ctx->DrawBuffer) {
   1964 	    struct radeon_renderbuffer *rrbStencil
   1965 	       = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
   1966 	    hw_stencil = (rrbStencil && rrbStencil->bo);
   1967 	 }
   1968 
   1969 	 if (hw_stencil) {
   1970 	    R200_STATECHANGE( rmesa, ctx );
   1971 	    if ( state ) {
   1972 	       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_STENCIL_ENABLE;
   1973 	    } else {
   1974 	       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE;
   1975 	    }
   1976 	 } else {
   1977 	    FALLBACK( rmesa, R200_FALLBACK_STENCIL, state );
   1978 	 }
   1979       }
   1980       break;
   1981 
   1982    case GL_TEXTURE_GEN_Q:
   1983    case GL_TEXTURE_GEN_R:
   1984    case GL_TEXTURE_GEN_S:
   1985    case GL_TEXTURE_GEN_T:
   1986       /* Picked up in r200UpdateTextureState.
   1987        */
   1988       rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
   1989       break;
   1990 
   1991    case GL_COLOR_SUM_EXT:
   1992       r200UpdateSpecular ( ctx );
   1993       break;
   1994 
   1995    case GL_VERTEX_PROGRAM_ARB:
   1996       if (!state) {
   1997 	 GLuint i;
   1998 	 rmesa->curr_vp_hw = NULL;
   1999 	 R200_STATECHANGE( rmesa, vap );
   2000 	 rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_PROG_VTX_SHADER_ENABLE;
   2001 	 /* mark all tcl atoms (tcl vector state got overwritten) dirty
   2002 	    not sure about tcl scalar state - we need at least grd
   2003 	    with vert progs too.
   2004 	    ucp looks like it doesn't get overwritten (may even work
   2005 	    with vp for pos-invariant progs if we're lucky) */
   2006 	 R200_STATECHANGE( rmesa, mtl[0] );
   2007 	 R200_STATECHANGE( rmesa, mtl[1] );
   2008 	 R200_STATECHANGE( rmesa, fog );
   2009 	 R200_STATECHANGE( rmesa, glt );
   2010 	 R200_STATECHANGE( rmesa, eye );
   2011 	 for (i = R200_MTX_MV; i <= R200_MTX_TEX5; i++) {
   2012 	    R200_STATECHANGE( rmesa, mat[i] );
   2013 	 }
   2014 	 for (i = 0 ; i < 8; i++) {
   2015 	    R200_STATECHANGE( rmesa, lit[i] );
   2016 	 }
   2017 	 R200_STATECHANGE( rmesa, tcl );
   2018 	 for (i = 0; i <= ctx->Const.MaxClipPlanes; i++) {
   2019 	    if (ctx->Transform.ClipPlanesEnabled & (1 << i)) {
   2020 	       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (R200_UCP_ENABLE_0 << i);
   2021 	    }
   2022 /*	    else {
   2023 	       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(R200_UCP_ENABLE_0 << i);
   2024 	    }*/
   2025 	 }
   2026 	 /* ugly. Need to call everything which might change compsel. */
   2027 	 r200UpdateSpecular( ctx );
   2028 #if 0
   2029 	/* shouldn't be necessary, as it's picked up anyway in r200ValidateState (_NEW_PROGRAM),
   2030 	   but without it doom3 locks up at always the same places. Why? */
   2031 	/* FIXME: This can (and should) be replaced by a call to the TCL_STATE_FLUSH reg before
   2032 	   accessing VAP_SE_VAP_CNTL. Requires drm changes (done). Remove after some time... */
   2033 	 r200UpdateTextureState( ctx );
   2034 	 /* if we call r200UpdateTextureState we need the code below because we are calling it with
   2035 	    non-current derived enabled values which may revert the state atoms for frag progs even when
   2036 	    they already got disabled... ugh
   2037 	    Should really figure out why we need to call r200UpdateTextureState in the first place */
   2038 	 GLuint unit;
   2039 	 for (unit = 0; unit < R200_MAX_TEXTURE_UNITS; unit++) {
   2040 	    R200_STATECHANGE( rmesa, pix[unit] );
   2041 	    R200_STATECHANGE( rmesa, tex[unit] );
   2042 	    rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &=
   2043 		~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
   2044 	    rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT;
   2045 	    /* need to guard this with drmSupportsFragmentShader? Should never get here if
   2046 	       we don't announce ATI_fs, right? */
   2047 	    rmesa->hw.tex[unit].cmd[TEX_PP_TXMULTI_CTL] = 0;
   2048          }
   2049 	 R200_STATECHANGE( rmesa, cst );
   2050 	 R200_STATECHANGE( rmesa, tf );
   2051 	 rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0;
   2052 #endif
   2053       }
   2054       else {
   2055 	 /* picked up later */
   2056       }
   2057       /* call functions which change hw state based on ARB_vp enabled or not. */
   2058       r200PointParameter( ctx, GL_POINT_DISTANCE_ATTENUATION, NULL );
   2059       r200Fogfv( ctx, GL_FOG_COORD_SRC, NULL );
   2060       break;
   2061 
   2062    case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
   2063       r200PointParameter( ctx, GL_POINT_DISTANCE_ATTENUATION, NULL );
   2064       break;
   2065 
   2066    case GL_FRAGMENT_SHADER_ATI:
   2067       if ( !state ) {
   2068 	 /* restore normal tex env colors and make sure tex env combine will get updated
   2069 	    mark env atoms dirty (as their data was overwritten by afs even
   2070 	    if they didn't change) and restore tex coord routing */
   2071 	 GLuint unit;
   2072 	 for (unit = 0; unit < R200_MAX_TEXTURE_UNITS; unit++) {
   2073 	    R200_STATECHANGE( rmesa, pix[unit] );
   2074 	    R200_STATECHANGE( rmesa, tex[unit] );
   2075 	    rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &=
   2076 		~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
   2077 	    rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT;
   2078 	    rmesa->hw.tex[unit].cmd[TEX_PP_TXMULTI_CTL] = 0;
   2079          }
   2080 	 R200_STATECHANGE( rmesa, cst );
   2081 	 R200_STATECHANGE( rmesa, tf );
   2082 	 rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0;
   2083       }
   2084       else {
   2085 	 /* need to mark this dirty as pix/tf atoms have overwritten the data
   2086 	    even if the data in the atoms didn't change */
   2087 	 R200_STATECHANGE( rmesa, atf );
   2088 	 R200_STATECHANGE( rmesa, afs[1] );
   2089 	 /* everything else picked up in r200UpdateTextureState hopefully */
   2090       }
   2091       break;
   2092    default:
   2093       return;
   2094    }
   2095 }
   2096 
   2097 
   2098 void r200LightingSpaceChange( struct gl_context *ctx )
   2099 {
   2100    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   2101    GLboolean tmp;
   2102 
   2103    if (R200_DEBUG & RADEON_STATE)
   2104       fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
   2105 	      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]);
   2106 
   2107    if (ctx->_NeedEyeCoords)
   2108       tmp = ctx->Transform.RescaleNormals;
   2109    else
   2110       tmp = !ctx->Transform.RescaleNormals;
   2111 
   2112    R200_STATECHANGE( rmesa, tcl );
   2113    if ( tmp ) {
   2114       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |=  R200_RESCALE_NORMALS;
   2115    } else {
   2116       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS;
   2117    }
   2118 
   2119    if (R200_DEBUG & RADEON_STATE)
   2120       fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
   2121 	      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]);
   2122 }
   2123 
   2124 /* =============================================================
   2125  * Deferred state management - matrices, textures, other?
   2126  */
   2127 
   2128 
   2129 
   2130 
   2131 static void upload_matrix( r200ContextPtr rmesa, GLfloat *src, int idx )
   2132 {
   2133    float *dest = ((float *)R200_DB_STATE( mat[idx] ))+MAT_ELT_0;
   2134    int i;
   2135 
   2136 
   2137    for (i = 0 ; i < 4 ; i++) {
   2138       *dest++ = src[i];
   2139       *dest++ = src[i+4];
   2140       *dest++ = src[i+8];
   2141       *dest++ = src[i+12];
   2142    }
   2143 
   2144    R200_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
   2145 }
   2146 
   2147 static void upload_matrix_t( r200ContextPtr rmesa, const GLfloat *src, int idx )
   2148 {
   2149    float *dest = ((float *)R200_DB_STATE( mat[idx] ))+MAT_ELT_0;
   2150    memcpy(dest, src, 16*sizeof(float));
   2151    R200_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
   2152 }
   2153 
   2154 
   2155 static void update_texturematrix( struct gl_context *ctx )
   2156 {
   2157    r200ContextPtr rmesa = R200_CONTEXT( ctx );
   2158    GLuint tpc = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0];
   2159    GLuint compsel = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL];
   2160    int unit;
   2161 
   2162    if (R200_DEBUG & RADEON_STATE)
   2163       fprintf(stderr, "%s before COMPSEL: %x\n", __FUNCTION__,
   2164 	      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]);
   2165 
   2166    rmesa->TexMatEnabled = 0;
   2167    rmesa->TexMatCompSel = 0;
   2168 
   2169    for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
   2170       if (!ctx->Texture.Unit[unit]._ReallyEnabled)
   2171 	 continue;
   2172 
   2173       if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
   2174 	 rmesa->TexMatEnabled |= (R200_TEXGEN_TEXMAT_0_ENABLE|
   2175 				  R200_TEXMAT_0_ENABLE) << unit;
   2176 
   2177 	 rmesa->TexMatCompSel |= R200_OUTPUT_TEX_0 << unit;
   2178 
   2179 	 if (rmesa->TexGenEnabled & (R200_TEXMAT_0_ENABLE << unit)) {
   2180 	    /* Need to preconcatenate any active texgen
   2181 	     * obj/eyeplane matrices:
   2182 	     */
   2183 	    _math_matrix_mul_matrix( &rmesa->tmpmat,
   2184 				     ctx->TextureMatrixStack[unit].Top,
   2185 				     &rmesa->TexGenMatrix[unit] );
   2186 	    upload_matrix( rmesa, rmesa->tmpmat.m, R200_MTX_TEX0+unit );
   2187 	 }
   2188 	 else {
   2189 	    upload_matrix( rmesa, ctx->TextureMatrixStack[unit].Top->m,
   2190 			   R200_MTX_TEX0+unit );
   2191 	 }
   2192       }
   2193       else if (rmesa->TexGenEnabled & (R200_TEXMAT_0_ENABLE << unit)) {
   2194 	 upload_matrix( rmesa, rmesa->TexGenMatrix[unit].m,
   2195 			R200_MTX_TEX0+unit );
   2196       }
   2197    }
   2198 
   2199    tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled);
   2200    if (tpc != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0]) {
   2201       R200_STATECHANGE(rmesa, tcg);
   2202       rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] = tpc;
   2203    }
   2204 
   2205    compsel &= ~R200_OUTPUT_TEX_MASK;
   2206    compsel |= rmesa->TexMatCompSel | rmesa->TexGenCompSel;
   2207    if (compsel != rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]) {
   2208       R200_STATECHANGE(rmesa, vtx);
   2209       rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = compsel;
   2210    }
   2211 }
   2212 
   2213 static GLboolean r200ValidateBuffers(struct gl_context *ctx)
   2214 {
   2215    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   2216    struct radeon_renderbuffer *rrb;
   2217    struct radeon_dma_bo *dma_bo;
   2218    int i, ret;
   2219 
   2220 	if (RADEON_DEBUG & RADEON_IOCTL)
   2221 		fprintf(stderr, "%s\n", __FUNCTION__);
   2222    radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
   2223 
   2224    rrb = radeon_get_colorbuffer(&rmesa->radeon);
   2225    /* color buffer */
   2226    if (rrb && rrb->bo) {
   2227      radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
   2228 				       0, RADEON_GEM_DOMAIN_VRAM);
   2229    }
   2230 
   2231    /* depth buffer */
   2232    rrb = radeon_get_depthbuffer(&rmesa->radeon);
   2233    /* color buffer */
   2234    if (rrb && rrb->bo) {
   2235      radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
   2236 				       0, RADEON_GEM_DOMAIN_VRAM);
   2237    }
   2238 
   2239    for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
   2240       radeonTexObj *t;
   2241 
   2242       if (!ctx->Texture.Unit[i]._ReallyEnabled)
   2243 	 continue;
   2244 
   2245       t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
   2246       if (t->image_override && t->bo)
   2247 	radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
   2248 			   RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
   2249       else if (t->mt->bo)
   2250 	radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
   2251 			   RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
   2252    }
   2253 
   2254    dma_bo = first_elem(&rmesa->radeon.dma.reserved);
   2255    {
   2256        ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, dma_bo->bo, RADEON_GEM_DOMAIN_GTT, 0);
   2257        if (ret)
   2258 	   return GL_FALSE;
   2259    }
   2260    return GL_TRUE;
   2261 }
   2262 
   2263 GLboolean r200ValidateState( struct gl_context *ctx )
   2264 {
   2265    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   2266    GLuint new_state = rmesa->radeon.NewGLState;
   2267 
   2268    if (new_state & _NEW_BUFFERS) {
   2269       _mesa_update_framebuffer(ctx);
   2270       /* this updates the DrawBuffer's Width/Height if it's a FBO */
   2271       _mesa_update_draw_buffer_bounds(ctx);
   2272 
   2273       R200_STATECHANGE(rmesa, ctx);
   2274    }
   2275 
   2276    if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)) {
   2277       r200UpdateTextureState( ctx );
   2278       new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
   2279       r200UpdateLocalViewer( ctx );
   2280    }
   2281 
   2282    /* we need to do a space check here */
   2283    if (!r200ValidateBuffers(ctx))
   2284      return GL_FALSE;
   2285 
   2286 /* FIXME: don't really need most of these when vertex progs are enabled */
   2287 
   2288    /* Need an event driven matrix update?
   2289     */
   2290    if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
   2291       upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, R200_MTX_MVP );
   2292 
   2293    /* Need these for lighting (shouldn't upload otherwise)
   2294     */
   2295    if (new_state & (_NEW_MODELVIEW)) {
   2296       upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, R200_MTX_MV );
   2297       upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, R200_MTX_IMV );
   2298    }
   2299 
   2300    /* Does this need to be triggered on eg. modelview for
   2301     * texgen-derived objplane/eyeplane matrices?
   2302     */
   2303    if (new_state & (_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) {
   2304       update_texturematrix( ctx );
   2305    }
   2306 
   2307    if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
   2308       update_light( ctx );
   2309    }
   2310 
   2311    /* emit all active clip planes if projection matrix changes.
   2312     */
   2313    if (new_state & (_NEW_PROJECTION)) {
   2314       if (ctx->Transform.ClipPlanesEnabled)
   2315 	 r200UpdateClipPlanes( ctx );
   2316    }
   2317 
   2318    if (new_state & (_NEW_PROGRAM|
   2319                     _NEW_PROGRAM_CONSTANTS |
   2320    /* need to test for pretty much anything due to possible parameter bindings */
   2321 	_NEW_MODELVIEW|_NEW_PROJECTION|_NEW_TRANSFORM|
   2322 	_NEW_LIGHT|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX|
   2323 	_NEW_FOG|_NEW_POINT|_NEW_TRACK_MATRIX)) {
   2324       if (ctx->VertexProgram._Enabled) {
   2325 	 r200SetupVertexProg( ctx );
   2326       }
   2327       else TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, 0);
   2328    }
   2329 
   2330    rmesa->radeon.NewGLState = 0;
   2331    return GL_TRUE;
   2332 }
   2333 
   2334 
   2335 static void r200InvalidateState( struct gl_context *ctx, GLuint new_state )
   2336 {
   2337    _swrast_InvalidateState( ctx, new_state );
   2338    _swsetup_InvalidateState( ctx, new_state );
   2339    _vbo_InvalidateState( ctx, new_state );
   2340    _tnl_InvalidateState( ctx, new_state );
   2341    _ae_invalidate_state( ctx, new_state );
   2342    R200_CONTEXT(ctx)->radeon.NewGLState |= new_state;
   2343 }
   2344 
   2345 /* A hack.  The r200 can actually cope just fine with materials
   2346  * between begin/ends, so fix this.
   2347  * Should map to inputs just like the generic vertex arrays for vertex progs.
   2348  * In theory there could still be too many and we'd still need a fallback.
   2349  */
   2350 static GLboolean check_material( struct gl_context *ctx )
   2351 {
   2352    TNLcontext *tnl = TNL_CONTEXT(ctx);
   2353    GLint i;
   2354 
   2355    for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
   2356 	i < _TNL_ATTRIB_MAT_BACK_INDEXES;
   2357 	i++)
   2358       if (tnl->vb.AttribPtr[i] &&
   2359 	  tnl->vb.AttribPtr[i]->stride)
   2360 	 return GL_TRUE;
   2361 
   2362    return GL_FALSE;
   2363 }
   2364 
   2365 static void r200WrapRunPipeline( struct gl_context *ctx )
   2366 {
   2367    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   2368    GLboolean has_material;
   2369 
   2370    if (0)
   2371       fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
   2372 
   2373    /* Validate state:
   2374     */
   2375    if (rmesa->radeon.NewGLState)
   2376       if (!r200ValidateState( ctx ))
   2377 	 FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
   2378 
   2379    has_material = !ctx->VertexProgram._Enabled && ctx->Light.Enabled && check_material( ctx );
   2380 
   2381    if (has_material) {
   2382       TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_TRUE );
   2383    }
   2384 
   2385    /* Run the pipeline.
   2386     */
   2387    _tnl_run_pipeline( ctx );
   2388 
   2389    if (has_material) {
   2390       TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_FALSE );
   2391    }
   2392 }
   2393 
   2394 
   2395 static void r200PolygonStipple( struct gl_context *ctx, const GLubyte *mask )
   2396 {
   2397    r200ContextPtr r200 = R200_CONTEXT(ctx);
   2398    GLint i;
   2399 
   2400    radeon_firevertices(&r200->radeon);
   2401 
   2402    radeon_print(RADEON_STATE, RADEON_TRACE,
   2403 		   "%s(%p) first 32 bits are %x.\n",
   2404 		   __func__,
   2405 		   ctx,
   2406 		   *(uint32_t*)mask);
   2407 
   2408    R200_STATECHANGE(r200, stp);
   2409 
   2410    /* Must flip pattern upside down.
   2411     */
   2412    for ( i = 31 ; i >= 0; i--) {
   2413      r200->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
   2414    }
   2415 }
   2416 /* Initialize the driver's state functions.
   2417  */
   2418 void r200InitStateFuncs( radeonContextPtr radeon, struct dd_function_table *functions )
   2419 {
   2420    functions->UpdateState		= r200InvalidateState;
   2421    functions->LightingSpaceChange	= r200LightingSpaceChange;
   2422 
   2423    functions->DrawBuffer		= radeonDrawBuffer;
   2424    functions->ReadBuffer		= radeonReadBuffer;
   2425 
   2426    functions->CopyPixels                = _mesa_meta_CopyPixels;
   2427    functions->DrawPixels                = _mesa_meta_DrawPixels;
   2428    functions->ReadPixels                = radeonReadPixels;
   2429 
   2430    functions->AlphaFunc			= r200AlphaFunc;
   2431    functions->BlendColor		= r200BlendColor;
   2432    functions->BlendEquationSeparate	= r200BlendEquationSeparate;
   2433    functions->BlendFuncSeparate		= r200BlendFuncSeparate;
   2434    functions->ClipPlane			= r200ClipPlane;
   2435    functions->ColorMask			= r200ColorMask;
   2436    functions->CullFace			= r200CullFace;
   2437    functions->DepthFunc			= r200DepthFunc;
   2438    functions->DepthMask			= r200DepthMask;
   2439    functions->DepthRange		= r200DepthRange;
   2440    functions->Enable			= r200Enable;
   2441    functions->Fogfv			= r200Fogfv;
   2442    functions->FrontFace			= r200FrontFace;
   2443    functions->Hint			= NULL;
   2444    functions->LightModelfv		= r200LightModelfv;
   2445    functions->Lightfv			= r200Lightfv;
   2446    functions->LineStipple		= r200LineStipple;
   2447    functions->LineWidth			= r200LineWidth;
   2448    functions->LogicOpcode		= r200LogicOpCode;
   2449    functions->PolygonMode		= r200PolygonMode;
   2450    functions->PolygonOffset		= r200PolygonOffset;
   2451    functions->PolygonStipple		= r200PolygonStipple;
   2452    functions->PointParameterfv		= r200PointParameter;
   2453    functions->PointSize			= r200PointSize;
   2454    functions->RenderMode		= r200RenderMode;
   2455    functions->Scissor			= radeonScissor;
   2456    functions->ShadeModel		= r200ShadeModel;
   2457    functions->StencilFuncSeparate	= r200StencilFuncSeparate;
   2458    functions->StencilMaskSeparate	= r200StencilMaskSeparate;
   2459    functions->StencilOpSeparate		= r200StencilOpSeparate;
   2460    functions->Viewport			= r200Viewport;
   2461 }
   2462 
   2463 
   2464 void r200InitTnlFuncs( struct gl_context *ctx )
   2465 {
   2466    TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = r200UpdateMaterial;
   2467    TNL_CONTEXT(ctx)->Driver.RunPipeline = r200WrapRunPipeline;
   2468 }
   2469