Subversion Repositories Kolibri OS

Rev

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

  1. /**************************************************************************
  2.  
  3. Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
  4.  
  5. All Rights Reserved.
  6.  
  7. Permission is hereby granted, free of charge, to any person obtaining
  8. a copy of this software and associated documentation files (the
  9. "Software"), to deal in the Software without restriction, including
  10. without limitation the rights to use, copy, modify, merge, publish,
  11. distribute, sublicense, and/or sell copies of the Software, and to
  12. permit persons to whom the Software is furnished to do so, subject to
  13. the following conditions:
  14.  
  15. The above copyright notice and this permission notice (including the
  16. next paragraph) shall be included in all copies or substantial
  17. portions of the Software.
  18.  
  19. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  20. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  22. IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
  23. LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  24. OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  25. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26.  
  27. **************************************************************************/
  28.  
  29. /*
  30.  * Authors:
  31.  *   Gareth Hughes <gareth@valinux.com>
  32.  *   Keith Whitwell <keith@tungstengraphics.com>
  33.  */
  34.  
  35. #include "main/glheader.h"
  36. #include "main/imports.h"
  37. #include "main/api_arrayelt.h"
  38. #include "main/enums.h"
  39. #include "main/light.h"
  40. #include "main/context.h"
  41. #include "main/framebuffer.h"
  42. #include "main/fbobject.h"
  43. #include "main/simple_list.h"
  44. #include "main/state.h"
  45. #include "main/core.h"
  46. #include "main/stencil.h"
  47.  
  48. #include "vbo/vbo.h"
  49. #include "tnl/tnl.h"
  50. #include "tnl/t_pipeline.h"
  51. #include "swrast_setup/swrast_setup.h"
  52. #include "drivers/common/meta.h"
  53.  
  54. #include "radeon_context.h"
  55. #include "radeon_mipmap_tree.h"
  56. #include "radeon_ioctl.h"
  57. #include "radeon_state.h"
  58. #include "radeon_tcl.h"
  59. #include "radeon_tex.h"
  60. #include "radeon_swtcl.h"
  61.  
  62. static void radeonUpdateSpecular( struct gl_context *ctx );
  63.  
  64. /* =============================================================
  65.  * Alpha blending
  66.  */
  67.  
  68. static void radeonAlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref )
  69. {
  70.    r100ContextPtr rmesa = R100_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.    RADEON_STATECHANGE( rmesa, ctx );
  77.  
  78.    pp_misc &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK);
  79.    pp_misc |= (refByte & RADEON_REF_ALPHA_MASK);
  80.  
  81.    switch ( func ) {
  82.    case GL_NEVER:
  83.       pp_misc |= RADEON_ALPHA_TEST_FAIL;
  84.       break;
  85.    case GL_LESS:
  86.       pp_misc |= RADEON_ALPHA_TEST_LESS;
  87.       break;
  88.    case GL_EQUAL:
  89.       pp_misc |= RADEON_ALPHA_TEST_EQUAL;
  90.       break;
  91.    case GL_LEQUAL:
  92.       pp_misc |= RADEON_ALPHA_TEST_LEQUAL;
  93.       break;
  94.    case GL_GREATER:
  95.       pp_misc |= RADEON_ALPHA_TEST_GREATER;
  96.       break;
  97.    case GL_NOTEQUAL:
  98.       pp_misc |= RADEON_ALPHA_TEST_NEQUAL;
  99.       break;
  100.    case GL_GEQUAL:
  101.       pp_misc |= RADEON_ALPHA_TEST_GEQUAL;
  102.       break;
  103.    case GL_ALWAYS:
  104.       pp_misc |= RADEON_ALPHA_TEST_PASS;
  105.       break;
  106.    }
  107.  
  108.    rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
  109. }
  110.  
  111. static void radeonBlendEquationSeparate( struct gl_context *ctx,
  112.                                          GLenum modeRGB, GLenum modeA )
  113. {
  114.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  115.    GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & ~RADEON_COMB_FCN_MASK;
  116.    GLboolean fallback = GL_FALSE;
  117.  
  118.    assert( modeRGB == modeA );
  119.  
  120.    switch ( modeRGB ) {
  121.    case GL_FUNC_ADD:
  122.    case GL_LOGIC_OP:
  123.       b |= RADEON_COMB_FCN_ADD_CLAMP;
  124.       break;
  125.  
  126.    case GL_FUNC_SUBTRACT:
  127.       b |= RADEON_COMB_FCN_SUB_CLAMP;
  128.       break;
  129.  
  130.    default:
  131.       if (ctx->Color.BlendEnabled)
  132.          fallback = GL_TRUE;
  133.       else
  134.          b |= RADEON_COMB_FCN_ADD_CLAMP;
  135.       break;
  136.    }
  137.  
  138.    FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, fallback );
  139.    if ( !fallback ) {
  140.       RADEON_STATECHANGE( rmesa, ctx );
  141.       rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
  142.       if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
  143.             && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
  144.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
  145.       } else {
  146.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
  147.       }
  148.    }
  149. }
  150.  
  151. static void radeonBlendFuncSeparate( struct gl_context *ctx,
  152.                                      GLenum sfactorRGB, GLenum dfactorRGB,
  153.                                      GLenum sfactorA, GLenum dfactorA )
  154. {
  155.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  156.    GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] &
  157.       ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK);
  158.    GLboolean fallback = GL_FALSE;
  159.  
  160.    switch ( ctx->Color.Blend[0].SrcRGB ) {
  161.    case GL_ZERO:
  162.       b |= RADEON_SRC_BLEND_GL_ZERO;
  163.       break;
  164.    case GL_ONE:
  165.       b |= RADEON_SRC_BLEND_GL_ONE;
  166.       break;
  167.    case GL_DST_COLOR:
  168.       b |= RADEON_SRC_BLEND_GL_DST_COLOR;
  169.       break;
  170.    case GL_ONE_MINUS_DST_COLOR:
  171.       b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR;
  172.       break;
  173.    case GL_SRC_COLOR:
  174.       b |= RADEON_SRC_BLEND_GL_SRC_COLOR;
  175.       break;
  176.    case GL_ONE_MINUS_SRC_COLOR:
  177.       b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR;
  178.       break;
  179.    case GL_SRC_ALPHA:
  180.       b |= RADEON_SRC_BLEND_GL_SRC_ALPHA;
  181.       break;
  182.    case GL_ONE_MINUS_SRC_ALPHA:
  183.       b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA;
  184.       break;
  185.    case GL_DST_ALPHA:
  186.       b |= RADEON_SRC_BLEND_GL_DST_ALPHA;
  187.       break;
  188.    case GL_ONE_MINUS_DST_ALPHA:
  189.       b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA;
  190.       break;
  191.    case GL_SRC_ALPHA_SATURATE:
  192.       b |= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE;
  193.       break;
  194.    case GL_CONSTANT_COLOR:
  195.    case GL_ONE_MINUS_CONSTANT_COLOR:
  196.    case GL_CONSTANT_ALPHA:
  197.    case GL_ONE_MINUS_CONSTANT_ALPHA:
  198.       if (ctx->Color.BlendEnabled)
  199.          fallback = GL_TRUE;
  200.       else
  201.          b |= RADEON_SRC_BLEND_GL_ONE;
  202.       break;
  203.    default:
  204.       break;
  205.    }
  206.  
  207.    switch ( ctx->Color.Blend[0].DstRGB ) {
  208.    case GL_ZERO:
  209.       b |= RADEON_DST_BLEND_GL_ZERO;
  210.       break;
  211.    case GL_ONE:
  212.       b |= RADEON_DST_BLEND_GL_ONE;
  213.       break;
  214.    case GL_SRC_COLOR:
  215.       b |= RADEON_DST_BLEND_GL_SRC_COLOR;
  216.       break;
  217.    case GL_ONE_MINUS_SRC_COLOR:
  218.       b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR;
  219.       break;
  220.    case GL_SRC_ALPHA:
  221.       b |= RADEON_DST_BLEND_GL_SRC_ALPHA;
  222.       break;
  223.    case GL_ONE_MINUS_SRC_ALPHA:
  224.       b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA;
  225.       break;
  226.    case GL_DST_COLOR:
  227.       b |= RADEON_DST_BLEND_GL_DST_COLOR;
  228.       break;
  229.    case GL_ONE_MINUS_DST_COLOR:
  230.       b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR;
  231.       break;
  232.    case GL_DST_ALPHA:
  233.       b |= RADEON_DST_BLEND_GL_DST_ALPHA;
  234.       break;
  235.    case GL_ONE_MINUS_DST_ALPHA:
  236.       b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA;
  237.       break;
  238.    case GL_CONSTANT_COLOR:
  239.    case GL_ONE_MINUS_CONSTANT_COLOR:
  240.    case GL_CONSTANT_ALPHA:
  241.    case GL_ONE_MINUS_CONSTANT_ALPHA:
  242.       if (ctx->Color.BlendEnabled)
  243.          fallback = GL_TRUE;
  244.       else
  245.          b |= RADEON_DST_BLEND_GL_ZERO;
  246.       break;
  247.    default:
  248.       break;
  249.    }
  250.  
  251.    FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, fallback );
  252.    if ( !fallback ) {
  253.       RADEON_STATECHANGE( rmesa, ctx );
  254.       rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
  255.    }
  256. }
  257.  
  258.  
  259. /* =============================================================
  260.  * Depth testing
  261.  */
  262.  
  263. static void radeonDepthFunc( struct gl_context *ctx, GLenum func )
  264. {
  265.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  266.  
  267.    RADEON_STATECHANGE( rmesa, ctx );
  268.    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_TEST_MASK;
  269.  
  270.    switch ( ctx->Depth.Func ) {
  271.    case GL_NEVER:
  272.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEVER;
  273.       break;
  274.    case GL_LESS:
  275.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LESS;
  276.       break;
  277.    case GL_EQUAL:
  278.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_EQUAL;
  279.       break;
  280.    case GL_LEQUAL:
  281.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_LEQUAL;
  282.       break;
  283.    case GL_GREATER:
  284.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GREATER;
  285.       break;
  286.    case GL_NOTEQUAL:
  287.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_NEQUAL;
  288.       break;
  289.    case GL_GEQUAL:
  290.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_GEQUAL;
  291.       break;
  292.    case GL_ALWAYS:
  293.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_TEST_ALWAYS;
  294.       break;
  295.    }
  296. }
  297.  
  298.  
  299. static void radeonDepthMask( struct gl_context *ctx, GLboolean flag )
  300. {
  301.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  302.    RADEON_STATECHANGE( rmesa, ctx );
  303.  
  304.    if ( ctx->Depth.Mask ) {
  305.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |=  RADEON_Z_WRITE_ENABLE;
  306.    } else {
  307.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_Z_WRITE_ENABLE;
  308.    }
  309. }
  310.  
  311.  
  312. /* =============================================================
  313.  * Fog
  314.  */
  315.  
  316.  
  317. static void radeonFogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param )
  318. {
  319.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  320.    union { int i; float f; } c, d;
  321.    GLubyte col[4];
  322.  
  323.    switch (pname) {
  324.    case GL_FOG_MODE:
  325.       if (!ctx->Fog.Enabled)
  326.          return;
  327.       RADEON_STATECHANGE(rmesa, tcl);
  328.       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
  329.       switch (ctx->Fog.Mode) {
  330.       case GL_LINEAR:
  331.          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR;
  332.          break;
  333.       case GL_EXP:
  334.          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP;
  335.          break;
  336.       case GL_EXP2:
  337.          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2;
  338.          break;
  339.       default:
  340.          return;
  341.       }
  342.    /* fallthrough */
  343.    case GL_FOG_DENSITY:
  344.    case GL_FOG_START:
  345.    case GL_FOG_END:
  346.       if (!ctx->Fog.Enabled)
  347.          return;
  348.       c.i = rmesa->hw.fog.cmd[FOG_C];
  349.       d.i = rmesa->hw.fog.cmd[FOG_D];
  350.       switch (ctx->Fog.Mode) {
  351.       case GL_EXP:
  352.          c.f = 0.0;
  353.          /* While this is the opposite sign from the DDK, it makes the fog test
  354.           * pass, and matches r200.
  355.           */
  356.          d.f = -ctx->Fog.Density;
  357.          break;
  358.       case GL_EXP2:
  359.          c.f = 0.0;
  360.          d.f = -(ctx->Fog.Density * ctx->Fog.Density);
  361.          break;
  362.       case GL_LINEAR:
  363.          if (ctx->Fog.Start == ctx->Fog.End) {
  364.             c.f = 1.0F;
  365.             d.f = 1.0F;
  366.          } else {
  367.             c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
  368.             /* While this is the opposite sign from the DDK, it makes the fog
  369.              * test pass, and matches r200.
  370.              */
  371.             d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
  372.          }
  373.          break;
  374.       default:
  375.          break;
  376.       }
  377.       if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
  378.          RADEON_STATECHANGE( rmesa, fog );
  379.          rmesa->hw.fog.cmd[FOG_C] = c.i;
  380.          rmesa->hw.fog.cmd[FOG_D] = d.i;
  381.       }
  382.       break;
  383.    case GL_FOG_COLOR:
  384.       RADEON_STATECHANGE( rmesa, ctx );
  385.       _mesa_unclamped_float_rgba_to_ubyte(col, ctx->Fog.Color );
  386.       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~RADEON_FOG_COLOR_MASK;
  387.       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |=
  388.          radeonPackColor( 4, col[0], col[1], col[2], 0 );
  389.       break;
  390.    case GL_FOG_COORD_SRC:
  391.       radeonUpdateSpecular( ctx );
  392.       break;
  393.    default:
  394.       return;
  395.    }
  396. }
  397.  
  398. /* =============================================================
  399.  * Culling
  400.  */
  401.  
  402. static void radeonCullFace( struct gl_context *ctx, GLenum unused )
  403. {
  404.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  405.    GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
  406.    GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL];
  407.  
  408.    s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID;
  409.    t &= ~(RADEON_CULL_FRONT | RADEON_CULL_BACK);
  410.  
  411.    if ( ctx->Polygon.CullFlag ) {
  412.       switch ( ctx->Polygon.CullFaceMode ) {
  413.       case GL_FRONT:
  414.          s &= ~RADEON_FFACE_SOLID;
  415.          t |= RADEON_CULL_FRONT;
  416.          break;
  417.       case GL_BACK:
  418.          s &= ~RADEON_BFACE_SOLID;
  419.          t |= RADEON_CULL_BACK;
  420.          break;
  421.       case GL_FRONT_AND_BACK:
  422.          s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID);
  423.          t |= (RADEON_CULL_FRONT | RADEON_CULL_BACK);
  424.          break;
  425.       }
  426.    }
  427.  
  428.    if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
  429.       RADEON_STATECHANGE(rmesa, set );
  430.       rmesa->hw.set.cmd[SET_SE_CNTL] = s;
  431.    }
  432.  
  433.    if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) {
  434.       RADEON_STATECHANGE(rmesa, tcl );
  435.       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t;
  436.    }
  437. }
  438.  
  439. static void radeonFrontFace( struct gl_context *ctx, GLenum mode )
  440. {
  441.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  442.    int cull_face = (mode == GL_CW) ? RADEON_FFACE_CULL_CW : RADEON_FFACE_CULL_CCW;
  443.  
  444.    RADEON_STATECHANGE( rmesa, set );
  445.    rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_FFACE_CULL_DIR_MASK;
  446.  
  447.    RADEON_STATECHANGE( rmesa, tcl );
  448.    rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW;
  449.  
  450.    /* Winding is inverted when rendering to FBO */
  451.    if (ctx->DrawBuffer && _mesa_is_user_fbo(ctx->DrawBuffer))
  452.       cull_face = (mode == GL_CCW) ? RADEON_FFACE_CULL_CW : RADEON_FFACE_CULL_CCW;
  453.    rmesa->hw.set.cmd[SET_SE_CNTL] |= cull_face;
  454.  
  455.    if ( mode == GL_CCW )
  456.       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_CULL_FRONT_IS_CCW;
  457. }
  458.  
  459.  
  460. /* =============================================================
  461.  * Line state
  462.  */
  463. static void radeonLineWidth( struct gl_context *ctx, GLfloat widthf )
  464. {
  465.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  466.  
  467.    RADEON_STATECHANGE( rmesa, lin );
  468.    RADEON_STATECHANGE( rmesa, set );
  469.  
  470.    /* Line width is stored in U6.4 format.
  471.     */
  472.    rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (GLuint)(widthf * 16.0);
  473.    if ( widthf > 1.0 ) {
  474.       rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_WIDELINE_ENABLE;
  475.    } else {
  476.       rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_WIDELINE_ENABLE;
  477.    }
  478. }
  479.  
  480. static void radeonLineStipple( struct gl_context *ctx, GLint factor, GLushort pattern )
  481. {
  482.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  483.  
  484.    RADEON_STATECHANGE( rmesa, lin );
  485.    rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
  486.       ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
  487. }
  488.  
  489.  
  490. /* =============================================================
  491.  * Masks
  492.  */
  493. static void radeonColorMask( struct gl_context *ctx,
  494.                              GLboolean r, GLboolean g,
  495.                              GLboolean b, GLboolean a )
  496. {
  497.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  498.    struct radeon_renderbuffer *rrb;
  499.    GLuint mask;
  500.  
  501.    rrb = radeon_get_colorbuffer(&rmesa->radeon);
  502.    if (!rrb)
  503.      return;
  504.  
  505.    mask = radeonPackColor( rrb->cpp,
  506.                            ctx->Color.ColorMask[0][RCOMP],
  507.                            ctx->Color.ColorMask[0][GCOMP],
  508.                            ctx->Color.ColorMask[0][BCOMP],
  509.                            ctx->Color.ColorMask[0][ACOMP] );
  510.  
  511.    if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
  512.       RADEON_STATECHANGE( rmesa, msk );
  513.       rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;
  514.    }
  515. }
  516.  
  517.  
  518. /* =============================================================
  519.  * Polygon state
  520.  */
  521.  
  522. static void radeonPolygonOffset( struct gl_context *ctx,
  523.                                  GLfloat factor, GLfloat units )
  524. {
  525.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  526.    const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
  527.    float_ui32_type constant =  { units * depthScale };
  528.    float_ui32_type factoru = { factor };
  529.  
  530.    RADEON_STATECHANGE( rmesa, zbs );
  531.    rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR]   = factoru.ui32;
  532.    rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
  533. }
  534.  
  535. static void radeonPolygonMode( struct gl_context *ctx, GLenum face, GLenum mode )
  536. {
  537.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  538.    GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL ||
  539.                          ctx->Polygon.BackMode != GL_FILL);
  540.  
  541.    /* Can't generally do unfilled via tcl, but some good special
  542.     * cases work.
  543.     */
  544.    TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, unfilled);
  545.    if (rmesa->radeon.TclFallback) {
  546.       radeonChooseRenderState( ctx );
  547.       radeonChooseVertexState( ctx );
  548.    }
  549. }
  550.  
  551.  
  552. /* =============================================================
  553.  * Rendering attributes
  554.  *
  555.  * We really don't want to recalculate all this every time we bind a
  556.  * texture.  These things shouldn't change all that often, so it makes
  557.  * sense to break them out of the core texture state update routines.
  558.  */
  559.  
  560. /* Examine lighting and texture state to determine if separate specular
  561.  * should be enabled.
  562.  */
  563. static void radeonUpdateSpecular( struct gl_context *ctx )
  564. {
  565.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  566.    uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
  567.    GLuint flag = 0;
  568.  
  569.    RADEON_STATECHANGE( rmesa, tcl );
  570.  
  571.    rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_SPECULAR;
  572.    rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &= ~RADEON_TCL_COMPUTE_DIFFUSE;
  573.    rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_SPEC;
  574.    rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~RADEON_TCL_VTX_PK_DIFFUSE;
  575.    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LIGHTING_ENABLE;
  576.  
  577.    p &= ~RADEON_SPECULAR_ENABLE;
  578.  
  579.    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_DIFFUSE_SPECULAR_COMBINE;
  580.  
  581.  
  582.    if (ctx->Light.Enabled &&
  583.        ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
  584.       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
  585.       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
  586.       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
  587.       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
  588.       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
  589.       p |=  RADEON_SPECULAR_ENABLE;
  590.       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &=
  591.          ~RADEON_DIFFUSE_SPECULAR_COMBINE;
  592.    }
  593.    else if (ctx->Light.Enabled) {
  594.       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_DIFFUSE;
  595.       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
  596.       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
  597.    } else if (ctx->Fog.ColorSumEnabled ) {
  598.       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
  599.       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
  600.       p |= RADEON_SPECULAR_ENABLE;
  601.    } else {
  602.       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
  603.    }
  604.  
  605.    if (ctx->Fog.Enabled) {
  606.       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
  607.       if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) {
  608.          rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
  609.       /* Bizzare: have to leave lighting enabled to get fog. */
  610.          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
  611.       }
  612.       else {
  613.       /* cannot do tcl fog factor calculation with fog coord source
  614.        * (send precomputed factors). Cannot use precomputed fog
  615.        * factors together with tcl spec light (need tcl fallback) */
  616.          flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &
  617.             RADEON_TCL_COMPUTE_SPECULAR) != 0;
  618.       }
  619.    }
  620.  
  621.    TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag);
  622.  
  623.    if (_mesa_need_secondary_color(ctx)) {
  624.       assert( (p & RADEON_SPECULAR_ENABLE) != 0 );
  625.    } else {
  626.       assert( (p & RADEON_SPECULAR_ENABLE) == 0 );
  627.    }
  628.  
  629.    if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
  630.       RADEON_STATECHANGE( rmesa, ctx );
  631.       rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
  632.    }
  633.  
  634.    /* Update vertex/render formats
  635.     */
  636.    if (rmesa->radeon.TclFallback) {
  637.       radeonChooseRenderState( ctx );
  638.       radeonChooseVertexState( ctx );
  639.    }
  640. }
  641.  
  642.  
  643. /* =============================================================
  644.  * Materials
  645.  */
  646.  
  647.  
  648. /* Update on colormaterial, material emmissive/ambient,
  649.  * lightmodel.globalambient
  650.  */
  651. static void update_global_ambient( struct gl_context *ctx )
  652. {
  653.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  654.    float *fcmd = (float *)RADEON_DB_STATE( glt );
  655.  
  656.    /* Need to do more if both emmissive & ambient are PREMULT:
  657.     * Hope this is not needed for MULT
  658.     */
  659.    if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &
  660.        ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
  661.         (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0)
  662.    {
  663.       COPY_3V( &fcmd[GLT_RED],
  664.                ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
  665.       ACC_SCALE_3V( &fcmd[GLT_RED],
  666.                    ctx->Light.Model.Ambient,
  667.                    ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
  668.    }
  669.    else
  670.    {
  671.       COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
  672.    }
  673.  
  674.    RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
  675. }
  676.  
  677. /* Update on change to
  678.  *    - light[p].colors
  679.  *    - light[p].enabled
  680.  */
  681. static void update_light_colors( struct gl_context *ctx, GLuint p )
  682. {
  683.    struct gl_light *l = &ctx->Light.Light[p];
  684.  
  685. /*     fprintf(stderr, "%s\n", __FUNCTION__); */
  686.  
  687.    if (l->Enabled) {
  688.       r100ContextPtr rmesa = R100_CONTEXT(ctx);
  689.       float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
  690.  
  691.       COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
  692.       COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
  693.       COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
  694.  
  695.       RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
  696.    }
  697. }
  698.  
  699. /* Also fallback for asym colormaterial mode in twoside lighting...
  700.  */
  701. static void check_twoside_fallback( struct gl_context *ctx )
  702. {
  703.    GLboolean fallback = GL_FALSE;
  704.    GLint i;
  705.  
  706.    if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
  707.       if (ctx->Light.ColorMaterialEnabled &&
  708.           (ctx->Light._ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
  709.           ((ctx->Light._ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
  710.          fallback = GL_TRUE;
  711.       else {
  712.          for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2)
  713.             if (memcmp( ctx->Light.Material.Attrib[i],
  714.                         ctx->Light.Material.Attrib[i+1],
  715.                         sizeof(GLfloat)*4) != 0) {
  716.                fallback = GL_TRUE;
  717.                break;
  718.             }
  719.       }
  720.    }
  721.  
  722.    TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_LIGHT_TWOSIDE, fallback );
  723. }
  724.  
  725.  
  726. static void radeonColorMaterial( struct gl_context *ctx, GLenum face, GLenum mode )
  727. {
  728.       r100ContextPtr rmesa = R100_CONTEXT(ctx);
  729.       GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
  730.  
  731.       light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
  732.                            (3 << RADEON_AMBIENT_SOURCE_SHIFT) |
  733.                            (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
  734.                            (3 << RADEON_SPECULAR_SOURCE_SHIFT));
  735.  
  736.    if (ctx->Light.ColorMaterialEnabled) {
  737.       GLuint mask = ctx->Light._ColorMaterialBitmask;
  738.  
  739.       if (mask & MAT_BIT_FRONT_EMISSION) {
  740.          light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
  741.                              RADEON_EMISSIVE_SOURCE_SHIFT);
  742.       }
  743.       else {
  744.          light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
  745.                              RADEON_EMISSIVE_SOURCE_SHIFT);
  746.       }
  747.  
  748.       if (mask & MAT_BIT_FRONT_AMBIENT) {
  749.          light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
  750.                              RADEON_AMBIENT_SOURCE_SHIFT);
  751.       }
  752.       else {
  753.          light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
  754.                              RADEON_AMBIENT_SOURCE_SHIFT);
  755.       }
  756.  
  757.       if (mask & MAT_BIT_FRONT_DIFFUSE) {
  758.          light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
  759.                              RADEON_DIFFUSE_SOURCE_SHIFT);
  760.       }
  761.       else {
  762.          light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
  763.                              RADEON_DIFFUSE_SOURCE_SHIFT);
  764.       }
  765.  
  766.       if (mask & MAT_BIT_FRONT_SPECULAR) {
  767.          light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
  768.                              RADEON_SPECULAR_SOURCE_SHIFT);
  769.       }
  770.       else {
  771.          light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
  772.                              RADEON_SPECULAR_SOURCE_SHIFT);
  773.       }
  774.    }
  775.    else {
  776.    /* Default to MULT:
  777.     */
  778.       light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) |
  779.                    (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) |
  780.                    (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
  781.                    (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT);
  782.    }
  783.  
  784.       if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
  785.          RADEON_STATECHANGE( rmesa, tcl );
  786.          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1;
  787.    }
  788. }
  789.  
  790. void radeonUpdateMaterial( struct gl_context *ctx )
  791. {
  792.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  793.    GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
  794.    GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );
  795.    GLuint mask = ~0;
  796.  
  797.    if (ctx->Light.ColorMaterialEnabled)
  798.       mask &= ~ctx->Light._ColorMaterialBitmask;
  799.  
  800.    if (RADEON_DEBUG & RADEON_STATE)
  801.       fprintf(stderr, "%s\n", __FUNCTION__);
  802.  
  803.  
  804.    if (mask & MAT_BIT_FRONT_EMISSION) {
  805.       fcmd[MTL_EMMISSIVE_RED]   = mat[MAT_ATTRIB_FRONT_EMISSION][0];
  806.       fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
  807.       fcmd[MTL_EMMISSIVE_BLUE]  = mat[MAT_ATTRIB_FRONT_EMISSION][2];
  808.       fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
  809.    }
  810.    if (mask & MAT_BIT_FRONT_AMBIENT) {
  811.       fcmd[MTL_AMBIENT_RED]     = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
  812.       fcmd[MTL_AMBIENT_GREEN]   = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
  813.       fcmd[MTL_AMBIENT_BLUE]    = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
  814.       fcmd[MTL_AMBIENT_ALPHA]   = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
  815.    }
  816.    if (mask & MAT_BIT_FRONT_DIFFUSE) {
  817.       fcmd[MTL_DIFFUSE_RED]     = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
  818.       fcmd[MTL_DIFFUSE_GREEN]   = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
  819.       fcmd[MTL_DIFFUSE_BLUE]    = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
  820.       fcmd[MTL_DIFFUSE_ALPHA]   = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
  821.    }
  822.    if (mask & MAT_BIT_FRONT_SPECULAR) {
  823.       fcmd[MTL_SPECULAR_RED]    = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
  824.       fcmd[MTL_SPECULAR_GREEN]  = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
  825.       fcmd[MTL_SPECULAR_BLUE]   = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
  826.       fcmd[MTL_SPECULAR_ALPHA]  = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
  827.    }
  828.    if (mask & MAT_BIT_FRONT_SHININESS) {
  829.       fcmd[MTL_SHININESS]       = mat[MAT_ATTRIB_FRONT_SHININESS][0];
  830.    }
  831.  
  832.    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mtl );
  833.  
  834.    check_twoside_fallback( ctx );
  835. /*   update_global_ambient( ctx );*/
  836. }
  837.  
  838. /* _NEW_LIGHT
  839.  * _NEW_MODELVIEW
  840.  * _MESA_NEW_NEED_EYE_COORDS
  841.  *
  842.  * Uses derived state from mesa:
  843.  *       _VP_inf_norm
  844.  *       _h_inf_norm
  845.  *       _Position
  846.  *       _NormSpotDirection
  847.  *       _ModelViewInvScale
  848.  *       _NeedEyeCoords
  849.  *       _EyeZDir
  850.  *
  851.  * which are calculated in light.c and are correct for the current
  852.  * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
  853.  * and _MESA_NEW_NEED_EYE_COORDS.
  854.  */
  855. static void update_light( struct gl_context *ctx )
  856. {
  857.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  858.  
  859.    /* Have to check these, or have an automatic shortcircuit mechanism
  860.     * to remove noop statechanges. (Or just do a better job on the
  861.     * front end).
  862.     */
  863.    {
  864.       GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL];
  865.  
  866.       if (ctx->_NeedEyeCoords)
  867.          tmp &= ~RADEON_LIGHT_IN_MODELSPACE;
  868.       else
  869.          tmp |= RADEON_LIGHT_IN_MODELSPACE;
  870.  
  871.  
  872.       /* Leave this test disabled: (unexplained q3 lockup) (even with
  873.          new packets)
  874.       */
  875.       if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])
  876.       {
  877.          RADEON_STATECHANGE( rmesa, tcl );
  878.          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;
  879.       }
  880.    }
  881.  
  882.    {
  883.       GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( eye );
  884.       fcmd[EYE_X] = ctx->_EyeZDir[0];
  885.       fcmd[EYE_Y] = ctx->_EyeZDir[1];
  886.       fcmd[EYE_Z] = - ctx->_EyeZDir[2];
  887.       fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
  888.       RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
  889.    }
  890.  
  891.  
  892.  
  893.    if (ctx->Light.Enabled) {
  894.       GLint p;
  895.       for (p = 0 ; p < MAX_LIGHTS; p++) {
  896.          if (ctx->Light.Light[p].Enabled) {
  897.             struct gl_light *l = &ctx->Light.Light[p];
  898.             GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );
  899.  
  900.             if (l->EyePosition[3] == 0.0) {
  901.                COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
  902.                COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
  903.                fcmd[LIT_POSITION_W] = 0;
  904.                fcmd[LIT_DIRECTION_W] = 0;
  905.             } else {
  906.                COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
  907.                fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
  908.                fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
  909.                fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
  910.                fcmd[LIT_DIRECTION_W] = 0;
  911.             }
  912.  
  913.             RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
  914.          }
  915.       }
  916.    }
  917. }
  918.  
  919. static void radeonLightfv( struct gl_context *ctx, GLenum light,
  920.                            GLenum pname, const GLfloat *params )
  921. {
  922.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  923.    GLint p = light - GL_LIGHT0;
  924.    struct gl_light *l = &ctx->Light.Light[p];
  925.    GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
  926.  
  927.  
  928.    switch (pname) {
  929.    case GL_AMBIENT:
  930.    case GL_DIFFUSE:
  931.    case GL_SPECULAR:
  932.       update_light_colors( ctx, p );
  933.       break;
  934.  
  935.    case GL_SPOT_DIRECTION:
  936.       /* picked up in update_light */
  937.       break;
  938.  
  939.    case GL_POSITION: {
  940.       /* positions picked up in update_light, but can do flag here */
  941.       GLuint flag;
  942.       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
  943.  
  944.       /* FIXME: Set RANGE_ATTEN only when needed */
  945.       if (p&1)
  946.          flag = RADEON_LIGHT_1_IS_LOCAL;
  947.       else
  948.          flag = RADEON_LIGHT_0_IS_LOCAL;
  949.  
  950.       RADEON_STATECHANGE(rmesa, tcl);
  951.       if (l->EyePosition[3] != 0.0F)
  952.          rmesa->hw.tcl.cmd[idx] |= flag;
  953.       else
  954.          rmesa->hw.tcl.cmd[idx] &= ~flag;
  955.       break;
  956.    }
  957.  
  958.    case GL_SPOT_EXPONENT:
  959.       RADEON_STATECHANGE(rmesa, lit[p]);
  960.       fcmd[LIT_SPOT_EXPONENT] = params[0];
  961.       break;
  962.  
  963.    case GL_SPOT_CUTOFF: {
  964.       GLuint flag = (p&1) ? RADEON_LIGHT_1_IS_SPOT : RADEON_LIGHT_0_IS_SPOT;
  965.       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
  966.  
  967.       RADEON_STATECHANGE(rmesa, lit[p]);
  968.       fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
  969.  
  970.       RADEON_STATECHANGE(rmesa, tcl);
  971.       if (l->SpotCutoff != 180.0F)
  972.          rmesa->hw.tcl.cmd[idx] |= flag;
  973.       else
  974.          rmesa->hw.tcl.cmd[idx] &= ~flag;
  975.  
  976.       break;
  977.    }
  978.  
  979.    case GL_CONSTANT_ATTENUATION:
  980.       RADEON_STATECHANGE(rmesa, lit[p]);
  981.       fcmd[LIT_ATTEN_CONST] = params[0];
  982.       if ( params[0] == 0.0 )
  983.          fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
  984.       else
  985.          fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
  986.       break;
  987.    case GL_LINEAR_ATTENUATION:
  988.       RADEON_STATECHANGE(rmesa, lit[p]);
  989.       fcmd[LIT_ATTEN_LINEAR] = params[0];
  990.       break;
  991.    case GL_QUADRATIC_ATTENUATION:
  992.       RADEON_STATECHANGE(rmesa, lit[p]);
  993.       fcmd[LIT_ATTEN_QUADRATIC] = params[0];
  994.       break;
  995.    default:
  996.       return;
  997.    }
  998.  
  999.    /* Set RANGE_ATTEN only when needed */
  1000.    switch (pname) {
  1001.    case GL_POSITION:
  1002.    case GL_CONSTANT_ATTENUATION:
  1003.    case GL_LINEAR_ATTENUATION:
  1004.    case GL_QUADRATIC_ATTENUATION:
  1005.    {
  1006.       GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl );
  1007.       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
  1008.       GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN
  1009.                                   : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN;
  1010.       GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN
  1011.                                   : RADEON_LIGHT_0_CONSTANT_RANGE_ATTEN;
  1012.  
  1013.       if ( l->EyePosition[3] == 0.0F ||
  1014.            ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
  1015.              fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
  1016.          /* Disable attenuation */
  1017.          icmd[idx] &= ~atten_flag;
  1018.       } else {
  1019.          if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
  1020.             /* Enable only constant portion of attenuation calculation */
  1021.             icmd[idx] |= ( atten_flag | atten_const_flag );
  1022.          } else {
  1023.             /* Enable full attenuation calculation */
  1024.             icmd[idx] &= ~atten_const_flag;
  1025.             icmd[idx] |= atten_flag;
  1026.          }
  1027.       }
  1028.  
  1029.       RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
  1030.       break;
  1031.    }
  1032.    default:
  1033.       break;
  1034.    }
  1035. }
  1036.  
  1037.  
  1038.  
  1039.  
  1040. static void radeonLightModelfv( struct gl_context *ctx, GLenum pname,
  1041.                                 const GLfloat *param )
  1042. {
  1043.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1044.  
  1045.    switch (pname) {
  1046.       case GL_LIGHT_MODEL_AMBIENT:
  1047.          update_global_ambient( ctx );
  1048.          break;
  1049.  
  1050.       case GL_LIGHT_MODEL_LOCAL_VIEWER:
  1051.          RADEON_STATECHANGE( rmesa, tcl );
  1052.          if (ctx->Light.Model.LocalViewer)
  1053.             rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LOCAL_VIEWER;
  1054.          else
  1055.             rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_LOCAL_VIEWER;
  1056.          break;
  1057.  
  1058.       case GL_LIGHT_MODEL_TWO_SIDE:
  1059.          RADEON_STATECHANGE( rmesa, tcl );
  1060.          if (ctx->Light.Model.TwoSide)
  1061.             rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_LIGHT_TWOSIDE;
  1062.          else
  1063.             rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_LIGHT_TWOSIDE;
  1064.  
  1065.          check_twoside_fallback( ctx );
  1066.  
  1067.          if (rmesa->radeon.TclFallback) {
  1068.             radeonChooseRenderState( ctx );
  1069.             radeonChooseVertexState( ctx );
  1070.          }
  1071.          break;
  1072.  
  1073.       case GL_LIGHT_MODEL_COLOR_CONTROL:
  1074.          radeonUpdateSpecular(ctx);
  1075.          break;
  1076.  
  1077.       default:
  1078.          break;
  1079.    }
  1080. }
  1081.  
  1082. static void radeonShadeModel( struct gl_context *ctx, GLenum mode )
  1083. {
  1084.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1085.    GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
  1086.  
  1087.    s &= ~(RADEON_DIFFUSE_SHADE_MASK |
  1088.           RADEON_ALPHA_SHADE_MASK |
  1089.           RADEON_SPECULAR_SHADE_MASK |
  1090.           RADEON_FOG_SHADE_MASK);
  1091.  
  1092.    switch ( mode ) {
  1093.    case GL_FLAT:
  1094.       s |= (RADEON_DIFFUSE_SHADE_FLAT |
  1095.             RADEON_ALPHA_SHADE_FLAT |
  1096.             RADEON_SPECULAR_SHADE_FLAT |
  1097.             RADEON_FOG_SHADE_FLAT);
  1098.       break;
  1099.    case GL_SMOOTH:
  1100.       s |= (RADEON_DIFFUSE_SHADE_GOURAUD |
  1101.             RADEON_ALPHA_SHADE_GOURAUD |
  1102.             RADEON_SPECULAR_SHADE_GOURAUD |
  1103.             RADEON_FOG_SHADE_GOURAUD);
  1104.       break;
  1105.    default:
  1106.       return;
  1107.    }
  1108.  
  1109.    if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
  1110.       RADEON_STATECHANGE( rmesa, set );
  1111.       rmesa->hw.set.cmd[SET_SE_CNTL] = s;
  1112.    }
  1113. }
  1114.  
  1115.  
  1116. /* =============================================================
  1117.  * User clip planes
  1118.  */
  1119.  
  1120. static void radeonClipPlane( struct gl_context *ctx, GLenum plane, const GLfloat *eq )
  1121. {
  1122.    GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
  1123.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1124.    GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
  1125.  
  1126.    RADEON_STATECHANGE( rmesa, ucp[p] );
  1127.    rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
  1128.    rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
  1129.    rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
  1130.    rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
  1131. }
  1132.  
  1133. static void radeonUpdateClipPlanes( struct gl_context *ctx )
  1134. {
  1135.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1136.    GLuint p;
  1137.  
  1138.    for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
  1139.       if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
  1140.          GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
  1141.  
  1142.          RADEON_STATECHANGE( rmesa, ucp[p] );
  1143.          rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
  1144.          rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
  1145.          rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
  1146.          rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
  1147.       }
  1148.    }
  1149. }
  1150.  
  1151.  
  1152. /* =============================================================
  1153.  * Stencil
  1154.  */
  1155.  
  1156. static void
  1157. radeonStencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
  1158.                            GLint ref, GLuint mask )
  1159. {
  1160.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1161.    GLuint refmask = ((_mesa_get_stencil_ref(ctx, 0) << RADEON_STENCIL_REF_SHIFT) |
  1162.                      ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT));
  1163.  
  1164.    RADEON_STATECHANGE( rmesa, ctx );
  1165.    RADEON_STATECHANGE( rmesa, msk );
  1166.  
  1167.    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~RADEON_STENCIL_TEST_MASK;
  1168.    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(RADEON_STENCIL_REF_MASK|
  1169.                                                    RADEON_STENCIL_VALUE_MASK);
  1170.  
  1171.    switch ( ctx->Stencil.Function[0] ) {
  1172.    case GL_NEVER:
  1173.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEVER;
  1174.       break;
  1175.    case GL_LESS:
  1176.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LESS;
  1177.       break;
  1178.    case GL_EQUAL:
  1179.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_EQUAL;
  1180.       break;
  1181.    case GL_LEQUAL:
  1182.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_LEQUAL;
  1183.       break;
  1184.    case GL_GREATER:
  1185.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GREATER;
  1186.       break;
  1187.    case GL_NOTEQUAL:
  1188.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_NEQUAL;
  1189.       break;
  1190.    case GL_GEQUAL:
  1191.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_GEQUAL;
  1192.       break;
  1193.    case GL_ALWAYS:
  1194.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_TEST_ALWAYS;
  1195.       break;
  1196.    }
  1197.  
  1198.    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
  1199. }
  1200.  
  1201. static void
  1202. radeonStencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
  1203. {
  1204.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1205.  
  1206.    RADEON_STATECHANGE( rmesa, msk );
  1207.    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK;
  1208.    rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
  1209.       ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT);
  1210. }
  1211.  
  1212. static void radeonStencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
  1213.                                      GLenum zfail, GLenum zpass )
  1214. {
  1215.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1216.  
  1217.    /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
  1218.       and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
  1219.       but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
  1220.  
  1221.    GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP;
  1222.    GLuint tempRADEON_STENCIL_FAIL_INC_WRAP;
  1223.    GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
  1224.    GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP;
  1225.    GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP;
  1226.    GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP;
  1227.  
  1228.    if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) {
  1229.       tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC;
  1230.       tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC;
  1231.       tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC;
  1232.       tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC;
  1233.       tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC;
  1234.       tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC;
  1235.    }
  1236.    else {
  1237.       tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC_WRAP;
  1238.       tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC_WRAP;
  1239.       tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC_WRAP;
  1240.       tempRADEON_STENCIL_ZFAIL_INC_WRAP = RADEON_STENCIL_ZFAIL_INC_WRAP;
  1241.       tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP;
  1242.       tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP;
  1243.    }
  1244.  
  1245.    RADEON_STATECHANGE( rmesa, ctx );
  1246.    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK |
  1247.                                                RADEON_STENCIL_ZFAIL_MASK |
  1248.                                                RADEON_STENCIL_ZPASS_MASK);
  1249.  
  1250.    switch ( ctx->Stencil.FailFunc[0] ) {
  1251.    case GL_KEEP:
  1252.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_KEEP;
  1253.       break;
  1254.    case GL_ZERO:
  1255.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_ZERO;
  1256.       break;
  1257.    case GL_REPLACE:
  1258.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_REPLACE;
  1259.       break;
  1260.    case GL_INCR:
  1261.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INC;
  1262.       break;
  1263.    case GL_DECR:
  1264.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_DEC;
  1265.       break;
  1266.    case GL_INCR_WRAP:
  1267.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_INC_WRAP;
  1268.       break;
  1269.    case GL_DECR_WRAP:
  1270.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_FAIL_DEC_WRAP;
  1271.       break;
  1272.    case GL_INVERT:
  1273.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_FAIL_INVERT;
  1274.       break;
  1275.    }
  1276.  
  1277.    switch ( ctx->Stencil.ZFailFunc[0] ) {
  1278.    case GL_KEEP:
  1279.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_KEEP;
  1280.       break;
  1281.    case GL_ZERO:
  1282.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_ZERO;
  1283.       break;
  1284.    case GL_REPLACE:
  1285.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_REPLACE;
  1286.       break;
  1287.    case GL_INCR:
  1288.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INC;
  1289.       break;
  1290.    case GL_DECR:
  1291.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_DEC;
  1292.       break;
  1293.    case GL_INCR_WRAP:
  1294.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_INC_WRAP;
  1295.       break;
  1296.    case GL_DECR_WRAP:
  1297.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
  1298.       break;
  1299.    case GL_INVERT:
  1300.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZFAIL_INVERT;
  1301.       break;
  1302.    }
  1303.  
  1304.    switch ( ctx->Stencil.ZPassFunc[0] ) {
  1305.    case GL_KEEP:
  1306.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_KEEP;
  1307.       break;
  1308.    case GL_ZERO:
  1309.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_ZERO;
  1310.       break;
  1311.    case GL_REPLACE:
  1312.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_REPLACE;
  1313.       break;
  1314.    case GL_INCR:
  1315.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INC;
  1316.       break;
  1317.    case GL_DECR:
  1318.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_DEC;
  1319.       break;
  1320.    case GL_INCR_WRAP:
  1321.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_INC_WRAP;
  1322.       break;
  1323.    case GL_DECR_WRAP:
  1324.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= tempRADEON_STENCIL_ZPASS_DEC_WRAP;
  1325.       break;
  1326.    case GL_INVERT:
  1327.       rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_STENCIL_ZPASS_INVERT;
  1328.       break;
  1329.    }
  1330. }
  1331.  
  1332.  
  1333.  
  1334. /* =============================================================
  1335.  * Window position and viewport transformation
  1336.  */
  1337.  
  1338. /*
  1339.  * To correctly position primitives:
  1340.  */
  1341. #define SUBPIXEL_X 0.125
  1342. #define SUBPIXEL_Y 0.125
  1343.  
  1344.  
  1345. /**
  1346.  * Called when window size or position changes or viewport or depth range
  1347.  * state is changed.  We update the hardware viewport state here.
  1348.  */
  1349. void radeonUpdateWindow( struct gl_context *ctx )
  1350. {
  1351.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1352.    __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
  1353.    GLfloat xoffset = 0.0;
  1354.    GLfloat yoffset = dPriv ? (GLfloat) dPriv->h : 0;
  1355.    const GLfloat *v = ctx->Viewport._WindowMap.m;
  1356.    const GLboolean render_to_fbo = (ctx->DrawBuffer ? _mesa_is_user_fbo(ctx->DrawBuffer) : 0);
  1357.    const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
  1358.    GLfloat y_scale, y_bias;
  1359.  
  1360.    if (render_to_fbo) {
  1361.       y_scale = 1.0;
  1362.       y_bias = 0;
  1363.    } else {
  1364.       y_scale = -1.0;
  1365.       y_bias = yoffset;
  1366.    }
  1367.  
  1368.    float_ui32_type sx = { v[MAT_SX] };
  1369.    float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
  1370.    float_ui32_type sy = { v[MAT_SY] * y_scale };
  1371.    float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y };
  1372.    float_ui32_type sz = { v[MAT_SZ] * depthScale };
  1373.    float_ui32_type tz = { v[MAT_TZ] * depthScale };
  1374.  
  1375.    RADEON_STATECHANGE( rmesa, vpt );
  1376.  
  1377.    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE]  = sx.ui32;
  1378.    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
  1379.    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE]  = sy.ui32;
  1380.    rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
  1381.    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE]  = sz.ui32;
  1382.    rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
  1383. }
  1384.  
  1385.  
  1386. static void radeonViewport( struct gl_context *ctx, GLint x, GLint y,
  1387.                             GLsizei width, GLsizei height )
  1388. {
  1389.    /* Don't pipeline viewport changes, conflict with window offset
  1390.     * setting below.  Could apply deltas to rescue pipelined viewport
  1391.     * values, or keep the originals hanging around.
  1392.     */
  1393.    radeonUpdateWindow( ctx );
  1394.  
  1395.    radeon_viewport(ctx, x, y, width, height);
  1396. }
  1397.  
  1398. static void radeonDepthRange( struct gl_context *ctx, GLclampd nearval,
  1399.                               GLclampd farval )
  1400. {
  1401.    radeonUpdateWindow( ctx );
  1402. }
  1403.  
  1404. void radeonUpdateViewportOffset( struct gl_context *ctx )
  1405. {
  1406.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1407.    __DRIdrawable *dPriv = radeon_get_drawable(&rmesa->radeon);
  1408.    GLfloat xoffset = 0.0;
  1409.    GLfloat yoffset = (GLfloat)dPriv->h;
  1410.    const GLfloat *v = ctx->Viewport._WindowMap.m;
  1411.  
  1412.    float_ui32_type tx;
  1413.    float_ui32_type ty;
  1414.  
  1415.    tx.f = v[MAT_TX] + xoffset + SUBPIXEL_X;
  1416.    ty.f = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
  1417.  
  1418.    if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 ||
  1419.         rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 )
  1420.    {
  1421.       /* Note: this should also modify whatever data the context reset
  1422.        * code uses...
  1423.        */
  1424.       RADEON_STATECHANGE( rmesa, vpt );
  1425.       rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
  1426.       rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
  1427.  
  1428.       /* update polygon stipple x/y screen offset */
  1429.       {
  1430.          GLuint stx, sty;
  1431.          GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
  1432.  
  1433.          m &= ~(RADEON_STIPPLE_X_OFFSET_MASK |
  1434.                 RADEON_STIPPLE_Y_OFFSET_MASK);
  1435.  
  1436.          /* add magic offsets, then invert */
  1437.          stx = 31 - ((-1) & RADEON_STIPPLE_COORD_MASK);
  1438.          sty = 31 - ((dPriv->h - 1)
  1439.                      & RADEON_STIPPLE_COORD_MASK);
  1440.  
  1441.          m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) |
  1442.                (sty << RADEON_STIPPLE_Y_OFFSET_SHIFT));
  1443.  
  1444.          if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
  1445.             RADEON_STATECHANGE( rmesa, msc );
  1446.             rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
  1447.          }
  1448.       }
  1449.    }
  1450.  
  1451.    radeonUpdateScissor( ctx );
  1452. }
  1453.  
  1454.  
  1455.  
  1456. /* =============================================================
  1457.  * Miscellaneous
  1458.  */
  1459.  
  1460. static void radeonRenderMode( struct gl_context *ctx, GLenum mode )
  1461. {
  1462.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1463.    FALLBACK( rmesa, RADEON_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
  1464. }
  1465.  
  1466.  
  1467. static GLuint radeon_rop_tab[] = {
  1468.    RADEON_ROP_CLEAR,
  1469.    RADEON_ROP_AND,
  1470.    RADEON_ROP_AND_REVERSE,
  1471.    RADEON_ROP_COPY,
  1472.    RADEON_ROP_AND_INVERTED,
  1473.    RADEON_ROP_NOOP,
  1474.    RADEON_ROP_XOR,
  1475.    RADEON_ROP_OR,
  1476.    RADEON_ROP_NOR,
  1477.    RADEON_ROP_EQUIV,
  1478.    RADEON_ROP_INVERT,
  1479.    RADEON_ROP_OR_REVERSE,
  1480.    RADEON_ROP_COPY_INVERTED,
  1481.    RADEON_ROP_OR_INVERTED,
  1482.    RADEON_ROP_NAND,
  1483.    RADEON_ROP_SET,
  1484. };
  1485.  
  1486. static void radeonLogicOpCode( struct gl_context *ctx, GLenum opcode )
  1487. {
  1488.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1489.    GLuint rop = (GLuint)opcode - GL_CLEAR;
  1490.  
  1491.    ASSERT( rop < 16 );
  1492.  
  1493.    RADEON_STATECHANGE( rmesa, msk );
  1494.    rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
  1495. }
  1496.  
  1497. /* =============================================================
  1498.  * State enable/disable
  1499.  */
  1500.  
  1501. static void radeonEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
  1502. {
  1503.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1504.    GLuint p, flag;
  1505.  
  1506.    if ( RADEON_DEBUG & RADEON_STATE )
  1507.       fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
  1508.                _mesa_lookup_enum_by_nr( cap ),
  1509.                state ? "GL_TRUE" : "GL_FALSE" );
  1510.  
  1511.    switch ( cap ) {
  1512.       /* Fast track this one...
  1513.        */
  1514.    case GL_TEXTURE_1D:
  1515.    case GL_TEXTURE_2D:
  1516.    case GL_TEXTURE_3D:
  1517.       break;
  1518.  
  1519.    case GL_ALPHA_TEST:
  1520.       RADEON_STATECHANGE( rmesa, ctx );
  1521.       if (state) {
  1522.          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_ALPHA_TEST_ENABLE;
  1523.       } else {
  1524.          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ALPHA_TEST_ENABLE;
  1525.       }
  1526.       break;
  1527.  
  1528.    case GL_BLEND:
  1529.       RADEON_STATECHANGE( rmesa, ctx );
  1530.       if (state) {
  1531.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ALPHA_BLEND_ENABLE;
  1532.       } else {
  1533.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
  1534.       }
  1535.       if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
  1536.             && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
  1537.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
  1538.       } else {
  1539.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
  1540.       }
  1541.  
  1542.       /* Catch a possible fallback:
  1543.        */
  1544.       if (state) {
  1545.          ctx->Driver.BlendEquationSeparate( ctx,
  1546.                                             ctx->Color.Blend[0].EquationRGB,
  1547.                                             ctx->Color.Blend[0].EquationA );
  1548.          ctx->Driver.BlendFuncSeparate( ctx, ctx->Color.Blend[0].SrcRGB,
  1549.                                         ctx->Color.Blend[0].DstRGB,
  1550.                                         ctx->Color.Blend[0].SrcA,
  1551.                                         ctx->Color.Blend[0].DstA );
  1552.       }
  1553.       else {
  1554.          FALLBACK( rmesa, RADEON_FALLBACK_BLEND_FUNC, GL_FALSE );
  1555.          FALLBACK( rmesa, RADEON_FALLBACK_BLEND_EQ, GL_FALSE );
  1556.       }
  1557.       break;
  1558.  
  1559.    case GL_CLIP_PLANE0:
  1560.    case GL_CLIP_PLANE1:
  1561.    case GL_CLIP_PLANE2:
  1562.    case GL_CLIP_PLANE3:
  1563.    case GL_CLIP_PLANE4:
  1564.    case GL_CLIP_PLANE5:
  1565.       p = cap-GL_CLIP_PLANE0;
  1566.       RADEON_STATECHANGE( rmesa, tcl );
  1567.       if (state) {
  1568.          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (RADEON_UCP_ENABLE_0<<p);
  1569.          radeonClipPlane( ctx, cap, NULL );
  1570.       }
  1571.       else {
  1572.          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(RADEON_UCP_ENABLE_0<<p);
  1573.       }
  1574.       break;
  1575.  
  1576.    case GL_COLOR_MATERIAL:
  1577.       radeonColorMaterial( ctx, 0, 0 );
  1578.       radeonUpdateMaterial( ctx );
  1579.       break;
  1580.  
  1581.    case GL_CULL_FACE:
  1582.       radeonCullFace( ctx, 0 );
  1583.       break;
  1584.  
  1585.    case GL_DEPTH_TEST:
  1586.       RADEON_STATECHANGE(rmesa, ctx );
  1587.       if ( state ) {
  1588.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_Z_ENABLE;
  1589.       } else {
  1590.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_Z_ENABLE;
  1591.       }
  1592.       break;
  1593.  
  1594.    case GL_DITHER:
  1595.       RADEON_STATECHANGE(rmesa, ctx );
  1596.       if ( state ) {
  1597.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_DITHER_ENABLE;
  1598.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
  1599.       } else {
  1600.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_DITHER_ENABLE;
  1601.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  rmesa->radeon.state.color.roundEnable;
  1602.       }
  1603.       break;
  1604.  
  1605.    case GL_FOG:
  1606.       RADEON_STATECHANGE(rmesa, ctx );
  1607.       if ( state ) {
  1608.          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= RADEON_FOG_ENABLE;
  1609.          radeonFogfv( ctx, GL_FOG_MODE, NULL );
  1610.       } else {
  1611.          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_FOG_ENABLE;
  1612.          RADEON_STATECHANGE(rmesa, tcl);
  1613.          rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
  1614.       }
  1615.       radeonUpdateSpecular( ctx ); /* for PK_SPEC */
  1616.       _mesa_allow_light_in_model( ctx, !state );
  1617.       break;
  1618.  
  1619.    case GL_LIGHT0:
  1620.    case GL_LIGHT1:
  1621.    case GL_LIGHT2:
  1622.    case GL_LIGHT3:
  1623.    case GL_LIGHT4:
  1624.    case GL_LIGHT5:
  1625.    case GL_LIGHT6:
  1626.    case GL_LIGHT7:
  1627.       RADEON_STATECHANGE(rmesa, tcl);
  1628.       p = cap - GL_LIGHT0;
  1629.       if (p&1)
  1630.          flag = (RADEON_LIGHT_1_ENABLE |
  1631.                  RADEON_LIGHT_1_ENABLE_AMBIENT |
  1632.                  RADEON_LIGHT_1_ENABLE_SPECULAR);
  1633.       else
  1634.          flag = (RADEON_LIGHT_0_ENABLE |
  1635.                  RADEON_LIGHT_0_ENABLE_AMBIENT |
  1636.                  RADEON_LIGHT_0_ENABLE_SPECULAR);
  1637.  
  1638.       if (state)
  1639.          rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
  1640.       else
  1641.          rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
  1642.  
  1643.       /*
  1644.        */
  1645.       update_light_colors( ctx, p );
  1646.       break;
  1647.  
  1648.    case GL_LIGHTING:
  1649.       RADEON_STATECHANGE(rmesa, tcl);
  1650.       radeonUpdateSpecular(ctx);
  1651.       check_twoside_fallback( ctx );
  1652.       break;
  1653.  
  1654.    case GL_LINE_SMOOTH:
  1655.       RADEON_STATECHANGE( rmesa, ctx );
  1656.       if ( state ) {
  1657.          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_ANTI_ALIAS_LINE;
  1658.       } else {
  1659.          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_LINE;
  1660.       }
  1661.       break;
  1662.  
  1663.    case GL_LINE_STIPPLE:
  1664.       RADEON_STATECHANGE( rmesa, ctx );
  1665.       if ( state ) {
  1666.          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_PATTERN_ENABLE;
  1667.       } else {
  1668.          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_PATTERN_ENABLE;
  1669.       }
  1670.       break;
  1671.  
  1672.    case GL_COLOR_LOGIC_OP:
  1673.       RADEON_STATECHANGE( rmesa, ctx );
  1674.       if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
  1675.             && ctx->Color.Blend[0].EquationRGB == GL_LOGIC_OP)) ) {
  1676.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_ROP_ENABLE;
  1677.       } else {
  1678.          rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
  1679.       }
  1680.       break;
  1681.  
  1682.    case GL_NORMALIZE:
  1683.       RADEON_STATECHANGE( rmesa, tcl );
  1684.       if ( state ) {
  1685.          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_NORMALIZE_NORMALS;
  1686.       } else {
  1687.          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_NORMALIZE_NORMALS;
  1688.       }
  1689.       break;
  1690.  
  1691.    case GL_POLYGON_OFFSET_POINT:
  1692.       RADEON_STATECHANGE( rmesa, set );
  1693.       if ( state ) {
  1694.          rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_POINT;
  1695.       } else {
  1696.          rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
  1697.       }
  1698.       break;
  1699.  
  1700.    case GL_POLYGON_OFFSET_LINE:
  1701.       RADEON_STATECHANGE( rmesa, set );
  1702.       if ( state ) {
  1703.          rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_LINE;
  1704.       } else {
  1705.          rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
  1706.       }
  1707.       break;
  1708.  
  1709.    case GL_POLYGON_OFFSET_FILL:
  1710.       RADEON_STATECHANGE( rmesa, set );
  1711.       if ( state ) {
  1712.          rmesa->hw.set.cmd[SET_SE_CNTL] |=  RADEON_ZBIAS_ENABLE_TRI;
  1713.       } else {
  1714.          rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
  1715.       }
  1716.       break;
  1717.  
  1718.    case GL_POLYGON_SMOOTH:
  1719.       RADEON_STATECHANGE( rmesa, ctx );
  1720.       if ( state ) {
  1721.          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_ANTI_ALIAS_POLY;
  1722.       } else {
  1723.          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_ANTI_ALIAS_POLY;
  1724.       }
  1725.       break;
  1726.  
  1727.    case GL_POLYGON_STIPPLE:
  1728.       RADEON_STATECHANGE(rmesa, ctx );
  1729.       if ( state ) {
  1730.          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  RADEON_STIPPLE_ENABLE;
  1731.       } else {
  1732.          rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~RADEON_STIPPLE_ENABLE;
  1733.       }
  1734.       break;
  1735.  
  1736.    case GL_RESCALE_NORMAL_EXT: {
  1737.       GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
  1738.       RADEON_STATECHANGE( rmesa, tcl );
  1739.       if ( tmp ) {
  1740.          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_RESCALE_NORMALS;
  1741.       } else {
  1742.          rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
  1743.       }
  1744.       break;
  1745.    }
  1746.  
  1747.    case GL_SCISSOR_TEST:
  1748.       radeon_firevertices(&rmesa->radeon);
  1749.       rmesa->radeon.state.scissor.enabled = state;
  1750.       radeonUpdateScissor( ctx );
  1751.       break;
  1752.  
  1753.    case GL_STENCIL_TEST:
  1754.       {
  1755.          GLboolean hw_stencil = GL_FALSE;
  1756.          if (ctx->DrawBuffer) {
  1757.             struct radeon_renderbuffer *rrbStencil
  1758.                = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
  1759.             hw_stencil = (rrbStencil && rrbStencil->bo);
  1760.          }
  1761.  
  1762.          if (hw_stencil) {
  1763.             RADEON_STATECHANGE( rmesa, ctx );
  1764.             if ( state ) {
  1765.                rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_STENCIL_ENABLE;
  1766.             } else {
  1767.                rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
  1768.             }
  1769.          } else {
  1770.             FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
  1771.          }
  1772.       }
  1773.       break;
  1774.  
  1775.    case GL_TEXTURE_GEN_Q:
  1776.    case GL_TEXTURE_GEN_R:
  1777.    case GL_TEXTURE_GEN_S:
  1778.    case GL_TEXTURE_GEN_T:
  1779.       /* Picked up in radeonUpdateTextureState.
  1780.        */
  1781.       rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
  1782.       break;
  1783.  
  1784.    case GL_COLOR_SUM_EXT:
  1785.       radeonUpdateSpecular ( ctx );
  1786.       break;
  1787.  
  1788.    default:
  1789.       return;
  1790.    }
  1791. }
  1792.  
  1793.  
  1794. static void radeonLightingSpaceChange( struct gl_context *ctx )
  1795. {
  1796.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1797.    GLboolean tmp;
  1798.    RADEON_STATECHANGE( rmesa, tcl );
  1799.  
  1800.    if (RADEON_DEBUG & RADEON_STATE)
  1801.       fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
  1802.               rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
  1803.  
  1804.    if (ctx->_NeedEyeCoords)
  1805.       tmp = ctx->Transform.RescaleNormals;
  1806.    else
  1807.       tmp = !ctx->Transform.RescaleNormals;
  1808.  
  1809.    if ( tmp ) {
  1810.       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |=  RADEON_RESCALE_NORMALS;
  1811.    } else {
  1812.       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
  1813.    }
  1814.  
  1815.    if (RADEON_DEBUG & RADEON_STATE)
  1816.       fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
  1817.               rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
  1818. }
  1819.  
  1820. /* =============================================================
  1821.  * Deferred state management - matrices, textures, other?
  1822.  */
  1823.  
  1824.  
  1825. void radeonUploadTexMatrix( r100ContextPtr rmesa,
  1826.                             int unit, GLboolean swapcols )
  1827. {
  1828. /* Here's how this works: on r100, only 3 tex coords can be submitted, so the
  1829.    vector looks like this probably: (s t r|q 0) (not sure if the last coord
  1830.    is hardwired to 0, could be 1 too). Interestingly, it actually looks like
  1831.    texgen generates all 4 coords, at least tests with projtex indicated that.
  1832.    So: if we need the q coord in the end (solely determined by the texture
  1833.    target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
  1834.    Additionally, if we don't have texgen but 4 tex coords submitted, we swap
  1835.    column 3 and 4 (for the 2d / 1d / texrect targets) since the q coord
  1836.    will get submitted in the "wrong", i.e. 3rd, slot.
  1837.    If an app submits 3 coords for 2d targets, we assume it is saving on vertex
  1838.    size and using the texture matrix to swap the r and q coords around (ut2k3
  1839.    does exactly that), so we don't need the 3rd / 4th column swap - still need
  1840.    the 3rd / 4th row swap of course. This will potentially break for apps which
  1841.    use TexCoord3x just for fun. Additionally, it will never work if an app uses
  1842.    an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
  1843.    the maximum needed 3. This seems impossible to do with hw tcl on r100, and
  1844.    incredibly hard to detect so we can't just fallback in such a case. Assume
  1845.    it never happens... - rs
  1846. */
  1847.  
  1848.    int idx = TEXMAT_0 + unit;
  1849.    float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0;
  1850.    int i;
  1851.    struct gl_texture_unit tUnit = rmesa->radeon.glCtx.Texture.Unit[unit];
  1852.    GLfloat *src = rmesa->tmpmat[unit].m;
  1853.  
  1854.    rmesa->TexMatColSwap &= ~(1 << unit);
  1855.    if ((tUnit._ReallyEnabled & (TEXTURE_3D_BIT | TEXTURE_CUBE_BIT)) == 0) {
  1856.       if (swapcols) {
  1857.          rmesa->TexMatColSwap |= 1 << unit;
  1858.          /* attention some elems are swapped 2 times! */
  1859.          *dest++ = src[0];
  1860.          *dest++ = src[4];
  1861.          *dest++ = src[12];
  1862.          *dest++ = src[8];
  1863.          *dest++ = src[1];
  1864.          *dest++ = src[5];
  1865.          *dest++ = src[13];
  1866.          *dest++ = src[9];
  1867.          *dest++ = src[2];
  1868.          *dest++ = src[6];
  1869.          *dest++ = src[15];
  1870.          *dest++ = src[11];
  1871.          /* those last 4 are probably never used */
  1872.          *dest++ = src[3];
  1873.          *dest++ = src[7];
  1874.          *dest++ = src[14];
  1875.          *dest++ = src[10];
  1876.       }
  1877.       else {
  1878.          for (i = 0; i < 2; i++) {
  1879.             *dest++ = src[i];
  1880.             *dest++ = src[i+4];
  1881.             *dest++ = src[i+8];
  1882.             *dest++ = src[i+12];
  1883.          }
  1884.          for (i = 3; i >= 2; i--) {
  1885.             *dest++ = src[i];
  1886.             *dest++ = src[i+4];
  1887.             *dest++ = src[i+8];
  1888.             *dest++ = src[i+12];
  1889.          }
  1890.       }
  1891.    }
  1892.    else {
  1893.       for (i = 0 ; i < 4 ; i++) {
  1894.          *dest++ = src[i];
  1895.          *dest++ = src[i+4];
  1896.          *dest++ = src[i+8];
  1897.          *dest++ = src[i+12];
  1898.       }
  1899.    }
  1900.  
  1901.    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
  1902. }
  1903.  
  1904.  
  1905. static void upload_matrix( r100ContextPtr rmesa, GLfloat *src, int idx )
  1906. {
  1907.    float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
  1908.    int i;
  1909.  
  1910.  
  1911.    for (i = 0 ; i < 4 ; i++) {
  1912.       *dest++ = src[i];
  1913.       *dest++ = src[i+4];
  1914.       *dest++ = src[i+8];
  1915.       *dest++ = src[i+12];
  1916.    }
  1917.  
  1918.    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
  1919. }
  1920.  
  1921. static void upload_matrix_t( r100ContextPtr rmesa, GLfloat *src, int idx )
  1922. {
  1923.    float *dest = ((float *)RADEON_DB_STATE( mat[idx] ))+MAT_ELT_0;
  1924.    memcpy(dest, src, 16*sizeof(float));
  1925.    RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
  1926. }
  1927.  
  1928.  
  1929. static void update_texturematrix( struct gl_context *ctx )
  1930. {
  1931.    r100ContextPtr rmesa = R100_CONTEXT( ctx );
  1932.    GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
  1933.    GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
  1934.    int unit;
  1935.    GLuint texMatEnabled = 0;
  1936.    rmesa->NeedTexMatrix = 0;
  1937.    rmesa->TexMatColSwap = 0;
  1938.  
  1939.    for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
  1940.       if (ctx->Texture.Unit[unit]._ReallyEnabled) {
  1941.          GLboolean needMatrix = GL_FALSE;
  1942.          if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
  1943.             needMatrix = GL_TRUE;
  1944.             texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE |
  1945.                               RADEON_TEXMAT_0_ENABLE) << unit;
  1946.  
  1947.             if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
  1948.                /* Need to preconcatenate any active texgen
  1949.                 * obj/eyeplane matrices:
  1950.                 */
  1951.                _math_matrix_mul_matrix( &rmesa->tmpmat[unit],
  1952.                                      ctx->TextureMatrixStack[unit].Top,
  1953.                                      &rmesa->TexGenMatrix[unit] );
  1954.             }
  1955.             else {
  1956.                _math_matrix_copy( &rmesa->tmpmat[unit],
  1957.                   ctx->TextureMatrixStack[unit].Top );
  1958.             }
  1959.          }
  1960.          else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
  1961.             _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] );
  1962.             needMatrix = GL_TRUE;
  1963.          }
  1964.          if (needMatrix) {
  1965.             rmesa->NeedTexMatrix |= 1 << unit;
  1966.             radeonUploadTexMatrix( rmesa, unit,
  1967.                         !ctx->Texture.Unit[unit].TexGenEnabled );
  1968.          }
  1969.       }
  1970.    }
  1971.  
  1972.    tpc = (texMatEnabled | rmesa->TexGenEnabled);
  1973.  
  1974.    /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
  1975.    vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
  1976.            (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
  1977.            (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
  1978.  
  1979.    vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) <<
  1980.          (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) |
  1981.       ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) <<
  1982.          (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) |
  1983.       ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) <<
  1984.          (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1)));
  1985.  
  1986.    if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
  1987.        vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
  1988.  
  1989.       RADEON_STATECHANGE(rmesa, tcl);
  1990.       rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
  1991.       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
  1992.    }
  1993. }
  1994.  
  1995. static GLboolean r100ValidateBuffers(struct gl_context *ctx)
  1996. {
  1997.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  1998.    struct radeon_renderbuffer *rrb;
  1999.    int i, ret;
  2000.  
  2001.    radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
  2002.  
  2003.    rrb = radeon_get_colorbuffer(&rmesa->radeon);
  2004.    /* color buffer */
  2005.    if (rrb && rrb->bo) {
  2006.      radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
  2007.                                        0, RADEON_GEM_DOMAIN_VRAM);
  2008.    }
  2009.  
  2010.    /* depth buffer */
  2011.    rrb = radeon_get_depthbuffer(&rmesa->radeon);
  2012.    /* color buffer */
  2013.    if (rrb && rrb->bo) {
  2014.      radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
  2015.                                        0, RADEON_GEM_DOMAIN_VRAM);
  2016.    }
  2017.  
  2018.    for (i = 0; i < ctx->Const.FragmentProgram.MaxTextureImageUnits; ++i) {
  2019.       radeonTexObj *t;
  2020.  
  2021.       if (!ctx->Texture.Unit[i]._ReallyEnabled)
  2022.          continue;
  2023.  
  2024.       t = rmesa->state.texture.unit[i].texobj;
  2025.  
  2026.       if (!t)
  2027.          continue;
  2028.       if (t->image_override && t->bo)
  2029.         radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
  2030.                            RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
  2031.       else if (t->mt->bo)
  2032.         radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
  2033.                            RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
  2034.    }
  2035.  
  2036.    ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
  2037.    if (ret)
  2038.        return GL_FALSE;
  2039.    return GL_TRUE;
  2040. }
  2041.  
  2042. GLboolean radeonValidateState( struct gl_context *ctx )
  2043. {
  2044.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  2045.    GLuint new_state = rmesa->radeon.NewGLState;
  2046.  
  2047.    if (new_state & _NEW_BUFFERS) {
  2048.      _mesa_update_framebuffer(ctx);
  2049.      /* this updates the DrawBuffer's Width/Height if it's a FBO */
  2050.      _mesa_update_draw_buffer_bounds(ctx);
  2051.      RADEON_STATECHANGE(rmesa, ctx);
  2052.    }
  2053.  
  2054.    if (new_state & _NEW_TEXTURE) {
  2055.       radeonUpdateTextureState( ctx );
  2056.       new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
  2057.    }
  2058.  
  2059.    /* we need to do a space check here */
  2060.    if (!r100ValidateBuffers(ctx))
  2061.      return GL_FALSE;
  2062.  
  2063.    /* Need an event driven matrix update?
  2064.     */
  2065.    if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
  2066.       upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
  2067.  
  2068.    /* Need these for lighting (shouldn't upload otherwise)
  2069.     */
  2070.    if (new_state & (_NEW_MODELVIEW)) {
  2071.       upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, MODEL );
  2072.       upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, MODEL_IT );
  2073.    }
  2074.  
  2075.    /* Does this need to be triggered on eg. modelview for
  2076.     * texgen-derived objplane/eyeplane matrices?
  2077.     */
  2078.    if (new_state & _NEW_TEXTURE_MATRIX) {
  2079.       update_texturematrix( ctx );
  2080.    }
  2081.  
  2082.    if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
  2083.       update_light( ctx );
  2084.    }
  2085.  
  2086.    /* emit all active clip planes if projection matrix changes.
  2087.     */
  2088.    if (new_state & (_NEW_PROJECTION)) {
  2089.       if (ctx->Transform.ClipPlanesEnabled)
  2090.          radeonUpdateClipPlanes( ctx );
  2091.    }
  2092.  
  2093.  
  2094.    rmesa->radeon.NewGLState = 0;
  2095.  
  2096.    return GL_TRUE;
  2097. }
  2098.  
  2099.  
  2100. static void radeonInvalidateState( struct gl_context *ctx, GLuint new_state )
  2101. {
  2102.    _swrast_InvalidateState( ctx, new_state );
  2103.    _swsetup_InvalidateState( ctx, new_state );
  2104.    _vbo_InvalidateState( ctx, new_state );
  2105.    _tnl_InvalidateState( ctx, new_state );
  2106.    _ae_invalidate_state( ctx, new_state );
  2107.    R100_CONTEXT(ctx)->radeon.NewGLState |= new_state;
  2108. }
  2109.  
  2110.  
  2111. /* A hack.  Need a faster way to find this out.
  2112.  */
  2113. static GLboolean check_material( struct gl_context *ctx )
  2114. {
  2115.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  2116.    GLint i;
  2117.  
  2118.    for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
  2119.         i < _TNL_ATTRIB_MAT_BACK_INDEXES;
  2120.         i++)
  2121.       if (tnl->vb.AttribPtr[i] &&
  2122.           tnl->vb.AttribPtr[i]->stride)
  2123.          return GL_TRUE;
  2124.  
  2125.    return GL_FALSE;
  2126. }
  2127.  
  2128.  
  2129. static void radeonWrapRunPipeline( struct gl_context *ctx )
  2130. {
  2131.    r100ContextPtr rmesa = R100_CONTEXT(ctx);
  2132.    GLboolean has_material;
  2133.  
  2134.    if (0)
  2135.       fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
  2136.  
  2137.    /* Validate state:
  2138.     */
  2139.    if (rmesa->radeon.NewGLState)
  2140.       if (!radeonValidateState( ctx ))
  2141.          FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
  2142.  
  2143.    has_material = (ctx->Light.Enabled && check_material( ctx ));
  2144.  
  2145.    if (has_material) {
  2146.       TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_TRUE );
  2147.    }
  2148.  
  2149.    /* Run the pipeline.
  2150.     */
  2151.    _tnl_run_pipeline( ctx );
  2152.  
  2153.    if (has_material) {
  2154.       TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_MATERIAL, GL_FALSE );
  2155.    }
  2156. }
  2157.  
  2158. static void radeonPolygonStipple( struct gl_context *ctx, const GLubyte *mask )
  2159. {
  2160.    r100ContextPtr r100 = R100_CONTEXT(ctx);
  2161.    GLint i;
  2162.  
  2163.    radeon_firevertices(&r100->radeon);
  2164.  
  2165.    RADEON_STATECHANGE(r100, stp);
  2166.  
  2167.    /* Must flip pattern upside down.
  2168.     */
  2169.    for ( i = 31 ; i >= 0; i--) {
  2170.      r100->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
  2171.    }
  2172. }
  2173.  
  2174.  
  2175. /* Initialize the driver's state functions.
  2176.  * Many of the ctx->Driver functions might have been initialized to
  2177.  * software defaults in the earlier _mesa_init_driver_functions() call.
  2178.  */
  2179. void radeonInitStateFuncs( struct gl_context *ctx )
  2180. {
  2181.    ctx->Driver.UpdateState              = radeonInvalidateState;
  2182.    ctx->Driver.LightingSpaceChange      = radeonLightingSpaceChange;
  2183.  
  2184.    ctx->Driver.DrawBuffer               = radeonDrawBuffer;
  2185.    ctx->Driver.ReadBuffer               = radeonReadBuffer;
  2186.    ctx->Driver.CopyPixels               = _mesa_meta_CopyPixels;
  2187.    ctx->Driver.DrawPixels               = _mesa_meta_DrawPixels;
  2188.    ctx->Driver.ReadPixels               = radeonReadPixels;
  2189.  
  2190.    ctx->Driver.AlphaFunc                = radeonAlphaFunc;
  2191.    ctx->Driver.BlendEquationSeparate    = radeonBlendEquationSeparate;
  2192.    ctx->Driver.BlendFuncSeparate        = radeonBlendFuncSeparate;
  2193.    ctx->Driver.ClipPlane                = radeonClipPlane;
  2194.    ctx->Driver.ColorMask                = radeonColorMask;
  2195.    ctx->Driver.CullFace                 = radeonCullFace;
  2196.    ctx->Driver.DepthFunc                = radeonDepthFunc;
  2197.    ctx->Driver.DepthMask                = radeonDepthMask;
  2198.    ctx->Driver.DepthRange               = radeonDepthRange;
  2199.    ctx->Driver.Enable                   = radeonEnable;
  2200.    ctx->Driver.Fogfv                    = radeonFogfv;
  2201.    ctx->Driver.FrontFace                = radeonFrontFace;
  2202.    ctx->Driver.Hint                     = NULL;
  2203.    ctx->Driver.LightModelfv             = radeonLightModelfv;
  2204.    ctx->Driver.Lightfv                  = radeonLightfv;
  2205.    ctx->Driver.LineStipple              = radeonLineStipple;
  2206.    ctx->Driver.LineWidth                = radeonLineWidth;
  2207.    ctx->Driver.LogicOpcode              = radeonLogicOpCode;
  2208.    ctx->Driver.PolygonMode              = radeonPolygonMode;
  2209.    ctx->Driver.PolygonOffset            = radeonPolygonOffset;
  2210.    ctx->Driver.PolygonStipple           = radeonPolygonStipple;
  2211.    ctx->Driver.RenderMode               = radeonRenderMode;
  2212.    ctx->Driver.Scissor                  = radeonScissor;
  2213.    ctx->Driver.ShadeModel               = radeonShadeModel;
  2214.    ctx->Driver.StencilFuncSeparate      = radeonStencilFuncSeparate;
  2215.    ctx->Driver.StencilMaskSeparate      = radeonStencilMaskSeparate;
  2216.    ctx->Driver.StencilOpSeparate        = radeonStencilOpSeparate;
  2217.    ctx->Driver.Viewport                 = radeonViewport;
  2218.  
  2219.    TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;
  2220.    TNL_CONTEXT(ctx)->Driver.RunPipeline = radeonWrapRunPipeline;
  2221. }
  2222.