1/* 2Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 3 4The Weather Channel (TM) funded Tungsten Graphics to develop the 5initial release of the Radeon 8500 driver under the XFree86 license. 6This notice must be preserved. 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 * Keith Whitwell <keithw@vmware.com> 33 */ 34 35#include "main/glheader.h" 36 37#include "main/context.h" 38#include "main/macros.h" 39#include "main/state.h" 40#include "main/teximage.h" 41#include "main/texobj.h" 42#include "main/enums.h" 43 44#include "radeon_common.h" 45#include "radeon_mipmap_tree.h" 46#include "r200_context.h" 47#include "r200_state.h" 48#include "r200_ioctl.h" 49#include "r200_swtcl.h" 50#include "r200_tex.h" 51#include "r200_tcl.h" 52 53#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \ 54 && (tx_table_be[f].format != 0xffffffff) ) 55 56/* ================================================================ 57 * Texture combine functions 58 */ 59 60/* GL_ARB_texture_env_combine support 61 */ 62 63/* The color tables have combine functions for GL_SRC_COLOR, 64 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. 65 */ 66static GLuint r200_register_color[][R200_MAX_TEXTURE_UNITS] = 67{ 68 { 69 R200_TXC_ARG_A_R0_COLOR, 70 R200_TXC_ARG_A_R1_COLOR, 71 R200_TXC_ARG_A_R2_COLOR, 72 R200_TXC_ARG_A_R3_COLOR, 73 R200_TXC_ARG_A_R4_COLOR, 74 R200_TXC_ARG_A_R5_COLOR 75 }, 76 { 77 R200_TXC_ARG_A_R0_COLOR | R200_TXC_COMP_ARG_A, 78 R200_TXC_ARG_A_R1_COLOR | R200_TXC_COMP_ARG_A, 79 R200_TXC_ARG_A_R2_COLOR | R200_TXC_COMP_ARG_A, 80 R200_TXC_ARG_A_R3_COLOR | R200_TXC_COMP_ARG_A, 81 R200_TXC_ARG_A_R4_COLOR | R200_TXC_COMP_ARG_A, 82 R200_TXC_ARG_A_R5_COLOR | R200_TXC_COMP_ARG_A 83 }, 84 { 85 R200_TXC_ARG_A_R0_ALPHA, 86 R200_TXC_ARG_A_R1_ALPHA, 87 R200_TXC_ARG_A_R2_ALPHA, 88 R200_TXC_ARG_A_R3_ALPHA, 89 R200_TXC_ARG_A_R4_ALPHA, 90 R200_TXC_ARG_A_R5_ALPHA 91 }, 92 { 93 R200_TXC_ARG_A_R0_ALPHA | R200_TXC_COMP_ARG_A, 94 R200_TXC_ARG_A_R1_ALPHA | R200_TXC_COMP_ARG_A, 95 R200_TXC_ARG_A_R2_ALPHA | R200_TXC_COMP_ARG_A, 96 R200_TXC_ARG_A_R3_ALPHA | R200_TXC_COMP_ARG_A, 97 R200_TXC_ARG_A_R4_ALPHA | R200_TXC_COMP_ARG_A, 98 R200_TXC_ARG_A_R5_ALPHA | R200_TXC_COMP_ARG_A 99 }, 100}; 101 102static GLuint r200_tfactor_color[] = 103{ 104 R200_TXC_ARG_A_TFACTOR_COLOR, 105 R200_TXC_ARG_A_TFACTOR_COLOR | R200_TXC_COMP_ARG_A, 106 R200_TXC_ARG_A_TFACTOR_ALPHA, 107 R200_TXC_ARG_A_TFACTOR_ALPHA | R200_TXC_COMP_ARG_A 108}; 109 110static GLuint r200_tfactor1_color[] = 111{ 112 R200_TXC_ARG_A_TFACTOR1_COLOR, 113 R200_TXC_ARG_A_TFACTOR1_COLOR | R200_TXC_COMP_ARG_A, 114 R200_TXC_ARG_A_TFACTOR1_ALPHA, 115 R200_TXC_ARG_A_TFACTOR1_ALPHA | R200_TXC_COMP_ARG_A 116}; 117 118static GLuint r200_primary_color[] = 119{ 120 R200_TXC_ARG_A_DIFFUSE_COLOR, 121 R200_TXC_ARG_A_DIFFUSE_COLOR | R200_TXC_COMP_ARG_A, 122 R200_TXC_ARG_A_DIFFUSE_ALPHA, 123 R200_TXC_ARG_A_DIFFUSE_ALPHA | R200_TXC_COMP_ARG_A 124}; 125 126/* GL_ZERO table - indices 0-3 127 * GL_ONE table - indices 1-4 128 */ 129static GLuint r200_zero_color[] = 130{ 131 R200_TXC_ARG_A_ZERO, 132 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A, 133 R200_TXC_ARG_A_ZERO, 134 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A, 135 R200_TXC_ARG_A_ZERO 136}; 137 138/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. 139 */ 140static GLuint r200_register_alpha[][R200_MAX_TEXTURE_UNITS] = 141{ 142 { 143 R200_TXA_ARG_A_R0_ALPHA, 144 R200_TXA_ARG_A_R1_ALPHA, 145 R200_TXA_ARG_A_R2_ALPHA, 146 R200_TXA_ARG_A_R3_ALPHA, 147 R200_TXA_ARG_A_R4_ALPHA, 148 R200_TXA_ARG_A_R5_ALPHA 149 }, 150 { 151 R200_TXA_ARG_A_R0_ALPHA | R200_TXA_COMP_ARG_A, 152 R200_TXA_ARG_A_R1_ALPHA | R200_TXA_COMP_ARG_A, 153 R200_TXA_ARG_A_R2_ALPHA | R200_TXA_COMP_ARG_A, 154 R200_TXA_ARG_A_R3_ALPHA | R200_TXA_COMP_ARG_A, 155 R200_TXA_ARG_A_R4_ALPHA | R200_TXA_COMP_ARG_A, 156 R200_TXA_ARG_A_R5_ALPHA | R200_TXA_COMP_ARG_A 157 }, 158}; 159 160static GLuint r200_tfactor_alpha[] = 161{ 162 R200_TXA_ARG_A_TFACTOR_ALPHA, 163 R200_TXA_ARG_A_TFACTOR_ALPHA | R200_TXA_COMP_ARG_A 164}; 165 166static GLuint r200_tfactor1_alpha[] = 167{ 168 R200_TXA_ARG_A_TFACTOR1_ALPHA, 169 R200_TXA_ARG_A_TFACTOR1_ALPHA | R200_TXA_COMP_ARG_A 170}; 171 172static GLuint r200_primary_alpha[] = 173{ 174 R200_TXA_ARG_A_DIFFUSE_ALPHA, 175 R200_TXA_ARG_A_DIFFUSE_ALPHA | R200_TXA_COMP_ARG_A 176}; 177 178/* GL_ZERO table - indices 0-1 179 * GL_ONE table - indices 1-2 180 */ 181static GLuint r200_zero_alpha[] = 182{ 183 R200_TXA_ARG_A_ZERO, 184 R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A, 185 R200_TXA_ARG_A_ZERO, 186}; 187 188 189/* Extract the arg from slot A, shift it into the correct argument slot 190 * and set the corresponding complement bit. 191 */ 192#define R200_COLOR_ARG( n, arg ) \ 193do { \ 194 color_combine |= \ 195 ((color_arg[n] & R200_TXC_ARG_A_MASK) \ 196 << R200_TXC_ARG_##arg##_SHIFT); \ 197 color_combine |= \ 198 ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \ 199 << R200_TXC_COMP_ARG_##arg##_SHIFT); \ 200} while (0) 201 202#define R200_ALPHA_ARG( n, arg ) \ 203do { \ 204 alpha_combine |= \ 205 ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \ 206 << R200_TXA_ARG_##arg##_SHIFT); \ 207 alpha_combine |= \ 208 ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \ 209 << R200_TXA_COMP_ARG_##arg##_SHIFT); \ 210} while (0) 211 212 213/* ================================================================ 214 * Texture unit state management 215 */ 216 217static GLboolean r200UpdateTextureEnv( struct gl_context *ctx, int unit, int slot, GLuint replaceargs ) 218{ 219 r200ContextPtr rmesa = R200_CONTEXT(ctx); 220 const struct gl_texture_unit *rtexUnit = &ctx->Texture.Unit[unit]; 221 const struct gl_fixedfunc_texture_unit *texUnit = 222 &ctx->Texture.FixedFuncUnit[unit]; 223 GLuint color_combine, alpha_combine; 224 GLuint color_scale = rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] & 225 ~(R200_TXC_SCALE_MASK | R200_TXC_OUTPUT_REG_MASK | R200_TXC_TFACTOR_SEL_MASK | 226 R200_TXC_TFACTOR1_SEL_MASK); 227 GLuint alpha_scale = rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] & 228 ~(R200_TXA_DOT_ALPHA | R200_TXA_SCALE_MASK | R200_TXA_OUTPUT_REG_MASK | 229 R200_TXA_TFACTOR_SEL_MASK | R200_TXA_TFACTOR1_SEL_MASK); 230 231 if ( R200_DEBUG & RADEON_TEXTURE ) { 232 fprintf( stderr, "%s( %p, %d )\n", __func__, (void *)ctx, unit ); 233 } 234 235 /* Set the texture environment state. Isn't this nice and clean? 236 * The chip will automagically set the texture alpha to 0xff when 237 * the texture format does not include an alpha component. This 238 * reduces the amount of special-casing we have to do, alpha-only 239 * textures being a notable exception. 240 */ 241 242 color_scale |= ((rmesa->state.texture.unit[unit].outputreg + 1) << R200_TXC_OUTPUT_REG_SHIFT) | 243 (unit << R200_TXC_TFACTOR_SEL_SHIFT) | 244 (replaceargs << R200_TXC_TFACTOR1_SEL_SHIFT); 245 alpha_scale |= ((rmesa->state.texture.unit[unit].outputreg + 1) << R200_TXA_OUTPUT_REG_SHIFT) | 246 (unit << R200_TXA_TFACTOR_SEL_SHIFT) | 247 (replaceargs << R200_TXA_TFACTOR1_SEL_SHIFT); 248 249 if ( !rtexUnit->_Current ) { 250 assert( unit == 0); 251 color_combine = R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO 252 | R200_TXC_ARG_C_DIFFUSE_COLOR | R200_TXC_OP_MADD; 253 alpha_combine = R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO 254 | R200_TXA_ARG_C_DIFFUSE_ALPHA | R200_TXA_OP_MADD; 255 } 256 else { 257 GLuint color_arg[3], alpha_arg[3]; 258 GLuint i; 259 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB; 260 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA; 261 GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB; 262 GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA; 263 264 265 const GLint replaceoprgb = 266 ctx->Texture.FixedFuncUnit[replaceargs]._CurrentCombine->OperandRGB[0] - GL_SRC_COLOR; 267 const GLint replaceopa = 268 ctx->Texture.FixedFuncUnit[replaceargs]._CurrentCombine->OperandA[0] - GL_SRC_ALPHA; 269 270 /* Step 1: 271 * Extract the color and alpha combine function arguments. 272 */ 273 for ( i = 0 ; i < numColorArgs ; i++ ) { 274 GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR; 275 const GLint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i]; 276 assert(op >= 0); 277 assert(op <= 3); 278 switch ( srcRGBi ) { 279 case GL_TEXTURE: 280 color_arg[i] = r200_register_color[op][unit]; 281 break; 282 case GL_CONSTANT: 283 color_arg[i] = r200_tfactor_color[op]; 284 break; 285 case GL_PRIMARY_COLOR: 286 color_arg[i] = r200_primary_color[op]; 287 break; 288 case GL_PREVIOUS: 289 if (replaceargs != unit) { 290 const GLint srcRGBreplace = 291 ctx->Texture.FixedFuncUnit[replaceargs]._CurrentCombine->SourceRGB[0]; 292 if (op >= 2) { 293 op = op ^ replaceopa; 294 } 295 else { 296 op = op ^ replaceoprgb; 297 } 298 switch (srcRGBreplace) { 299 case GL_TEXTURE: 300 color_arg[i] = r200_register_color[op][replaceargs]; 301 break; 302 case GL_CONSTANT: 303 color_arg[i] = r200_tfactor1_color[op]; 304 break; 305 case GL_PRIMARY_COLOR: 306 color_arg[i] = r200_primary_color[op]; 307 break; 308 case GL_PREVIOUS: 309 if (slot == 0) 310 color_arg[i] = r200_primary_color[op]; 311 else 312 color_arg[i] = r200_register_color[op] 313 [rmesa->state.texture.unit[replaceargs - 1].outputreg]; 314 break; 315 case GL_ZERO: 316 color_arg[i] = r200_zero_color[op]; 317 break; 318 case GL_ONE: 319 color_arg[i] = r200_zero_color[op+1]; 320 break; 321 case GL_TEXTURE0: 322 case GL_TEXTURE1: 323 case GL_TEXTURE2: 324 case GL_TEXTURE3: 325 case GL_TEXTURE4: 326 case GL_TEXTURE5: 327 color_arg[i] = r200_register_color[op][srcRGBreplace - GL_TEXTURE0]; 328 break; 329 default: 330 return GL_FALSE; 331 } 332 } 333 else { 334 if (slot == 0) 335 color_arg[i] = r200_primary_color[op]; 336 else 337 color_arg[i] = r200_register_color[op] 338 [rmesa->state.texture.unit[unit - 1].outputreg]; 339 } 340 break; 341 case GL_ZERO: 342 color_arg[i] = r200_zero_color[op]; 343 break; 344 case GL_ONE: 345 color_arg[i] = r200_zero_color[op+1]; 346 break; 347 case GL_TEXTURE0: 348 case GL_TEXTURE1: 349 case GL_TEXTURE2: 350 case GL_TEXTURE3: 351 case GL_TEXTURE4: 352 case GL_TEXTURE5: 353 color_arg[i] = r200_register_color[op][srcRGBi - GL_TEXTURE0]; 354 break; 355 default: 356 return GL_FALSE; 357 } 358 } 359 360 for ( i = 0 ; i < numAlphaArgs ; i++ ) { 361 GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA; 362 const GLint srcAi = texUnit->_CurrentCombine->SourceA[i]; 363 assert(op >= 0); 364 assert(op <= 1); 365 switch ( srcAi ) { 366 case GL_TEXTURE: 367 alpha_arg[i] = r200_register_alpha[op][unit]; 368 break; 369 case GL_CONSTANT: 370 alpha_arg[i] = r200_tfactor_alpha[op]; 371 break; 372 case GL_PRIMARY_COLOR: 373 alpha_arg[i] = r200_primary_alpha[op]; 374 break; 375 case GL_PREVIOUS: 376 if (replaceargs != unit) { 377 const GLint srcAreplace = 378 ctx->Texture.FixedFuncUnit[replaceargs]._CurrentCombine->SourceA[0]; 379 op = op ^ replaceopa; 380 switch (srcAreplace) { 381 case GL_TEXTURE: 382 alpha_arg[i] = r200_register_alpha[op][replaceargs]; 383 break; 384 case GL_CONSTANT: 385 alpha_arg[i] = r200_tfactor1_alpha[op]; 386 break; 387 case GL_PRIMARY_COLOR: 388 alpha_arg[i] = r200_primary_alpha[op]; 389 break; 390 case GL_PREVIOUS: 391 if (slot == 0) 392 alpha_arg[i] = r200_primary_alpha[op]; 393 else 394 alpha_arg[i] = r200_register_alpha[op] 395 [rmesa->state.texture.unit[replaceargs - 1].outputreg]; 396 break; 397 case GL_ZERO: 398 alpha_arg[i] = r200_zero_alpha[op]; 399 break; 400 case GL_ONE: 401 alpha_arg[i] = r200_zero_alpha[op+1]; 402 break; 403 case GL_TEXTURE0: 404 case GL_TEXTURE1: 405 case GL_TEXTURE2: 406 case GL_TEXTURE3: 407 case GL_TEXTURE4: 408 case GL_TEXTURE5: 409 alpha_arg[i] = r200_register_alpha[op][srcAreplace - GL_TEXTURE0]; 410 break; 411 default: 412 return GL_FALSE; 413 } 414 } 415 else { 416 if (slot == 0) 417 alpha_arg[i] = r200_primary_alpha[op]; 418 else 419 alpha_arg[i] = r200_register_alpha[op] 420 [rmesa->state.texture.unit[unit - 1].outputreg]; 421 } 422 break; 423 case GL_ZERO: 424 alpha_arg[i] = r200_zero_alpha[op]; 425 break; 426 case GL_ONE: 427 alpha_arg[i] = r200_zero_alpha[op+1]; 428 break; 429 case GL_TEXTURE0: 430 case GL_TEXTURE1: 431 case GL_TEXTURE2: 432 case GL_TEXTURE3: 433 case GL_TEXTURE4: 434 case GL_TEXTURE5: 435 alpha_arg[i] = r200_register_alpha[op][srcAi - GL_TEXTURE0]; 436 break; 437 default: 438 return GL_FALSE; 439 } 440 } 441 442 /* Step 2: 443 * Build up the color and alpha combine functions. 444 */ 445 switch ( texUnit->_CurrentCombine->ModeRGB ) { 446 case GL_REPLACE: 447 color_combine = (R200_TXC_ARG_A_ZERO | 448 R200_TXC_ARG_B_ZERO | 449 R200_TXC_OP_MADD); 450 R200_COLOR_ARG( 0, C ); 451 break; 452 case GL_MODULATE: 453 color_combine = (R200_TXC_ARG_C_ZERO | 454 R200_TXC_OP_MADD); 455 R200_COLOR_ARG( 0, A ); 456 R200_COLOR_ARG( 1, B ); 457 break; 458 case GL_ADD: 459 color_combine = (R200_TXC_ARG_B_ZERO | 460 R200_TXC_COMP_ARG_B | 461 R200_TXC_OP_MADD); 462 R200_COLOR_ARG( 0, A ); 463 R200_COLOR_ARG( 1, C ); 464 break; 465 case GL_ADD_SIGNED: 466 color_combine = (R200_TXC_ARG_B_ZERO | 467 R200_TXC_COMP_ARG_B | 468 R200_TXC_BIAS_ARG_C | /* new */ 469 R200_TXC_OP_MADD); /* was ADDSIGNED */ 470 R200_COLOR_ARG( 0, A ); 471 R200_COLOR_ARG( 1, C ); 472 break; 473 case GL_SUBTRACT: 474 color_combine = (R200_TXC_ARG_B_ZERO | 475 R200_TXC_COMP_ARG_B | 476 R200_TXC_NEG_ARG_C | 477 R200_TXC_OP_MADD); 478 R200_COLOR_ARG( 0, A ); 479 R200_COLOR_ARG( 1, C ); 480 break; 481 case GL_INTERPOLATE: 482 color_combine = (R200_TXC_OP_LERP); 483 R200_COLOR_ARG( 0, B ); 484 R200_COLOR_ARG( 1, A ); 485 R200_COLOR_ARG( 2, C ); 486 break; 487 488 case GL_DOT3_RGB_EXT: 489 case GL_DOT3_RGBA_EXT: 490 /* The EXT version of the DOT3 extension does not support the 491 * scale factor, but the ARB version (and the version in OpenGL 492 * 1.3) does. 493 */ 494 RGBshift = 0; 495 FALLTHROUGH; 496 497 case GL_DOT3_RGB: 498 case GL_DOT3_RGBA: 499 /* DOT3 works differently on R200 than on R100. On R100, just 500 * setting the DOT3 mode did everything for you. On R200, the 501 * driver has to enable the biasing and scale in the inputs to 502 * put them in the proper [-1,1] range. This is what the 4x and 503 * the -0.5 in the DOT3 spec do. The post-scale is then set 504 * normally. 505 */ 506 507 color_combine = (R200_TXC_ARG_C_ZERO | 508 R200_TXC_OP_DOT3 | 509 R200_TXC_BIAS_ARG_A | 510 R200_TXC_BIAS_ARG_B | 511 R200_TXC_SCALE_ARG_A | 512 R200_TXC_SCALE_ARG_B); 513 R200_COLOR_ARG( 0, A ); 514 R200_COLOR_ARG( 1, B ); 515 break; 516 517 case GL_MODULATE_ADD_ATI: 518 color_combine = (R200_TXC_OP_MADD); 519 R200_COLOR_ARG( 0, A ); 520 R200_COLOR_ARG( 1, C ); 521 R200_COLOR_ARG( 2, B ); 522 break; 523 case GL_MODULATE_SIGNED_ADD_ATI: 524 color_combine = (R200_TXC_BIAS_ARG_C | /* new */ 525 R200_TXC_OP_MADD); /* was ADDSIGNED */ 526 R200_COLOR_ARG( 0, A ); 527 R200_COLOR_ARG( 1, C ); 528 R200_COLOR_ARG( 2, B ); 529 break; 530 case GL_MODULATE_SUBTRACT_ATI: 531 color_combine = (R200_TXC_NEG_ARG_C | 532 R200_TXC_OP_MADD); 533 R200_COLOR_ARG( 0, A ); 534 R200_COLOR_ARG( 1, C ); 535 R200_COLOR_ARG( 2, B ); 536 break; 537 default: 538 return GL_FALSE; 539 } 540 541 switch ( texUnit->_CurrentCombine->ModeA ) { 542 case GL_REPLACE: 543 alpha_combine = (R200_TXA_ARG_A_ZERO | 544 R200_TXA_ARG_B_ZERO | 545 R200_TXA_OP_MADD); 546 R200_ALPHA_ARG( 0, C ); 547 break; 548 case GL_MODULATE: 549 alpha_combine = (R200_TXA_ARG_C_ZERO | 550 R200_TXA_OP_MADD); 551 R200_ALPHA_ARG( 0, A ); 552 R200_ALPHA_ARG( 1, B ); 553 break; 554 case GL_ADD: 555 alpha_combine = (R200_TXA_ARG_B_ZERO | 556 R200_TXA_COMP_ARG_B | 557 R200_TXA_OP_MADD); 558 R200_ALPHA_ARG( 0, A ); 559 R200_ALPHA_ARG( 1, C ); 560 break; 561 case GL_ADD_SIGNED: 562 alpha_combine = (R200_TXA_ARG_B_ZERO | 563 R200_TXA_COMP_ARG_B | 564 R200_TXA_BIAS_ARG_C | /* new */ 565 R200_TXA_OP_MADD); /* was ADDSIGNED */ 566 R200_ALPHA_ARG( 0, A ); 567 R200_ALPHA_ARG( 1, C ); 568 break; 569 case GL_SUBTRACT: 570 alpha_combine = (R200_TXA_ARG_B_ZERO | 571 R200_TXA_COMP_ARG_B | 572 R200_TXA_NEG_ARG_C | 573 R200_TXA_OP_MADD); 574 R200_ALPHA_ARG( 0, A ); 575 R200_ALPHA_ARG( 1, C ); 576 break; 577 case GL_INTERPOLATE: 578 alpha_combine = (R200_TXA_OP_LERP); 579 R200_ALPHA_ARG( 0, B ); 580 R200_ALPHA_ARG( 1, A ); 581 R200_ALPHA_ARG( 2, C ); 582 break; 583 584 case GL_MODULATE_ADD_ATI: 585 alpha_combine = (R200_TXA_OP_MADD); 586 R200_ALPHA_ARG( 0, A ); 587 R200_ALPHA_ARG( 1, C ); 588 R200_ALPHA_ARG( 2, B ); 589 break; 590 case GL_MODULATE_SIGNED_ADD_ATI: 591 alpha_combine = (R200_TXA_BIAS_ARG_C | /* new */ 592 R200_TXA_OP_MADD); /* was ADDSIGNED */ 593 R200_ALPHA_ARG( 0, A ); 594 R200_ALPHA_ARG( 1, C ); 595 R200_ALPHA_ARG( 2, B ); 596 break; 597 case GL_MODULATE_SUBTRACT_ATI: 598 alpha_combine = (R200_TXA_NEG_ARG_C | 599 R200_TXA_OP_MADD); 600 R200_ALPHA_ARG( 0, A ); 601 R200_ALPHA_ARG( 1, C ); 602 R200_ALPHA_ARG( 2, B ); 603 break; 604 default: 605 return GL_FALSE; 606 } 607 608 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT) 609 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) { 610 alpha_scale |= R200_TXA_DOT_ALPHA; 611 Ashift = RGBshift; 612 } 613 614 /* Step 3: 615 * Apply the scale factor. 616 */ 617 color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT); 618 alpha_scale |= (Ashift << R200_TXA_SCALE_SHIFT); 619 620 /* All done! 621 */ 622 } 623 624 if ( rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND] != color_combine || 625 rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND] != alpha_combine || 626 rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] != color_scale || 627 rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] != alpha_scale) { 628 R200_STATECHANGE( rmesa, pix[slot] ); 629 rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND] = color_combine; 630 rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND] = alpha_combine; 631 rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] = color_scale; 632 rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] = alpha_scale; 633 } 634 635 return GL_TRUE; 636} 637 638void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format, 639 __DRIdrawable *dPriv) 640{ 641 struct gl_texture_object *texObj; 642 struct gl_texture_image *texImage; 643 struct radeon_renderbuffer *rb; 644 radeon_texture_image *rImage; 645 radeonContextPtr radeon; 646 struct radeon_framebuffer *rfb; 647 radeonTexObjPtr t; 648 uint32_t pitch_val; 649 mesa_format texFormat; 650 651 radeon = pDRICtx->driverPrivate; 652 653 rfb = dPriv->driverPrivate; 654 texObj = _mesa_get_current_tex_object(&radeon->glCtx, target); 655 texImage = _mesa_get_tex_image(&radeon->glCtx, texObj, target, 0); 656 657 rImage = get_radeon_texture_image(texImage); 658 t = radeon_tex_obj(texObj); 659 if (t == NULL) { 660 return; 661 } 662 663 radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE); 664 rb = rfb->color_rb[0]; 665 if (rb->bo == NULL) { 666 /* Failed to BO for the buffer */ 667 return; 668 } 669 670 _mesa_lock_texture(&radeon->glCtx, texObj); 671 if (t->bo) { 672 radeon_bo_unref(t->bo); 673 t->bo = NULL; 674 } 675 if (rImage->bo) { 676 radeon_bo_unref(rImage->bo); 677 rImage->bo = NULL; 678 } 679 680 radeon_miptree_unreference(&t->mt); 681 radeon_miptree_unreference(&rImage->mt); 682 683 rImage->bo = rb->bo; 684 radeon_bo_ref(rImage->bo); 685 t->bo = rb->bo; 686 radeon_bo_ref(t->bo); 687 t->tile_bits = 0; 688 t->image_override = GL_TRUE; 689 t->override_offset = 0; 690 t->pp_txpitch &= (1 << 13) -1; 691 pitch_val = rb->pitch; 692 switch (rb->cpp) { 693 case 4: 694 if (texture_format == __DRI_TEXTURE_FORMAT_RGB) 695 texFormat = MESA_FORMAT_BGR_UNORM8; 696 else 697 texFormat = MESA_FORMAT_B8G8R8A8_UNORM; 698 break; 699 case 3: 700 default: 701 texFormat = MESA_FORMAT_BGR_UNORM8; 702 break; 703 case 2: 704 texFormat = MESA_FORMAT_B5G6R5_UNORM; 705 break; 706 } 707 708 t->pp_txformat = tx_table_le[texFormat].format; 709 t->pp_txfilter |= tx_table_le[texFormat].filter; 710 711 _mesa_init_teximage_fields(&radeon->glCtx, texImage, 712 rb->base.Base.Width, rb->base.Base.Height, 713 1, 0, 714 rb->cpp, texFormat); 715 rImage->base.RowStride = rb->pitch / rb->cpp; 716 717 718 t->pp_txsize = ((rb->base.Base.Width - 1) << RADEON_TEX_USIZE_SHIFT) 719 | ((rb->base.Base.Height - 1) << RADEON_TEX_VSIZE_SHIFT); 720 721 if (target == GL_TEXTURE_RECTANGLE_NV) { 722 t->pp_txformat |= R200_TXFORMAT_NON_POWER2; 723 t->pp_txpitch = pitch_val; 724 t->pp_txpitch -= 32; 725 } else { 726 t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK | 727 R200_TXFORMAT_HEIGHT_MASK | 728 R200_TXFORMAT_CUBIC_MAP_ENABLE | 729 R200_TXFORMAT_F5_WIDTH_MASK | 730 R200_TXFORMAT_F5_HEIGHT_MASK); 731 t->pp_txformat |= ((texImage->WidthLog2 << R200_TXFORMAT_WIDTH_SHIFT) | 732 (texImage->HeightLog2 << R200_TXFORMAT_HEIGHT_SHIFT)); 733 } 734 735 t->validated = GL_TRUE; 736 _mesa_unlock_texture(&radeon->glCtx, texObj); 737 return; 738} 739 740 741void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) 742{ 743 r200SetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv); 744} 745 746 747#define REF_COLOR 1 748#define REF_ALPHA 2 749 750static GLboolean r200UpdateAllTexEnv( struct gl_context *ctx ) 751{ 752 r200ContextPtr rmesa = R200_CONTEXT(ctx); 753 GLint i, j, currslot; 754 GLint maxunitused = -1; 755 GLboolean texregfree[6] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}; 756 GLubyte stageref[7] = {0, 0, 0, 0, 0, 0, 0}; 757 GLint nextunit[R200_MAX_TEXTURE_UNITS] = {0, 0, 0, 0, 0, 0}; 758 GLint currentnext = -1; 759 GLboolean ok; 760 761 /* find highest used unit */ 762 for ( j = 0; j < R200_MAX_TEXTURE_UNITS; j++) { 763 if (ctx->Texture.Unit[j]._Current) { 764 maxunitused = j; 765 } 766 } 767 stageref[maxunitused + 1] = REF_COLOR | REF_ALPHA; 768 769 for ( j = maxunitused; j >= 0; j-- ) { 770 const struct gl_texture_unit *rtexUnit = &ctx->Texture.Unit[j]; 771 const struct gl_fixedfunc_texture_unit *texUnit = 772 &ctx->Texture.FixedFuncUnit[j]; 773 774 rmesa->state.texture.unit[j].outputreg = -1; 775 776 if (stageref[j + 1]) { 777 778 /* use the lowest available reg. That gets us automatically reg0 for the last stage. 779 need this even for disabled units, as it may get referenced due to the replace 780 optimization */ 781 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS; i++ ) { 782 if (texregfree[i]) { 783 rmesa->state.texture.unit[j].outputreg = i; 784 break; 785 } 786 } 787 if (rmesa->state.texture.unit[j].outputreg == -1) { 788 /* no more free regs we can use. Need a fallback :-( */ 789 return GL_FALSE; 790 } 791 792 nextunit[j] = currentnext; 793 794 if (!rtexUnit->_Current) { 795 /* the not enabled stages are referenced "indirectly", 796 must not cut off the lower stages */ 797 stageref[j] = REF_COLOR | REF_ALPHA; 798 continue; 799 } 800 currentnext = j; 801 802 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB; 803 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA; 804 const GLboolean isdot3rgba = (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) || 805 (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT); 806 807 808 /* check if we need the color part, special case for dot3_rgba 809 as if only the alpha part is referenced later on it still is using the color part */ 810 if ((stageref[j + 1] & REF_COLOR) || isdot3rgba) { 811 for ( i = 0 ; i < numColorArgs ; i++ ) { 812 const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i]; 813 const GLuint op = texUnit->_CurrentCombine->OperandRGB[i]; 814 switch ( srcRGBi ) { 815 case GL_PREVIOUS: 816 /* op 0/1 are referencing color, op 2/3 alpha */ 817 stageref[j] |= (op >> 1) + 1; 818 break; 819 case GL_TEXTURE: 820 texregfree[j] = GL_FALSE; 821 break; 822 case GL_TEXTURE0: 823 case GL_TEXTURE1: 824 case GL_TEXTURE2: 825 case GL_TEXTURE3: 826 case GL_TEXTURE4: 827 case GL_TEXTURE5: 828 texregfree[srcRGBi - GL_TEXTURE0] = GL_FALSE; 829 break; 830 default: /* don't care about other sources here */ 831 break; 832 } 833 } 834 } 835 836 /* alpha args are ignored for dot3_rgba */ 837 if ((stageref[j + 1] & REF_ALPHA) && !isdot3rgba) { 838 839 for ( i = 0 ; i < numAlphaArgs ; i++ ) { 840 const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i]; 841 switch ( srcAi ) { 842 case GL_PREVIOUS: 843 stageref[j] |= REF_ALPHA; 844 break; 845 case GL_TEXTURE: 846 texregfree[j] = GL_FALSE; 847 break; 848 case GL_TEXTURE0: 849 case GL_TEXTURE1: 850 case GL_TEXTURE2: 851 case GL_TEXTURE3: 852 case GL_TEXTURE4: 853 case GL_TEXTURE5: 854 texregfree[srcAi - GL_TEXTURE0] = GL_FALSE; 855 break; 856 default: /* don't care about other sources here */ 857 break; 858 } 859 } 860 } 861 } 862 } 863 864 /* don't enable texture sampling for units if the result is not used */ 865 for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) { 866 if (ctx->Texture.Unit[i]._Current && !texregfree[i]) 867 rmesa->state.texture.unit[i].unitneeded = 1 << _mesa_tex_target_to_index(ctx, ctx->Texture.Unit[i]._Current->Target); 868 else rmesa->state.texture.unit[i].unitneeded = 0; 869 } 870 871 ok = GL_TRUE; 872 currslot = 0; 873 rmesa->state.envneeded = 1; 874 875 i = 0; 876 while ((i <= maxunitused) && (i >= 0)) { 877 /* only output instruction if the results are referenced */ 878 if (ctx->Texture.Unit[i]._Current && stageref[i+1]) { 879 GLuint replaceunit = i; 880 /* try to optimize GL_REPLACE away (only one level deep though) */ 881 if ( (ctx->Texture.FixedFuncUnit[i]._CurrentCombine->ModeRGB == GL_REPLACE) && 882 (ctx->Texture.FixedFuncUnit[i]._CurrentCombine->ModeA == GL_REPLACE) && 883 (ctx->Texture.FixedFuncUnit[i]._CurrentCombine->ScaleShiftRGB == 0) && 884 (ctx->Texture.FixedFuncUnit[i]._CurrentCombine->ScaleShiftA == 0) && 885 (nextunit[i] > 0) ) { 886 /* yippie! can optimize it away! */ 887 replaceunit = i; 888 i = nextunit[i]; 889 } 890 891 /* need env instruction slot */ 892 rmesa->state.envneeded |= 1 << currslot; 893 ok = r200UpdateTextureEnv( ctx, i, currslot, replaceunit ); 894 if (!ok) return GL_FALSE; 895 currslot++; 896 } 897 i = i + 1; 898 } 899 900 if (currslot == 0) { 901 /* need one stage at least */ 902 rmesa->state.texture.unit[0].outputreg = 0; 903 ok = r200UpdateTextureEnv( ctx, 0, 0, 0 ); 904 } 905 906 R200_STATECHANGE( rmesa, ctx ); 907 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_BLEND_ENABLE_MASK | R200_MULTI_PASS_ENABLE); 908 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= rmesa->state.envneeded << R200_TEX_BLEND_0_ENABLE_SHIFT; 909 910 return ok; 911} 912 913#undef REF_COLOR 914#undef REF_ALPHA 915 916 917#define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \ 918 R200_MIN_FILTER_MASK | \ 919 R200_MAG_FILTER_MASK | \ 920 R200_MAX_ANISO_MASK | \ 921 R200_YUV_TO_RGB | \ 922 R200_YUV_TEMPERATURE_MASK | \ 923 R200_CLAMP_S_MASK | \ 924 R200_CLAMP_T_MASK | \ 925 R200_BORDER_MODE_D3D ) 926 927#define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \ 928 R200_TXFORMAT_HEIGHT_MASK | \ 929 R200_TXFORMAT_FORMAT_MASK | \ 930 R200_TXFORMAT_F5_WIDTH_MASK | \ 931 R200_TXFORMAT_F5_HEIGHT_MASK | \ 932 R200_TXFORMAT_ALPHA_IN_MAP | \ 933 R200_TXFORMAT_CUBIC_MAP_ENABLE | \ 934 R200_TXFORMAT_NON_POWER2) 935 936#define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \ 937 R200_TEXCOORD_MASK | \ 938 R200_MIN_MIP_LEVEL_MASK | \ 939 R200_CLAMP_Q_MASK | \ 940 R200_VOLUME_FILTER_MASK) 941 942 943static void disable_tex_obj_state( r200ContextPtr rmesa, 944 int unit ) 945{ 946 947 R200_STATECHANGE( rmesa, vtx ); 948 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3)); 949 950 R200_STATECHANGE( rmesa, ctx ); 951 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_0_ENABLE << unit); 952 if (rmesa->radeon.TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) { 953 TCL_FALLBACK( &rmesa->radeon.glCtx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE); 954 } 955 956 /* Actually want to keep all units less than max active texture 957 * enabled, right? Fix this for >2 texunits. 958 */ 959 960 { 961 GLuint tmp = rmesa->TexGenEnabled; 962 963 rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit); 964 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit); 965 rmesa->TexGenNeedNormals[unit] = GL_FALSE; 966 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit); 967 968 if (tmp != rmesa->TexGenEnabled) { 969 rmesa->recheck_texgen[unit] = GL_TRUE; 970 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; 971 } 972 } 973} 974static void import_tex_obj_state( r200ContextPtr rmesa, 975 int unit, 976 radeonTexObjPtr texobj ) 977{ 978/* do not use RADEON_DB_STATE to avoid stale texture caches */ 979 GLuint *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0]; 980 981 R200_STATECHANGE( rmesa, tex[unit] ); 982 983 cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK; 984 cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK; 985 cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; 986 cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK; 987 cmd[TEX_PP_TXFORMAT_X] &= ~TEXOBJ_TXFORMAT_X_MASK; 988 cmd[TEX_PP_TXFORMAT_X] |= texobj->pp_txformat_x & TEXOBJ_TXFORMAT_X_MASK; 989 cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */ 990 cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */ 991 cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color; 992 993 if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) { 994 GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0]; 995 996 R200_STATECHANGE( rmesa, cube[unit] ); 997 cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces; 998 /* that value is submitted twice. could change cube atom 999 to not include that command when new drm is used */ 1000 cmd[TEX_PP_CUBIC_FACES] = texobj->pp_cubic_faces; 1001 } 1002 1003} 1004 1005static void set_texgen_matrix( r200ContextPtr rmesa, 1006 GLuint unit, 1007 const GLfloat *s_plane, 1008 const GLfloat *t_plane, 1009 const GLfloat *r_plane, 1010 const GLfloat *q_plane ) 1011{ 1012 GLfloat m[16]; 1013 1014 m[0] = s_plane[0]; 1015 m[4] = s_plane[1]; 1016 m[8] = s_plane[2]; 1017 m[12] = s_plane[3]; 1018 1019 m[1] = t_plane[0]; 1020 m[5] = t_plane[1]; 1021 m[9] = t_plane[2]; 1022 m[13] = t_plane[3]; 1023 1024 m[2] = r_plane[0]; 1025 m[6] = r_plane[1]; 1026 m[10] = r_plane[2]; 1027 m[14] = r_plane[3]; 1028 1029 m[3] = q_plane[0]; 1030 m[7] = q_plane[1]; 1031 m[11] = q_plane[2]; 1032 m[15] = q_plane[3]; 1033 1034 _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m); 1035 _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) ); 1036 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit; 1037} 1038 1039 1040static GLuint r200_need_dis_texgen(const GLbitfield texGenEnabled, 1041 const GLfloat *planeS, 1042 const GLfloat *planeT, 1043 const GLfloat *planeR, 1044 const GLfloat *planeQ) 1045{ 1046 GLuint needtgenable = 0; 1047 1048 if (!(texGenEnabled & S_BIT)) { 1049 if (((texGenEnabled & T_BIT) && planeT[0] != 0.0) || 1050 ((texGenEnabled & R_BIT) && planeR[0] != 0.0) || 1051 ((texGenEnabled & Q_BIT) && planeQ[0] != 0.0)) { 1052 needtgenable |= S_BIT; 1053 } 1054 } 1055 if (!(texGenEnabled & T_BIT)) { 1056 if (((texGenEnabled & S_BIT) && planeS[1] != 0.0) || 1057 ((texGenEnabled & R_BIT) && planeR[1] != 0.0) || 1058 ((texGenEnabled & Q_BIT) && planeQ[1] != 0.0)) { 1059 needtgenable |= T_BIT; 1060 } 1061 } 1062 if (!(texGenEnabled & R_BIT)) { 1063 if (((texGenEnabled & S_BIT) && planeS[2] != 0.0) || 1064 ((texGenEnabled & T_BIT) && planeT[2] != 0.0) || 1065 ((texGenEnabled & Q_BIT) && planeQ[2] != 0.0)) { 1066 needtgenable |= R_BIT; 1067 } 1068 } 1069 if (!(texGenEnabled & Q_BIT)) { 1070 if (((texGenEnabled & S_BIT) && planeS[3] != 0.0) || 1071 ((texGenEnabled & T_BIT) && planeT[3] != 0.0) || 1072 ((texGenEnabled & R_BIT) && planeR[3] != 0.0)) { 1073 needtgenable |= Q_BIT; 1074 } 1075 } 1076 1077 return needtgenable; 1078} 1079 1080 1081/* 1082 * Returns GL_FALSE if fallback required. 1083 */ 1084static GLboolean r200_validate_texgen( struct gl_context *ctx, GLuint unit ) 1085{ 1086 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1087 const struct gl_fixedfunc_texture_unit *texUnit = 1088 &ctx->Texture.FixedFuncUnit[unit]; 1089 GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4; 1090 GLuint tgi, tgcm; 1091 GLuint mode = 0; 1092 GLboolean mixed_fallback = GL_FALSE; 1093 static const GLfloat I[16] = { 1094 1, 0, 0, 0, 1095 0, 1, 0, 0, 1096 0, 0, 1, 0, 1097 0, 0, 0, 1 }; 1098 static const GLfloat reflect[16] = { 1099 -1, 0, 0, 0, 1100 0, -1, 0, 0, 1101 0, 0, -1, 0, 1102 0, 0, 0, 1 }; 1103 1104 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit); 1105 rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit); 1106 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit); 1107 rmesa->TexGenNeedNormals[unit] = GL_FALSE; 1108 tgi = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] & ~(R200_TEXGEN_INPUT_MASK << 1109 inputshift); 1110 tgcm = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] & ~(R200_TEXGEN_COMP_MASK << 1111 (unit * 4)); 1112 1113 if (0) 1114 fprintf(stderr, "%s unit %d\n", __func__, unit); 1115 1116 if (texUnit->TexGenEnabled & S_BIT) { 1117 mode = texUnit->GenS.Mode; 1118 } else { 1119 tgcm |= R200_TEXGEN_COMP_S << (unit * 4); 1120 } 1121 1122 if (texUnit->TexGenEnabled & T_BIT) { 1123 if (texUnit->GenT.Mode != mode) 1124 mixed_fallback = GL_TRUE; 1125 } else { 1126 tgcm |= R200_TEXGEN_COMP_T << (unit * 4); 1127 } 1128 if (texUnit->TexGenEnabled & R_BIT) { 1129 if (texUnit->GenR.Mode != mode) 1130 mixed_fallback = GL_TRUE; 1131 } else { 1132 tgcm |= R200_TEXGEN_COMP_R << (unit * 4); 1133 } 1134 1135 if (texUnit->TexGenEnabled & Q_BIT) { 1136 if (texUnit->GenQ.Mode != mode) 1137 mixed_fallback = GL_TRUE; 1138 } else { 1139 tgcm |= R200_TEXGEN_COMP_Q << (unit * 4); 1140 } 1141 1142 if (mixed_fallback) { 1143 if (R200_DEBUG & RADEON_FALLBACKS) 1144 fprintf(stderr, "fallback mixed texgen, 0x%x (0x%x 0x%x 0x%x 0x%x)\n", 1145 texUnit->TexGenEnabled, texUnit->GenS.Mode, texUnit->GenT.Mode, 1146 texUnit->GenR.Mode, texUnit->GenQ.Mode); 1147 return GL_FALSE; 1148 } 1149 1150/* we CANNOT do mixed mode if the texgen mode requires a plane where the input 1151 is not enabled for texgen, since the planes are concatenated into texmat, 1152 and thus the input will come from texcoord rather than tex gen equation! 1153 Either fallback or just hope that those texcoords aren't really needed... 1154 Assuming the former will cause lots of unnecessary fallbacks, the latter will 1155 generate bogus results sometimes - it's pretty much impossible to really know 1156 when a fallback is needed, depends on texmat and what sort of texture is bound 1157 etc, - for now fallback if we're missing either S or T bits, there's a high 1158 probability we need the texcoords in that case. 1159 That's a lot of work for some obscure texgen mixed mode fixup - why oh why 1160 doesn't the chip just directly accept the plane parameters :-(. */ 1161 switch (mode) { 1162 case GL_OBJECT_LINEAR: { 1163 GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled, 1164 texUnit->ObjectPlane[GEN_S], 1165 texUnit->ObjectPlane[GEN_T], 1166 texUnit->ObjectPlane[GEN_R], 1167 texUnit->ObjectPlane[GEN_Q] ); 1168 if (needtgenable & (S_BIT | T_BIT)) { 1169 if (R200_DEBUG & RADEON_FALLBACKS) 1170 fprintf(stderr, "fallback mixed texgen / obj plane, 0x%x\n", 1171 texUnit->TexGenEnabled); 1172 return GL_FALSE; 1173 } 1174 if (needtgenable & (R_BIT)) { 1175 tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4)); 1176 } 1177 if (needtgenable & (Q_BIT)) { 1178 tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4)); 1179 } 1180 1181 tgi |= R200_TEXGEN_INPUT_OBJ << inputshift; 1182 set_texgen_matrix( rmesa, unit, 1183 (texUnit->TexGenEnabled & S_BIT) ? texUnit->ObjectPlane[GEN_S] : I, 1184 (texUnit->TexGenEnabled & T_BIT) ? texUnit->ObjectPlane[GEN_T] : I + 4, 1185 (texUnit->TexGenEnabled & R_BIT) ? texUnit->ObjectPlane[GEN_R] : I + 8, 1186 (texUnit->TexGenEnabled & Q_BIT) ? texUnit->ObjectPlane[GEN_Q] : I + 12); 1187 } 1188 break; 1189 1190 case GL_EYE_LINEAR: { 1191 GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled, 1192 texUnit->EyePlane[GEN_S], 1193 texUnit->EyePlane[GEN_T], 1194 texUnit->EyePlane[GEN_R], 1195 texUnit->EyePlane[GEN_Q] ); 1196 if (needtgenable & (S_BIT | T_BIT)) { 1197 if (R200_DEBUG & RADEON_FALLBACKS) 1198 fprintf(stderr, "fallback mixed texgen / eye plane, 0x%x\n", 1199 texUnit->TexGenEnabled); 1200 return GL_FALSE; 1201 } 1202 if (needtgenable & (R_BIT)) { 1203 tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4)); 1204 } 1205 if (needtgenable & (Q_BIT)) { 1206 tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4)); 1207 } 1208 tgi |= R200_TEXGEN_INPUT_EYE << inputshift; 1209 set_texgen_matrix( rmesa, unit, 1210 (texUnit->TexGenEnabled & S_BIT) ? texUnit->EyePlane[GEN_S] : I, 1211 (texUnit->TexGenEnabled & T_BIT) ? texUnit->EyePlane[GEN_T] : I + 4, 1212 (texUnit->TexGenEnabled & R_BIT) ? texUnit->EyePlane[GEN_R] : I + 8, 1213 (texUnit->TexGenEnabled & Q_BIT) ? texUnit->EyePlane[GEN_Q] : I + 12); 1214 } 1215 break; 1216 1217 case GL_REFLECTION_MAP_NV: 1218 rmesa->TexGenNeedNormals[unit] = GL_TRUE; 1219 tgi |= R200_TEXGEN_INPUT_EYE_REFLECT << inputshift; 1220 /* pretty weird, must only negate when lighting is enabled? */ 1221 if (ctx->Light.Enabled) 1222 set_texgen_matrix( rmesa, unit, 1223 (texUnit->TexGenEnabled & S_BIT) ? reflect : I, 1224 (texUnit->TexGenEnabled & T_BIT) ? reflect + 4 : I + 4, 1225 (texUnit->TexGenEnabled & R_BIT) ? reflect + 8 : I + 8, 1226 I + 12); 1227 break; 1228 1229 case GL_NORMAL_MAP_NV: 1230 rmesa->TexGenNeedNormals[unit] = GL_TRUE; 1231 tgi |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift; 1232 break; 1233 1234 case GL_SPHERE_MAP: 1235 rmesa->TexGenNeedNormals[unit] = GL_TRUE; 1236 tgi |= R200_TEXGEN_INPUT_SPHERE<<inputshift; 1237 break; 1238 1239 case 0: 1240 /* All texgen units were disabled, so just pass coords through. */ 1241 tgi |= unit << inputshift; 1242 break; 1243 1244 default: 1245 /* Unsupported mode, fallback: 1246 */ 1247 if (R200_DEBUG & RADEON_FALLBACKS) 1248 fprintf(stderr, "fallback unsupported texgen, %d\n", 1249 texUnit->GenS.Mode); 1250 return GL_FALSE; 1251 } 1252 1253 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit; 1254 rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit; 1255 1256 if (tgi != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] || 1257 tgcm != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2]) 1258 { 1259 R200_STATECHANGE(rmesa, tcg); 1260 rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] = tgi; 1261 rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = tgcm; 1262 } 1263 1264 return GL_TRUE; 1265} 1266 1267void set_re_cntl_d3d( struct gl_context *ctx, int unit, GLboolean use_d3d ) 1268{ 1269 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1270 1271 GLuint re_cntl; 1272 1273 re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D << (2 * unit)); 1274 if (use_d3d) 1275 re_cntl |= R200_VTX_STQ0_D3D << (2 * unit); 1276 1277 if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) { 1278 R200_STATECHANGE( rmesa, set ); 1279 rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl; 1280 } 1281} 1282 1283/** 1284 * Compute the cached hardware register values for the given texture object. 1285 * 1286 * \param rmesa Context pointer 1287 * \param t the r300 texture object 1288 */ 1289static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t) 1290{ 1291 const struct gl_texture_image *firstImage = t->base.Image[0][t->minLod]; 1292 GLint log2Width, log2Height, log2Depth, texelBytes; 1293 uint extra_size = 0; 1294 1295 if ( t->bo ) { 1296 return; 1297 } 1298 1299 log2Width = firstImage->WidthLog2; 1300 log2Height = firstImage->HeightLog2; 1301 log2Depth = firstImage->DepthLog2; 1302 texelBytes = _mesa_get_format_bytes(firstImage->TexFormat); 1303 1304 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 1305 "%s(%p, tex %p) log2(w %d, h %d, d %d), texelBytes %d. format %d\n", 1306 __func__, rmesa, t, log2Width, log2Height, 1307 log2Depth, texelBytes, firstImage->TexFormat); 1308 1309 if (!t->image_override) { 1310 if (VALID_FORMAT(firstImage->TexFormat)) { 1311#if UTIL_ARCH_LITTLE_ENDIAN 1312 const struct tx_table *table = tx_table_le; 1313#else 1314 const struct tx_table *table = tx_table_be; 1315#endif 1316 1317 t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK | 1318 R200_TXFORMAT_ALPHA_IN_MAP); 1319 t->pp_txfilter &= ~R200_YUV_TO_RGB; 1320 1321 t->pp_txformat |= table[ firstImage->TexFormat ].format; 1322 t->pp_txfilter |= table[ firstImage->TexFormat ].filter; 1323 1324 1325 } else { 1326 _mesa_problem(NULL, "unexpected texture format in %s", 1327 __func__); 1328 return; 1329 } 1330 } 1331 1332 t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK; 1333 t->pp_txfilter |= ((t->maxLod) << R200_MAX_MIP_LEVEL_SHIFT) 1334 & R200_MAX_MIP_LEVEL_MASK; 1335 1336 if ( t->pp_txfilter & 1337 (R200_MIN_FILTER_NEAREST_MIP_NEAREST 1338 | R200_MIN_FILTER_NEAREST_MIP_LINEAR 1339 | R200_MIN_FILTER_LINEAR_MIP_NEAREST 1340 | R200_MIN_FILTER_LINEAR_MIP_LINEAR 1341 | R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST 1342 | R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR)) 1343 extra_size = t->minLod; 1344 1345 t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK | 1346 R200_TXFORMAT_HEIGHT_MASK | 1347 R200_TXFORMAT_CUBIC_MAP_ENABLE | 1348 R200_TXFORMAT_F5_WIDTH_MASK | 1349 R200_TXFORMAT_F5_HEIGHT_MASK); 1350 t->pp_txformat |= (((log2Width + extra_size) << R200_TXFORMAT_WIDTH_SHIFT) | 1351 ((log2Height + extra_size)<< R200_TXFORMAT_HEIGHT_SHIFT)); 1352 1353 t->tile_bits = 0; 1354 1355 t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK 1356 | R200_MIN_MIP_LEVEL_MASK); 1357 1358 t->pp_txformat_x |= (t->minLod << R200_MIN_MIP_LEVEL_SHIFT) 1359 & R200_MIN_MIP_LEVEL_MASK; 1360 1361 if (t->base.Target == GL_TEXTURE_3D) { 1362 t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT); 1363 t->pp_txformat_x |= R200_TEXCOORD_VOLUME; 1364 1365 } 1366 else if (t->base.Target == GL_TEXTURE_CUBE_MAP) { 1367 assert(log2Width == log2Height); 1368 t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) | 1369 (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) | 1370 /* don't think we need this bit, if it exists at all - fglrx does not set it */ 1371 (R200_TXFORMAT_CUBIC_MAP_ENABLE)); 1372 t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV; 1373 t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) | 1374 (log2Height << R200_FACE_HEIGHT_1_SHIFT) | 1375 (log2Width << R200_FACE_WIDTH_2_SHIFT) | 1376 (log2Height << R200_FACE_HEIGHT_2_SHIFT) | 1377 (log2Width << R200_FACE_WIDTH_3_SHIFT) | 1378 (log2Height << R200_FACE_HEIGHT_3_SHIFT) | 1379 (log2Width << R200_FACE_WIDTH_4_SHIFT) | 1380 (log2Height << R200_FACE_HEIGHT_4_SHIFT)); 1381 } 1382 else { 1383 /* If we don't in fact send enough texture coordinates, q will be 1, 1384 * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?) 1385 */ 1386 t->pp_txformat_x |= R200_TEXCOORD_PROJ; 1387 } 1388 /* FIXME: NPOT sizes, is it correct really? */ 1389 t->pp_txsize = (((firstImage->Width - 1) << R200_PP_TX_WIDTHMASK_SHIFT) 1390 | ((firstImage->Height - 1) << R200_PP_TX_HEIGHTMASK_SHIFT)); 1391 1392 if ( !t->image_override ) { 1393 if (_mesa_is_format_compressed(firstImage->TexFormat)) 1394 t->pp_txpitch = (firstImage->Width + 63) & ~(63); 1395 else 1396 t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63); 1397 t->pp_txpitch -= 32; 1398 } 1399 1400 if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) { 1401 t->pp_txformat |= R200_TXFORMAT_NON_POWER2; 1402 } 1403 1404} 1405 1406static GLboolean r200_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit) 1407{ 1408 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1409 radeonTexObj *t = radeon_tex_obj(texObj); 1410 1411 if (!radeon_validate_texture_miptree(ctx, _mesa_get_samplerobj(ctx, unit), texObj)) 1412 return GL_FALSE; 1413 1414 r200_validate_texgen(ctx, unit); 1415 /* Configure the hardware registers (more precisely, the cached version 1416 * of the hardware registers). */ 1417 setup_hardware_state(rmesa, t); 1418 1419 if (texObj->Target == GL_TEXTURE_RECTANGLE_NV || 1420 texObj->Target == GL_TEXTURE_2D || 1421 texObj->Target == GL_TEXTURE_1D) 1422 set_re_cntl_d3d( ctx, unit, GL_FALSE ); 1423 else 1424 set_re_cntl_d3d( ctx, unit, GL_TRUE ); 1425 R200_STATECHANGE( rmesa, ctx ); 1426 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit; 1427 1428 R200_STATECHANGE( rmesa, vtx ); 1429 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3)); 1430 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3); 1431 1432 rmesa->recheck_texgen[unit] = GL_TRUE; 1433 r200TexUpdateParameters(ctx, unit); 1434 import_tex_obj_state( rmesa, unit, t ); 1435 1436 if (rmesa->recheck_texgen[unit]) { 1437 GLboolean fallback = !r200_validate_texgen( ctx, unit ); 1438 TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback); 1439 rmesa->recheck_texgen[unit] = 0; 1440 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; 1441 } 1442 1443 t->validated = GL_TRUE; 1444 1445 FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback ); 1446 1447 return !t->border_fallback; 1448} 1449 1450static GLboolean r200UpdateTextureUnit(struct gl_context *ctx, int unit) 1451{ 1452 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1453 GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded; 1454 1455 if (!unitneeded) { 1456 /* disable the unit */ 1457 disable_tex_obj_state(rmesa, unit); 1458 return GL_TRUE; 1459 } 1460 1461 if (!r200_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) { 1462 _mesa_warning(ctx, 1463 "failed to validate texture for unit %d.\n", 1464 unit); 1465 rmesa->state.texture.unit[unit].texobj = NULL; 1466 return GL_FALSE; 1467 } 1468 1469 rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current); 1470 return GL_TRUE; 1471} 1472 1473 1474void r200UpdateTextureState( struct gl_context *ctx ) 1475{ 1476 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1477 GLboolean ok; 1478 GLuint dbg; 1479 1480 /* NOTE: must not manipulate rmesa->state.texture.unit[].unitneeded or 1481 rmesa->state.envneeded before a R200_STATECHANGE (or R200_NEWPRIM) since 1482 we use these to determine if we want to emit the corresponding state 1483 atoms. */ 1484 R200_NEWPRIM( rmesa ); 1485 1486 if (_mesa_ati_fragment_shader_enabled(ctx)) { 1487 GLuint i; 1488 for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) { 1489 if (ctx->Texture.Unit[i]._Current) 1490 rmesa->state.texture.unit[i].unitneeded = 1 << _mesa_tex_target_to_index(ctx, ctx->Texture.Unit[i]._Current->Target); 1491 else 1492 rmesa->state.texture.unit[i].unitneeded = 0; 1493 } 1494 ok = GL_TRUE; 1495 } 1496 else { 1497 ok = r200UpdateAllTexEnv( ctx ); 1498 } 1499 if (ok) { 1500 ok = (r200UpdateTextureUnit( ctx, 0 ) && 1501 r200UpdateTextureUnit( ctx, 1 ) && 1502 r200UpdateTextureUnit( ctx, 2 ) && 1503 r200UpdateTextureUnit( ctx, 3 ) && 1504 r200UpdateTextureUnit( ctx, 4 ) && 1505 r200UpdateTextureUnit( ctx, 5 )); 1506 } 1507 1508 if (ok && _mesa_ati_fragment_shader_enabled(ctx)) { 1509 r200UpdateFragmentShader(ctx); 1510 } 1511 1512 FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok ); 1513 1514 if (rmesa->radeon.TclFallback) 1515 r200ChooseVertexState( ctx ); 1516 1517 1518 if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) { 1519 1520 /* 1521 * T0 hang workaround ------------- 1522 * not needed for r200 derivatives 1523 */ 1524 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) == R200_TEX_0_ENABLE && 1525 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) { 1526 1527 R200_STATECHANGE(rmesa, ctx); 1528 R200_STATECHANGE(rmesa, tex[1]); 1529 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE; 1530 if (!(rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_1_ENABLE)) 1531 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; 1532 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= R200_TXFORMAT_LOOKUP_DISABLE; 1533 } 1534 else if (!_mesa_ati_fragment_shader_enabled(ctx)) { 1535 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) && 1536 (rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] & R200_TXFORMAT_LOOKUP_DISABLE)) { 1537 R200_STATECHANGE(rmesa, tex[1]); 1538 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~R200_TXFORMAT_LOOKUP_DISABLE; 1539 } 1540 } 1541 /* do the same workaround for the first pass of a fragment shader. 1542 * completely unknown if necessary / sufficient. 1543 */ 1544 if ((rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_ENABLE_MASK) == R200_PPX_TEX_0_ENABLE && 1545 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) { 1546 1547 R200_STATECHANGE(rmesa, cst); 1548 R200_STATECHANGE(rmesa, tex[1]); 1549 rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_1_ENABLE; 1550 if (!(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE)) 1551 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; 1552 rmesa->hw.tex[1].cmd[TEX_PP_TXMULTI_CTL] |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE; 1553 } 1554 1555 /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ? 1556 looks like that's not the case, if 8500/9100 owners don't complain remove this... 1557 for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) { 1558 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE | 1559 R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) && 1560 ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > 1561 R200_MIN_FILTER_LINEAR)) { 1562 R200_STATECHANGE(rmesa, ctx); 1563 R200_STATECHANGE(rmesa, tex[i+1]); 1564 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i); 1565 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; 1566 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000; 1567 } 1568 else { 1569 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) && 1570 (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) { 1571 R200_STATECHANGE(rmesa, tex[i+1]); 1572 rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000; 1573 } 1574 } 1575 } */ 1576 1577 /* 1578 * Texture cache LRU hang workaround ------------- 1579 * not needed for r200 derivatives 1580 * hopefully this covers first pass of a shader as well 1581 */ 1582 1583 /* While the cases below attempt to only enable the workaround in the 1584 * specific cases necessary, they were insufficient. See bugzilla #1519, 1585 * #729, #814. Tests with quake3 showed no impact on performance. 1586 */ 1587 dbg = 0x6; 1588 1589 /* 1590 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE )) && 1591 ((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 1592 0x04) == 0)) || 1593 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) && 1594 ((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 1595 0x04) == 0)) || 1596 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) && 1597 ((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 1598 0x04) == 0))) 1599 { 1600 dbg |= 0x02; 1601 } 1602 1603 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE )) && 1604 ((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 1605 0x04) == 0)) || 1606 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) && 1607 ((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 1608 0x04) == 0)) || 1609 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) && 1610 ((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 1611 0x04) == 0))) 1612 { 1613 dbg |= 0x04; 1614 }*/ 1615 1616 if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) { 1617 R200_STATECHANGE( rmesa, tam ); 1618 rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg; 1619 if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg); 1620 } 1621 } 1622} 1623