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