Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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