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