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