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