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