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