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