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