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