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