r200_texstate.c revision bcc6eddd335e97d49ed2ef3a1440f94d58dce12d
1/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_texstate.c,v 1.3 2003/02/15 22:18:47 dawes Exp $ */ 2/* 3Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. 4 5The Weather Channel (TM) funded Tungsten Graphics to develop the 6initial release of the Radeon 8500 driver under the XFree86 license. 7This notice must be preserved. 8 9Permission is hereby granted, free of charge, to any person obtaining 10a copy of this software and associated documentation files (the 11"Software"), to deal in the Software without restriction, including 12without limitation the rights to use, copy, modify, merge, publish, 13distribute, sublicense, and/or sell copies of the Software, and to 14permit persons to whom the Software is furnished to do so, subject to 15the following conditions: 16 17The above copyright notice and this permission notice (including the 18next paragraph) shall be included in all copies or substantial 19portions of the Software. 20 21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 25LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 29**************************************************************************/ 30 31/* 32 * Authors: 33 * Keith Whitwell <keith@tungstengraphics.com> 34 */ 35 36#include "glheader.h" 37#include "imports.h" 38#include "context.h" 39#include "macros.h" 40#include "texformat.h" 41#include "enums.h" 42 43#include "r200_context.h" 44#include "r200_state.h" 45#include "r200_ioctl.h" 46#include "r200_swtcl.h" 47#include "r200_tex.h" 48#include "r200_tcl.h" 49 50 51#define R200_TXFORMAT_AL88 R200_TXFORMAT_AI88 52#define R200_TXFORMAT_YCBCR R200_TXFORMAT_YVYU422 53#define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422 54 55#define _COLOR(f) \ 56 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 } 57#define _ALPHA(f) \ 58 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 } 59#define _YUV(f) \ 60 [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB } 61#define _INVALID(f) \ 62 [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 } 63#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \ 64 && (tx_table[f].format != 0xffffffff) ) 65 66static const struct { 67 GLuint format, filter; 68} 69tx_table[] = 70{ 71 _ALPHA(RGBA8888), 72 _ALPHA(ARGB8888), 73 _INVALID(RGB888), 74 _COLOR(RGB565), 75 _ALPHA(ARGB4444), 76 _ALPHA(ARGB1555), 77 _ALPHA(AL88), 78 _INVALID(A8), 79 _INVALID(L8), 80 _COLOR(I8), 81 _INVALID(CI8), 82 _YUV(YCBCR), 83 _YUV(YCBCR_REV), 84}; 85 86#undef _COLOR 87#undef _ALPHA 88#undef _INVALID 89 90/** 91 * This function computes the number of bytes of storage needed for 92 * the given texture object (all mipmap levels, all cube faces). 93 * The \c image[face][level].x/y/width/height parameters for upload/blitting 94 * are computed here. \c pp_txfilter, \c pp_txformat, etc. will be set here 95 * too. 96 * 97 * \param rmesa Context pointer 98 * \param tObj GL texture object whose images are to be posted to 99 * hardware state. 100 */ 101static void r200SetTexImages( r200ContextPtr rmesa, 102 struct gl_texture_object *tObj ) 103{ 104 r200TexObjPtr t = (r200TexObjPtr)tObj->DriverData; 105 const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel]; 106 GLint curOffset; 107 GLint i; 108 GLint numLevels; 109 GLint log2Width, log2Height, log2Depth; 110 111 /* Set the hardware texture format 112 */ 113 114 t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK | 115 R200_TXFORMAT_ALPHA_IN_MAP); 116 t->pp_txfilter &= ~R200_YUV_TO_RGB; 117 118 if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) { 119 t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format; 120 t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter; 121 } 122 else { 123 _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); 124 return; 125 } 126 127 128 /* Compute which mipmap levels we really want to send to the hardware. 129 */ 130 131 driCalculateTextureFirstLastLevel( (driTextureObject *) t ); 132 log2Width = tObj->Image[t->base.firstLevel]->WidthLog2; 133 log2Height = tObj->Image[t->base.firstLevel]->HeightLog2; 134 log2Depth = tObj->Image[t->base.firstLevel]->DepthLog2; 135 136 numLevels = t->base.lastLevel - t->base.firstLevel + 1; 137 138 assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS); 139 140 /* Calculate mipmap offsets and dimensions for blitting (uploading) 141 * The idea is that we lay out the mipmap levels within a block of 142 * memory organized as a rectangle of width BLIT_WIDTH_BYTES. 143 */ 144 curOffset = 0; 145 146 for (i = 0; i < numLevels; i++) { 147 const struct gl_texture_image *texImage; 148 GLuint size; 149 150 texImage = tObj->Image[i + t->base.firstLevel]; 151 if ( !texImage ) 152 break; 153 154 /* find image size in bytes */ 155 if (texImage->IsCompressed) { 156 size = texImage->CompressedSize; 157 } 158 else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { 159 size = ((texImage->Width * texImage->TexFormat->TexelBytes + 63) 160 & ~63) * texImage->Height; 161 } 162 else { 163 int w = texImage->Width * texImage->TexFormat->TexelBytes; 164 if (w < 32) 165 w = 32; 166 size = w * texImage->Height * texImage->Depth; 167 } 168 assert(size > 0); 169 170 171 /* Align to 32-byte offset. It is faster to do this unconditionally 172 * (no branch penalty). 173 */ 174 175 curOffset = (curOffset + 0x1f) & ~0x1f; 176 177 t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES; 178 t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES; 179 t->image[0][i].width = MIN2(size, BLIT_WIDTH_BYTES); 180 t->image[0][i].height = size / t->image[0][i].width; 181 182#if 0 183 /* for debugging only and only applicable to non-rectangle targets */ 184 assert(size % t->image[0][i].width == 0); 185 assert(t->image[0][i].x == 0 186 || (size < BLIT_WIDTH_BYTES && t->image[0][i].height == 1)); 187#endif 188 189 if (0) 190 fprintf(stderr, 191 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n", 192 i, texImage->Width, texImage->Height, 193 t->image[0][i].x, t->image[0][i].y, 194 t->image[0][i].width, t->image[0][i].height, size, curOffset); 195 196 curOffset += size; 197 198 } 199 200 /* Align the total size of texture memory block. 201 */ 202 t->base.totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; 203 204 /* Setup remaining cube face blits, if needed */ 205 if (tObj->Target == GL_TEXTURE_CUBE_MAP) { 206 /* Round totalSize up to multiple of BLIT_WIDTH_BYTES */ 207 const GLuint faceSize = (t->base.totalSize + BLIT_WIDTH_BYTES - 1) 208 & ~(BLIT_WIDTH_BYTES-1); 209 const GLuint lines = faceSize / BLIT_WIDTH_BYTES; 210 GLuint face; 211 /* reuse face 0 x/y/width/height - just adjust y */ 212 for (face = 1; face < 6; face++) { 213 for (i = 0; i < numLevels; i++) { 214 t->image[face][i].x = t->image[0][i].x; 215 t->image[face][i].y = t->image[0][i].y + face * lines; 216 t->image[face][i].width = t->image[0][i].width; 217 t->image[face][i].height = t->image[0][i].height; 218 } 219 } 220 t->base.totalSize = 6 * faceSize; /* total texmem needed */ 221 } 222 223 224 /* Hardware state: 225 */ 226 t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK; 227 t->pp_txfilter |= (numLevels - 1) << R200_MAX_MIP_LEVEL_SHIFT; 228 229 t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK | 230 R200_TXFORMAT_HEIGHT_MASK | 231 R200_TXFORMAT_CUBIC_MAP_ENABLE | 232 R200_TXFORMAT_F5_WIDTH_MASK | 233 R200_TXFORMAT_F5_HEIGHT_MASK); 234 t->pp_txformat |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) | 235 (log2Height << R200_TXFORMAT_HEIGHT_SHIFT)); 236 237 t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK); 238 if (tObj->Target == GL_TEXTURE_3D) { 239 t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT); 240 t->pp_txformat_x |= R200_TEXCOORD_VOLUME; 241 } 242 else if (tObj->Target == GL_TEXTURE_CUBE_MAP) { 243 ASSERT(log2Width == log2height); 244 t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) | 245 (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) | 246 (R200_TXFORMAT_CUBIC_MAP_ENABLE)); 247 t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV; 248 t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) | 249 (log2Height << R200_FACE_HEIGHT_1_SHIFT) | 250 (log2Width << R200_FACE_WIDTH_2_SHIFT) | 251 (log2Height << R200_FACE_HEIGHT_2_SHIFT) | 252 (log2Width << R200_FACE_WIDTH_3_SHIFT) | 253 (log2Height << R200_FACE_HEIGHT_3_SHIFT) | 254 (log2Width << R200_FACE_WIDTH_4_SHIFT) | 255 (log2Height << R200_FACE_HEIGHT_4_SHIFT)); 256 } 257 258 t->pp_txsize = (((tObj->Image[t->base.firstLevel]->Width - 1) << 0) | 259 ((tObj->Image[t->base.firstLevel]->Height - 1) << 16)); 260 261 /* Only need to round to nearest 32 for textures, but the blitter 262 * requires 64-byte aligned pitches, and we may/may not need the 263 * blitter. NPOT only! 264 */ 265 if (baseImage->IsCompressed) 266 t->pp_txpitch = (tObj->Image[t->base.firstLevel]->Width + 63) & ~(63); 267 else 268 t->pp_txpitch = ((tObj->Image[t->base.firstLevel]->Width * baseImage->TexFormat->TexelBytes) + 63) & ~(63); 269 t->pp_txpitch -= 32; 270 271 t->dirty_state = TEX_ALL; 272 273 /* FYI: r200UploadTexImages( rmesa, t ) used to be called here */ 274} 275 276 277 278/* ================================================================ 279 * Texture combine functions 280 */ 281 282#define R200_DISABLE 0 283#define R200_REPLACE 1 284#define R200_MODULATE 2 285#define R200_DECAL 3 286#define R200_BLEND 4 287#define R200_ADD 5 288#define R200_MAX_COMBFUNC 6 289 290static GLuint r200_color_combine[][R200_MAX_COMBFUNC] = 291{ 292 /* Unit 0: 293 */ 294 { 295 /* Disable combiner stage 296 */ 297 (R200_TXC_ARG_A_ZERO | 298 R200_TXC_ARG_B_ZERO | 299 R200_TXC_ARG_C_DIFFUSE_COLOR | 300 R200_TXC_OP_MADD), 301 302 /* GL_REPLACE = 0x00802800 303 */ 304 (R200_TXC_ARG_A_ZERO | 305 R200_TXC_ARG_B_ZERO | 306 R200_TXC_ARG_C_R0_COLOR | 307 R200_TXC_OP_MADD), 308 309 /* GL_MODULATE = 0x00800142 310 */ 311 (R200_TXC_ARG_A_DIFFUSE_COLOR | /* current starts in DIFFUSE */ 312 R200_TXC_ARG_B_R0_COLOR | 313 R200_TXC_ARG_C_ZERO | 314 R200_TXC_OP_MADD), 315 316 /* GL_DECAL = 0x008c2d42 317 */ 318 (R200_TXC_ARG_A_DIFFUSE_COLOR | 319 R200_TXC_ARG_B_R0_COLOR | 320 R200_TXC_ARG_C_R0_ALPHA | 321 R200_TXC_OP_LERP), 322 323 /* GL_BLEND = 0x008c2902 324 */ 325 (R200_TXC_ARG_A_DIFFUSE_COLOR | 326 R200_TXC_ARG_B_TFACTOR_COLOR | 327 R200_TXC_ARG_C_R0_COLOR | 328 R200_TXC_OP_LERP), 329 330 /* GL_ADD = 0x00812802 331 */ 332 (R200_TXC_ARG_A_DIFFUSE_COLOR | 333 R200_TXC_ARG_B_ZERO | 334 R200_TXC_ARG_C_R0_COLOR | 335 R200_TXC_COMP_ARG_B | 336 R200_TXC_OP_MADD), 337 }, 338 339 /* Unit 1: 340 */ 341 { 342 /* Disable combiner stage 343 */ 344 (R200_TXC_ARG_A_ZERO | 345 R200_TXC_ARG_B_ZERO | 346 R200_TXC_ARG_C_R0_COLOR | 347 R200_TXC_OP_MADD), 348 349 /* GL_REPLACE = 0x00803000 350 */ 351 (R200_TXC_ARG_A_ZERO | 352 R200_TXC_ARG_B_ZERO | 353 R200_TXC_ARG_C_R1_COLOR | 354 R200_TXC_OP_MADD), 355 356 /* GL_MODULATE = 0x00800182 357 */ 358 (R200_TXC_ARG_A_R0_COLOR | /* current in R0 thereafter */ 359 R200_TXC_ARG_B_R1_COLOR | 360 R200_TXC_ARG_C_ZERO | 361 R200_TXC_OP_MADD), 362 363 /* GL_DECAL = 0x008c3582 364 */ 365 (R200_TXC_ARG_A_R0_COLOR | 366 R200_TXC_ARG_B_R1_COLOR | 367 R200_TXC_ARG_C_R1_ALPHA | 368 R200_TXC_OP_LERP), 369 370 /* GL_BLEND = 0x008c3102 371 */ 372 (R200_TXC_ARG_A_R0_COLOR | 373 R200_TXC_ARG_B_TFACTOR_COLOR | 374 R200_TXC_ARG_C_R1_COLOR | 375 R200_TXC_OP_LERP), 376 377 /* GL_ADD = 0x00813002 378 */ 379 (R200_TXC_ARG_A_R0_COLOR | 380 R200_TXC_ARG_B_ZERO | 381 R200_TXC_ARG_C_R1_COLOR | 382 R200_TXC_COMP_ARG_B | 383 R200_TXC_OP_MADD), 384 }, 385 386 /* Unit 2: 387 */ 388 { 389 /* Disable combiner stage 390 */ 391 (R200_TXC_ARG_A_ZERO | 392 R200_TXC_ARG_B_ZERO | 393 R200_TXC_ARG_C_R0_COLOR | 394 R200_TXC_OP_MADD), 395 396 /* GL_REPLACE = 0x00803800 397 */ 398 (R200_TXC_ARG_A_ZERO | 399 R200_TXC_ARG_B_ZERO | 400 R200_TXC_ARG_C_R2_COLOR | 401 R200_TXC_OP_MADD), 402 403 /* GL_MODULATE = 0x008001c2 404 */ 405 (R200_TXC_ARG_A_R0_COLOR | 406 R200_TXC_ARG_B_R2_COLOR | 407 R200_TXC_ARG_C_ZERO | 408 R200_TXC_OP_MADD), 409 410 /* GL_DECAL = 0x008c3dc2 411 */ 412 (R200_TXC_ARG_A_R0_COLOR | 413 R200_TXC_ARG_B_R2_COLOR | 414 R200_TXC_ARG_C_R2_ALPHA | 415 R200_TXC_OP_LERP), 416 417 /* GL_BLEND = 0x008c3902 418 */ 419 (R200_TXC_ARG_A_R0_COLOR | 420 R200_TXC_ARG_B_TFACTOR_COLOR | 421 R200_TXC_ARG_C_R2_COLOR | 422 R200_TXC_OP_LERP), 423 424 /* GL_ADD = 0x00813802 425 */ 426 (R200_TXC_ARG_A_R0_COLOR | 427 R200_TXC_ARG_B_ZERO | 428 R200_TXC_ARG_C_R2_COLOR | 429 R200_TXC_COMP_ARG_B | 430 R200_TXC_OP_MADD), 431 } 432}; 433 434static GLuint r200_alpha_combine[][R200_MAX_COMBFUNC] = 435{ 436 /* Unit 0: 437 */ 438 { 439 /* Disable combiner stage 440 */ 441 (R200_TXA_ARG_A_ZERO | 442 R200_TXA_ARG_B_ZERO | 443 R200_TXA_ARG_C_DIFFUSE_ALPHA | 444 R200_TXA_OP_MADD), 445 446 447 /* GL_REPLACE = 0x00800500 448 */ 449 (R200_TXA_ARG_A_ZERO | 450 R200_TXA_ARG_B_ZERO | 451 R200_TXA_ARG_C_R0_ALPHA | 452 R200_TXA_OP_MADD), 453 454 /* GL_MODULATE = 0x00800051 455 */ 456 (R200_TXA_ARG_A_DIFFUSE_ALPHA | 457 R200_TXA_ARG_B_R0_ALPHA | 458 R200_TXA_ARG_C_ZERO | 459 R200_TXA_OP_MADD), 460 461 /* GL_DECAL = 0x00800100 462 */ 463 (R200_TXA_ARG_A_ZERO | 464 R200_TXA_ARG_B_ZERO | 465 R200_TXA_ARG_C_DIFFUSE_ALPHA | 466 R200_TXA_OP_MADD), 467 468 /* GL_BLEND = 0x00800051 469 */ 470 (R200_TXA_ARG_A_DIFFUSE_ALPHA | 471 R200_TXA_ARG_B_TFACTOR_ALPHA | 472 R200_TXA_ARG_C_R0_ALPHA | 473 R200_TXA_OP_LERP), 474 475 /* GL_ADD = 0x00800051 476 */ 477 (R200_TXA_ARG_A_DIFFUSE_ALPHA | 478 R200_TXA_ARG_B_ZERO | 479 R200_TXA_ARG_C_R0_ALPHA | 480 R200_TXA_COMP_ARG_B | 481 R200_TXA_OP_MADD), 482 }, 483 484 /* Unit 1: 485 */ 486 { 487 /* Disable combiner stage 488 */ 489 (R200_TXA_ARG_A_ZERO | 490 R200_TXA_ARG_B_ZERO | 491 R200_TXA_ARG_C_R0_ALPHA | 492 R200_TXA_OP_MADD), 493 494 /* GL_REPLACE = 0x00800600 495 */ 496 (R200_TXA_ARG_A_ZERO | 497 R200_TXA_ARG_B_ZERO | 498 R200_TXA_ARG_C_R1_ALPHA | 499 R200_TXA_OP_MADD), 500 501 /* GL_MODULATE = 0x00800061 502 */ 503 (R200_TXA_ARG_A_R0_ALPHA | 504 R200_TXA_ARG_B_R1_ALPHA | 505 R200_TXA_ARG_C_ZERO | 506 R200_TXA_OP_MADD), 507 508 /* GL_DECAL = 0x00800100 509 */ 510 (R200_TXA_ARG_A_ZERO | 511 R200_TXA_ARG_B_ZERO | 512 R200_TXA_ARG_C_R0_ALPHA | 513 R200_TXA_OP_MADD), 514 515 /* GL_BLEND = 0x00800061 516 */ 517 (R200_TXA_ARG_A_R0_ALPHA | 518 R200_TXA_ARG_B_TFACTOR_ALPHA | 519 R200_TXA_ARG_C_R1_ALPHA | 520 R200_TXA_OP_LERP), 521 522 /* GL_ADD = 0x00800061 523 */ 524 (R200_TXA_ARG_A_R0_ALPHA | 525 R200_TXA_ARG_B_ZERO | 526 R200_TXA_ARG_C_R1_ALPHA | 527 R200_TXA_COMP_ARG_B | 528 R200_TXA_OP_MADD), 529 }, 530 531 /* Unit 2: 532 */ 533 { 534 /* Disable combiner stage 535 */ 536 (R200_TXA_ARG_A_ZERO | 537 R200_TXA_ARG_B_ZERO | 538 R200_TXA_ARG_C_R0_ALPHA | 539 R200_TXA_OP_MADD), 540 541 /* GL_REPLACE = 0x00800700 542 */ 543 (R200_TXA_ARG_A_ZERO | 544 R200_TXA_ARG_B_ZERO | 545 R200_TXA_ARG_C_R2_ALPHA | 546 R200_TXA_OP_MADD), 547 548 /* GL_MODULATE = 0x00800071 549 */ 550 (R200_TXA_ARG_A_R0_ALPHA | 551 R200_TXA_ARG_B_R2_ALPHA | 552 R200_TXA_ARG_C_ZERO | 553 R200_TXA_OP_MADD), 554 555 /* GL_DECAL = 0x00800100 556 */ 557 (R200_TXA_ARG_A_ZERO | 558 R200_TXA_ARG_B_ZERO | 559 R200_TXA_ARG_C_R0_ALPHA | 560 R200_TXA_OP_MADD), 561 562 /* GL_BLEND = 0x00800071 563 */ 564 (R200_TXA_ARG_A_R0_ALPHA | 565 R200_TXA_ARG_B_TFACTOR_ALPHA | 566 R200_TXA_ARG_C_R2_ALPHA | 567 R200_TXA_OP_LERP), 568 569 /* GL_ADD = 0x00800021 570 */ 571 (R200_TXA_ARG_A_R0_ALPHA | 572 R200_TXA_ARG_B_ZERO | 573 R200_TXA_ARG_C_R2_ALPHA | 574 R200_TXA_COMP_ARG_B | 575 R200_TXA_OP_MADD), 576 } 577}; 578 579 580/* GL_ARB_texture_env_combine support 581 */ 582 583/* The color tables have combine functions for GL_SRC_COLOR, 584 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. 585 */ 586static GLuint r200_register_color[][R200_MAX_TEXTURE_UNITS] = 587{ 588 { 589 R200_TXC_ARG_A_R0_COLOR, 590 R200_TXC_ARG_A_R1_COLOR, 591 R200_TXC_ARG_A_R2_COLOR 592 }, 593 { 594 R200_TXC_ARG_A_R0_COLOR | R200_TXC_COMP_ARG_A, 595 R200_TXC_ARG_A_R1_COLOR | R200_TXC_COMP_ARG_A, 596 R200_TXC_ARG_A_R2_COLOR | R200_TXC_COMP_ARG_A 597 }, 598 { 599 R200_TXC_ARG_A_R0_ALPHA, 600 R200_TXC_ARG_A_R1_ALPHA, 601 R200_TXC_ARG_A_R2_ALPHA 602 }, 603 { 604 R200_TXC_ARG_A_R0_ALPHA | R200_TXC_COMP_ARG_A, 605 R200_TXC_ARG_A_R1_ALPHA | R200_TXC_COMP_ARG_A, 606 R200_TXC_ARG_A_R2_ALPHA | R200_TXC_COMP_ARG_A 607 }, 608}; 609 610static GLuint r200_tfactor_color[] = 611{ 612 R200_TXC_ARG_A_TFACTOR_COLOR, 613 R200_TXC_ARG_A_TFACTOR_COLOR | R200_TXC_COMP_ARG_A, 614 R200_TXC_ARG_A_TFACTOR_ALPHA, 615 R200_TXC_ARG_A_TFACTOR_ALPHA | R200_TXC_COMP_ARG_A 616}; 617 618static GLuint r200_primary_color[] = 619{ 620 R200_TXC_ARG_A_DIFFUSE_COLOR, 621 R200_TXC_ARG_A_DIFFUSE_COLOR | R200_TXC_COMP_ARG_A, 622 R200_TXC_ARG_A_DIFFUSE_ALPHA, 623 R200_TXC_ARG_A_DIFFUSE_ALPHA | R200_TXC_COMP_ARG_A 624}; 625 626/* GL_ZERO table - indices 0-3 627 * GL_ONE table - indices 1-4 628 */ 629static GLuint r200_zero_color[] = 630{ 631 R200_TXC_ARG_A_ZERO, 632 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A, 633 R200_TXC_ARG_A_ZERO, 634 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A, 635 R200_TXC_ARG_A_ZERO 636}; 637 638/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. 639 */ 640static GLuint r200_register_alpha[][R200_MAX_TEXTURE_UNITS] = 641{ 642 { 643 R200_TXA_ARG_A_R0_ALPHA, 644 R200_TXA_ARG_A_R1_ALPHA, 645 R200_TXA_ARG_A_R2_ALPHA 646 }, 647 { 648 R200_TXA_ARG_A_R0_ALPHA | R200_TXA_COMP_ARG_A, 649 R200_TXA_ARG_A_R1_ALPHA | R200_TXA_COMP_ARG_A, 650 R200_TXA_ARG_A_R2_ALPHA | R200_TXA_COMP_ARG_A 651 }, 652}; 653 654static GLuint r200_tfactor_alpha[] = 655{ 656 R200_TXA_ARG_A_TFACTOR_ALPHA, 657 R200_TXA_ARG_A_TFACTOR_ALPHA | R200_TXA_COMP_ARG_A 658}; 659 660static GLuint r200_primary_alpha[] = 661{ 662 R200_TXA_ARG_A_DIFFUSE_ALPHA, 663 R200_TXA_ARG_A_DIFFUSE_ALPHA | R200_TXA_COMP_ARG_A 664}; 665 666/* GL_ZERO table - indices 0-1 667 * GL_ONE table - indices 1-2 668 */ 669static GLuint r200_zero_alpha[] = 670{ 671 R200_TXA_ARG_A_ZERO, 672 R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A, 673 R200_TXA_ARG_A_ZERO, 674}; 675 676 677/* Extract the arg from slot A, shift it into the correct argument slot 678 * and set the corresponding complement bit. 679 */ 680#define R200_COLOR_ARG( n, arg ) \ 681do { \ 682 color_combine |= \ 683 ((color_arg[n] & R200_TXC_ARG_A_MASK) \ 684 << R200_TXC_ARG_##arg##_SHIFT); \ 685 color_combine |= \ 686 ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \ 687 << R200_TXC_COMP_ARG_##arg##_SHIFT); \ 688} while (0) 689 690#define R200_ALPHA_ARG( n, arg ) \ 691do { \ 692 alpha_combine |= \ 693 ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \ 694 << R200_TXA_ARG_##arg##_SHIFT); \ 695 alpha_combine |= \ 696 ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \ 697 << R200_TXA_COMP_ARG_##arg##_SHIFT); \ 698} while (0) 699 700 701/* ================================================================ 702 * Texture unit state management 703 */ 704 705static GLboolean r200UpdateTextureEnv( GLcontext *ctx, int unit ) 706{ 707 r200ContextPtr rmesa = R200_CONTEXT(ctx); 708 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 709 GLuint color_combine, alpha_combine; 710 GLuint color_scale = rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2]; 711 GLuint alpha_scale = rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2]; 712 713 /* texUnit->_Current can be NULL if and only if the texture unit is 714 * not actually enabled. 715 */ 716 assert( (texUnit->_ReallyEnabled == 0) 717 || (texUnit->_Current != NULL) ); 718 719 if ( R200_DEBUG & DEBUG_TEXTURE ) { 720 fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, ctx, unit ); 721 } 722 723 /* Set the texture environment state. Isn't this nice and clean? 724 * The chip will automagically set the texture alpha to 0xff when 725 * the texture format does not include an alpha component. This 726 * reduces the amount of special-casing we have to do, alpha-only 727 * textures being a notable exception. 728 */ 729 if ( !texUnit->_ReallyEnabled ) { 730 /* Don't cache these results. 731 */ 732 rmesa->state.texture.unit[unit].format = 0; 733 rmesa->state.texture.unit[unit].envMode = 0; 734 color_combine = r200_color_combine[unit][R200_DISABLE]; 735 alpha_combine = r200_alpha_combine[unit][R200_DISABLE]; 736 } 737 else { 738 const struct gl_texture_object *tObj = texUnit->_Current; 739 const GLenum format = tObj->Image[tObj->BaseLevel]->Format; 740 GLuint color_arg[3], alpha_arg[3]; 741 GLuint i, numColorArgs = 0, numAlphaArgs = 0; 742 GLuint RGBshift = texUnit->CombineScaleShiftRGB; 743 GLuint Ashift = texUnit->CombineScaleShiftA; 744 745 switch ( texUnit->EnvMode ) { 746 case GL_REPLACE: 747 switch ( format ) { 748 case GL_RGBA: 749 case GL_LUMINANCE_ALPHA: 750 case GL_INTENSITY: 751 color_combine = r200_color_combine[unit][R200_REPLACE]; 752 alpha_combine = r200_alpha_combine[unit][R200_REPLACE]; 753 break; 754 case GL_ALPHA: 755 color_combine = r200_color_combine[unit][R200_DISABLE]; 756 alpha_combine = r200_alpha_combine[unit][R200_REPLACE]; 757 break; 758 case GL_LUMINANCE: 759 case GL_RGB: 760 case GL_YCBCR_MESA: 761 color_combine = r200_color_combine[unit][R200_REPLACE]; 762 alpha_combine = r200_alpha_combine[unit][R200_DISABLE]; 763 break; 764 case GL_COLOR_INDEX: 765 default: 766 return GL_FALSE; 767 } 768 break; 769 770 case GL_MODULATE: 771 switch ( format ) { 772 case GL_RGBA: 773 case GL_LUMINANCE_ALPHA: 774 case GL_INTENSITY: 775 color_combine = r200_color_combine[unit][R200_MODULATE]; 776 alpha_combine = r200_alpha_combine[unit][R200_MODULATE]; 777 break; 778 case GL_ALPHA: 779 color_combine = r200_color_combine[unit][R200_DISABLE]; 780 alpha_combine = r200_alpha_combine[unit][R200_MODULATE]; 781 break; 782 case GL_RGB: 783 case GL_LUMINANCE: 784 case GL_YCBCR_MESA: 785 color_combine = r200_color_combine[unit][R200_MODULATE]; 786 alpha_combine = r200_alpha_combine[unit][R200_DISABLE]; 787 break; 788 case GL_COLOR_INDEX: 789 default: 790 return GL_FALSE; 791 } 792 break; 793 794 case GL_DECAL: 795 switch ( format ) { 796 case GL_RGBA: 797 case GL_RGB: 798 case GL_YCBCR_MESA: 799 color_combine = r200_color_combine[unit][R200_DECAL]; 800 alpha_combine = r200_alpha_combine[unit][R200_DISABLE]; 801 break; 802 case GL_ALPHA: 803 case GL_LUMINANCE: 804 case GL_LUMINANCE_ALPHA: 805 case GL_INTENSITY: 806 color_combine = r200_color_combine[unit][R200_DISABLE]; 807 alpha_combine = r200_alpha_combine[unit][R200_DISABLE]; 808 break; 809 case GL_COLOR_INDEX: 810 default: 811 return GL_FALSE; 812 } 813 break; 814 815 case GL_BLEND: 816 switch ( format ) { 817 case GL_RGBA: 818 case GL_RGB: 819 case GL_LUMINANCE: 820 case GL_LUMINANCE_ALPHA: 821 case GL_YCBCR_MESA: 822 color_combine = r200_color_combine[unit][R200_BLEND]; 823 alpha_combine = r200_alpha_combine[unit][R200_MODULATE]; 824 break; 825 case GL_ALPHA: 826 color_combine = r200_color_combine[unit][R200_DISABLE]; 827 alpha_combine = r200_alpha_combine[unit][R200_MODULATE]; 828 break; 829 case GL_INTENSITY: 830 color_combine = r200_color_combine[unit][R200_BLEND]; 831 alpha_combine = r200_alpha_combine[unit][R200_BLEND]; 832 break; 833 case GL_COLOR_INDEX: 834 default: 835 return GL_FALSE; 836 } 837 break; 838 839 case GL_ADD: 840 switch ( format ) { 841 case GL_RGBA: 842 case GL_RGB: 843 case GL_LUMINANCE: 844 case GL_LUMINANCE_ALPHA: 845 case GL_YCBCR_MESA: 846 color_combine = r200_color_combine[unit][R200_ADD]; 847 alpha_combine = r200_alpha_combine[unit][R200_MODULATE]; 848 break; 849 case GL_ALPHA: 850 color_combine = r200_color_combine[unit][R200_DISABLE]; 851 alpha_combine = r200_alpha_combine[unit][R200_MODULATE]; 852 break; 853 case GL_INTENSITY: 854 color_combine = r200_color_combine[unit][R200_ADD]; 855 alpha_combine = r200_alpha_combine[unit][R200_ADD]; 856 break; 857 case GL_COLOR_INDEX: 858 default: 859 return GL_FALSE; 860 } 861 break; 862 863 case GL_COMBINE: 864 /* Don't cache these results. 865 */ 866 rmesa->state.texture.unit[unit].format = 0; 867 rmesa->state.texture.unit[unit].envMode = 0; 868 869 /* Step 0: 870 * Calculate how many arguments we need to process. 871 */ 872 switch ( texUnit->CombineModeRGB ) { 873 case GL_REPLACE: 874 numColorArgs = 1; 875 break; 876 case GL_MODULATE: 877 case GL_ADD: 878 case GL_ADD_SIGNED: 879 case GL_SUBTRACT: 880 case GL_DOT3_RGB: 881 case GL_DOT3_RGBA: 882 case GL_DOT3_RGB_EXT: 883 case GL_DOT3_RGBA_EXT: 884 numColorArgs = 2; 885 break; 886 case GL_INTERPOLATE: 887 case GL_MODULATE_ADD_ATI: 888 case GL_MODULATE_SIGNED_ADD_ATI: 889 case GL_MODULATE_SUBTRACT_ATI: 890 numColorArgs = 3; 891 break; 892 default: 893 return GL_FALSE; 894 } 895 896 switch ( texUnit->CombineModeA ) { 897 case GL_REPLACE: 898 numAlphaArgs = 1; 899 break; 900 case GL_MODULATE: 901 case GL_ADD: 902 case GL_ADD_SIGNED: 903 case GL_SUBTRACT: 904 numAlphaArgs = 2; 905 break; 906 case GL_INTERPOLATE: 907 case GL_MODULATE_ADD_ATI: 908 case GL_MODULATE_SIGNED_ADD_ATI: 909 case GL_MODULATE_SUBTRACT_ATI: 910 numAlphaArgs = 3; 911 break; 912 default: 913 return GL_FALSE; 914 } 915 916 /* Step 1: 917 * Extract the color and alpha combine function arguments. 918 */ 919 for ( i = 0 ; i < numColorArgs ; i++ ) { 920 const GLuint op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR; 921 assert(op >= 0); 922 assert(op <= 3); 923 switch ( texUnit->CombineSourceRGB[i] ) { 924 case GL_TEXTURE: 925 color_arg[i] = r200_register_color[op][unit]; 926 break; 927 case GL_CONSTANT: 928 color_arg[i] = r200_tfactor_color[op]; 929 break; 930 case GL_PRIMARY_COLOR: 931 color_arg[i] = r200_primary_color[op]; 932 break; 933 case GL_PREVIOUS: 934 if (unit == 0) 935 color_arg[i] = r200_primary_color[op]; 936 else 937 color_arg[i] = r200_register_color[op][0]; 938 break; 939 case GL_ZERO: 940 color_arg[i] = r200_zero_color[op]; 941 break; 942 case GL_ONE: 943 color_arg[i] = r200_zero_color[op+1]; 944 break; 945 default: 946 return GL_FALSE; 947 } 948 } 949 950 for ( i = 0 ; i < numAlphaArgs ; i++ ) { 951 const GLuint op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA; 952 assert(op >= 0); 953 assert(op <= 1); 954 switch ( texUnit->CombineSourceA[i] ) { 955 case GL_TEXTURE: 956 alpha_arg[i] = r200_register_alpha[op][unit]; 957 break; 958 case GL_CONSTANT: 959 alpha_arg[i] = r200_tfactor_alpha[op]; 960 break; 961 case GL_PRIMARY_COLOR: 962 alpha_arg[i] = r200_primary_alpha[op]; 963 break; 964 case GL_PREVIOUS: 965 if (unit == 0) 966 alpha_arg[i] = r200_primary_alpha[op]; 967 else 968 alpha_arg[i] = r200_register_alpha[op][0]; 969 break; 970 case GL_ZERO: 971 alpha_arg[i] = r200_zero_alpha[op]; 972 break; 973 case GL_ONE: 974 alpha_arg[i] = r200_zero_alpha[op+1]; 975 break; 976 default: 977 return GL_FALSE; 978 } 979 } 980 981 /* Step 2: 982 * Build up the color and alpha combine functions. 983 */ 984 switch ( texUnit->CombineModeRGB ) { 985 case GL_REPLACE: 986 color_combine = (R200_TXC_ARG_A_ZERO | 987 R200_TXC_ARG_B_ZERO | 988 R200_TXC_OP_MADD); 989 R200_COLOR_ARG( 0, C ); 990 break; 991 case GL_MODULATE: 992 color_combine = (R200_TXC_ARG_C_ZERO | 993 R200_TXC_OP_MADD); 994 R200_COLOR_ARG( 0, A ); 995 R200_COLOR_ARG( 1, B ); 996 break; 997 case GL_ADD: 998 color_combine = (R200_TXC_ARG_B_ZERO | 999 R200_TXC_COMP_ARG_B | 1000 R200_TXC_OP_MADD); 1001 R200_COLOR_ARG( 0, A ); 1002 R200_COLOR_ARG( 1, C ); 1003 break; 1004 case GL_ADD_SIGNED: 1005 color_combine = (R200_TXC_ARG_B_ZERO | 1006 R200_TXC_COMP_ARG_B | 1007 R200_TXC_BIAS_ARG_C | /* new */ 1008 R200_TXC_OP_MADD); /* was ADDSIGNED */ 1009 R200_COLOR_ARG( 0, A ); 1010 R200_COLOR_ARG( 1, C ); 1011 break; 1012 case GL_SUBTRACT: 1013 color_combine = (R200_TXC_ARG_B_ZERO | 1014 R200_TXC_COMP_ARG_B | 1015 R200_TXC_NEG_ARG_C | 1016 R200_TXC_OP_MADD); 1017 R200_COLOR_ARG( 0, A ); 1018 R200_COLOR_ARG( 1, C ); 1019 break; 1020 case GL_INTERPOLATE: 1021 color_combine = (R200_TXC_OP_LERP); 1022 R200_COLOR_ARG( 0, B ); 1023 R200_COLOR_ARG( 1, A ); 1024 R200_COLOR_ARG( 2, C ); 1025 break; 1026 1027 case GL_DOT3_RGB_EXT: 1028 case GL_DOT3_RGBA_EXT: 1029 /* The EXT version of the DOT3 extension does not support the 1030 * scale factor, but the ARB version (and the version in OpenGL 1031 * 1.3) does. 1032 */ 1033 RGBshift = 0; 1034 Ashift = 0; 1035 /* FALLTHROUGH */ 1036 1037 case GL_DOT3_RGB: 1038 case GL_DOT3_RGBA: 1039 /* DOT3 works differently on R200 than on R100. On R100, just 1040 * setting the DOT3 mode did everything for you. On R200, the 1041 * driver has to enable the biasing (the -0.5 in the combine 1042 * equation), and it has add the 4x scale factor. The hardware 1043 * only supports up to 8x in the post filter, so 2x part of it 1044 * happens on the inputs going into the combiner. 1045 */ 1046 1047 RGBshift++; 1048 Ashift = RGBshift; 1049 1050 color_combine = (R200_TXC_ARG_C_ZERO | 1051 R200_TXC_OP_DOT3 | 1052 R200_TXC_BIAS_ARG_A | 1053 R200_TXC_BIAS_ARG_B | 1054 R200_TXC_SCALE_ARG_A | 1055 R200_TXC_SCALE_ARG_B); 1056 R200_COLOR_ARG( 0, A ); 1057 R200_COLOR_ARG( 1, B ); 1058 break; 1059 1060 case GL_MODULATE_ADD_ATI: 1061 color_combine = (R200_TXC_OP_MADD); 1062 R200_COLOR_ARG( 0, A ); 1063 R200_COLOR_ARG( 1, C ); 1064 R200_COLOR_ARG( 2, B ); 1065 break; 1066 case GL_MODULATE_SIGNED_ADD_ATI: 1067 color_combine = (R200_TXC_BIAS_ARG_C | /* new */ 1068 R200_TXC_OP_MADD); /* was ADDSIGNED */ 1069 R200_COLOR_ARG( 0, A ); 1070 R200_COLOR_ARG( 1, C ); 1071 R200_COLOR_ARG( 2, B ); 1072 break; 1073 case GL_MODULATE_SUBTRACT_ATI: 1074 color_combine = (R200_TXC_NEG_ARG_C | 1075 R200_TXC_OP_MADD); 1076 R200_COLOR_ARG( 0, A ); 1077 R200_COLOR_ARG( 1, C ); 1078 R200_COLOR_ARG( 2, B ); 1079 break; 1080 default: 1081 return GL_FALSE; 1082 } 1083 1084 switch ( texUnit->CombineModeA ) { 1085 case GL_REPLACE: 1086 alpha_combine = (R200_TXA_ARG_A_ZERO | 1087 R200_TXA_ARG_B_ZERO | 1088 R200_TXA_OP_MADD); 1089 R200_ALPHA_ARG( 0, C ); 1090 break; 1091 case GL_MODULATE: 1092 alpha_combine = (R200_TXA_ARG_C_ZERO | 1093 R200_TXA_OP_MADD); 1094 R200_ALPHA_ARG( 0, A ); 1095 R200_ALPHA_ARG( 1, B ); 1096 break; 1097 case GL_ADD: 1098 alpha_combine = (R200_TXA_ARG_B_ZERO | 1099 R200_TXA_COMP_ARG_B | 1100 R200_TXA_OP_MADD); 1101 R200_ALPHA_ARG( 0, A ); 1102 R200_ALPHA_ARG( 1, C ); 1103 break; 1104 case GL_ADD_SIGNED: 1105 alpha_combine = (R200_TXA_ARG_B_ZERO | 1106 R200_TXA_COMP_ARG_B | 1107 R200_TXA_BIAS_ARG_C | /* new */ 1108 R200_TXA_OP_MADD); /* was ADDSIGNED */ 1109 R200_ALPHA_ARG( 0, A ); 1110 R200_ALPHA_ARG( 1, C ); 1111 break; 1112 case GL_SUBTRACT: 1113 alpha_combine = (R200_TXA_ARG_B_ZERO | 1114 R200_TXA_COMP_ARG_B | 1115 R200_TXA_NEG_ARG_C | 1116 R200_TXA_OP_MADD); 1117 R200_ALPHA_ARG( 0, A ); 1118 R200_ALPHA_ARG( 1, C ); 1119 break; 1120 case GL_INTERPOLATE: 1121 alpha_combine = (R200_TXA_OP_LERP); 1122 R200_ALPHA_ARG( 0, B ); 1123 R200_ALPHA_ARG( 1, A ); 1124 R200_ALPHA_ARG( 2, C ); 1125 break; 1126 1127 case GL_MODULATE_ADD_ATI: 1128 alpha_combine = (R200_TXA_OP_MADD); 1129 R200_ALPHA_ARG( 0, A ); 1130 R200_ALPHA_ARG( 1, C ); 1131 R200_ALPHA_ARG( 2, B ); 1132 break; 1133 case GL_MODULATE_SIGNED_ADD_ATI: 1134 alpha_combine = (R200_TXA_BIAS_ARG_C | /* new */ 1135 R200_TXA_OP_MADD); /* was ADDSIGNED */ 1136 R200_ALPHA_ARG( 0, A ); 1137 R200_ALPHA_ARG( 1, C ); 1138 R200_ALPHA_ARG( 2, B ); 1139 break; 1140 case GL_MODULATE_SUBTRACT_ATI: 1141 alpha_combine = (R200_TXA_NEG_ARG_C | 1142 R200_TXA_OP_MADD); 1143 R200_ALPHA_ARG( 0, A ); 1144 R200_ALPHA_ARG( 1, C ); 1145 R200_ALPHA_ARG( 2, B ); 1146 break; 1147 default: 1148 return GL_FALSE; 1149 } 1150 1151 if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT) 1152 || (texUnit->CombineModeRGB == GL_DOT3_RGB) ) { 1153 alpha_scale |= R200_TXA_DOT_ALPHA; 1154 } 1155 1156 /* Step 3: 1157 * Apply the scale factor. 1158 */ 1159 color_scale &= ~R200_TXC_SCALE_MASK; 1160 alpha_scale &= ~R200_TXA_SCALE_MASK; 1161 color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT); 1162 alpha_scale |= (Ashift << R200_TXA_SCALE_SHIFT); 1163 1164 /* All done! 1165 */ 1166 break; 1167 1168 default: 1169 return GL_FALSE; 1170 } 1171 } 1172 1173 if ( rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] != color_combine || 1174 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND] != alpha_combine || 1175 rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] != color_scale || 1176 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] != alpha_scale) { 1177 R200_STATECHANGE( rmesa, pix[unit] ); 1178 rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] = color_combine; 1179 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND] = alpha_combine; 1180 rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] = color_scale; 1181 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] = alpha_scale; 1182 } 1183 1184 return GL_TRUE; 1185} 1186 1187#define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \ 1188 R200_MIN_FILTER_MASK | \ 1189 R200_MAG_FILTER_MASK | \ 1190 R200_MAX_ANISO_MASK | \ 1191 R200_YUV_TO_RGB | \ 1192 R200_YUV_TEMPERATURE_MASK | \ 1193 R200_CLAMP_S_MASK | \ 1194 R200_CLAMP_T_MASK | \ 1195 R200_BORDER_MODE_D3D ) 1196 1197#define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \ 1198 R200_TXFORMAT_HEIGHT_MASK | \ 1199 R200_TXFORMAT_FORMAT_MASK | \ 1200 R200_TXFORMAT_F5_WIDTH_MASK | \ 1201 R200_TXFORMAT_F5_HEIGHT_MASK | \ 1202 R200_TXFORMAT_ALPHA_IN_MAP | \ 1203 R200_TXFORMAT_CUBIC_MAP_ENABLE | \ 1204 R200_TXFORMAT_NON_POWER2) 1205 1206#define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \ 1207 R200_TEXCOORD_MASK | \ 1208 R200_VOLUME_FILTER_MASK) 1209 1210 1211static void import_tex_obj_state( r200ContextPtr rmesa, 1212 int unit, 1213 r200TexObjPtr texobj ) 1214{ 1215 GLuint *cmd = R200_DB_STATE( tex[unit] ); 1216 1217 cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK; 1218 cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK; 1219 cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; 1220 cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK; 1221 cmd[TEX_PP_TXFORMAT_X] &= ~TEXOBJ_TXFORMAT_X_MASK; 1222 cmd[TEX_PP_TXFORMAT_X] |= texobj->pp_txformat_x & TEXOBJ_TXFORMAT_X_MASK; 1223 cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */ 1224 cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */ 1225 cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset; 1226 cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color; 1227 R200_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] ); 1228 1229 if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) { 1230 GLuint *cube_cmd = R200_DB_STATE( cube[unit] ); 1231 GLuint bytesPerFace = texobj->base.totalSize / 6; 1232 ASSERT(texobj->totalSize % 6 == 0); 1233 cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces; 1234 cube_cmd[CUBE_PP_CUBIC_OFFSET_F1] = texobj->pp_txoffset + 1 * bytesPerFace; 1235 cube_cmd[CUBE_PP_CUBIC_OFFSET_F2] = texobj->pp_txoffset + 2 * bytesPerFace; 1236 cube_cmd[CUBE_PP_CUBIC_OFFSET_F3] = texobj->pp_txoffset + 3 * bytesPerFace; 1237 cube_cmd[CUBE_PP_CUBIC_OFFSET_F4] = texobj->pp_txoffset + 4 * bytesPerFace; 1238 cube_cmd[CUBE_PP_CUBIC_OFFSET_F5] = texobj->pp_txoffset + 5 * bytesPerFace; 1239 R200_DB_STATECHANGE( rmesa, &rmesa->hw.cube[unit] ); 1240 } 1241 1242 texobj->dirty_state &= ~(1<<unit); 1243} 1244 1245 1246 1247 1248static void set_texgen_matrix( r200ContextPtr rmesa, 1249 GLuint unit, 1250 const GLfloat *s_plane, 1251 const GLfloat *t_plane, 1252 const GLfloat *r_plane ) 1253{ 1254 static const GLfloat scale_identity[4] = { 1,1,1,1 }; 1255 1256 if (!TEST_EQ_4V( s_plane, scale_identity) || 1257 !TEST_EQ_4V( t_plane, scale_identity) || 1258 !TEST_EQ_4V( r_plane, scale_identity)) { 1259 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit; 1260 rmesa->TexGenMatrix[unit].m[0] = s_plane[0]; 1261 rmesa->TexGenMatrix[unit].m[4] = s_plane[1]; 1262 rmesa->TexGenMatrix[unit].m[8] = s_plane[2]; 1263 rmesa->TexGenMatrix[unit].m[12] = s_plane[3]; 1264 1265 rmesa->TexGenMatrix[unit].m[1] = t_plane[0]; 1266 rmesa->TexGenMatrix[unit].m[5] = t_plane[1]; 1267 rmesa->TexGenMatrix[unit].m[9] = t_plane[2]; 1268 rmesa->TexGenMatrix[unit].m[13] = t_plane[3]; 1269 1270 /* NOTE: r_plane goes in the 4th row, not 3rd! */ 1271 rmesa->TexGenMatrix[unit].m[3] = r_plane[0]; 1272 rmesa->TexGenMatrix[unit].m[7] = r_plane[1]; 1273 rmesa->TexGenMatrix[unit].m[11] = r_plane[2]; 1274 rmesa->TexGenMatrix[unit].m[15] = r_plane[3]; 1275 1276 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; 1277 } 1278} 1279 1280/* Need this special matrix to get correct reflection map coords */ 1281static void 1282set_texgen_reflection_matrix( r200ContextPtr rmesa, GLuint unit ) 1283{ 1284 static const GLfloat m[16] = { 1285 -1, 0, 0, 0, 1286 0, -1, 0, 0, 1287 0, 0, 0, -1, 1288 0, 0, -1, 0 }; 1289 _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m); 1290 _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) ); 1291 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit; 1292} 1293 1294/* Need this special matrix to get correct normal map coords */ 1295static void 1296set_texgen_normal_map_matrix( r200ContextPtr rmesa, GLuint unit ) 1297{ 1298 static const GLfloat m[16] = { 1299 1, 0, 0, 0, 1300 0, 1, 0, 0, 1301 0, 0, 0, 1, 1302 0, 0, 1, 0 }; 1303 _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m); 1304 _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) ); 1305 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit; 1306} 1307 1308 1309/* Ignoring the Q texcoord for now. 1310 * 1311 * Returns GL_FALSE if fallback required. 1312 */ 1313static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit ) 1314{ 1315 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1316 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1317 GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4; 1318 GLuint tmp = rmesa->TexGenEnabled; 1319 1320 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit); 1321 rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit); 1322 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit); 1323 rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift); 1324 rmesa->TexGenNeedNormals[unit] = 0; 1325 1326 if (0) 1327 fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit); 1328 1329 if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT)) == 0) { 1330 /* Disabled, no fallback: 1331 */ 1332 rmesa->TexGenInputs |= 1333 (R200_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; 1334 return GL_TRUE; 1335 } 1336 else if (texUnit->TexGenEnabled & Q_BIT) { 1337 /* Very easy to do this, in fact would remove a fallback case 1338 * elsewhere, but I haven't done it yet... Fallback: 1339 */ 1340 /*fprintf(stderr, "fallback Q_BIT\n");*/ 1341 return GL_FALSE; 1342 } 1343 else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) && 1344 texUnit->GenModeS == texUnit->GenModeT) { 1345 /* OK */ 1346 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit; 1347 /* continue */ 1348 } 1349 else if (texUnit->TexGenEnabled == (S_BIT|T_BIT|R_BIT) && 1350 texUnit->GenModeS == texUnit->GenModeT && 1351 texUnit->GenModeT == texUnit->GenModeR) { 1352 /* OK */ 1353 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit; 1354 /* continue */ 1355 } 1356 else { 1357 /* Mixed modes, fallback: 1358 */ 1359 /* fprintf(stderr, "fallback mixed texgen\n"); */ 1360 return GL_FALSE; 1361 } 1362 1363 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit; 1364 1365 switch (texUnit->GenModeS) { 1366 case GL_OBJECT_LINEAR: 1367 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_OBJ << inputshift; 1368 set_texgen_matrix( rmesa, unit, 1369 texUnit->ObjectPlaneS, 1370 texUnit->ObjectPlaneT, 1371 texUnit->ObjectPlaneR); 1372 break; 1373 1374 case GL_EYE_LINEAR: 1375 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE << inputshift; 1376 set_texgen_matrix( rmesa, unit, 1377 texUnit->EyePlaneS, 1378 texUnit->EyePlaneT, 1379 texUnit->EyePlaneR); 1380 break; 1381 1382 case GL_REFLECTION_MAP_NV: 1383 rmesa->TexGenNeedNormals[unit] = GL_TRUE; 1384 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE_REFLECT<<inputshift; 1385 set_texgen_reflection_matrix(rmesa, unit); 1386 break; 1387 1388 case GL_NORMAL_MAP_NV: 1389 rmesa->TexGenNeedNormals[unit] = GL_TRUE; 1390 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift; 1391 set_texgen_normal_map_matrix(rmesa, unit); 1392 break; 1393 1394 case GL_SPHERE_MAP: 1395 rmesa->TexGenNeedNormals[unit] = GL_TRUE; 1396 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_SPHERE<<inputshift; 1397 break; 1398 1399 default: 1400 /* Unsupported mode, fallback: 1401 */ 1402 /* fprintf(stderr, "fallback unsupported texgen\n"); */ 1403 return GL_FALSE; 1404 } 1405 1406 rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit; 1407 1408 if (tmp != rmesa->TexGenEnabled) { 1409 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; 1410 } 1411 1412 return GL_TRUE; 1413} 1414 1415 1416static void disable_tex( GLcontext *ctx, int unit ) 1417{ 1418 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1419 1420 if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit)) { 1421 /* Texture unit disabled */ 1422 if ( rmesa->state.texture.unit[unit].texobj != NULL ) { 1423 /* The old texture is no longer bound to this texture unit. 1424 * Mark it as such. 1425 */ 1426 1427 rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit); 1428 rmesa->state.texture.unit[unit].texobj = NULL; 1429 } 1430 1431 R200_STATECHANGE( rmesa, ctx ); 1432 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((R200_TEX_0_ENABLE | 1433 R200_TEX_BLEND_0_ENABLE) << unit); 1434 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_BLEND_0_ENABLE; 1435 1436 R200_STATECHANGE( rmesa, tcl ); 1437 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3)); 1438 1439 if (rmesa->TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) { 1440 TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE); 1441 } 1442 1443 /* Actually want to keep all units less than max active texture 1444 * enabled, right? Fix this for >2 texunits. 1445 */ 1446 /* FIXME: What should happen here if r200UpdateTextureEnv fails? */ 1447 if (unit == 0) 1448 r200UpdateTextureEnv( ctx, unit ); 1449 1450 1451 { 1452 GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4; 1453 GLuint tmp = rmesa->TexGenEnabled; 1454 1455 rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit); 1456 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit); 1457 rmesa->TexGenEnabled &= ~(R200_TEXGEN_INPUT_MASK<<inputshift); 1458 rmesa->TexGenNeedNormals[unit] = 0; 1459 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit); 1460 rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift); 1461 1462 if (tmp != rmesa->TexGenEnabled) { 1463 rmesa->recheck_texgen[unit] = GL_TRUE; 1464 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; 1465 } 1466 } 1467 } 1468} 1469 1470static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) 1471{ 1472 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1473 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1474 struct gl_texture_object *tObj = texUnit->_Current; 1475 r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; 1476 1477 /* Need to load the 2d images associated with this unit. 1478 */ 1479 if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { 1480 t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; 1481 t->base.dirty_images[0] = ~0; 1482 } 1483 1484 ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D); 1485 1486 if ( t->base.dirty_images[0] ) { 1487 R200_FIREVERTICES( rmesa ); 1488 r200SetTexImages( rmesa, tObj ); 1489 r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); 1490 if ( !t->base.memBlock ) 1491 return GL_FALSE; 1492 } 1493 1494 return GL_TRUE; 1495} 1496 1497#if ENABLE_HW_3D_TEXTURE 1498static GLboolean enable_tex_3d( GLcontext *ctx, int unit ) 1499{ 1500 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1501 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1502 struct gl_texture_object *tObj = texUnit->_Current; 1503 r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; 1504 1505 /* Need to load the 3d images associated with this unit. 1506 */ 1507 if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { 1508 t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; 1509 t->base.dirty_images[0] = ~0; 1510 } 1511 1512 ASSERT(tObj->Target == GL_TEXTURE_3D); 1513 1514 /* R100 & R200 do not support mipmaps for 3D textures. 1515 */ 1516 if ( (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR) ) { 1517 return GL_FALSE; 1518 } 1519 1520 if ( t->base.dirty_images[0] ) { 1521 R200_FIREVERTICES( rmesa ); 1522 r200SetTexImages( rmesa, tObj ); 1523 r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); 1524 if ( !t->base.memBlock ) 1525 return GL_FALSE; 1526 } 1527 1528 return GL_TRUE; 1529} 1530#endif 1531 1532static GLboolean enable_tex_cube( GLcontext *ctx, int unit ) 1533{ 1534 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1535 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1536 struct gl_texture_object *tObj = texUnit->_Current; 1537 r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; 1538 GLuint face; 1539 1540 /* Need to load the 2d images associated with this unit. 1541 */ 1542 if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { 1543 t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; 1544 for (face = 0; face < 6; face++) 1545 t->base.dirty_images[face] = ~0; 1546 } 1547 1548 ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP); 1549 1550 if ( t->base.dirty_images[0] || t->base.dirty_images[1] || 1551 t->base.dirty_images[2] || t->base.dirty_images[3] || 1552 t->base.dirty_images[4] || t->base.dirty_images[5] ) { 1553 /* flush */ 1554 R200_FIREVERTICES( rmesa ); 1555 /* layout memory space, once for all faces */ 1556 r200SetTexImages( rmesa, tObj ); 1557 } 1558 1559 /* upload (per face) */ 1560 for (face = 0; face < 6; face++) { 1561 if (t->base.dirty_images[face]) { 1562 r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, face ); 1563 } 1564 } 1565 1566 if ( !t->base.memBlock ) { 1567 /* texmem alloc failed, use s/w fallback */ 1568 return GL_FALSE; 1569 } 1570 1571 return GL_TRUE; 1572} 1573 1574static GLboolean enable_tex_rect( GLcontext *ctx, int unit ) 1575{ 1576 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1577 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1578 struct gl_texture_object *tObj = texUnit->_Current; 1579 r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; 1580 1581 if (!(t->pp_txformat & R200_TXFORMAT_NON_POWER2)) { 1582 t->pp_txformat |= R200_TXFORMAT_NON_POWER2; 1583 t->base.dirty_images[0] = ~0; 1584 } 1585 1586 ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV); 1587 1588 if ( t->base.dirty_images[0] ) { 1589 R200_FIREVERTICES( rmesa ); 1590 r200SetTexImages( rmesa, tObj ); 1591 r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); 1592 if ( !t->base.memBlock && !rmesa->prefer_gart_client_texturing ) 1593 return GL_FALSE; 1594 } 1595 1596 return GL_TRUE; 1597} 1598 1599 1600static GLboolean update_tex_common( GLcontext *ctx, int unit ) 1601{ 1602 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1603 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1604 struct gl_texture_object *tObj = texUnit->_Current; 1605 r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; 1606 GLenum format; 1607 1608 /* Fallback if there's a texture border */ 1609 if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) 1610 return GL_FALSE; 1611 1612 /* Update state if this is a different texture object to last 1613 * time. 1614 */ 1615 if ( rmesa->state.texture.unit[unit].texobj != t ) { 1616 if ( rmesa->state.texture.unit[unit].texobj != NULL ) { 1617 /* The old texture is no longer bound to this texture unit. 1618 * Mark it as such. 1619 */ 1620 1621 rmesa->state.texture.unit[unit].texobj->base.bound &= 1622 ~(1UL << unit); 1623 } 1624 1625 rmesa->state.texture.unit[unit].texobj = t; 1626 t->base.bound |= (1UL << unit); 1627 t->dirty_state |= 1<<unit; 1628 driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */ 1629 } 1630 1631 1632 /* Newly enabled? 1633 */ 1634 if ( 1|| !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit))) { 1635 R200_STATECHANGE( rmesa, ctx ); 1636 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_0_ENABLE | 1637 R200_TEX_BLEND_0_ENABLE) << unit; 1638 1639 R200_STATECHANGE( rmesa, vtx ); 1640 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3); 1641 1642 rmesa->recheck_texgen[unit] = GL_TRUE; 1643 } 1644 1645 if (t->dirty_state & (1<<unit)) { 1646 import_tex_obj_state( rmesa, unit, t ); 1647 } 1648 1649 if (rmesa->recheck_texgen[unit]) { 1650 GLboolean fallback = !r200_validate_texgen( ctx, unit ); 1651 TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback); 1652 rmesa->recheck_texgen[unit] = 0; 1653 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; 1654 } 1655 1656 format = tObj->Image[tObj->BaseLevel]->Format; 1657 if ( rmesa->state.texture.unit[unit].format != format || 1658 rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) { 1659 rmesa->state.texture.unit[unit].format = format; 1660 rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode; 1661 if ( ! r200UpdateTextureEnv( ctx, unit ) ) { 1662 return GL_FALSE; 1663 } 1664 } 1665 1666 FALLBACK( rmesa, R200_FALLBACK_BORDER_MODE, t->border_fallback ); 1667 return !t->border_fallback; 1668} 1669 1670 1671 1672static GLboolean r200UpdateTextureUnit( GLcontext *ctx, int unit ) 1673{ 1674 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1675 1676 if ( texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT) ) { 1677 return (enable_tex_rect( ctx, unit ) && 1678 update_tex_common( ctx, unit )); 1679 } 1680 else if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) { 1681 return (enable_tex_2d( ctx, unit ) && 1682 update_tex_common( ctx, unit )); 1683 } 1684#if ENABLE_HW_3D_TEXTURE 1685 else if ( texUnit->_ReallyEnabled & (TEXTURE_3D_BIT) ) { 1686 return (enable_tex_3d( ctx, unit ) && 1687 update_tex_common( ctx, unit )); 1688 } 1689#endif 1690 else if ( texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT) ) { 1691 return (enable_tex_cube( ctx, unit ) && 1692 update_tex_common( ctx, unit )); 1693 } 1694 else if ( texUnit->_ReallyEnabled ) { 1695 return GL_FALSE; 1696 } 1697 else { 1698 disable_tex( ctx, unit ); 1699 return GL_TRUE; 1700 } 1701} 1702 1703 1704void r200UpdateTextureState( GLcontext *ctx ) 1705{ 1706 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1707 GLboolean ok; 1708 GLuint dbg; 1709 1710 ok = (r200UpdateTextureUnit( ctx, 0 ) && 1711 r200UpdateTextureUnit( ctx, 1 )); 1712 1713 FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok ); 1714 1715 if (rmesa->TclFallback) 1716 r200ChooseVertexState( ctx ); 1717 1718 /* 1719 * T0 hang workaround ------------- 1720 */ 1721#if 1 1722 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) == R200_TEX_0_ENABLE && 1723 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) { 1724 1725 R200_STATECHANGE(rmesa, ctx); 1726 R200_STATECHANGE(rmesa, tex[1]); 1727 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE; 1728 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; 1729 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= 0x08000000; 1730 } 1731 else { 1732 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) && 1733 (rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) { 1734 R200_STATECHANGE(rmesa, tex[1]); 1735 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000; 1736 } 1737 } 1738#endif 1739 1740#if 1 1741 /* 1742 * Texture cache LRU hang workaround ------------- 1743 */ 1744 dbg = 0x0; 1745 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_0_ENABLE) && 1746 ((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 1747 0x04) == 0))) 1748 { 1749 dbg |= 0x02; 1750 } 1751 1752 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) && 1753 ((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 1754 0x04) == 0))) 1755 { 1756 dbg |= 0x04; 1757 } 1758 1759 if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) { 1760 R200_STATECHANGE( rmesa, tam ); 1761 rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg; 1762 if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg); 1763 } 1764#endif 1765} 1766 1767/* 1768 also tests for higher texunits: 1769 1770 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) && 1771 ((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0)) || 1772 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) && 1773 ((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0))) 1774 1775 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) && 1776 ((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0)) || 1777 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) && 1778 ((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0))) 1779 1780*/ 1781