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