r200_state.c revision 4322181e6a07ecb8891c2d1ada74fd48c996a8fc
12861e737e84e4884109b9526ac645194ba892a74Michal Krol/**************************************************************************
22861e737e84e4884109b9526ac645194ba892a74Michal Krol
3ebcedd2d8909cc00d8528d76d3a1990315f270eaBrian PaulCopyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
42861e737e84e4884109b9526ac645194ba892a74Michal Krol
58a97946e0a25aff2d56bbaf3ed20ba1588129993Brian PaulThe Weather Channel (TM) funded Tungsten Graphics to develop the
62861e737e84e4884109b9526ac645194ba892a74Michal Krolinitial release of the Radeon 8500 driver under the XFree86 license.
72861e737e84e4884109b9526ac645194ba892a74Michal KrolThis notice must be preserved.
82861e737e84e4884109b9526ac645194ba892a74Michal Krol
92861e737e84e4884109b9526ac645194ba892a74Michal KrolPermission is hereby granted, free of charge, to any person obtaining
102861e737e84e4884109b9526ac645194ba892a74Michal Krola copy of this software and associated documentation files (the
112861e737e84e4884109b9526ac645194ba892a74Michal Krol"Software"), to deal in the Software without restriction, including
122861e737e84e4884109b9526ac645194ba892a74Michal Krolwithout limitation the rights to use, copy, modify, merge, publish,
132861e737e84e4884109b9526ac645194ba892a74Michal Kroldistribute, sublicense, and/or sell copies of the Software, and to
142861e737e84e4884109b9526ac645194ba892a74Michal Krolpermit persons to whom the Software is furnished to do so, subject to
152861e737e84e4884109b9526ac645194ba892a74Michal Krolthe following conditions:
162861e737e84e4884109b9526ac645194ba892a74Michal Krol
172861e737e84e4884109b9526ac645194ba892a74Michal KrolThe above copyright notice and this permission notice (including the
182861e737e84e4884109b9526ac645194ba892a74Michal Krolnext paragraph) shall be included in all copies or substantial
192861e737e84e4884109b9526ac645194ba892a74Michal Krolportions of the Software.
202861e737e84e4884109b9526ac645194ba892a74Michal Krol
212861e737e84e4884109b9526ac645194ba892a74Michal KrolTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
222861e737e84e4884109b9526ac645194ba892a74Michal KrolEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
232861e737e84e4884109b9526ac645194ba892a74Michal KrolMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
242861e737e84e4884109b9526ac645194ba892a74Michal KrolIN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
252861e737e84e4884109b9526ac645194ba892a74Michal KrolLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
262861e737e84e4884109b9526ac645194ba892a74Michal KrolOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
272861e737e84e4884109b9526ac645194ba892a74Michal KrolWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
282861e737e84e4884109b9526ac645194ba892a74Michal Krol
292861e737e84e4884109b9526ac645194ba892a74Michal Krol**************************************************************************/
302861e737e84e4884109b9526ac645194ba892a74Michal Krol
312861e737e84e4884109b9526ac645194ba892a74Michal Krol/*
322861e737e84e4884109b9526ac645194ba892a74Michal Krol * Authors:
332861e737e84e4884109b9526ac645194ba892a74Michal Krol *   Keith Whitwell <keith@tungstengraphics.com>
342861e737e84e4884109b9526ac645194ba892a74Michal Krol */
352861e737e84e4884109b9526ac645194ba892a74Michal Krol
362861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "main/glheader.h"
372861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "main/imports.h"
382861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "main/api_arrayelt.h"
392861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "main/enums.h"
40bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h"
41bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/light.h"
42bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/framebuffer.h"
43bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul
44bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "swrast/swrast.h"
45bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "vbo/vbo.h"
4657d9531cd644226d15be4a09ad1492ab647165dcBrian#include "tnl/tnl.h"
4757d9531cd644226d15be4a09ad1492ab647165dcBrian#include "tnl/t_pipeline.h"
486232438acb205ea44dee2d5eb68fb618e40b47d6Brian#include "swrast_setup/swrast_setup.h"
492861e737e84e4884109b9526ac645194ba892a74Michal Krol
502861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "radeon_common.h"
512861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "radeon_mipmap_tree.h"
522861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "r200_context.h"
532861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "r200_ioctl.h"
542861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "r200_state.h"
552861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "r200_tcl.h"
562861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "r200_tex.h"
572861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "r200_swtcl.h"
582861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "r200_vertprog.h"
592861e737e84e4884109b9526ac645194ba892a74Michal Krol
602861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "drirenderbuffer.h"
61122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul
622861e737e84e4884109b9526ac645194ba892a74Michal Krol
632861e737e84e4884109b9526ac645194ba892a74Michal Krol/* =============================================================
642861e737e84e4884109b9526ac645194ba892a74Michal Krol * Alpha blending
652861e737e84e4884109b9526ac645194ba892a74Michal Krol */
662861e737e84e4884109b9526ac645194ba892a74Michal Krol
672861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200AlphaFunc( GLcontext *ctx, GLenum func, GLfloat ref )
682861e737e84e4884109b9526ac645194ba892a74Michal Krol{
692861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
702861e737e84e4884109b9526ac645194ba892a74Michal Krol   int pp_misc = rmesa->hw.ctx.cmd[CTX_PP_MISC];
712861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte refByte;
724d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul
732861e737e84e4884109b9526ac645194ba892a74Michal Krol   CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
742861e737e84e4884109b9526ac645194ba892a74Michal Krol
752861e737e84e4884109b9526ac645194ba892a74Michal Krol   R200_STATECHANGE( rmesa, ctx );
762861e737e84e4884109b9526ac645194ba892a74Michal Krol
772861e737e84e4884109b9526ac645194ba892a74Michal Krol   pp_misc &= ~(R200_ALPHA_TEST_OP_MASK | R200_REF_ALPHA_MASK);
782861e737e84e4884109b9526ac645194ba892a74Michal Krol   pp_misc |= (refByte & R200_REF_ALPHA_MASK);
79740a8b0b66f0e00807f064e3105fd6b045e5a2d0Brian
802861e737e84e4884109b9526ac645194ba892a74Michal Krol   switch ( func ) {
812861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_NEVER:
822861e737e84e4884109b9526ac645194ba892a74Michal Krol      pp_misc |= R200_ALPHA_TEST_FAIL;
832861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
842861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_LESS:
852861e737e84e4884109b9526ac645194ba892a74Michal Krol      pp_misc |= R200_ALPHA_TEST_LESS;
862861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
872861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_EQUAL:
8881968ec49d9e06be0e095fa0084aa61b68b23d75Brian Paul      pp_misc |= R200_ALPHA_TEST_EQUAL;
8981968ec49d9e06be0e095fa0084aa61b68b23d75Brian Paul      break;
9081968ec49d9e06be0e095fa0084aa61b68b23d75Brian Paul   case GL_LEQUAL:
912861e737e84e4884109b9526ac645194ba892a74Michal Krol      pp_misc |= R200_ALPHA_TEST_LEQUAL;
922861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
932861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_GREATER:
942861e737e84e4884109b9526ac645194ba892a74Michal Krol      pp_misc |= R200_ALPHA_TEST_GREATER;
952861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
962861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_NOTEQUAL:
972861e737e84e4884109b9526ac645194ba892a74Michal Krol      pp_misc |= R200_ALPHA_TEST_NEQUAL;
982861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
992861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_GEQUAL:
1002861e737e84e4884109b9526ac645194ba892a74Michal Krol      pp_misc |= R200_ALPHA_TEST_GEQUAL;
1012861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1022861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_ALWAYS:
103122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul      pp_misc |= R200_ALPHA_TEST_PASS;
1042861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1052861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
1062861e737e84e4884109b9526ac645194ba892a74Michal Krol
1072861e737e84e4884109b9526ac645194ba892a74Michal Krol   rmesa->hw.ctx.cmd[CTX_PP_MISC] = pp_misc;
1084d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul}
1092861e737e84e4884109b9526ac645194ba892a74Michal Krol
1102861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200BlendColor( GLcontext *ctx, const GLfloat cf[4] )
1112861e737e84e4884109b9526ac645194ba892a74Michal Krol{
1122861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLubyte color[4];
1132861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1142861e737e84e4884109b9526ac645194ba892a74Michal Krol   R200_STATECHANGE( rmesa, ctx );
1152861e737e84e4884109b9526ac645194ba892a74Michal Krol   CLAMPED_FLOAT_TO_UBYTE(color[0], cf[0]);
1162861e737e84e4884109b9526ac645194ba892a74Michal Krol   CLAMPED_FLOAT_TO_UBYTE(color[1], cf[1]);
1172861e737e84e4884109b9526ac645194ba892a74Michal Krol   CLAMPED_FLOAT_TO_UBYTE(color[2], cf[2]);
1182861e737e84e4884109b9526ac645194ba892a74Michal Krol   CLAMPED_FLOAT_TO_UBYTE(color[3], cf[3]);
1192861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (rmesa->radeon.radeonScreen->drmSupportsBlendColor)
1202861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCOLOR] = radeonPackColor( 4, color[0], color[1], color[2], color[3] );
1212861e737e84e4884109b9526ac645194ba892a74Michal Krol}
1222861e737e84e4884109b9526ac645194ba892a74Michal Krol
1232861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
1242861e737e84e4884109b9526ac645194ba892a74Michal Krol * Calculate the hardware blend factor setting.  This same function is used
1252861e737e84e4884109b9526ac645194ba892a74Michal Krol * for source and destination of both alpha and RGB.
1262861e737e84e4884109b9526ac645194ba892a74Michal Krol *
1272861e737e84e4884109b9526ac645194ba892a74Michal Krol * \returns
1282861e737e84e4884109b9526ac645194ba892a74Michal Krol * The hardware register value for the specified blend factor.  This value
1292861e737e84e4884109b9526ac645194ba892a74Michal Krol * will need to be shifted into the correct position for either source or
1302861e737e84e4884109b9526ac645194ba892a74Michal Krol * destination factor.
1312861e737e84e4884109b9526ac645194ba892a74Michal Krol *
1322861e737e84e4884109b9526ac645194ba892a74Michal Krol * \todo
1332861e737e84e4884109b9526ac645194ba892a74Michal Krol * Since the two cases where source and destination are handled differently
1342861e737e84e4884109b9526ac645194ba892a74Michal Krol * are essentially error cases, they should never happen.  Determine if these
1352861e737e84e4884109b9526ac645194ba892a74Michal Krol * cases can be removed.
1362861e737e84e4884109b9526ac645194ba892a74Michal Krol */
1372861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic int blend_factor( GLenum factor, GLboolean is_src )
1382861e737e84e4884109b9526ac645194ba892a74Michal Krol{
1392861e737e84e4884109b9526ac645194ba892a74Michal Krol   int func;
1402861e737e84e4884109b9526ac645194ba892a74Michal Krol
1412861e737e84e4884109b9526ac645194ba892a74Michal Krol   switch ( factor ) {
1422861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_ZERO:
1432861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_ZERO;
1442861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1452861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_ONE:
1462861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_ONE;
1472861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1482861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_DST_COLOR:
149122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul      func = R200_BLEND_GL_DST_COLOR;
1502861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1512861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_ONE_MINUS_DST_COLOR:
1522861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_ONE_MINUS_DST_COLOR;
1532861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1542861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_SRC_COLOR:
1552861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_SRC_COLOR;
1564d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul      break;
1572861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_ONE_MINUS_SRC_COLOR:
1582861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_ONE_MINUS_SRC_COLOR;
1592861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1602861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_SRC_ALPHA:
1612861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_SRC_ALPHA;
1629ca83924848070d02a5ac2f0aa4e20444eec2183Brian Paul      break;
1632861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_ONE_MINUS_SRC_ALPHA:
1642861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_ONE_MINUS_SRC_ALPHA;
1652861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1662861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_DST_ALPHA:
1672861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_DST_ALPHA;
1682861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1692861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_ONE_MINUS_DST_ALPHA:
1702861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_ONE_MINUS_DST_ALPHA;
1712861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1722861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_SRC_ALPHA_SATURATE:
1732861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = (is_src) ? R200_BLEND_GL_SRC_ALPHA_SATURATE : R200_BLEND_GL_ZERO;
1742861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1752861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_CONSTANT_COLOR:
1762861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_CONST_COLOR;
1772861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1782861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_ONE_MINUS_CONSTANT_COLOR:
1792861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_ONE_MINUS_CONST_COLOR;
1802861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1812861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_CONSTANT_ALPHA:
1822861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_CONST_ALPHA;
1832861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1842861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_ONE_MINUS_CONSTANT_ALPHA:
1852861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = R200_BLEND_GL_ONE_MINUS_CONST_ALPHA;
1862861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
1872861e737e84e4884109b9526ac645194ba892a74Michal Krol   default:
1882861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = (is_src) ? R200_BLEND_GL_ONE : R200_BLEND_GL_ZERO;
1892861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
1902861e737e84e4884109b9526ac645194ba892a74Michal Krol   return func;
1912861e737e84e4884109b9526ac645194ba892a74Michal Krol}
1922861e737e84e4884109b9526ac645194ba892a74Michal Krol
1932861e737e84e4884109b9526ac645194ba892a74Michal Krol/**
1942861e737e84e4884109b9526ac645194ba892a74Michal Krol * Sets both the blend equation and the blend function.
1952861e737e84e4884109b9526ac645194ba892a74Michal Krol * This is done in a single
1962861e737e84e4884109b9526ac645194ba892a74Michal Krol * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX)
1972861e737e84e4884109b9526ac645194ba892a74Michal Krol * change the interpretation of the blend function.
1982861e737e84e4884109b9526ac645194ba892a74Michal Krol * Also, make sure that blend function and blend equation are set to their default
1992861e737e84e4884109b9526ac645194ba892a74Michal Krol * value if color blending is not enabled, since at least blend equations GL_MIN
2002861e737e84e4884109b9526ac645194ba892a74Michal Krol * and GL_FUNC_REVERSE_SUBTRACT will cause wrong results otherwise for
2012861e737e84e4884109b9526ac645194ba892a74Michal Krol * unknown reasons.
2022861e737e84e4884109b9526ac645194ba892a74Michal Krol */
2032861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200_set_blend_state( GLcontext * ctx )
2042861e737e84e4884109b9526ac645194ba892a74Michal Krol{
2052861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
2062861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint cntl = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &
2072861e737e84e4884109b9526ac645194ba892a74Michal Krol      ~(R200_ROP_ENABLE | R200_ALPHA_BLEND_ENABLE | R200_SEPARATE_ALPHA_ENABLE);
2082861e737e84e4884109b9526ac645194ba892a74Michal Krol
2092861e737e84e4884109b9526ac645194ba892a74Michal Krol   int func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
2102861e737e84e4884109b9526ac645194ba892a74Michal Krol      (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
2112861e737e84e4884109b9526ac645194ba892a74Michal Krol   int eqn = R200_COMB_FCN_ADD_CLAMP;
2122861e737e84e4884109b9526ac645194ba892a74Michal Krol   int funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
2132861e737e84e4884109b9526ac645194ba892a74Michal Krol      (R200_BLEND_GL_ZERO << R200_DST_BLEND_SHIFT);
2142861e737e84e4884109b9526ac645194ba892a74Michal Krol   int eqnA = R200_COMB_FCN_ADD_CLAMP;
2152861e737e84e4884109b9526ac645194ba892a74Michal Krol
2162861e737e84e4884109b9526ac645194ba892a74Michal Krol   R200_STATECHANGE( rmesa, ctx );
2172861e737e84e4884109b9526ac645194ba892a74Michal Krol
2182861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
2192861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (ctx->Color.ColorLogicOpEnabled) {
2202861e737e84e4884109b9526ac645194ba892a74Michal Krol         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =  cntl | R200_ROP_ENABLE;
2212861e737e84e4884109b9526ac645194ba892a74Michal Krol         rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqn | func;
2222861e737e84e4884109b9526ac645194ba892a74Michal Krol         rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
2232861e737e84e4884109b9526ac645194ba892a74Michal Krol         return;
2242861e737e84e4884109b9526ac645194ba892a74Michal Krol      } else if (ctx->Color.BlendEnabled) {
2252861e737e84e4884109b9526ac645194ba892a74Michal Krol         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =  cntl | R200_ALPHA_BLEND_ENABLE | R200_SEPARATE_ALPHA_ENABLE;
2262861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
2272861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
2282861e737e84e4884109b9526ac645194ba892a74Michal Krol         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
2292861e737e84e4884109b9526ac645194ba892a74Michal Krol         rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqn | func;
2302861e737e84e4884109b9526ac645194ba892a74Michal Krol         rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
2312861e737e84e4884109b9526ac645194ba892a74Michal Krol         return;
2322861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
2332861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
2342861e737e84e4884109b9526ac645194ba892a74Michal Krol   else {
2352861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (ctx->Color.ColorLogicOpEnabled) {
2362861e737e84e4884109b9526ac645194ba892a74Michal Krol         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =  cntl | R200_ROP_ENABLE;
2372861e737e84e4884109b9526ac645194ba892a74Michal Krol         rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
2382861e737e84e4884109b9526ac645194ba892a74Michal Krol         return;
2392861e737e84e4884109b9526ac645194ba892a74Michal Krol      } else if (ctx->Color.BlendEnabled) {
2402861e737e84e4884109b9526ac645194ba892a74Michal Krol         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] =  cntl | R200_ALPHA_BLEND_ENABLE;
2412861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
2422861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
2432861e737e84e4884109b9526ac645194ba892a74Michal Krol         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = cntl;
2442861e737e84e4884109b9526ac645194ba892a74Michal Krol         rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
2452861e737e84e4884109b9526ac645194ba892a74Michal Krol         return;
246122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul      }
2472861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
2482861e737e84e4884109b9526ac645194ba892a74Michal Krol
249548be3846db59ad43934a159c051b359db6e56dbBrian Paul   func = (blend_factor( ctx->Color.BlendSrcRGB, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
2502861e737e84e4884109b9526ac645194ba892a74Michal Krol      (blend_factor( ctx->Color.BlendDstRGB, GL_FALSE ) << R200_DST_BLEND_SHIFT);
2514d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul
2522861e737e84e4884109b9526ac645194ba892a74Michal Krol   switch(ctx->Color.BlendEquationRGB) {
2532861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_FUNC_ADD:
2542861e737e84e4884109b9526ac645194ba892a74Michal Krol      eqn = R200_COMB_FCN_ADD_CLAMP;
2552861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
2562861e737e84e4884109b9526ac645194ba892a74Michal Krol
2572861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_FUNC_SUBTRACT:
2582861e737e84e4884109b9526ac645194ba892a74Michal Krol      eqn = R200_COMB_FCN_SUB_CLAMP;
2592861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
2602861e737e84e4884109b9526ac645194ba892a74Michal Krol
2612861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_FUNC_REVERSE_SUBTRACT:
2626258b76c49f49a56a7c713914b798e80c6553b06Karl Schultz      eqn = R200_COMB_FCN_RSUB_CLAMP;
2632861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
2642861e737e84e4884109b9526ac645194ba892a74Michal Krol
2652861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_MIN:
2662861e737e84e4884109b9526ac645194ba892a74Michal Krol      eqn = R200_COMB_FCN_MIN;
2672861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
2682861e737e84e4884109b9526ac645194ba892a74Michal Krol         (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
2692861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
2702861e737e84e4884109b9526ac645194ba892a74Michal Krol
2712861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_MAX:
2722861e737e84e4884109b9526ac645194ba892a74Michal Krol      eqn = R200_COMB_FCN_MAX;
2732861e737e84e4884109b9526ac645194ba892a74Michal Krol      func = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
2742861e737e84e4884109b9526ac645194ba892a74Michal Krol         (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
2752861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
2762861e737e84e4884109b9526ac645194ba892a74Michal Krol
2772861e737e84e4884109b9526ac645194ba892a74Michal Krol   default:
2782861e737e84e4884109b9526ac645194ba892a74Michal Krol      fprintf( stderr, "[%s:%u] Invalid RGB blend equation (0x%04x).\n",
2792861e737e84e4884109b9526ac645194ba892a74Michal Krol         __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB );
2802861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
2812861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
282122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul
2832861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!rmesa->radeon.radeonScreen->drmSupportsBlendColor) {
2842861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = eqn | func;
285548be3846db59ad43934a159c051b359db6e56dbBrian Paul      return;
2862861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
2872861e737e84e4884109b9526ac645194ba892a74Michal Krol
2882861e737e84e4884109b9526ac645194ba892a74Michal Krol   funcA = (blend_factor( ctx->Color.BlendSrcA, GL_TRUE ) << R200_SRC_BLEND_SHIFT) |
2892861e737e84e4884109b9526ac645194ba892a74Michal Krol      (blend_factor( ctx->Color.BlendDstA, GL_FALSE ) << R200_DST_BLEND_SHIFT);
2902861e737e84e4884109b9526ac645194ba892a74Michal Krol
2912861e737e84e4884109b9526ac645194ba892a74Michal Krol   switch(ctx->Color.BlendEquationA) {
2924d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul   case GL_FUNC_ADD:
2932861e737e84e4884109b9526ac645194ba892a74Michal Krol      eqnA = R200_COMB_FCN_ADD_CLAMP;
2942861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
2952861e737e84e4884109b9526ac645194ba892a74Michal Krol
2962861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_FUNC_SUBTRACT:
2972861e737e84e4884109b9526ac645194ba892a74Michal Krol      eqnA = R200_COMB_FCN_SUB_CLAMP;
2982861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
2992861e737e84e4884109b9526ac645194ba892a74Michal Krol
3002861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_FUNC_REVERSE_SUBTRACT:
3012861e737e84e4884109b9526ac645194ba892a74Michal Krol      eqnA = R200_COMB_FCN_RSUB_CLAMP;
3022861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
3032861e737e84e4884109b9526ac645194ba892a74Michal Krol
3042861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_MIN:
3052861e737e84e4884109b9526ac645194ba892a74Michal Krol      eqnA = R200_COMB_FCN_MIN;
3062861e737e84e4884109b9526ac645194ba892a74Michal Krol      funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
3072861e737e84e4884109b9526ac645194ba892a74Michal Krol         (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
3082861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
3092861e737e84e4884109b9526ac645194ba892a74Michal Krol
3102861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_MAX:
3112861e737e84e4884109b9526ac645194ba892a74Michal Krol      eqnA = R200_COMB_FCN_MAX;
3122861e737e84e4884109b9526ac645194ba892a74Michal Krol      funcA = (R200_BLEND_GL_ONE << R200_SRC_BLEND_SHIFT) |
3132861e737e84e4884109b9526ac645194ba892a74Michal Krol         (R200_BLEND_GL_ONE << R200_DST_BLEND_SHIFT);
3142861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
3152861e737e84e4884109b9526ac645194ba892a74Michal Krol
3162861e737e84e4884109b9526ac645194ba892a74Michal Krol   default:
3172861e737e84e4884109b9526ac645194ba892a74Michal Krol      fprintf( stderr, "[%s:%u] Invalid A blend equation (0x%04x).\n",
3182861e737e84e4884109b9526ac645194ba892a74Michal Krol         __FUNCTION__, __LINE__, ctx->Color.BlendEquationA );
3192861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
3202861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3212861e737e84e4884109b9526ac645194ba892a74Michal Krol
3222861e737e84e4884109b9526ac645194ba892a74Michal Krol   rmesa->hw.ctx.cmd[CTX_RB3D_ABLENDCNTL] = eqnA | funcA;
3232861e737e84e4884109b9526ac645194ba892a74Michal Krol   rmesa->hw.ctx.cmd[CTX_RB3D_CBLENDCNTL] = eqn | func;
3242861e737e84e4884109b9526ac645194ba892a74Michal Krol
3252861e737e84e4884109b9526ac645194ba892a74Michal Krol}
3262861e737e84e4884109b9526ac645194ba892a74Michal Krol
3272861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200BlendEquationSeparate( GLcontext *ctx,
3282861e737e84e4884109b9526ac645194ba892a74Michal Krol				       GLenum modeRGB, GLenum modeA )
3292861e737e84e4884109b9526ac645194ba892a74Michal Krol{
3302861e737e84e4884109b9526ac645194ba892a74Michal Krol      r200_set_blend_state( ctx );
3312861e737e84e4884109b9526ac645194ba892a74Michal Krol}
3322861e737e84e4884109b9526ac645194ba892a74Michal Krol
3332861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200BlendFuncSeparate( GLcontext *ctx,
3342861e737e84e4884109b9526ac645194ba892a74Michal Krol				     GLenum sfactorRGB, GLenum dfactorRGB,
3352861e737e84e4884109b9526ac645194ba892a74Michal Krol				     GLenum sfactorA, GLenum dfactorA )
3362861e737e84e4884109b9526ac645194ba892a74Michal Krol{
3372861e737e84e4884109b9526ac645194ba892a74Michal Krol      r200_set_blend_state( ctx );
3382861e737e84e4884109b9526ac645194ba892a74Michal Krol}
3392861e737e84e4884109b9526ac645194ba892a74Michal Krol
3402861e737e84e4884109b9526ac645194ba892a74Michal Krol
3412861e737e84e4884109b9526ac645194ba892a74Michal Krol/* =============================================================
3422861e737e84e4884109b9526ac645194ba892a74Michal Krol * Depth testing
3432861e737e84e4884109b9526ac645194ba892a74Michal Krol */
3442861e737e84e4884109b9526ac645194ba892a74Michal Krol
3452861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200DepthFunc( GLcontext *ctx, GLenum func )
3462861e737e84e4884109b9526ac645194ba892a74Michal Krol{
3472861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
3482861e737e84e4884109b9526ac645194ba892a74Michal Krol
3492861e737e84e4884109b9526ac645194ba892a74Michal Krol   R200_STATECHANGE( rmesa, ctx );
3502861e737e84e4884109b9526ac645194ba892a74Michal Krol   rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_Z_TEST_MASK;
3512861e737e84e4884109b9526ac645194ba892a74Michal Krol
3522861e737e84e4884109b9526ac645194ba892a74Michal Krol   switch ( ctx->Depth.Func ) {
3532861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_NEVER:
3542861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_NEVER;
3552861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
3562861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_LESS:
357667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_LESS;
3582861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
3592861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_EQUAL:
3602861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_EQUAL;
361120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul      break;
3622861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_LEQUAL:
3632861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_LEQUAL;
3642861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
3652861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_GREATER:
366667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_GREATER;
367667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul      break;
3682861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_NOTEQUAL:
3692861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_NEQUAL;
370667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul      break;
3712861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_GEQUAL:
3722861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_GEQUAL;
373667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul      break;
3742861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_ALWAYS:
3752861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_Z_TEST_ALWAYS;
376667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul      break;
3772861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3782861e737e84e4884109b9526ac645194ba892a74Michal Krol}
379120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul
380120584a1e650c5c72c889666a82624af4f5df1c1Brian Paulstatic void r200ClearDepth( GLcontext *ctx, GLclampd d )
381120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul{
382120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul   r200ContextPtr rmesa = R200_CONTEXT(ctx);
383120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul   GLuint format = (rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &
3842861e737e84e4884109b9526ac645194ba892a74Michal Krol		    R200_DEPTH_FORMAT_MASK);
3852861e737e84e4884109b9526ac645194ba892a74Michal Krol
3862861e737e84e4884109b9526ac645194ba892a74Michal Krol   switch ( format ) {
3872861e737e84e4884109b9526ac645194ba892a74Michal Krol   case R200_DEPTH_FORMAT_16BIT_INT_Z:
3882861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->radeon.state.depth.clear = d * 0x0000ffff;
3892861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
3902861e737e84e4884109b9526ac645194ba892a74Michal Krol   case R200_DEPTH_FORMAT_24BIT_INT_Z:
3912861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->radeon.state.depth.clear = d * 0x00ffffff;
3922861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
3932861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
3942861e737e84e4884109b9526ac645194ba892a74Michal Krol}
3952861e737e84e4884109b9526ac645194ba892a74Michal Krol
3962861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200DepthMask( GLcontext *ctx, GLboolean flag )
3972861e737e84e4884109b9526ac645194ba892a74Michal Krol{
3982861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
3992861e737e84e4884109b9526ac645194ba892a74Michal Krol   R200_STATECHANGE( rmesa, ctx );
4002861e737e84e4884109b9526ac645194ba892a74Michal Krol
401667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul   if ( ctx->Depth.Mask ) {
4022861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |=  R200_Z_WRITE_ENABLE;
4032861e737e84e4884109b9526ac645194ba892a74Michal Krol   } else {
4042861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_Z_WRITE_ENABLE;
405120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul   }
4062861e737e84e4884109b9526ac645194ba892a74Michal Krol}
4072861e737e84e4884109b9526ac645194ba892a74Michal Krol
4082861e737e84e4884109b9526ac645194ba892a74Michal Krol
4092861e737e84e4884109b9526ac645194ba892a74Michal Krol/* =============================================================
410667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul * Fog
411667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul */
4122861e737e84e4884109b9526ac645194ba892a74Michal Krol
4132861e737e84e4884109b9526ac645194ba892a74Michal Krol
414667a4037fac4fd154ebfa7513b3bbba935077241Brian Paulstatic void r200Fogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
4152861e737e84e4884109b9526ac645194ba892a74Michal Krol{
4162861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
417667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul   union { int i; float f; } c, d;
4182861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLchan col[4];
4192861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint i;
420667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul
4212861e737e84e4884109b9526ac645194ba892a74Michal Krol   c.i = rmesa->hw.fog.cmd[FOG_C];
4222861e737e84e4884109b9526ac645194ba892a74Michal Krol   d.i = rmesa->hw.fog.cmd[FOG_D];
423120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul
424120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul   switch (pname) {
425120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul   case GL_FOG_MODE:
426120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul      if (!ctx->Fog.Enabled)
427120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul	 return;
4282861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE(rmesa, tcl);
4292861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_TCL_FOG_MASK;
4302861e737e84e4884109b9526ac645194ba892a74Michal Krol      switch (ctx->Fog.Mode) {
4312861e737e84e4884109b9526ac645194ba892a74Michal Krol      case GL_LINEAR:
4322861e737e84e4884109b9526ac645194ba892a74Michal Krol	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_LINEAR;
4332861e737e84e4884109b9526ac645194ba892a74Michal Krol	 if (ctx->Fog.Start == ctx->Fog.End) {
4342861e737e84e4884109b9526ac645194ba892a74Michal Krol	    c.f = 1.0F;
4352861e737e84e4884109b9526ac645194ba892a74Michal Krol	    d.f = 1.0F;
4362861e737e84e4884109b9526ac645194ba892a74Michal Krol	 }
4372861e737e84e4884109b9526ac645194ba892a74Michal Krol	 else {
4382861e737e84e4884109b9526ac645194ba892a74Michal Krol	    c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
4392861e737e84e4884109b9526ac645194ba892a74Michal Krol	    d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
4402861e737e84e4884109b9526ac645194ba892a74Michal Krol	 }
4412861e737e84e4884109b9526ac645194ba892a74Michal Krol	 break;
4422861e737e84e4884109b9526ac645194ba892a74Michal Krol      case GL_EXP:
4432861e737e84e4884109b9526ac645194ba892a74Michal Krol	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_EXP;
4442861e737e84e4884109b9526ac645194ba892a74Michal Krol	 c.f = 0.0;
445667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul	 d.f = -ctx->Fog.Density;
4462861e737e84e4884109b9526ac645194ba892a74Michal Krol	 break;
4472861e737e84e4884109b9526ac645194ba892a74Michal Krol      case GL_EXP2:
4482861e737e84e4884109b9526ac645194ba892a74Michal Krol	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_TCL_FOG_EXP2;
449120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul	 c.f = 0.0;
4502861e737e84e4884109b9526ac645194ba892a74Michal Krol	 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
4512861e737e84e4884109b9526ac645194ba892a74Michal Krol	 break;
4522861e737e84e4884109b9526ac645194ba892a74Michal Krol      default:
4532861e737e84e4884109b9526ac645194ba892a74Michal Krol	 return;
454667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul      }
455667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul      break;
4562861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_FOG_DENSITY:
4572861e737e84e4884109b9526ac645194ba892a74Michal Krol      switch (ctx->Fog.Mode) {
458667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul      case GL_EXP:
4592861e737e84e4884109b9526ac645194ba892a74Michal Krol	 c.f = 0.0;
4602861e737e84e4884109b9526ac645194ba892a74Michal Krol	 d.f = -ctx->Fog.Density;
461667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul	 break;
4622861e737e84e4884109b9526ac645194ba892a74Michal Krol      case GL_EXP2:
4632861e737e84e4884109b9526ac645194ba892a74Michal Krol	 c.f = 0.0;
464667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul	 d.f = -(ctx->Fog.Density * ctx->Fog.Density);
4652861e737e84e4884109b9526ac645194ba892a74Michal Krol	 break;
4662861e737e84e4884109b9526ac645194ba892a74Michal Krol      default:
467120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul	 break;
468120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul      }
469120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul      break;
470120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul   case GL_FOG_START:
471120584a1e650c5c72c889666a82624af4f5df1c1Brian Paul   case GL_FOG_END:
4722861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (ctx->Fog.Mode == GL_LINEAR) {
4732861e737e84e4884109b9526ac645194ba892a74Michal Krol	 if (ctx->Fog.Start == ctx->Fog.End) {
4742861e737e84e4884109b9526ac645194ba892a74Michal Krol	    c.f = 1.0F;
4752861e737e84e4884109b9526ac645194ba892a74Michal Krol	    d.f = 1.0F;
4762861e737e84e4884109b9526ac645194ba892a74Michal Krol	 } else {
4772861e737e84e4884109b9526ac645194ba892a74Michal Krol	    c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
4782861e737e84e4884109b9526ac645194ba892a74Michal Krol	    d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
479667a4037fac4fd154ebfa7513b3bbba935077241Brian Paul	 }
4802861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
4812861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
4822861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_FOG_COLOR:
4832861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE( rmesa, ctx );
4842861e737e84e4884109b9526ac645194ba892a74Michal Krol      UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color );
4852861e737e84e4884109b9526ac645194ba892a74Michal Krol      i = radeonPackColor( 4, col[0], col[1], col[2], 0 );
4862861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_COLOR_MASK;
4872861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= i;
4882861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
4892861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_FOG_COORD_SRC: {
4902861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLuint out_0 = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0];
4912861e737e84e4884109b9526ac645194ba892a74Michal Krol      GLuint fog   = rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR];
4922861e737e84e4884109b9526ac645194ba892a74Michal Krol
4932861e737e84e4884109b9526ac645194ba892a74Michal Krol      fog &= ~R200_FOG_USE_MASK;
4942861e737e84e4884109b9526ac645194ba892a74Michal Krol      if ( ctx->Fog.FogCoordinateSource == GL_FOG_COORD || ctx->VertexProgram.Enabled) {
4952861e737e84e4884109b9526ac645194ba892a74Michal Krol	 fog   |= R200_FOG_USE_VTX_FOG;
4962861e737e84e4884109b9526ac645194ba892a74Michal Krol	 out_0 |= R200_VTX_DISCRETE_FOG;
4972861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
4982861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
4992861e737e84e4884109b9526ac645194ba892a74Michal Krol	 fog   |=  R200_FOG_USE_SPEC_ALPHA;
5002861e737e84e4884109b9526ac645194ba892a74Michal Krol	 out_0 &= ~R200_VTX_DISCRETE_FOG;
5012861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
5022861e737e84e4884109b9526ac645194ba892a74Michal Krol
5032861e737e84e4884109b9526ac645194ba892a74Michal Krol      if ( fog != rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] ) {
5042861e737e84e4884109b9526ac645194ba892a74Michal Krol	 R200_STATECHANGE( rmesa, ctx );
5052861e737e84e4884109b9526ac645194ba892a74Michal Krol	 rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = fog;
5062861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
5072861e737e84e4884109b9526ac645194ba892a74Michal Krol
5082861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (out_0 != rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0]) {
509ee34e6ef716bb630440299ac1efbc2055ef09ffdIan Romanick	 R200_STATECHANGE( rmesa, vtx );
5102861e737e84e4884109b9526ac645194ba892a74Michal Krol	 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] = out_0;
5112861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
512726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt
513726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt      break;
514726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   }
515726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   default:
516726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt      return;
517726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   }
518726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt
519726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
520726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt      R200_STATECHANGE( rmesa, fog );
521726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt      rmesa->hw.fog.cmd[FOG_C] = c.i;
522726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt      rmesa->hw.fog.cmd[FOG_D] = d.i;
523726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   }
524726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt}
525726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt
526726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt/* =============================================================
5272861e737e84e4884109b9526ac645194ba892a74Michal Krol * Culling
528726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt */
529726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt
530726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholtstatic void r200CullFace( GLcontext *ctx, GLenum unused )
531726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt{
532726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   r200ContextPtr rmesa = R200_CONTEXT(ctx);
533726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
534726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   GLuint t = rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL];
535726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt
536726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   s |= R200_FFACE_SOLID | R200_BFACE_SOLID;
537726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   t &= ~(R200_CULL_FRONT | R200_CULL_BACK);
538726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt
539726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   if ( ctx->Polygon.CullFlag ) {
540726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt      switch ( ctx->Polygon.CullFaceMode ) {
541726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt      case GL_FRONT:
542726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt	 s &= ~R200_FFACE_SOLID;
543726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt	 t |= R200_CULL_FRONT;
544726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt	 break;
545726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt      case GL_BACK:
546726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt	 s &= ~R200_BFACE_SOLID;
547726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt	 t |= R200_CULL_BACK;
548726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt	 break;
549726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt      case GL_FRONT_AND_BACK:
550726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt	 s &= ~(R200_FFACE_SOLID | R200_BFACE_SOLID);
551726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt	 t |= (R200_CULL_FRONT | R200_CULL_BACK);
552726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt	 break;
553726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt      }
554726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   }
555726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt
556726a04a2cd1bf159a6c40584b4b2b9bc5948a82eEric Anholt   if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
5572861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE(rmesa, set );
558601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt      rmesa->hw.set.cmd[SET_SE_CNTL] = s;
559601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   }
560601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt
561601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   if ( rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] != t ) {
562601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt      R200_STATECHANGE(rmesa, tcl );
563601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt      rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = t;
564601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   }
565601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt}
566601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt
567601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholtstatic void r200FrontFace( GLcontext *ctx, GLenum mode )
568601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt{
569601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   r200ContextPtr rmesa = R200_CONTEXT(ctx);
570601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt
571601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   R200_STATECHANGE( rmesa, set );
572601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_FFACE_CULL_DIR_MASK;
573601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt
574601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   R200_STATECHANGE( rmesa, tcl );
575601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_CULL_FRONT_IS_CCW;
576601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt
577601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   /* Winding is inverted when rendering to FBO */
578601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
579601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt      mode = (mode == GL_CW) ? GL_CCW : GL_CW;
580601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt
581601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   switch ( mode ) {
582601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   case GL_CW:
583601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt      rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_FFACE_CULL_CW;
584601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt      break;
585601769a2c0071e23ade32de4e8911d75d7f324d2Eric Anholt   case GL_CCW:
5862861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.set.cmd[SET_SE_CNTL] |= R200_FFACE_CULL_CCW;
5872861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= R200_CULL_FRONT_IS_CCW;
5882861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
5892861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
5902861e737e84e4884109b9526ac645194ba892a74Michal Krol}
5912861e737e84e4884109b9526ac645194ba892a74Michal Krol
5922861e737e84e4884109b9526ac645194ba892a74Michal Krol/* =============================================================
5932861e737e84e4884109b9526ac645194ba892a74Michal Krol * Point state
594122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul */
5952861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200PointSize( GLcontext *ctx, GLfloat size )
5962861e737e84e4884109b9526ac645194ba892a74Michal Krol{
5972861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
5982861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
5992861e737e84e4884109b9526ac645194ba892a74Michal Krol
6002861e737e84e4884109b9526ac645194ba892a74Michal Krol   R200_STATECHANGE( rmesa, cst );
6018a97946e0a25aff2d56bbaf3ed20ba1588129993Brian Paul   R200_STATECHANGE( rmesa, ptp );
6028a97946e0a25aff2d56bbaf3ed20ba1588129993Brian Paul   rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= ~0xffff;
6038a97946e0a25aff2d56bbaf3ed20ba1588129993Brian Paul   rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= ((GLuint)(ctx->Point.Size * 16.0));
6048a97946e0a25aff2d56bbaf3ed20ba1588129993Brian Paul/* this is the size param of the point size calculation (point size reg value
6058a97946e0a25aff2d56bbaf3ed20ba1588129993Brian Paul   is not used when calculation is active). */
6062861e737e84e4884109b9526ac645194ba892a74Michal Krol   fcmd[PTP_VPORT_SCALE_PTSIZE] = ctx->Point.Size;
6072861e737e84e4884109b9526ac645194ba892a74Michal Krol}
6082861e737e84e4884109b9526ac645194ba892a74Michal Krol
6092861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200PointParameter( GLcontext *ctx, GLenum pname, const GLfloat *params)
6104d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul{
6112861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
6122861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
6132861e737e84e4884109b9526ac645194ba892a74Michal Krol
6142861e737e84e4884109b9526ac645194ba892a74Michal Krol   switch (pname) {
6152861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_POINT_SIZE_MIN:
6162861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Can clamp both in tcl and setup - just set both (as does fglrx) */
6172861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE( rmesa, lin );
6182861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE( rmesa, ptp );
6192861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= 0xffff;
620122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul      rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)(ctx->Point.MinSize * 16.0) << 16;
6219ca83924848070d02a5ac2f0aa4e20444eec2183Brian Paul      fcmd[PTP_CLAMP_MIN] = ctx->Point.MinSize;
622122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul      break;
6230590786f8af98bb849cee11fffd51be7db04f1b5Brian Paul   case GL_POINT_SIZE_MAX:
6242861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE( rmesa, cst );
6252861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE( rmesa, ptp );
6262861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= 0xffff;
6272861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= (GLuint)(ctx->Point.MaxSize * 16.0) << 16;
6282861e737e84e4884109b9526ac645194ba892a74Michal Krol      fcmd[PTP_CLAMP_MAX] = ctx->Point.MaxSize;
6292861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
6302861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_POINT_DISTANCE_ATTENUATION:
6312861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE( rmesa, vtx );
6322861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE( rmesa, spr );
6332861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE( rmesa, ptp );
634122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul      GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
6359ca83924848070d02a5ac2f0aa4e20444eec2183Brian Paul      rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &=
636122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul	 ~(R200_PS_MULT_MASK | R200_PS_LIN_ATT_ZERO | R200_PS_SE_SEL_STATE);
6370590786f8af98bb849cee11fffd51be7db04f1b5Brian Paul      /* can't rely on ctx->Point._Attenuated here and test for NEW_POINT in
6382861e737e84e4884109b9526ac645194ba892a74Michal Krol	 r200ValidateState looks like overkill */
6392861e737e84e4884109b9526ac645194ba892a74Michal Krol      if (ctx->Point.Params[0] != 1.0 ||
6402861e737e84e4884109b9526ac645194ba892a74Michal Krol	  ctx->Point.Params[1] != 0.0 ||
6412861e737e84e4884109b9526ac645194ba892a74Michal Krol	  ctx->Point.Params[2] != 0.0 ||
6422861e737e84e4884109b9526ac645194ba892a74Michal Krol	  (ctx->VertexProgram.Enabled && ctx->VertexProgram.PointSizeEnabled)) {
6432861e737e84e4884109b9526ac645194ba892a74Michal Krol	 /* all we care for vp would be the ps_se_sel_state setting */
6442861e737e84e4884109b9526ac645194ba892a74Michal Krol	 fcmd[PTP_ATT_CONST_QUAD] = ctx->Point.Params[2];
6452861e737e84e4884109b9526ac645194ba892a74Michal Krol	 fcmd[PTP_ATT_CONST_LIN] = ctx->Point.Params[1];
6462861e737e84e4884109b9526ac645194ba892a74Michal Krol	 fcmd[PTP_ATT_CONST_CON] = ctx->Point.Params[0];
6472861e737e84e4884109b9526ac645194ba892a74Michal Krol	 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_MULT_ATTENCONST;
6482861e737e84e4884109b9526ac645194ba892a74Michal Krol	 if (ctx->Point.Params[1] == 0.0)
6492861e737e84e4884109b9526ac645194ba892a74Michal Krol	    rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_LIN_ATT_ZERO;
6502861e737e84e4884109b9526ac645194ba892a74Michal Krol/* FIXME: setting this here doesn't look quite ok - we only want to do
6512861e737e84e4884109b9526ac645194ba892a74Michal Krol          that if we're actually drawing points probably */
6522861e737e84e4884109b9526ac645194ba892a74Michal Krol	 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_PT_SIZE;
6532861e737e84e4884109b9526ac645194ba892a74Michal Krol	 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= R200_VTX_POINT_SIZE;
6542861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
6552861e737e84e4884109b9526ac645194ba892a74Michal Krol      else {
6562861e737e84e4884109b9526ac645194ba892a74Michal Krol	 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |=
6572861e737e84e4884109b9526ac645194ba892a74Michal Krol	    R200_PS_SE_SEL_STATE | R200_PS_MULT_CONST;
6582861e737e84e4884109b9526ac645194ba892a74Michal Krol	 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_PT_SIZE;
6592861e737e84e4884109b9526ac645194ba892a74Michal Krol	 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~R200_VTX_POINT_SIZE;
6602861e737e84e4884109b9526ac645194ba892a74Michal Krol      }
6612861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
6622861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_POINT_FADE_THRESHOLD_SIZE:
6632861e737e84e4884109b9526ac645194ba892a74Michal Krol      /* don't support multisampling, so doesn't matter. */
6642861e737e84e4884109b9526ac645194ba892a74Michal Krol      break;
6652861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* can't do these but don't need them.
6662861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_POINT_SPRITE_R_MODE_NV:
6672861e737e84e4884109b9526ac645194ba892a74Michal Krol   case GL_POINT_SPRITE_COORD_ORIGIN: */
6682861e737e84e4884109b9526ac645194ba892a74Michal Krol   default:
6692861e737e84e4884109b9526ac645194ba892a74Michal Krol      fprintf(stderr, "bad pname parameter in r200PointParameter\n");
6702861e737e84e4884109b9526ac645194ba892a74Michal Krol      return;
6712861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6722861e737e84e4884109b9526ac645194ba892a74Michal Krol}
6732861e737e84e4884109b9526ac645194ba892a74Michal Krol
6742861e737e84e4884109b9526ac645194ba892a74Michal Krol/* =============================================================
6752861e737e84e4884109b9526ac645194ba892a74Michal Krol * Line state
6762861e737e84e4884109b9526ac645194ba892a74Michal Krol */
6772861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200LineWidth( GLcontext *ctx, GLfloat widthf )
6782861e737e84e4884109b9526ac645194ba892a74Michal Krol{
6792861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
6802861e737e84e4884109b9526ac645194ba892a74Michal Krol
6812861e737e84e4884109b9526ac645194ba892a74Michal Krol   R200_STATECHANGE( rmesa, lin );
6822861e737e84e4884109b9526ac645194ba892a74Michal Krol   R200_STATECHANGE( rmesa, set );
6832861e737e84e4884109b9526ac645194ba892a74Michal Krol
6842861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Line width is stored in U6.4 format.
6852861e737e84e4884109b9526ac645194ba892a74Michal Krol    * Same min/max limits for AA, non-AA lines.
6862861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
6872861e737e84e4884109b9526ac645194ba892a74Michal Krol   rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= ~0xffff;
6882861e737e84e4884109b9526ac645194ba892a74Michal Krol   rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)
6892861e737e84e4884109b9526ac645194ba892a74Michal Krol      (CLAMP(widthf, ctx->Const.MinLineWidth, ctx->Const.MaxLineWidth) * 16.0);
6902861e737e84e4884109b9526ac645194ba892a74Michal Krol
6912861e737e84e4884109b9526ac645194ba892a74Michal Krol   if ( widthf > 1.0 ) {
6922861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_WIDELINE_ENABLE;
6932861e737e84e4884109b9526ac645194ba892a74Michal Krol   } else {
6942861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_WIDELINE_ENABLE;
6952861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
6962861e737e84e4884109b9526ac645194ba892a74Michal Krol}
6972861e737e84e4884109b9526ac645194ba892a74Michal Krol
6982861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200LineStipple( GLcontext *ctx, GLint factor, GLushort pattern )
6992861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7002861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
7012861e737e84e4884109b9526ac645194ba892a74Michal Krol
7022861e737e84e4884109b9526ac645194ba892a74Michal Krol   R200_STATECHANGE( rmesa, lin );
7032861e737e84e4884109b9526ac645194ba892a74Michal Krol   rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
7042861e737e84e4884109b9526ac645194ba892a74Michal Krol      ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
705daea7176347f15f1c916c4a1131fce0bd1f062bcIan Romanick}
7062861e737e84e4884109b9526ac645194ba892a74Michal Krol
7072861e737e84e4884109b9526ac645194ba892a74Michal Krol
7082861e737e84e4884109b9526ac645194ba892a74Michal Krol/* =============================================================
7092861e737e84e4884109b9526ac645194ba892a74Michal Krol * Masks
7102861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7112861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200ColorMask( GLcontext *ctx,
7122861e737e84e4884109b9526ac645194ba892a74Michal Krol			   GLboolean r, GLboolean g,
7132861e737e84e4884109b9526ac645194ba892a74Michal Krol			   GLboolean b, GLboolean a )
7142861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7152861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
7162861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint mask;
7172861e737e84e4884109b9526ac645194ba892a74Michal Krol   struct radeon_renderbuffer *rrb;
7182861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLuint flag = rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] & ~R200_PLANE_MASK_ENABLE;
7192861e737e84e4884109b9526ac645194ba892a74Michal Krol
7202861e737e84e4884109b9526ac645194ba892a74Michal Krol   rrb = radeon_get_colorbuffer(&rmesa->radeon);
7212861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!rrb)
7222861e737e84e4884109b9526ac645194ba892a74Michal Krol     return;
7232861e737e84e4884109b9526ac645194ba892a74Michal Krol   mask = radeonPackColor( rrb->cpp,
7242861e737e84e4884109b9526ac645194ba892a74Michal Krol			   ctx->Color.ColorMask[RCOMP],
7252861e737e84e4884109b9526ac645194ba892a74Michal Krol			   ctx->Color.ColorMask[GCOMP],
7262861e737e84e4884109b9526ac645194ba892a74Michal Krol			   ctx->Color.ColorMask[BCOMP],
7272861e737e84e4884109b9526ac645194ba892a74Michal Krol			   ctx->Color.ColorMask[ACOMP] );
7282861e737e84e4884109b9526ac645194ba892a74Michal Krol
7292861e737e84e4884109b9526ac645194ba892a74Michal Krol
7302861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (!(r && g && b && a))
7312861e737e84e4884109b9526ac645194ba892a74Michal Krol      flag |= R200_PLANE_MASK_ENABLE;
7322861e737e84e4884109b9526ac645194ba892a74Michal Krol
7332861e737e84e4884109b9526ac645194ba892a74Michal Krol   if ( rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] != flag ) {
7342861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE( rmesa, ctx );
7352861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = flag;
7362861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7372861e737e84e4884109b9526ac645194ba892a74Michal Krol
7382861e737e84e4884109b9526ac645194ba892a74Michal Krol   if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
7392861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE( rmesa, msk );
7402861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = mask;
7412861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7422861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7432861e737e84e4884109b9526ac645194ba892a74Michal Krol
7442861e737e84e4884109b9526ac645194ba892a74Michal Krol
7452861e737e84e4884109b9526ac645194ba892a74Michal Krol/* =============================================================
7462861e737e84e4884109b9526ac645194ba892a74Michal Krol * Polygon state
7472861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7482861e737e84e4884109b9526ac645194ba892a74Michal Krol
7492861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200PolygonOffset( GLcontext *ctx,
7502861e737e84e4884109b9526ac645194ba892a74Michal Krol			       GLfloat factor, GLfloat units )
7512861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7522861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
7532861e737e84e4884109b9526ac645194ba892a74Michal Krol   const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
7542861e737e84e4884109b9526ac645194ba892a74Michal Krol   float_ui32_type constant =  { units * depthScale };
7552861e737e84e4884109b9526ac645194ba892a74Michal Krol   float_ui32_type factoru = { factor };
7562861e737e84e4884109b9526ac645194ba892a74Michal Krol
7572861e737e84e4884109b9526ac645194ba892a74Michal Krol/*    factor *= 2; */
7582861e737e84e4884109b9526ac645194ba892a74Michal Krol/*    constant *= 2; */
7592861e737e84e4884109b9526ac645194ba892a74Michal Krol
7602861e737e84e4884109b9526ac645194ba892a74Michal Krol/*    fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
7612861e737e84e4884109b9526ac645194ba892a74Michal Krol
7622861e737e84e4884109b9526ac645194ba892a74Michal Krol   R200_STATECHANGE( rmesa, zbs );
7632861e737e84e4884109b9526ac645194ba892a74Michal Krol   rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR]   = factoru.ui32;
7642861e737e84e4884109b9526ac645194ba892a74Michal Krol   rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
7652861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7662861e737e84e4884109b9526ac645194ba892a74Michal Krol
7672861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200PolygonMode( GLcontext *ctx, GLenum face, GLenum mode )
7682861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7692861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
7702861e737e84e4884109b9526ac645194ba892a74Michal Krol   GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0;
7712861e737e84e4884109b9526ac645194ba892a74Michal Krol
7722861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Can't generally do unfilled via tcl, but some good special
7732861e737e84e4884109b9526ac645194ba892a74Michal Krol    * cases work.
7742861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
7752861e737e84e4884109b9526ac645194ba892a74Michal Krol   TCL_FALLBACK( ctx, R200_TCL_FALLBACK_UNFILLED, flag);
7762861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (rmesa->radeon.TclFallback) {
7772861e737e84e4884109b9526ac645194ba892a74Michal Krol      r200ChooseRenderState( ctx );
7782861e737e84e4884109b9526ac645194ba892a74Michal Krol      r200ChooseVertexState( ctx );
7792861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
7802861e737e84e4884109b9526ac645194ba892a74Michal Krol}
7812861e737e84e4884109b9526ac645194ba892a74Michal Krol
7822861e737e84e4884109b9526ac645194ba892a74Michal Krol
783122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul/* =============================================================
784122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul * Rendering attributes
7852861e737e84e4884109b9526ac645194ba892a74Michal Krol *
7862861e737e84e4884109b9526ac645194ba892a74Michal Krol * We really don't want to recalculate all this every time we bind a
7872861e737e84e4884109b9526ac645194ba892a74Michal Krol * texture.  These things shouldn't change all that often, so it makes
7882861e737e84e4884109b9526ac645194ba892a74Michal Krol * sense to break them out of the core texture state update routines.
7892861e737e84e4884109b9526ac645194ba892a74Michal Krol */
790027ed1b505a1bf6e3f5ad4412734d7edf337c08bBrian Paul
7912861e737e84e4884109b9526ac645194ba892a74Michal Krol/* Examine lighting and texture state to determine if separate specular
7924d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul * should be enabled.
7932861e737e84e4884109b9526ac645194ba892a74Michal Krol */
7942861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void r200UpdateSpecular( GLcontext *ctx )
7952861e737e84e4884109b9526ac645194ba892a74Michal Krol{
7962861e737e84e4884109b9526ac645194ba892a74Michal Krol   r200ContextPtr rmesa = R200_CONTEXT(ctx);
7972861e737e84e4884109b9526ac645194ba892a74Michal Krol   uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
7982861e737e84e4884109b9526ac645194ba892a74Michal Krol
7999ca83924848070d02a5ac2f0aa4e20444eec2183Brian Paul   R200_STATECHANGE( rmesa, tcl );
8002861e737e84e4884109b9526ac645194ba892a74Michal Krol   R200_STATECHANGE( rmesa, vtx );
8012861e737e84e4884109b9526ac645194ba892a74Michal Krol
8022861e737e84e4884109b9526ac645194ba892a74Michal Krol   rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_0_SHIFT);
803122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul   rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~(3<<R200_VTX_COLOR_1_SHIFT);
804de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul   rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_0;
805de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul   rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_COLOR_1;
8062861e737e84e4884109b9526ac645194ba892a74Michal Krol   rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LIGHTING_ENABLE;
8072861e737e84e4884109b9526ac645194ba892a74Michal Krol
8082861e737e84e4884109b9526ac645194ba892a74Michal Krol   p &= ~R200_SPECULAR_ENABLE;
8092861e737e84e4884109b9526ac645194ba892a74Michal Krol
8102861e737e84e4884109b9526ac645194ba892a74Michal Krol   rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_DIFFUSE_SPECULAR_COMBINE;
8112861e737e84e4884109b9526ac645194ba892a74Michal Krol
8122861e737e84e4884109b9526ac645194ba892a74Michal Krol
8132861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (ctx->Light.Enabled &&
8149ca83924848070d02a5ac2f0aa4e20444eec2183Brian Paul       ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) {
8152861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
8162861e737e84e4884109b9526ac645194ba892a74Michal Krol	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) |
8172861e737e84e4884109b9526ac645194ba892a74Michal Krol	  (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
8182861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0;
8192861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1;
8202861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE;
8212861e737e84e4884109b9526ac645194ba892a74Michal Krol      p |=  R200_SPECULAR_ENABLE;
8222861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &=
8232861e737e84e4884109b9526ac645194ba892a74Michal Krol	 ~R200_DIFFUSE_SPECULAR_COMBINE;
8242861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8252861e737e84e4884109b9526ac645194ba892a74Michal Krol   else if (ctx->Light.Enabled) {
8262861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
8272861e737e84e4884109b9526ac645194ba892a74Michal Krol	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT));
8282861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_0;
8292861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHTING_ENABLE;
8302861e737e84e4884109b9526ac645194ba892a74Michal Krol   } else if (ctx->Fog.ColorSumEnabled ) {
8312861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
8322861e737e84e4884109b9526ac645194ba892a74Michal Krol	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT) |
8332861e737e84e4884109b9526ac645194ba892a74Michal Krol	  (R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
8342861e737e84e4884109b9526ac645194ba892a74Michal Krol      p |=  R200_SPECULAR_ENABLE;
8352861e737e84e4884109b9526ac645194ba892a74Michal Krol   } else {
8362861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
8372861e737e84e4884109b9526ac645194ba892a74Michal Krol	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT));
8382861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8392861e737e84e4884109b9526ac645194ba892a74Michal Krol
8402861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (ctx->Fog.Enabled) {
8412861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |=
8422861e737e84e4884109b9526ac645194ba892a74Michal Krol	 ((R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT));
8432861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_COLOR_1;
8442861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8452861e737e84e4884109b9526ac645194ba892a74Michal Krol
8462861e737e84e4884109b9526ac645194ba892a74Michal Krol   if ( rmesa->hw.ctx.cmd[CTX_PP_CNTL] != p ) {
8472861e737e84e4884109b9526ac645194ba892a74Michal Krol      R200_STATECHANGE( rmesa, ctx );
8482861e737e84e4884109b9526ac645194ba892a74Michal Krol      rmesa->hw.ctx.cmd[CTX_PP_CNTL] = p;
849122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul   }
850122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul
8512861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Update vertex/render formats
8522861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
8532861e737e84e4884109b9526ac645194ba892a74Michal Krol   if (rmesa->radeon.TclFallback) {
8542861e737e84e4884109b9526ac645194ba892a74Michal Krol      r200ChooseRenderState( ctx );
855548be3846db59ad43934a159c051b359db6e56dbBrian Paul      r200ChooseVertexState( ctx );
8562861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8574d12a05e6c11ca8d7325503131b2594dfe304164Brian Paul}
8582861e737e84e4884109b9526ac645194ba892a74Michal Krol
8592861e737e84e4884109b9526ac645194ba892a74Michal Krol
8602861e737e84e4884109b9526ac645194ba892a74Michal Krol/* =============================================================
8612861e737e84e4884109b9526ac645194ba892a74Michal Krol * Materials
8622861e737e84e4884109b9526ac645194ba892a74Michal Krol */
8632861e737e84e4884109b9526ac645194ba892a74Michal Krol
8642861e737e84e4884109b9526ac645194ba892a74Michal Krol
8652861e737e84e4884109b9526ac645194ba892a74Michal Krol/* Update on colormaterial, material emmissive/ambient,
8662861e737e84e4884109b9526ac645194ba892a74Michal Krol * lightmodel.globalambient
8672861e737e84e4884109b9526ac645194ba892a74Michal Krol */
868122629f27925a9dc50029bebc5079f87f416a7e1Brian Paulstatic void update_global_ambient( GLcontext *ctx )
869de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul{
870de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul   r200ContextPtr rmesa = R200_CONTEXT(ctx);
8712861e737e84e4884109b9526ac645194ba892a74Michal Krol   float *fcmd = (float *)R200_DB_STATE( glt );
8722861e737e84e4884109b9526ac645194ba892a74Michal Krol
8732861e737e84e4884109b9526ac645194ba892a74Michal Krol   /* Need to do more if both emmissive & ambient are PREMULT:
8742861e737e84e4884109b9526ac645194ba892a74Michal Krol    * I believe this is not nessary when using source_material. This condition thus
8752861e737e84e4884109b9526ac645194ba892a74Michal Krol    * will never happen currently, and the function has no dependencies on materials now
8762861e737e84e4884109b9526ac645194ba892a74Michal Krol    */
8772861e737e84e4884109b9526ac645194ba892a74Michal Krol   if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] &
8782861e737e84e4884109b9526ac645194ba892a74Michal Krol       ((3 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
8792861e737e84e4884109b9526ac645194ba892a74Michal Krol	(3 << R200_FRONT_AMBIENT_SOURCE_SHIFT))) == 0)
8802861e737e84e4884109b9526ac645194ba892a74Michal Krol   {
8812861e737e84e4884109b9526ac645194ba892a74Michal Krol      COPY_3V( &fcmd[GLT_RED],
8822861e737e84e4884109b9526ac645194ba892a74Michal Krol	       ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
8832861e737e84e4884109b9526ac645194ba892a74Michal Krol      ACC_SCALE_3V( &fcmd[GLT_RED],
8842861e737e84e4884109b9526ac645194ba892a74Michal Krol		   ctx->Light.Model.Ambient,
8852861e737e84e4884109b9526ac645194ba892a74Michal Krol		   ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
8862861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
8872861e737e84e4884109b9526ac645194ba892a74Michal Krol   else
8882861e737e84e4884109b9526ac645194ba892a74Michal Krol   {
8892861e737e84e4884109b9526ac645194ba892a74Michal Krol      COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
8902861e737e84e4884109b9526ac645194ba892a74Michal Krol   }
891
892   R200_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
893}
894
895/* Update on change to
896 *    - light[p].colors
897 *    - light[p].enabled
898 */
899static void update_light_colors( GLcontext *ctx, GLuint p )
900{
901   struct gl_light *l = &ctx->Light.Light[p];
902
903/*     fprintf(stderr, "%s\n", __FUNCTION__); */
904
905   if (l->Enabled) {
906      r200ContextPtr rmesa = R200_CONTEXT(ctx);
907      float *fcmd = (float *)R200_DB_STATE( lit[p] );
908
909      COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
910      COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
911      COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
912
913      R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
914   }
915}
916
917static void r200ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
918{
919      r200ContextPtr rmesa = R200_CONTEXT(ctx);
920      GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1];
921      light_model_ctl1 &= ~((0xf << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
922			   (0xf << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
923			   (0xf << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
924		   (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
925		   (0xf << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
926		   (0xf << R200_BACK_AMBIENT_SOURCE_SHIFT) |
927		   (0xf << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
928		   (0xf << R200_BACK_SPECULAR_SOURCE_SHIFT));
929
930   if (ctx->Light.ColorMaterialEnabled) {
931      GLuint mask = ctx->Light.ColorMaterialBitmask;
932
933      if (mask & MAT_BIT_FRONT_EMISSION) {
934	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
935			     R200_FRONT_EMISSIVE_SOURCE_SHIFT);
936      }
937      else
938	 light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
939			     R200_FRONT_EMISSIVE_SOURCE_SHIFT);
940
941      if (mask & MAT_BIT_FRONT_AMBIENT) {
942	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
943			     R200_FRONT_AMBIENT_SOURCE_SHIFT);
944      }
945      else
946         light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
947			     R200_FRONT_AMBIENT_SOURCE_SHIFT);
948
949      if (mask & MAT_BIT_FRONT_DIFFUSE) {
950	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
951			     R200_FRONT_DIFFUSE_SOURCE_SHIFT);
952      }
953      else
954         light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
955			     R200_FRONT_DIFFUSE_SOURCE_SHIFT);
956
957      if (mask & MAT_BIT_FRONT_SPECULAR) {
958	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
959			     R200_FRONT_SPECULAR_SOURCE_SHIFT);
960      }
961      else {
962         light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 <<
963			     R200_FRONT_SPECULAR_SOURCE_SHIFT);
964      }
965
966      if (mask & MAT_BIT_BACK_EMISSION) {
967	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
968			     R200_BACK_EMISSIVE_SOURCE_SHIFT);
969      }
970
971      else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
972			     R200_BACK_EMISSIVE_SOURCE_SHIFT);
973
974      if (mask & MAT_BIT_BACK_AMBIENT) {
975	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
976			     R200_BACK_AMBIENT_SOURCE_SHIFT);
977      }
978      else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
979			     R200_BACK_AMBIENT_SOURCE_SHIFT);
980
981      if (mask & MAT_BIT_BACK_DIFFUSE) {
982	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
983			     R200_BACK_DIFFUSE_SOURCE_SHIFT);
984   }
985      else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
986			     R200_BACK_DIFFUSE_SOURCE_SHIFT);
987
988      if (mask & MAT_BIT_BACK_SPECULAR) {
989	 light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 <<
990			     R200_BACK_SPECULAR_SOURCE_SHIFT);
991      }
992      else {
993         light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 <<
994			     R200_BACK_SPECULAR_SOURCE_SHIFT);
995      }
996      }
997   else {
998       /* Default to SOURCE_MATERIAL:
999        */
1000     light_model_ctl1 |=
1001        (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) |
1002        (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_AMBIENT_SOURCE_SHIFT) |
1003        (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_DIFFUSE_SOURCE_SHIFT) |
1004        (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_SPECULAR_SOURCE_SHIFT) |
1005        (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_EMISSIVE_SOURCE_SHIFT) |
1006        (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_AMBIENT_SOURCE_SHIFT) |
1007        (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_DIFFUSE_SOURCE_SHIFT) |
1008        (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_SPECULAR_SOURCE_SHIFT);
1009   }
1010
1011   if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]) {
1012      R200_STATECHANGE( rmesa, tcl );
1013      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] = light_model_ctl1;
1014   }
1015
1016
1017}
1018
1019void r200UpdateMaterial( GLcontext *ctx )
1020{
1021   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1022   GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
1023   GLfloat *fcmd = (GLfloat *)R200_DB_STATE( mtl[0] );
1024   GLfloat *fcmd2 = (GLfloat *)R200_DB_STATE( mtl[1] );
1025   GLuint mask = ~0;
1026
1027   /* Might be possible and faster to update everything unconditionally? */
1028   if (ctx->Light.ColorMaterialEnabled)
1029      mask &= ~ctx->Light.ColorMaterialBitmask;
1030
1031   if (R200_DEBUG & DEBUG_STATE)
1032      fprintf(stderr, "%s\n", __FUNCTION__);
1033
1034   if (mask & MAT_BIT_FRONT_EMISSION) {
1035      fcmd[MTL_EMMISSIVE_RED]   = mat[MAT_ATTRIB_FRONT_EMISSION][0];
1036      fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
1037      fcmd[MTL_EMMISSIVE_BLUE]  = mat[MAT_ATTRIB_FRONT_EMISSION][2];
1038      fcmd[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_FRONT_EMISSION][3];
1039   }
1040   if (mask & MAT_BIT_FRONT_AMBIENT) {
1041      fcmd[MTL_AMBIENT_RED]     = mat[MAT_ATTRIB_FRONT_AMBIENT][0];
1042      fcmd[MTL_AMBIENT_GREEN]   = mat[MAT_ATTRIB_FRONT_AMBIENT][1];
1043      fcmd[MTL_AMBIENT_BLUE]    = mat[MAT_ATTRIB_FRONT_AMBIENT][2];
1044      fcmd[MTL_AMBIENT_ALPHA]   = mat[MAT_ATTRIB_FRONT_AMBIENT][3];
1045   }
1046   if (mask & MAT_BIT_FRONT_DIFFUSE) {
1047      fcmd[MTL_DIFFUSE_RED]     = mat[MAT_ATTRIB_FRONT_DIFFUSE][0];
1048      fcmd[MTL_DIFFUSE_GREEN]   = mat[MAT_ATTRIB_FRONT_DIFFUSE][1];
1049      fcmd[MTL_DIFFUSE_BLUE]    = mat[MAT_ATTRIB_FRONT_DIFFUSE][2];
1050      fcmd[MTL_DIFFUSE_ALPHA]   = mat[MAT_ATTRIB_FRONT_DIFFUSE][3];
1051   }
1052   if (mask & MAT_BIT_FRONT_SPECULAR) {
1053      fcmd[MTL_SPECULAR_RED]    = mat[MAT_ATTRIB_FRONT_SPECULAR][0];
1054      fcmd[MTL_SPECULAR_GREEN]  = mat[MAT_ATTRIB_FRONT_SPECULAR][1];
1055      fcmd[MTL_SPECULAR_BLUE]   = mat[MAT_ATTRIB_FRONT_SPECULAR][2];
1056      fcmd[MTL_SPECULAR_ALPHA]  = mat[MAT_ATTRIB_FRONT_SPECULAR][3];
1057   }
1058   if (mask & MAT_BIT_FRONT_SHININESS) {
1059      fcmd[MTL_SHININESS]       = mat[MAT_ATTRIB_FRONT_SHININESS][0];
1060   }
1061
1062   if (mask & MAT_BIT_BACK_EMISSION) {
1063      fcmd2[MTL_EMMISSIVE_RED]   = mat[MAT_ATTRIB_BACK_EMISSION][0];
1064      fcmd2[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_BACK_EMISSION][1];
1065      fcmd2[MTL_EMMISSIVE_BLUE]  = mat[MAT_ATTRIB_BACK_EMISSION][2];
1066      fcmd2[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_BACK_EMISSION][3];
1067   }
1068   if (mask & MAT_BIT_BACK_AMBIENT) {
1069      fcmd2[MTL_AMBIENT_RED]     = mat[MAT_ATTRIB_BACK_AMBIENT][0];
1070      fcmd2[MTL_AMBIENT_GREEN]   = mat[MAT_ATTRIB_BACK_AMBIENT][1];
1071      fcmd2[MTL_AMBIENT_BLUE]    = mat[MAT_ATTRIB_BACK_AMBIENT][2];
1072      fcmd2[MTL_AMBIENT_ALPHA]   = mat[MAT_ATTRIB_BACK_AMBIENT][3];
1073   }
1074   if (mask & MAT_BIT_BACK_DIFFUSE) {
1075      fcmd2[MTL_DIFFUSE_RED]     = mat[MAT_ATTRIB_BACK_DIFFUSE][0];
1076      fcmd2[MTL_DIFFUSE_GREEN]   = mat[MAT_ATTRIB_BACK_DIFFUSE][1];
1077      fcmd2[MTL_DIFFUSE_BLUE]    = mat[MAT_ATTRIB_BACK_DIFFUSE][2];
1078      fcmd2[MTL_DIFFUSE_ALPHA]   = mat[MAT_ATTRIB_BACK_DIFFUSE][3];
1079   }
1080   if (mask & MAT_BIT_BACK_SPECULAR) {
1081      fcmd2[MTL_SPECULAR_RED]    = mat[MAT_ATTRIB_BACK_SPECULAR][0];
1082      fcmd2[MTL_SPECULAR_GREEN]  = mat[MAT_ATTRIB_BACK_SPECULAR][1];
1083      fcmd2[MTL_SPECULAR_BLUE]   = mat[MAT_ATTRIB_BACK_SPECULAR][2];
1084      fcmd2[MTL_SPECULAR_ALPHA]  = mat[MAT_ATTRIB_BACK_SPECULAR][3];
1085   }
1086   if (mask & MAT_BIT_BACK_SHININESS) {
1087      fcmd2[MTL_SHININESS]       = mat[MAT_ATTRIB_BACK_SHININESS][0];
1088   }
1089
1090   R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[0] );
1091   R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[1] );
1092
1093   /* currently material changes cannot trigger a global ambient change, I believe this is correct
1094    update_global_ambient( ctx ); */
1095}
1096
1097/* _NEW_LIGHT
1098 * _NEW_MODELVIEW
1099 * _MESA_NEW_NEED_EYE_COORDS
1100 *
1101 * Uses derived state from mesa:
1102 *       _VP_inf_norm
1103 *       _h_inf_norm
1104 *       _Position
1105 *       _NormSpotDirection
1106 *       _ModelViewInvScale
1107 *       _NeedEyeCoords
1108 *       _EyeZDir
1109 *
1110 * which are calculated in light.c and are correct for the current
1111 * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
1112 * and _MESA_NEW_NEED_EYE_COORDS.
1113 */
1114static void update_light( GLcontext *ctx )
1115{
1116   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1117
1118   /* Have to check these, or have an automatic shortcircuit mechanism
1119    * to remove noop statechanges. (Or just do a better job on the
1120    * front end).
1121    */
1122   {
1123      GLuint tmp = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0];
1124
1125      if (ctx->_NeedEyeCoords)
1126	 tmp &= ~R200_LIGHT_IN_MODELSPACE;
1127      else
1128	 tmp |= R200_LIGHT_IN_MODELSPACE;
1129
1130      if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0])
1131      {
1132	 R200_STATECHANGE( rmesa, tcl );
1133	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] = tmp;
1134      }
1135   }
1136
1137   {
1138      GLfloat *fcmd = (GLfloat *)R200_DB_STATE( eye );
1139      fcmd[EYE_X] = ctx->_EyeZDir[0];
1140      fcmd[EYE_Y] = ctx->_EyeZDir[1];
1141      fcmd[EYE_Z] = - ctx->_EyeZDir[2];
1142      fcmd[EYE_RESCALE_FACTOR] = ctx->_ModelViewInvScale;
1143      R200_DB_STATECHANGE( rmesa, &rmesa->hw.eye );
1144   }
1145
1146
1147
1148   if (ctx->Light.Enabled) {
1149      GLint p;
1150      for (p = 0 ; p < MAX_LIGHTS; p++) {
1151	 if (ctx->Light.Light[p].Enabled) {
1152	    struct gl_light *l = &ctx->Light.Light[p];
1153	    GLfloat *fcmd = (GLfloat *)R200_DB_STATE( lit[p] );
1154
1155	    if (l->EyePosition[3] == 0.0) {
1156	       COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
1157	       COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
1158	       fcmd[LIT_POSITION_W] = 0;
1159	       fcmd[LIT_DIRECTION_W] = 0;
1160	    } else {
1161	       COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
1162	       fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
1163	       fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
1164	       fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
1165	       fcmd[LIT_DIRECTION_W] = 0;
1166	    }
1167
1168	    R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
1169	 }
1170      }
1171   }
1172}
1173
1174static void r200Lightfv( GLcontext *ctx, GLenum light,
1175			   GLenum pname, const GLfloat *params )
1176{
1177   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1178   GLint p = light - GL_LIGHT0;
1179   struct gl_light *l = &ctx->Light.Light[p];
1180   GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
1181
1182
1183   switch (pname) {
1184   case GL_AMBIENT:
1185   case GL_DIFFUSE:
1186   case GL_SPECULAR:
1187      update_light_colors( ctx, p );
1188      break;
1189
1190   case GL_SPOT_DIRECTION:
1191      /* picked up in update_light */
1192      break;
1193
1194   case GL_POSITION: {
1195      /* positions picked up in update_light, but can do flag here */
1196      GLuint flag = (p&1)? R200_LIGHT_1_IS_LOCAL : R200_LIGHT_0_IS_LOCAL;
1197      GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1198
1199      R200_STATECHANGE(rmesa, tcl);
1200      if (l->EyePosition[3] != 0.0F)
1201	 rmesa->hw.tcl.cmd[idx] |= flag;
1202      else
1203	 rmesa->hw.tcl.cmd[idx] &= ~flag;
1204      break;
1205   }
1206
1207   case GL_SPOT_EXPONENT:
1208      R200_STATECHANGE(rmesa, lit[p]);
1209      fcmd[LIT_SPOT_EXPONENT] = params[0];
1210      break;
1211
1212   case GL_SPOT_CUTOFF: {
1213      GLuint flag = (p&1) ? R200_LIGHT_1_IS_SPOT : R200_LIGHT_0_IS_SPOT;
1214      GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1215
1216      R200_STATECHANGE(rmesa, lit[p]);
1217      fcmd[LIT_SPOT_CUTOFF] = l->_CosCutoff;
1218
1219      R200_STATECHANGE(rmesa, tcl);
1220      if (l->SpotCutoff != 180.0F)
1221	 rmesa->hw.tcl.cmd[idx] |= flag;
1222      else
1223	 rmesa->hw.tcl.cmd[idx] &= ~flag;
1224
1225      break;
1226   }
1227
1228   case GL_CONSTANT_ATTENUATION:
1229      R200_STATECHANGE(rmesa, lit[p]);
1230      fcmd[LIT_ATTEN_CONST] = params[0];
1231      if ( params[0] == 0.0 )
1232	 fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
1233      else
1234	 fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
1235      break;
1236   case GL_LINEAR_ATTENUATION:
1237      R200_STATECHANGE(rmesa, lit[p]);
1238      fcmd[LIT_ATTEN_LINEAR] = params[0];
1239      break;
1240   case GL_QUADRATIC_ATTENUATION:
1241      R200_STATECHANGE(rmesa, lit[p]);
1242      fcmd[LIT_ATTEN_QUADRATIC] = params[0];
1243      break;
1244   default:
1245      return;
1246   }
1247
1248   /* Set RANGE_ATTEN only when needed */
1249   switch (pname) {
1250   case GL_POSITION:
1251   case GL_CONSTANT_ATTENUATION:
1252   case GL_LINEAR_ATTENUATION:
1253   case GL_QUADRATIC_ATTENUATION: {
1254      GLuint *icmd = (GLuint *)R200_DB_STATE( tcl );
1255      GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
1256      GLuint atten_flag = ( p&1 ) ? R200_LIGHT_1_ENABLE_RANGE_ATTEN
1257				  : R200_LIGHT_0_ENABLE_RANGE_ATTEN;
1258      GLuint atten_const_flag = ( p&1 ) ? R200_LIGHT_1_CONSTANT_RANGE_ATTEN
1259				  : R200_LIGHT_0_CONSTANT_RANGE_ATTEN;
1260
1261      if ( l->EyePosition[3] == 0.0F ||
1262	   ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
1263	     fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
1264	 /* Disable attenuation */
1265	 icmd[idx] &= ~atten_flag;
1266      } else {
1267	 if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
1268	    /* Enable only constant portion of attenuation calculation */
1269	    icmd[idx] |= ( atten_flag | atten_const_flag );
1270	 } else {
1271	    /* Enable full attenuation calculation */
1272	    icmd[idx] &= ~atten_const_flag;
1273	    icmd[idx] |= atten_flag;
1274	 }
1275      }
1276
1277      R200_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
1278      break;
1279   }
1280   default:
1281     break;
1282   }
1283}
1284
1285static void r200UpdateLocalViewer ( GLcontext *ctx )
1286{
1287/* It looks like for the texgen modes GL_SPHERE_MAP, GL_NORMAL_MAP and
1288   GL_REFLECTION_MAP we need R200_LOCAL_VIEWER set (fglrx does exactly that
1289   for these and only these modes). This means specular highlights may turn out
1290   wrong in some cases when lighting is enabled but GL_LIGHT_MODEL_LOCAL_VIEWER
1291   is not set, though it seems to happen rarely and the effect seems quite
1292   subtle. May need TCL fallback to fix it completely, though I'm not sure
1293   how you'd identify the cases where the specular highlights indeed will
1294   be wrong. Don't know if fglrx does something special in that case.
1295*/
1296   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1297   R200_STATECHANGE( rmesa, tcl );
1298   if (ctx->Light.Model.LocalViewer ||
1299       ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS)
1300      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LOCAL_VIEWER;
1301   else
1302      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LOCAL_VIEWER;
1303}
1304
1305static void r200LightModelfv( GLcontext *ctx, GLenum pname,
1306				const GLfloat *param )
1307{
1308   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1309
1310   switch (pname) {
1311      case GL_LIGHT_MODEL_AMBIENT:
1312	 update_global_ambient( ctx );
1313	 break;
1314
1315      case GL_LIGHT_MODEL_LOCAL_VIEWER:
1316	 r200UpdateLocalViewer( ctx );
1317         break;
1318
1319      case GL_LIGHT_MODEL_TWO_SIDE:
1320	 R200_STATECHANGE( rmesa, tcl );
1321	 if (ctx->Light.Model.TwoSide)
1322	    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHT_TWOSIDE;
1323	 else
1324	    rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~(R200_LIGHT_TWOSIDE);
1325	 if (rmesa->radeon.TclFallback) {
1326	    r200ChooseRenderState( ctx );
1327	    r200ChooseVertexState( ctx );
1328	 }
1329         break;
1330
1331      case GL_LIGHT_MODEL_COLOR_CONTROL:
1332	 r200UpdateSpecular(ctx);
1333         break;
1334
1335      default:
1336         break;
1337   }
1338}
1339
1340static void r200ShadeModel( GLcontext *ctx, GLenum mode )
1341{
1342   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1343   GLuint s = rmesa->hw.set.cmd[SET_SE_CNTL];
1344
1345   s &= ~(R200_DIFFUSE_SHADE_MASK |
1346	  R200_ALPHA_SHADE_MASK |
1347	  R200_SPECULAR_SHADE_MASK |
1348	  R200_FOG_SHADE_MASK |
1349	  R200_DISC_FOG_SHADE_MASK);
1350
1351   switch ( mode ) {
1352   case GL_FLAT:
1353      s |= (R200_DIFFUSE_SHADE_FLAT |
1354	    R200_ALPHA_SHADE_FLAT |
1355	    R200_SPECULAR_SHADE_FLAT |
1356	    R200_FOG_SHADE_FLAT |
1357	    R200_DISC_FOG_SHADE_FLAT);
1358      break;
1359   case GL_SMOOTH:
1360      s |= (R200_DIFFUSE_SHADE_GOURAUD |
1361	    R200_ALPHA_SHADE_GOURAUD |
1362	    R200_SPECULAR_SHADE_GOURAUD |
1363	    R200_FOG_SHADE_GOURAUD |
1364	    R200_DISC_FOG_SHADE_GOURAUD);
1365      break;
1366   default:
1367      return;
1368   }
1369
1370   if ( rmesa->hw.set.cmd[SET_SE_CNTL] != s ) {
1371      R200_STATECHANGE( rmesa, set );
1372      rmesa->hw.set.cmd[SET_SE_CNTL] = s;
1373   }
1374}
1375
1376
1377/* =============================================================
1378 * User clip planes
1379 */
1380
1381static void r200ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq )
1382{
1383   GLint p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
1384   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1385   GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1386
1387   R200_STATECHANGE( rmesa, ucp[p] );
1388   rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1389   rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1390   rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1391   rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1392}
1393
1394static void r200UpdateClipPlanes( GLcontext *ctx )
1395{
1396   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1397   GLuint p;
1398
1399   for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
1400      if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
1401	 GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p];
1402
1403	 R200_STATECHANGE( rmesa, ucp[p] );
1404	 rmesa->hw.ucp[p].cmd[UCP_X] = ip[0];
1405	 rmesa->hw.ucp[p].cmd[UCP_Y] = ip[1];
1406	 rmesa->hw.ucp[p].cmd[UCP_Z] = ip[2];
1407	 rmesa->hw.ucp[p].cmd[UCP_W] = ip[3];
1408      }
1409   }
1410}
1411
1412
1413/* =============================================================
1414 * Stencil
1415 */
1416
1417static void
1418r200StencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func,
1419                         GLint ref, GLuint mask )
1420{
1421   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1422   GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << R200_STENCIL_REF_SHIFT) |
1423		     ((ctx->Stencil.ValueMask[0] & 0xff) << R200_STENCIL_MASK_SHIFT));
1424
1425   R200_STATECHANGE( rmesa, ctx );
1426   R200_STATECHANGE( rmesa, msk );
1427
1428   rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~R200_STENCIL_TEST_MASK;
1429   rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~(R200_STENCIL_REF_MASK|
1430						   R200_STENCIL_VALUE_MASK);
1431
1432   switch ( ctx->Stencil.Function[0] ) {
1433   case GL_NEVER:
1434      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_NEVER;
1435      break;
1436   case GL_LESS:
1437      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_LESS;
1438      break;
1439   case GL_EQUAL:
1440      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_EQUAL;
1441      break;
1442   case GL_LEQUAL:
1443      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_LEQUAL;
1444      break;
1445   case GL_GREATER:
1446      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_GREATER;
1447      break;
1448   case GL_NOTEQUAL:
1449      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_NEQUAL;
1450      break;
1451   case GL_GEQUAL:
1452      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_GEQUAL;
1453      break;
1454   case GL_ALWAYS:
1455      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_TEST_ALWAYS;
1456      break;
1457   }
1458
1459   rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
1460}
1461
1462static void
1463r200StencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask )
1464{
1465   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1466
1467   R200_STATECHANGE( rmesa, msk );
1468   rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~R200_STENCIL_WRITE_MASK;
1469   rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
1470      ((ctx->Stencil.WriteMask[0] & 0xff) << R200_STENCIL_WRITEMASK_SHIFT);
1471}
1472
1473static void
1474r200StencilOpSeparate( GLcontext *ctx, GLenum face, GLenum fail,
1475                       GLenum zfail, GLenum zpass )
1476{
1477   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1478
1479   R200_STATECHANGE( rmesa, ctx );
1480   rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(R200_STENCIL_FAIL_MASK |
1481					       R200_STENCIL_ZFAIL_MASK |
1482					       R200_STENCIL_ZPASS_MASK);
1483
1484   switch ( ctx->Stencil.FailFunc[0] ) {
1485   case GL_KEEP:
1486      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_KEEP;
1487      break;
1488   case GL_ZERO:
1489      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_ZERO;
1490      break;
1491   case GL_REPLACE:
1492      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_REPLACE;
1493      break;
1494   case GL_INCR:
1495      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INC;
1496      break;
1497   case GL_DECR:
1498      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_DEC;
1499      break;
1500   case GL_INCR_WRAP_EXT:
1501      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INC_WRAP;
1502      break;
1503   case GL_DECR_WRAP_EXT:
1504      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_DEC_WRAP;
1505      break;
1506   case GL_INVERT:
1507      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_FAIL_INVERT;
1508      break;
1509   }
1510
1511   switch ( ctx->Stencil.ZFailFunc[0] ) {
1512   case GL_KEEP:
1513      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_KEEP;
1514      break;
1515   case GL_ZERO:
1516      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_ZERO;
1517      break;
1518   case GL_REPLACE:
1519      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_REPLACE;
1520      break;
1521   case GL_INCR:
1522      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INC;
1523      break;
1524   case GL_DECR:
1525      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_DEC;
1526      break;
1527   case GL_INCR_WRAP_EXT:
1528      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INC_WRAP;
1529      break;
1530   case GL_DECR_WRAP_EXT:
1531      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_DEC_WRAP;
1532      break;
1533   case GL_INVERT:
1534      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZFAIL_INVERT;
1535      break;
1536   }
1537
1538   switch ( ctx->Stencil.ZPassFunc[0] ) {
1539   case GL_KEEP:
1540      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_KEEP;
1541      break;
1542   case GL_ZERO:
1543      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_ZERO;
1544      break;
1545   case GL_REPLACE:
1546      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_REPLACE;
1547      break;
1548   case GL_INCR:
1549      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INC;
1550      break;
1551   case GL_DECR:
1552      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_DEC;
1553      break;
1554   case GL_INCR_WRAP_EXT:
1555      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INC_WRAP;
1556      break;
1557   case GL_DECR_WRAP_EXT:
1558      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_DEC_WRAP;
1559      break;
1560   case GL_INVERT:
1561      rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= R200_STENCIL_ZPASS_INVERT;
1562      break;
1563   }
1564}
1565
1566static void r200ClearStencil( GLcontext *ctx, GLint s )
1567{
1568   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1569
1570   rmesa->radeon.state.stencil.clear =
1571      ((GLuint) (ctx->Stencil.Clear & 0xff) |
1572       (0xff << R200_STENCIL_MASK_SHIFT) |
1573       ((ctx->Stencil.WriteMask[0] & 0xff) << R200_STENCIL_WRITEMASK_SHIFT));
1574}
1575
1576
1577/* =============================================================
1578 * Window position and viewport transformation
1579 */
1580
1581/*
1582 * To correctly position primitives:
1583 */
1584#define SUBPIXEL_X 0.125
1585#define SUBPIXEL_Y 0.125
1586
1587
1588/**
1589 * Called when window size or position changes or viewport or depth range
1590 * state is changed.  We update the hardware viewport state here.
1591 */
1592void r200UpdateWindow( GLcontext *ctx )
1593{
1594   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1595   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
1596   GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
1597   GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
1598   const GLfloat *v = ctx->Viewport._WindowMap.m;
1599   const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0);
1600   const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
1601   GLfloat y_scale, y_bias;
1602
1603   if (render_to_fbo) {
1604      y_scale = 1.0;
1605      y_bias = 0;
1606   } else {
1607      y_scale = -1.0;
1608      y_bias = yoffset;
1609   }
1610
1611   float_ui32_type sx = { v[MAT_SX] };
1612   float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
1613   float_ui32_type sy = { v[MAT_SY] * y_scale };
1614   float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y };
1615   float_ui32_type sz = { v[MAT_SZ] * depthScale };
1616   float_ui32_type tz = { v[MAT_TZ] * depthScale };
1617
1618   R200_STATECHANGE( rmesa, vpt );
1619
1620   rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE]  = sx.ui32;
1621   rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1622   rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE]  = sy.ui32;
1623   rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1624   rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE]  = sz.ui32;
1625   rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
1626}
1627
1628void r200_vtbl_update_scissor( GLcontext *ctx )
1629{
1630   r200ContextPtr r200 = R200_CONTEXT(ctx);
1631   unsigned x1, y1, x2, y2;
1632   struct radeon_renderbuffer *rrb;
1633
1634   R200_SET_STATE(r200, set, SET_RE_CNTL, R200_SCISSOR_ENABLE | r200->hw.set.cmd[SET_RE_CNTL]);
1635
1636   if (r200->radeon.state.scissor.enabled) {
1637      x1 = r200->radeon.state.scissor.rect.x1;
1638      y1 = r200->radeon.state.scissor.rect.y1;
1639      x2 = r200->radeon.state.scissor.rect.x2;
1640      y2 = r200->radeon.state.scissor.rect.y2;
1641   } else {
1642      rrb = radeon_get_colorbuffer(&r200->radeon);
1643      x1 = 0;
1644      y1 = 0;
1645      x2 = rrb->base.Width - 1;
1646      y2 = rrb->base.Height - 1;
1647   }
1648
1649   R200_SET_STATE(r200, sci, SCI_XY_1, x1 | (y1 << 16));
1650   R200_SET_STATE(r200, sci, SCI_XY_2, x2 | (y2 << 16));
1651}
1652
1653
1654static void r200Viewport( GLcontext *ctx, GLint x, GLint y,
1655			    GLsizei width, GLsizei height )
1656{
1657   /* Don't pipeline viewport changes, conflict with window offset
1658    * setting below.  Could apply deltas to rescue pipelined viewport
1659    * values, or keep the originals hanging around.
1660    */
1661   r200UpdateWindow( ctx );
1662
1663   radeon_viewport(ctx, x, y, width, height);
1664}
1665
1666static void r200DepthRange( GLcontext *ctx, GLclampd nearval,
1667			      GLclampd farval )
1668{
1669   r200UpdateWindow( ctx );
1670}
1671
1672void r200UpdateViewportOffset( GLcontext *ctx )
1673{
1674   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1675   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
1676   GLfloat xoffset = (GLfloat)dPriv->x;
1677   GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
1678   const GLfloat *v = ctx->Viewport._WindowMap.m;
1679
1680   float_ui32_type tx;
1681   float_ui32_type ty;
1682
1683   tx.f = v[MAT_TX] + xoffset + SUBPIXEL_X;
1684   ty.f = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
1685
1686   if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 ||
1687	rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 )
1688   {
1689      /* Note: this should also modify whatever data the context reset
1690       * code uses...
1691       */
1692      R200_STATECHANGE( rmesa, vpt );
1693      rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
1694      rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
1695
1696      /* update polygon stipple x/y screen offset */
1697      {
1698         GLuint stx, sty;
1699         GLuint m = rmesa->hw.msc.cmd[MSC_RE_MISC];
1700
1701         m &= ~(R200_STIPPLE_X_OFFSET_MASK |
1702                R200_STIPPLE_Y_OFFSET_MASK);
1703
1704         /* add magic offsets, then invert */
1705         stx = 31 - ((dPriv->x - 1) & R200_STIPPLE_COORD_MASK);
1706         sty = 31 - ((dPriv->y + dPriv->h - 1)
1707                     & R200_STIPPLE_COORD_MASK);
1708
1709         m |= ((stx << R200_STIPPLE_X_OFFSET_SHIFT) |
1710               (sty << R200_STIPPLE_Y_OFFSET_SHIFT));
1711
1712         if ( rmesa->hw.msc.cmd[MSC_RE_MISC] != m ) {
1713            R200_STATECHANGE( rmesa, msc );
1714	    rmesa->hw.msc.cmd[MSC_RE_MISC] = m;
1715         }
1716      }
1717   }
1718
1719   radeonUpdateScissor( ctx );
1720}
1721
1722
1723
1724/* =============================================================
1725 * Miscellaneous
1726 */
1727
1728static void r200ClearColor( GLcontext *ctx, const GLfloat c[4] )
1729{
1730   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1731   GLubyte color[4];
1732   struct radeon_renderbuffer *rrb;
1733
1734   rrb = radeon_get_colorbuffer(&rmesa->radeon);
1735   if (!rrb)
1736     return;
1737   CLAMPED_FLOAT_TO_UBYTE(color[0], c[0]);
1738   CLAMPED_FLOAT_TO_UBYTE(color[1], c[1]);
1739   CLAMPED_FLOAT_TO_UBYTE(color[2], c[2]);
1740   CLAMPED_FLOAT_TO_UBYTE(color[3], c[3]);
1741   rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
1742                                             color[0], color[1],
1743                                             color[2], color[3] );
1744}
1745
1746
1747static void r200RenderMode( GLcontext *ctx, GLenum mode )
1748{
1749   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1750   FALLBACK( rmesa, R200_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
1751}
1752
1753
1754static GLuint r200_rop_tab[] = {
1755   R200_ROP_CLEAR,
1756   R200_ROP_AND,
1757   R200_ROP_AND_REVERSE,
1758   R200_ROP_COPY,
1759   R200_ROP_AND_INVERTED,
1760   R200_ROP_NOOP,
1761   R200_ROP_XOR,
1762   R200_ROP_OR,
1763   R200_ROP_NOR,
1764   R200_ROP_EQUIV,
1765   R200_ROP_INVERT,
1766   R200_ROP_OR_REVERSE,
1767   R200_ROP_COPY_INVERTED,
1768   R200_ROP_OR_INVERTED,
1769   R200_ROP_NAND,
1770   R200_ROP_SET,
1771};
1772
1773static void r200LogicOpCode( GLcontext *ctx, GLenum opcode )
1774{
1775   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1776   GLuint rop = (GLuint)opcode - GL_CLEAR;
1777
1778   ASSERT( rop < 16 );
1779
1780   R200_STATECHANGE( rmesa, msk );
1781   rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = r200_rop_tab[rop];
1782}
1783
1784/* =============================================================
1785 * State enable/disable
1786 */
1787
1788static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state )
1789{
1790   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1791   GLuint p, flag;
1792
1793   if ( R200_DEBUG & DEBUG_STATE )
1794      fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
1795	       _mesa_lookup_enum_by_nr( cap ),
1796	       state ? "GL_TRUE" : "GL_FALSE" );
1797
1798   switch ( cap ) {
1799      /* Fast track this one...
1800       */
1801   case GL_TEXTURE_1D:
1802   case GL_TEXTURE_2D:
1803   case GL_TEXTURE_3D:
1804      break;
1805
1806   case GL_ALPHA_TEST:
1807      R200_STATECHANGE( rmesa, ctx );
1808      if (state) {
1809	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_ALPHA_TEST_ENABLE;
1810      } else {
1811	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ALPHA_TEST_ENABLE;
1812      }
1813      break;
1814
1815   case GL_BLEND:
1816   case GL_COLOR_LOGIC_OP:
1817      r200_set_blend_state( ctx );
1818      break;
1819
1820   case GL_CLIP_PLANE0:
1821   case GL_CLIP_PLANE1:
1822   case GL_CLIP_PLANE2:
1823   case GL_CLIP_PLANE3:
1824   case GL_CLIP_PLANE4:
1825   case GL_CLIP_PLANE5:
1826      p = cap-GL_CLIP_PLANE0;
1827      R200_STATECHANGE( rmesa, tcl );
1828      if (state) {
1829	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (R200_UCP_ENABLE_0<<p);
1830	 r200ClipPlane( ctx, cap, NULL );
1831      }
1832      else {
1833	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(R200_UCP_ENABLE_0<<p);
1834      }
1835      break;
1836
1837   case GL_COLOR_MATERIAL:
1838      r200ColorMaterial( ctx, 0, 0 );
1839      r200UpdateMaterial( ctx );
1840      break;
1841
1842   case GL_CULL_FACE:
1843      r200CullFace( ctx, 0 );
1844      break;
1845
1846   case GL_DEPTH_TEST:
1847      R200_STATECHANGE(rmesa, ctx );
1848      if ( state ) {
1849	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_Z_ENABLE;
1850      } else {
1851	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_Z_ENABLE;
1852      }
1853      break;
1854
1855   case GL_DITHER:
1856      R200_STATECHANGE(rmesa, ctx );
1857      if ( state ) {
1858	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_DITHER_ENABLE;
1859	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~rmesa->radeon.state.color.roundEnable;
1860      } else {
1861	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_DITHER_ENABLE;
1862	 rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  rmesa->radeon.state.color.roundEnable;
1863      }
1864      break;
1865
1866   case GL_FOG:
1867      R200_STATECHANGE(rmesa, ctx );
1868      if ( state ) {
1869	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_FOG_ENABLE;
1870	 r200Fogfv( ctx, GL_FOG_MODE, NULL );
1871      } else {
1872	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_FOG_ENABLE;
1873	 R200_STATECHANGE(rmesa, tcl);
1874	 rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~R200_TCL_FOG_MASK;
1875      }
1876      r200UpdateSpecular( ctx ); /* for PK_SPEC */
1877      if (rmesa->radeon.TclFallback)
1878	 r200ChooseVertexState( ctx );
1879      _mesa_allow_light_in_model( ctx, !state );
1880      break;
1881
1882   case GL_LIGHT0:
1883   case GL_LIGHT1:
1884   case GL_LIGHT2:
1885   case GL_LIGHT3:
1886   case GL_LIGHT4:
1887   case GL_LIGHT5:
1888   case GL_LIGHT6:
1889   case GL_LIGHT7:
1890      R200_STATECHANGE(rmesa, tcl);
1891      p = cap - GL_LIGHT0;
1892      if (p&1)
1893	 flag = (R200_LIGHT_1_ENABLE |
1894		 R200_LIGHT_1_ENABLE_AMBIENT |
1895		 R200_LIGHT_1_ENABLE_SPECULAR);
1896      else
1897	 flag = (R200_LIGHT_0_ENABLE |
1898		 R200_LIGHT_0_ENABLE_AMBIENT |
1899		 R200_LIGHT_0_ENABLE_SPECULAR);
1900
1901      if (state)
1902	 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] |= flag;
1903      else
1904	 rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
1905
1906      /*
1907       */
1908      update_light_colors( ctx, p );
1909      break;
1910
1911   case GL_LIGHTING:
1912      r200UpdateSpecular(ctx);
1913      /* for reflection map fixup - might set recheck_texgen for all units too */
1914      rmesa->radeon.NewGLState |= _NEW_TEXTURE;
1915      break;
1916
1917   case GL_LINE_SMOOTH:
1918      R200_STATECHANGE( rmesa, ctx );
1919      if ( state ) {
1920	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  R200_ANTI_ALIAS_LINE;
1921      } else {
1922	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ANTI_ALIAS_LINE;
1923      }
1924      break;
1925
1926   case GL_LINE_STIPPLE:
1927      R200_STATECHANGE( rmesa, set );
1928      if ( state ) {
1929	 rmesa->hw.set.cmd[SET_RE_CNTL] |=  R200_PATTERN_ENABLE;
1930      } else {
1931	 rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PATTERN_ENABLE;
1932      }
1933      break;
1934
1935   case GL_NORMALIZE:
1936      R200_STATECHANGE( rmesa, tcl );
1937      if ( state ) {
1938	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |=  R200_NORMALIZE_NORMALS;
1939      } else {
1940	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_NORMALIZE_NORMALS;
1941      }
1942      break;
1943
1944      /* Pointsize registers on r200 only work for point sprites, and point smooth
1945       * doesn't work for point sprites (and isn't needed for 1.0 sized aa points).
1946       * In any case, setting pointmin == pointsizemax == 1.0 for aa points
1947       * is enough to satisfy conform.
1948       */
1949   case GL_POINT_SMOOTH:
1950      break;
1951
1952      /* These don't really do anything, as we don't use the 3vtx
1953       * primitives yet.
1954       */
1955#if 0
1956   case GL_POLYGON_OFFSET_POINT:
1957      R200_STATECHANGE( rmesa, set );
1958      if ( state ) {
1959	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_ZBIAS_ENABLE_POINT;
1960      } else {
1961	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_POINT;
1962      }
1963      break;
1964
1965   case GL_POLYGON_OFFSET_LINE:
1966      R200_STATECHANGE( rmesa, set );
1967      if ( state ) {
1968	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_ZBIAS_ENABLE_LINE;
1969      } else {
1970	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_LINE;
1971      }
1972      break;
1973#endif
1974
1975   case GL_POINT_SPRITE_ARB:
1976      R200_STATECHANGE( rmesa, spr );
1977      if ( state ) {
1978	 int i;
1979	 for (i = 0; i < 6; i++) {
1980	    rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |=
1981		ctx->Point.CoordReplace[i] << (R200_PS_GEN_TEX_0_SHIFT + i);
1982	 }
1983      } else {
1984	 rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &= ~R200_PS_GEN_TEX_MASK;
1985      }
1986      break;
1987
1988   case GL_POLYGON_OFFSET_FILL:
1989      R200_STATECHANGE( rmesa, set );
1990      if ( state ) {
1991	 rmesa->hw.set.cmd[SET_SE_CNTL] |=  R200_ZBIAS_ENABLE_TRI;
1992      } else {
1993	 rmesa->hw.set.cmd[SET_SE_CNTL] &= ~R200_ZBIAS_ENABLE_TRI;
1994      }
1995      break;
1996
1997   case GL_POLYGON_SMOOTH:
1998      R200_STATECHANGE( rmesa, ctx );
1999      if ( state ) {
2000	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=  R200_ANTI_ALIAS_POLY;
2001      } else {
2002	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~R200_ANTI_ALIAS_POLY;
2003      }
2004      break;
2005
2006   case GL_POLYGON_STIPPLE:
2007      R200_STATECHANGE(rmesa, set );
2008      if ( state ) {
2009	 rmesa->hw.set.cmd[SET_RE_CNTL] |=  R200_STIPPLE_ENABLE;
2010      } else {
2011	 rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_STIPPLE_ENABLE;
2012      }
2013      break;
2014
2015   case GL_RESCALE_NORMAL_EXT: {
2016      GLboolean tmp = ctx->_NeedEyeCoords ? state : !state;
2017      R200_STATECHANGE( rmesa, tcl );
2018      if ( tmp ) {
2019	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |=  R200_RESCALE_NORMALS;
2020      } else {
2021	 rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS;
2022      }
2023      break;
2024   }
2025
2026   case GL_SCISSOR_TEST:
2027      radeon_firevertices(&rmesa->radeon);
2028      rmesa->radeon.state.scissor.enabled = state;
2029      radeonUpdateScissor( ctx );
2030      break;
2031
2032   case GL_STENCIL_TEST:
2033      {
2034	 GLboolean hw_stencil = GL_FALSE;
2035	 if (ctx->DrawBuffer) {
2036	    struct radeon_renderbuffer *rrbStencil
2037	       = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
2038	    hw_stencil = (rrbStencil && rrbStencil->bo);
2039	 }
2040
2041	 if (hw_stencil) {
2042	    R200_STATECHANGE( rmesa, ctx );
2043	    if ( state ) {
2044	       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_STENCIL_ENABLE;
2045	    } else {
2046	       rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE;
2047	    }
2048	 } else {
2049	    FALLBACK( rmesa, R200_FALLBACK_STENCIL, state );
2050	 }
2051      }
2052      break;
2053
2054   case GL_TEXTURE_GEN_Q:
2055   case GL_TEXTURE_GEN_R:
2056   case GL_TEXTURE_GEN_S:
2057   case GL_TEXTURE_GEN_T:
2058      /* Picked up in r200UpdateTextureState.
2059       */
2060      rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
2061      break;
2062
2063   case GL_COLOR_SUM_EXT:
2064      r200UpdateSpecular ( ctx );
2065      break;
2066
2067   case GL_VERTEX_PROGRAM_ARB:
2068      if (!state) {
2069	 GLuint i;
2070	 rmesa->curr_vp_hw = NULL;
2071	 R200_STATECHANGE( rmesa, vap );
2072	 rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] &= ~R200_VAP_PROG_VTX_SHADER_ENABLE;
2073	 /* mark all tcl atoms (tcl vector state got overwritten) dirty
2074	    not sure about tcl scalar state - we need at least grd
2075	    with vert progs too.
2076	    ucp looks like it doesn't get overwritten (may even work
2077	    with vp for pos-invariant progs if we're lucky) */
2078	 R200_STATECHANGE( rmesa, mtl[0] );
2079	 R200_STATECHANGE( rmesa, mtl[1] );
2080	 R200_STATECHANGE( rmesa, fog );
2081	 R200_STATECHANGE( rmesa, glt );
2082	 R200_STATECHANGE( rmesa, eye );
2083	 for (i = R200_MTX_MV; i <= R200_MTX_TEX5; i++) {
2084	    R200_STATECHANGE( rmesa, mat[i] );
2085	 }
2086	 for (i = 0 ; i < 8; i++) {
2087	    R200_STATECHANGE( rmesa, lit[i] );
2088	 }
2089	 R200_STATECHANGE( rmesa, tcl );
2090	 for (i = 0; i <= ctx->Const.MaxClipPlanes; i++) {
2091	    if (ctx->Transform.ClipPlanesEnabled & (1 << i)) {
2092	       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= (R200_UCP_ENABLE_0 << i);
2093	    }
2094/*	    else {
2095	       rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~(R200_UCP_ENABLE_0 << i);
2096	    }*/
2097	 }
2098	 /* ugly. Need to call everything which might change compsel. */
2099	 r200UpdateSpecular( ctx );
2100#if 0
2101	/* shouldn't be necessary, as it's picked up anyway in r200ValidateState (_NEW_PROGRAM),
2102	   but without it doom3 locks up at always the same places. Why? */
2103	/* FIXME: This can (and should) be replaced by a call to the TCL_STATE_FLUSH reg before
2104	   accessing VAP_SE_VAP_CNTL. Requires drm changes (done). Remove after some time... */
2105	 r200UpdateTextureState( ctx );
2106	 /* if we call r200UpdateTextureState we need the code below because we are calling it with
2107	    non-current derived enabled values which may revert the state atoms for frag progs even when
2108	    they already got disabled... ugh
2109	    Should really figure out why we need to call r200UpdateTextureState in the first place */
2110	 GLuint unit;
2111	 for (unit = 0; unit < R200_MAX_TEXTURE_UNITS; unit++) {
2112	    R200_STATECHANGE( rmesa, pix[unit] );
2113	    R200_STATECHANGE( rmesa, tex[unit] );
2114	    rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &=
2115		~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
2116	    rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT;
2117	    /* need to guard this with drmSupportsFragmentShader? Should never get here if
2118	       we don't announce ATI_fs, right? */
2119	    rmesa->hw.tex[unit].cmd[TEX_PP_TXMULTI_CTL] = 0;
2120         }
2121	 R200_STATECHANGE( rmesa, cst );
2122	 R200_STATECHANGE( rmesa, tf );
2123	 rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0;
2124#endif
2125      }
2126      else {
2127	 /* picked up later */
2128      }
2129      /* call functions which change hw state based on ARB_vp enabled or not. */
2130      r200PointParameter( ctx, GL_POINT_DISTANCE_ATTENUATION, NULL );
2131      r200Fogfv( ctx, GL_FOG_COORD_SRC, NULL );
2132      break;
2133
2134   case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
2135      r200PointParameter( ctx, GL_POINT_DISTANCE_ATTENUATION, NULL );
2136      break;
2137
2138   case GL_FRAGMENT_SHADER_ATI:
2139      if ( !state ) {
2140	 /* restore normal tex env colors and make sure tex env combine will get updated
2141	    mark env atoms dirty (as their data was overwritten by afs even
2142	    if they didn't change) and restore tex coord routing */
2143	 GLuint unit;
2144	 for (unit = 0; unit < R200_MAX_TEXTURE_UNITS; unit++) {
2145	    R200_STATECHANGE( rmesa, pix[unit] );
2146	    R200_STATECHANGE( rmesa, tex[unit] );
2147	    rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &=
2148		~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
2149	    rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT;
2150	    /* need to guard this with drmSupportsFragmentShader? Should never get here if
2151	       we don't announce ATI_fs, right? */
2152	    rmesa->hw.tex[unit].cmd[TEX_PP_TXMULTI_CTL] = 0;
2153         }
2154	 R200_STATECHANGE( rmesa, cst );
2155	 R200_STATECHANGE( rmesa, tf );
2156	 rmesa->hw.cst.cmd[CST_PP_CNTL_X] = 0;
2157      }
2158      else {
2159	 /* need to mark this dirty as pix/tf atoms have overwritten the data
2160	    even if the data in the atoms didn't change */
2161	 R200_STATECHANGE( rmesa, atf );
2162	 R200_STATECHANGE( rmesa, afs[1] );
2163	 /* everything else picked up in r200UpdateTextureState hopefully */
2164      }
2165      break;
2166   default:
2167      return;
2168   }
2169}
2170
2171
2172void r200LightingSpaceChange( GLcontext *ctx )
2173{
2174   r200ContextPtr rmesa = R200_CONTEXT(ctx);
2175   GLboolean tmp;
2176
2177   if (R200_DEBUG & DEBUG_STATE)
2178      fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
2179	      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]);
2180
2181   if (ctx->_NeedEyeCoords)
2182      tmp = ctx->Transform.RescaleNormals;
2183   else
2184      tmp = !ctx->Transform.RescaleNormals;
2185
2186   R200_STATECHANGE( rmesa, tcl );
2187   if ( tmp ) {
2188      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |=  R200_RESCALE_NORMALS;
2189   } else {
2190      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS;
2191   }
2192
2193   if (R200_DEBUG & DEBUG_STATE)
2194      fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
2195	      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]);
2196}
2197
2198/* =============================================================
2199 * Deferred state management - matrices, textures, other?
2200 */
2201
2202
2203
2204
2205static void upload_matrix( r200ContextPtr rmesa, GLfloat *src, int idx )
2206{
2207   float *dest = ((float *)R200_DB_STATE( mat[idx] ))+MAT_ELT_0;
2208   int i;
2209
2210
2211   for (i = 0 ; i < 4 ; i++) {
2212      *dest++ = src[i];
2213      *dest++ = src[i+4];
2214      *dest++ = src[i+8];
2215      *dest++ = src[i+12];
2216   }
2217
2218   R200_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
2219}
2220
2221static void upload_matrix_t( r200ContextPtr rmesa, const GLfloat *src, int idx )
2222{
2223   float *dest = ((float *)R200_DB_STATE( mat[idx] ))+MAT_ELT_0;
2224   memcpy(dest, src, 16*sizeof(float));
2225   R200_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
2226}
2227
2228
2229static void update_texturematrix( GLcontext *ctx )
2230{
2231   r200ContextPtr rmesa = R200_CONTEXT( ctx );
2232   GLuint tpc = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0];
2233   GLuint compsel = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL];
2234   int unit;
2235
2236   if (R200_DEBUG & DEBUG_STATE)
2237      fprintf(stderr, "%s before COMPSEL: %x\n", __FUNCTION__,
2238	      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]);
2239
2240   rmesa->TexMatEnabled = 0;
2241   rmesa->TexMatCompSel = 0;
2242
2243   for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
2244      if (!ctx->Texture.Unit[unit]._ReallyEnabled)
2245	 continue;
2246
2247      if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
2248	 rmesa->TexMatEnabled |= (R200_TEXGEN_TEXMAT_0_ENABLE|
2249				  R200_TEXMAT_0_ENABLE) << unit;
2250
2251	 rmesa->TexMatCompSel |= R200_OUTPUT_TEX_0 << unit;
2252
2253	 if (rmesa->TexGenEnabled & (R200_TEXMAT_0_ENABLE << unit)) {
2254	    /* Need to preconcatenate any active texgen
2255	     * obj/eyeplane matrices:
2256	     */
2257	    _math_matrix_mul_matrix( &rmesa->tmpmat,
2258				     ctx->TextureMatrixStack[unit].Top,
2259				     &rmesa->TexGenMatrix[unit] );
2260	    upload_matrix( rmesa, rmesa->tmpmat.m, R200_MTX_TEX0+unit );
2261	 }
2262	 else {
2263	    upload_matrix( rmesa, ctx->TextureMatrixStack[unit].Top->m,
2264			   R200_MTX_TEX0+unit );
2265	 }
2266      }
2267      else if (rmesa->TexGenEnabled & (R200_TEXMAT_0_ENABLE << unit)) {
2268	 upload_matrix( rmesa, rmesa->TexGenMatrix[unit].m,
2269			R200_MTX_TEX0+unit );
2270      }
2271   }
2272
2273   tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled);
2274   if (tpc != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0]) {
2275      R200_STATECHANGE(rmesa, tcg);
2276      rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_0] = tpc;
2277   }
2278
2279   compsel &= ~R200_OUTPUT_TEX_MASK;
2280   compsel |= rmesa->TexMatCompSel | rmesa->TexGenCompSel;
2281   if (compsel != rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]) {
2282      R200_STATECHANGE(rmesa, vtx);
2283      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = compsel;
2284   }
2285}
2286
2287static GLboolean r200ValidateBuffers(GLcontext *ctx)
2288{
2289   r200ContextPtr rmesa = R200_CONTEXT(ctx);
2290   struct radeon_renderbuffer *rrb;
2291   struct radeon_dma_bo *dma_bo;
2292   int i, ret;
2293
2294	if (RADEON_DEBUG & DEBUG_IOCTL)
2295		fprintf(stderr, "%s\n", __FUNCTION__);
2296   radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
2297
2298   rrb = radeon_get_colorbuffer(&rmesa->radeon);
2299   /* color buffer */
2300   if (rrb && rrb->bo) {
2301     radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2302				       0, RADEON_GEM_DOMAIN_VRAM);
2303   }
2304
2305   /* depth buffer */
2306   rrb = radeon_get_depthbuffer(&rmesa->radeon);
2307   /* color buffer */
2308   if (rrb && rrb->bo) {
2309     radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
2310				       0, RADEON_GEM_DOMAIN_VRAM);
2311   }
2312
2313   for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
2314      radeonTexObj *t;
2315
2316      if (!ctx->Texture.Unit[i]._ReallyEnabled)
2317	 continue;
2318
2319      t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
2320      if (t->image_override && t->bo)
2321	radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
2322			   RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2323      else if (t->mt->bo)
2324	radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
2325			   RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
2326   }
2327
2328   dma_bo = first_elem(&rmesa->radeon.dma.reserved);
2329   {
2330       ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, dma_bo->bo, RADEON_GEM_DOMAIN_GTT, 0);
2331       if (ret)
2332	   return GL_FALSE;
2333   }
2334   return GL_TRUE;
2335}
2336
2337GLboolean r200ValidateState( GLcontext *ctx )
2338{
2339   r200ContextPtr rmesa = R200_CONTEXT(ctx);
2340   GLuint new_state = rmesa->radeon.NewGLState;
2341
2342   if (new_state & _NEW_BUFFERS) {
2343      _mesa_update_framebuffer(ctx);
2344      /* this updates the DrawBuffer's Width/Height if it's a FBO */
2345      _mesa_update_draw_buffer_bounds(ctx);
2346
2347      R200_STATECHANGE(rmesa, ctx);
2348   }
2349
2350   if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)) {
2351      r200UpdateTextureState( ctx );
2352      new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
2353      r200UpdateLocalViewer( ctx );
2354   }
2355
2356   /* we need to do a space check here */
2357   if (!r200ValidateBuffers(ctx))
2358     return GL_FALSE;
2359
2360/* FIXME: don't really need most of these when vertex progs are enabled */
2361
2362   /* Need an event driven matrix update?
2363    */
2364   if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
2365      upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, R200_MTX_MVP );
2366
2367   /* Need these for lighting (shouldn't upload otherwise)
2368    */
2369   if (new_state & (_NEW_MODELVIEW)) {
2370      upload_matrix( rmesa, ctx->ModelviewMatrixStack.Top->m, R200_MTX_MV );
2371      upload_matrix_t( rmesa, ctx->ModelviewMatrixStack.Top->inv, R200_MTX_IMV );
2372   }
2373
2374   /* Does this need to be triggered on eg. modelview for
2375    * texgen-derived objplane/eyeplane matrices?
2376    */
2377   if (new_state & (_NEW_TEXTURE|_NEW_TEXTURE_MATRIX)) {
2378      update_texturematrix( ctx );
2379   }
2380
2381   if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
2382      update_light( ctx );
2383   }
2384
2385   /* emit all active clip planes if projection matrix changes.
2386    */
2387   if (new_state & (_NEW_PROJECTION)) {
2388      if (ctx->Transform.ClipPlanesEnabled)
2389	 r200UpdateClipPlanes( ctx );
2390   }
2391
2392   if (new_state & (_NEW_PROGRAM|
2393                    _NEW_PROGRAM_CONSTANTS |
2394   /* need to test for pretty much anything due to possible parameter bindings */
2395	_NEW_MODELVIEW|_NEW_PROJECTION|_NEW_TRANSFORM|
2396	_NEW_LIGHT|_NEW_TEXTURE|_NEW_TEXTURE_MATRIX|
2397	_NEW_FOG|_NEW_POINT|_NEW_TRACK_MATRIX)) {
2398      if (ctx->VertexProgram._Enabled) {
2399	 r200SetupVertexProg( ctx );
2400      }
2401      else TCL_FALLBACK(ctx, R200_TCL_FALLBACK_VERTEX_PROGRAM, 0);
2402   }
2403
2404   rmesa->radeon.NewGLState = 0;
2405   return GL_TRUE;
2406}
2407
2408
2409static void r200InvalidateState( GLcontext *ctx, GLuint new_state )
2410{
2411   _swrast_InvalidateState( ctx, new_state );
2412   _swsetup_InvalidateState( ctx, new_state );
2413   _vbo_InvalidateState( ctx, new_state );
2414   _tnl_InvalidateState( ctx, new_state );
2415   _ae_invalidate_state( ctx, new_state );
2416   R200_CONTEXT(ctx)->radeon.NewGLState |= new_state;
2417}
2418
2419/* A hack.  The r200 can actually cope just fine with materials
2420 * between begin/ends, so fix this.
2421 * Should map to inputs just like the generic vertex arrays for vertex progs.
2422 * In theory there could still be too many and we'd still need a fallback.
2423 */
2424static GLboolean check_material( GLcontext *ctx )
2425{
2426   TNLcontext *tnl = TNL_CONTEXT(ctx);
2427   GLint i;
2428
2429   for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
2430	i < _TNL_ATTRIB_MAT_BACK_INDEXES;
2431	i++)
2432      if (tnl->vb.AttribPtr[i] &&
2433	  tnl->vb.AttribPtr[i]->stride)
2434	 return GL_TRUE;
2435
2436   return GL_FALSE;
2437}
2438
2439static void r200WrapRunPipeline( GLcontext *ctx )
2440{
2441   r200ContextPtr rmesa = R200_CONTEXT(ctx);
2442   GLboolean has_material;
2443
2444   if (0)
2445      fprintf(stderr, "%s, newstate: %x\n", __FUNCTION__, rmesa->radeon.NewGLState);
2446
2447   /* Validate state:
2448    */
2449   if (rmesa->radeon.NewGLState)
2450      if (!r200ValidateState( ctx ))
2451	 FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
2452
2453   has_material = !ctx->VertexProgram._Enabled && ctx->Light.Enabled && check_material( ctx );
2454
2455   if (has_material) {
2456      TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_TRUE );
2457   }
2458
2459   /* Run the pipeline.
2460    */
2461   _tnl_run_pipeline( ctx );
2462
2463   if (has_material) {
2464      TCL_FALLBACK( ctx, R200_TCL_FALLBACK_MATERIAL, GL_FALSE );
2465   }
2466}
2467
2468
2469/* Initialize the driver's state functions.
2470 */
2471void r200InitStateFuncs( struct dd_function_table *functions, GLboolean dri2 )
2472{
2473   functions->UpdateState		= r200InvalidateState;
2474   functions->LightingSpaceChange	= r200LightingSpaceChange;
2475
2476   functions->DrawBuffer		= radeonDrawBuffer;
2477   functions->ReadBuffer		= radeonReadBuffer;
2478
2479   functions->AlphaFunc			= r200AlphaFunc;
2480   functions->BlendColor		= r200BlendColor;
2481   functions->BlendEquationSeparate	= r200BlendEquationSeparate;
2482   functions->BlendFuncSeparate		= r200BlendFuncSeparate;
2483   functions->ClearColor		= r200ClearColor;
2484   functions->ClearDepth		= r200ClearDepth;
2485   functions->ClearIndex		= NULL;
2486   functions->ClearStencil		= r200ClearStencil;
2487   functions->ClipPlane			= r200ClipPlane;
2488   functions->ColorMask			= r200ColorMask;
2489   functions->CullFace			= r200CullFace;
2490   functions->DepthFunc			= r200DepthFunc;
2491   functions->DepthMask			= r200DepthMask;
2492   functions->DepthRange		= r200DepthRange;
2493   functions->Enable			= r200Enable;
2494   functions->Fogfv			= r200Fogfv;
2495   functions->FrontFace			= r200FrontFace;
2496   functions->Hint			= NULL;
2497   functions->IndexMask			= NULL;
2498   functions->LightModelfv		= r200LightModelfv;
2499   functions->Lightfv			= r200Lightfv;
2500   functions->LineStipple		= r200LineStipple;
2501   functions->LineWidth			= r200LineWidth;
2502   functions->LogicOpcode		= r200LogicOpCode;
2503   functions->PolygonMode		= r200PolygonMode;
2504   functions->PolygonOffset		= r200PolygonOffset;
2505   if (dri2)
2506      functions->PolygonStipple		= radeonPolygonStipple;
2507   else
2508      functions->PolygonStipple		= radeonPolygonStipplePreKMS;
2509   functions->PointParameterfv		= r200PointParameter;
2510   functions->PointSize			= r200PointSize;
2511   functions->RenderMode		= r200RenderMode;
2512   functions->Scissor			= radeonScissor;
2513   functions->ShadeModel		= r200ShadeModel;
2514   functions->StencilFuncSeparate	= r200StencilFuncSeparate;
2515   functions->StencilMaskSeparate	= r200StencilMaskSeparate;
2516   functions->StencilOpSeparate		= r200StencilOpSeparate;
2517   functions->Viewport			= r200Viewport;
2518}
2519
2520
2521void r200InitTnlFuncs( GLcontext *ctx )
2522{
2523   TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = r200UpdateMaterial;
2524   TNL_CONTEXT(ctx)->Driver.RunPipeline = r200WrapRunPipeline;
2525}
2526