r200_texstate.c revision 95a0bd6762737bb25bdf5c4147da9d1372f6aac3
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[0][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[0][t->base.firstLevel]->WidthLog2; 133 log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2; 134 log2Depth = tObj->Image[0][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[0][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[0][t->base.firstLevel]->Width - 1) << 0) | 259 ((tObj->Image[0][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[0][t->base.firstLevel]->Width + 63) & ~(63); 267 else 268 t->pp_txpitch = ((tObj->Image[0][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/* GL_ARB_texture_env_combine support 283 */ 284 285/* The color tables have combine functions for GL_SRC_COLOR, 286 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. 287 */ 288static GLuint r200_register_color[][R200_MAX_TEXTURE_UNITS] = 289{ 290 { 291 R200_TXC_ARG_A_R0_COLOR, 292 R200_TXC_ARG_A_R1_COLOR, 293 R200_TXC_ARG_A_R2_COLOR 294 }, 295 { 296 R200_TXC_ARG_A_R0_COLOR | R200_TXC_COMP_ARG_A, 297 R200_TXC_ARG_A_R1_COLOR | R200_TXC_COMP_ARG_A, 298 R200_TXC_ARG_A_R2_COLOR | R200_TXC_COMP_ARG_A 299 }, 300 { 301 R200_TXC_ARG_A_R0_ALPHA, 302 R200_TXC_ARG_A_R1_ALPHA, 303 R200_TXC_ARG_A_R2_ALPHA 304 }, 305 { 306 R200_TXC_ARG_A_R0_ALPHA | R200_TXC_COMP_ARG_A, 307 R200_TXC_ARG_A_R1_ALPHA | R200_TXC_COMP_ARG_A, 308 R200_TXC_ARG_A_R2_ALPHA | R200_TXC_COMP_ARG_A 309 }, 310}; 311 312static GLuint r200_tfactor_color[] = 313{ 314 R200_TXC_ARG_A_TFACTOR_COLOR, 315 R200_TXC_ARG_A_TFACTOR_COLOR | R200_TXC_COMP_ARG_A, 316 R200_TXC_ARG_A_TFACTOR_ALPHA, 317 R200_TXC_ARG_A_TFACTOR_ALPHA | R200_TXC_COMP_ARG_A 318}; 319 320static GLuint r200_primary_color[] = 321{ 322 R200_TXC_ARG_A_DIFFUSE_COLOR, 323 R200_TXC_ARG_A_DIFFUSE_COLOR | R200_TXC_COMP_ARG_A, 324 R200_TXC_ARG_A_DIFFUSE_ALPHA, 325 R200_TXC_ARG_A_DIFFUSE_ALPHA | R200_TXC_COMP_ARG_A 326}; 327 328/* GL_ZERO table - indices 0-3 329 * GL_ONE table - indices 1-4 330 */ 331static GLuint r200_zero_color[] = 332{ 333 R200_TXC_ARG_A_ZERO, 334 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A, 335 R200_TXC_ARG_A_ZERO, 336 R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A, 337 R200_TXC_ARG_A_ZERO 338}; 339 340/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. 341 */ 342static GLuint r200_register_alpha[][R200_MAX_TEXTURE_UNITS] = 343{ 344 { 345 R200_TXA_ARG_A_R0_ALPHA, 346 R200_TXA_ARG_A_R1_ALPHA, 347 R200_TXA_ARG_A_R2_ALPHA 348 }, 349 { 350 R200_TXA_ARG_A_R0_ALPHA | R200_TXA_COMP_ARG_A, 351 R200_TXA_ARG_A_R1_ALPHA | R200_TXA_COMP_ARG_A, 352 R200_TXA_ARG_A_R2_ALPHA | R200_TXA_COMP_ARG_A 353 }, 354}; 355 356static GLuint r200_tfactor_alpha[] = 357{ 358 R200_TXA_ARG_A_TFACTOR_ALPHA, 359 R200_TXA_ARG_A_TFACTOR_ALPHA | R200_TXA_COMP_ARG_A 360}; 361 362static GLuint r200_primary_alpha[] = 363{ 364 R200_TXA_ARG_A_DIFFUSE_ALPHA, 365 R200_TXA_ARG_A_DIFFUSE_ALPHA | R200_TXA_COMP_ARG_A 366}; 367 368/* GL_ZERO table - indices 0-1 369 * GL_ONE table - indices 1-2 370 */ 371static GLuint r200_zero_alpha[] = 372{ 373 R200_TXA_ARG_A_ZERO, 374 R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A, 375 R200_TXA_ARG_A_ZERO, 376}; 377 378 379/* Extract the arg from slot A, shift it into the correct argument slot 380 * and set the corresponding complement bit. 381 */ 382#define R200_COLOR_ARG( n, arg ) \ 383do { \ 384 color_combine |= \ 385 ((color_arg[n] & R200_TXC_ARG_A_MASK) \ 386 << R200_TXC_ARG_##arg##_SHIFT); \ 387 color_combine |= \ 388 ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT) \ 389 << R200_TXC_COMP_ARG_##arg##_SHIFT); \ 390} while (0) 391 392#define R200_ALPHA_ARG( n, arg ) \ 393do { \ 394 alpha_combine |= \ 395 ((alpha_arg[n] & R200_TXA_ARG_A_MASK) \ 396 << R200_TXA_ARG_##arg##_SHIFT); \ 397 alpha_combine |= \ 398 ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT) \ 399 << R200_TXA_COMP_ARG_##arg##_SHIFT); \ 400} while (0) 401 402 403/* ================================================================ 404 * Texture unit state management 405 */ 406 407static GLboolean r200UpdateTextureEnv( GLcontext *ctx, int unit ) 408{ 409 r200ContextPtr rmesa = R200_CONTEXT(ctx); 410 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 411 GLuint color_combine, alpha_combine; 412 GLuint color_scale = rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2]; 413 GLuint alpha_scale = rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2]; 414 415 /* texUnit->_Current can be NULL if and only if the texture unit is 416 * not actually enabled. 417 */ 418 assert( (texUnit->_ReallyEnabled == 0) 419 || (texUnit->_Current != NULL) ); 420 421 if ( R200_DEBUG & DEBUG_TEXTURE ) { 422 fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit ); 423 } 424 425 /* Set the texture environment state. Isn't this nice and clean? 426 * The chip will automagically set the texture alpha to 0xff when 427 * the texture format does not include an alpha component. This 428 * reduces the amount of special-casing we have to do, alpha-only 429 * textures being a notable exception. 430 */ 431 if ( !texUnit->_ReallyEnabled ) { 432 /* Don't cache these results. 433 */ 434 rmesa->state.texture.unit[unit].format = 0; 435 rmesa->state.texture.unit[unit].envMode = 0; 436 if ( unit == 0 ) { 437 color_combine = R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO 438 | R200_TXC_ARG_C_DIFFUSE_COLOR | R200_TXC_OP_MADD; 439 alpha_combine = R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO 440 | R200_TXA_ARG_C_DIFFUSE_ALPHA | R200_TXA_OP_MADD; 441 } 442 else { 443 color_combine = R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO 444 | R200_TXC_ARG_C_R0_COLOR | R200_TXC_OP_MADD; 445 alpha_combine = R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO 446 | R200_TXA_ARG_C_R0_ALPHA | R200_TXA_OP_MADD; 447 } 448 } 449 else { 450 GLuint color_arg[3], alpha_arg[3]; 451 GLuint i; 452 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB; 453 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA; 454 GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB; 455 GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA; 456 457 /* Don't cache these results. 458 */ 459 rmesa->state.texture.unit[unit].format = 0; 460 rmesa->state.texture.unit[unit].envMode = 0; 461 462 463 /* Step 1: 464 * Extract the color and alpha combine function arguments. 465 */ 466 for ( i = 0 ; i < numColorArgs ; i++ ) { 467 const GLuint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR; 468 assert(op >= 0); 469 assert(op <= 3); 470 switch ( texUnit->_CurrentCombine->SourceRGB[i] ) { 471 case GL_TEXTURE: 472 color_arg[i] = r200_register_color[op][unit]; 473 break; 474 case GL_CONSTANT: 475 color_arg[i] = r200_tfactor_color[op]; 476 break; 477 case GL_PRIMARY_COLOR: 478 color_arg[i] = r200_primary_color[op]; 479 break; 480 case GL_PREVIOUS: 481 if (unit == 0) 482 color_arg[i] = r200_primary_color[op]; 483 else 484 color_arg[i] = r200_register_color[op][0]; 485 break; 486 case GL_ZERO: 487 color_arg[i] = r200_zero_color[op]; 488 break; 489 case GL_ONE: 490 color_arg[i] = r200_zero_color[op+1]; 491 break; 492 default: 493 return GL_FALSE; 494 } 495 } 496 497 for ( i = 0 ; i < numAlphaArgs ; i++ ) { 498 const GLuint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA; 499 assert(op >= 0); 500 assert(op <= 1); 501 switch ( texUnit->_CurrentCombine->SourceA[i] ) { 502 case GL_TEXTURE: 503 alpha_arg[i] = r200_register_alpha[op][unit]; 504 break; 505 case GL_CONSTANT: 506 alpha_arg[i] = r200_tfactor_alpha[op]; 507 break; 508 case GL_PRIMARY_COLOR: 509 alpha_arg[i] = r200_primary_alpha[op]; 510 break; 511 case GL_PREVIOUS: 512 if (unit == 0) 513 alpha_arg[i] = r200_primary_alpha[op]; 514 else 515 alpha_arg[i] = r200_register_alpha[op][0]; 516 break; 517 case GL_ZERO: 518 alpha_arg[i] = r200_zero_alpha[op]; 519 break; 520 case GL_ONE: 521 alpha_arg[i] = r200_zero_alpha[op+1]; 522 break; 523 default: 524 return GL_FALSE; 525 } 526 } 527 528 /* Step 2: 529 * Build up the color and alpha combine functions. 530 */ 531 switch ( texUnit->_CurrentCombine->ModeRGB ) { 532 case GL_REPLACE: 533 color_combine = (R200_TXC_ARG_A_ZERO | 534 R200_TXC_ARG_B_ZERO | 535 R200_TXC_OP_MADD); 536 R200_COLOR_ARG( 0, C ); 537 break; 538 case GL_MODULATE: 539 color_combine = (R200_TXC_ARG_C_ZERO | 540 R200_TXC_OP_MADD); 541 R200_COLOR_ARG( 0, A ); 542 R200_COLOR_ARG( 1, B ); 543 break; 544 case GL_ADD: 545 color_combine = (R200_TXC_ARG_B_ZERO | 546 R200_TXC_COMP_ARG_B | 547 R200_TXC_OP_MADD); 548 R200_COLOR_ARG( 0, A ); 549 R200_COLOR_ARG( 1, C ); 550 break; 551 case GL_ADD_SIGNED: 552 color_combine = (R200_TXC_ARG_B_ZERO | 553 R200_TXC_COMP_ARG_B | 554 R200_TXC_BIAS_ARG_C | /* new */ 555 R200_TXC_OP_MADD); /* was ADDSIGNED */ 556 R200_COLOR_ARG( 0, A ); 557 R200_COLOR_ARG( 1, C ); 558 break; 559 case GL_SUBTRACT: 560 color_combine = (R200_TXC_ARG_B_ZERO | 561 R200_TXC_COMP_ARG_B | 562 R200_TXC_NEG_ARG_C | 563 R200_TXC_OP_MADD); 564 R200_COLOR_ARG( 0, A ); 565 R200_COLOR_ARG( 1, C ); 566 break; 567 case GL_INTERPOLATE: 568 color_combine = (R200_TXC_OP_LERP); 569 R200_COLOR_ARG( 0, B ); 570 R200_COLOR_ARG( 1, A ); 571 R200_COLOR_ARG( 2, C ); 572 break; 573 574 case GL_DOT3_RGB_EXT: 575 case GL_DOT3_RGBA_EXT: 576 /* The EXT version of the DOT3 extension does not support the 577 * scale factor, but the ARB version (and the version in OpenGL 578 * 1.3) does. 579 */ 580 RGBshift = 0; 581 Ashift = 0; 582 /* FALLTHROUGH */ 583 584 case GL_DOT3_RGB: 585 case GL_DOT3_RGBA: 586 /* DOT3 works differently on R200 than on R100. On R100, just 587 * setting the DOT3 mode did everything for you. On R200, the 588 * driver has to enable the biasing and scale in the inputs to 589 * put them in the proper [-1,1] range. This is what the 4x and 590 * the -0.5 in the DOT3 spec do. The post-scale is then set 591 * normally. 592 */ 593 594 RGBshift++; 595 Ashift = RGBshift; 596 597 color_combine = (R200_TXC_ARG_C_ZERO | 598 R200_TXC_OP_DOT3 | 599 R200_TXC_BIAS_ARG_A | 600 R200_TXC_BIAS_ARG_B | 601 R200_TXC_SCALE_ARG_A | 602 R200_TXC_SCALE_ARG_B); 603 R200_COLOR_ARG( 0, A ); 604 R200_COLOR_ARG( 1, B ); 605 break; 606 607 case GL_MODULATE_ADD_ATI: 608 color_combine = (R200_TXC_OP_MADD); 609 R200_COLOR_ARG( 0, A ); 610 R200_COLOR_ARG( 1, C ); 611 R200_COLOR_ARG( 2, B ); 612 break; 613 case GL_MODULATE_SIGNED_ADD_ATI: 614 color_combine = (R200_TXC_BIAS_ARG_C | /* new */ 615 R200_TXC_OP_MADD); /* was ADDSIGNED */ 616 R200_COLOR_ARG( 0, A ); 617 R200_COLOR_ARG( 1, C ); 618 R200_COLOR_ARG( 2, B ); 619 break; 620 case GL_MODULATE_SUBTRACT_ATI: 621 color_combine = (R200_TXC_NEG_ARG_C | 622 R200_TXC_OP_MADD); 623 R200_COLOR_ARG( 0, A ); 624 R200_COLOR_ARG( 1, C ); 625 R200_COLOR_ARG( 2, B ); 626 break; 627 default: 628 return GL_FALSE; 629 } 630 631 switch ( texUnit->_CurrentCombine->ModeA ) { 632 case GL_REPLACE: 633 alpha_combine = (R200_TXA_ARG_A_ZERO | 634 R200_TXA_ARG_B_ZERO | 635 R200_TXA_OP_MADD); 636 R200_ALPHA_ARG( 0, C ); 637 break; 638 case GL_MODULATE: 639 alpha_combine = (R200_TXA_ARG_C_ZERO | 640 R200_TXA_OP_MADD); 641 R200_ALPHA_ARG( 0, A ); 642 R200_ALPHA_ARG( 1, B ); 643 break; 644 case GL_ADD: 645 alpha_combine = (R200_TXA_ARG_B_ZERO | 646 R200_TXA_COMP_ARG_B | 647 R200_TXA_OP_MADD); 648 R200_ALPHA_ARG( 0, A ); 649 R200_ALPHA_ARG( 1, C ); 650 break; 651 case GL_ADD_SIGNED: 652 alpha_combine = (R200_TXA_ARG_B_ZERO | 653 R200_TXA_COMP_ARG_B | 654 R200_TXA_BIAS_ARG_C | /* new */ 655 R200_TXA_OP_MADD); /* was ADDSIGNED */ 656 R200_ALPHA_ARG( 0, A ); 657 R200_ALPHA_ARG( 1, C ); 658 break; 659 case GL_SUBTRACT: 660 alpha_combine = (R200_TXA_ARG_B_ZERO | 661 R200_TXA_COMP_ARG_B | 662 R200_TXA_NEG_ARG_C | 663 R200_TXA_OP_MADD); 664 R200_ALPHA_ARG( 0, A ); 665 R200_ALPHA_ARG( 1, C ); 666 break; 667 case GL_INTERPOLATE: 668 alpha_combine = (R200_TXA_OP_LERP); 669 R200_ALPHA_ARG( 0, B ); 670 R200_ALPHA_ARG( 1, A ); 671 R200_ALPHA_ARG( 2, C ); 672 break; 673 674 case GL_MODULATE_ADD_ATI: 675 alpha_combine = (R200_TXA_OP_MADD); 676 R200_ALPHA_ARG( 0, A ); 677 R200_ALPHA_ARG( 1, C ); 678 R200_ALPHA_ARG( 2, B ); 679 break; 680 case GL_MODULATE_SIGNED_ADD_ATI: 681 alpha_combine = (R200_TXA_BIAS_ARG_C | /* new */ 682 R200_TXA_OP_MADD); /* was ADDSIGNED */ 683 R200_ALPHA_ARG( 0, A ); 684 R200_ALPHA_ARG( 1, C ); 685 R200_ALPHA_ARG( 2, B ); 686 break; 687 case GL_MODULATE_SUBTRACT_ATI: 688 alpha_combine = (R200_TXA_NEG_ARG_C | 689 R200_TXA_OP_MADD); 690 R200_ALPHA_ARG( 0, A ); 691 R200_ALPHA_ARG( 1, C ); 692 R200_ALPHA_ARG( 2, B ); 693 break; 694 default: 695 return GL_FALSE; 696 } 697 698 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB_EXT) 699 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB) ) { 700 alpha_scale |= R200_TXA_DOT_ALPHA; 701 } 702 703 /* Step 3: 704 * Apply the scale factor. 705 */ 706 color_scale &= ~R200_TXC_SCALE_MASK; 707 alpha_scale &= ~R200_TXA_SCALE_MASK; 708 color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT); 709 alpha_scale |= (Ashift << R200_TXA_SCALE_SHIFT); 710 711 /* All done! 712 */ 713 } 714 715 if ( rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] != color_combine || 716 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND] != alpha_combine || 717 rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] != color_scale || 718 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] != alpha_scale) { 719 R200_STATECHANGE( rmesa, pix[unit] ); 720 rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] = color_combine; 721 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND] = alpha_combine; 722 rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] = color_scale; 723 rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] = alpha_scale; 724 } 725 726 return GL_TRUE; 727} 728 729#define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK | \ 730 R200_MIN_FILTER_MASK | \ 731 R200_MAG_FILTER_MASK | \ 732 R200_MAX_ANISO_MASK | \ 733 R200_YUV_TO_RGB | \ 734 R200_YUV_TEMPERATURE_MASK | \ 735 R200_CLAMP_S_MASK | \ 736 R200_CLAMP_T_MASK | \ 737 R200_BORDER_MODE_D3D ) 738 739#define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK | \ 740 R200_TXFORMAT_HEIGHT_MASK | \ 741 R200_TXFORMAT_FORMAT_MASK | \ 742 R200_TXFORMAT_F5_WIDTH_MASK | \ 743 R200_TXFORMAT_F5_HEIGHT_MASK | \ 744 R200_TXFORMAT_ALPHA_IN_MAP | \ 745 R200_TXFORMAT_CUBIC_MAP_ENABLE | \ 746 R200_TXFORMAT_NON_POWER2) 747 748#define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK | \ 749 R200_TEXCOORD_MASK | \ 750 R200_CLAMP_Q_MASK | \ 751 R200_VOLUME_FILTER_MASK) 752 753 754static void import_tex_obj_state( r200ContextPtr rmesa, 755 int unit, 756 r200TexObjPtr texobj ) 757{ 758 GLuint *cmd = R200_DB_STATE( tex[unit] ); 759 760 cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK; 761 cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK; 762 cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; 763 cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK; 764 cmd[TEX_PP_TXFORMAT_X] &= ~TEXOBJ_TXFORMAT_X_MASK; 765 cmd[TEX_PP_TXFORMAT_X] |= texobj->pp_txformat_x & TEXOBJ_TXFORMAT_X_MASK; 766 cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */ 767 cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */ 768 cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset; 769 cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color; 770 R200_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] ); 771 772 if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) { 773 GLuint *cube_cmd = R200_DB_STATE( cube[unit] ); 774 GLuint bytesPerFace = texobj->base.totalSize / 6; 775 ASSERT(texobj->totalSize % 6 == 0); 776 cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces; 777 cube_cmd[CUBE_PP_CUBIC_OFFSET_F1] = texobj->pp_txoffset + 1 * bytesPerFace; 778 cube_cmd[CUBE_PP_CUBIC_OFFSET_F2] = texobj->pp_txoffset + 2 * bytesPerFace; 779 cube_cmd[CUBE_PP_CUBIC_OFFSET_F3] = texobj->pp_txoffset + 3 * bytesPerFace; 780 cube_cmd[CUBE_PP_CUBIC_OFFSET_F4] = texobj->pp_txoffset + 4 * bytesPerFace; 781 cube_cmd[CUBE_PP_CUBIC_OFFSET_F5] = texobj->pp_txoffset + 5 * bytesPerFace; 782 R200_DB_STATECHANGE( rmesa, &rmesa->hw.cube[unit] ); 783 } 784 785 texobj->dirty_state &= ~(1<<unit); 786} 787 788 789 790 791static void set_texgen_matrix( r200ContextPtr rmesa, 792 GLuint unit, 793 const GLfloat *s_plane, 794 const GLfloat *t_plane, 795 const GLfloat *r_plane ) 796{ 797 static const GLfloat scale_identity[4] = { 1,1,1,1 }; 798 799 if (!TEST_EQ_4V( s_plane, scale_identity) || 800 !TEST_EQ_4V( t_plane, scale_identity) || 801 !TEST_EQ_4V( r_plane, scale_identity)) { 802 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit; 803 rmesa->TexGenMatrix[unit].m[0] = s_plane[0]; 804 rmesa->TexGenMatrix[unit].m[4] = s_plane[1]; 805 rmesa->TexGenMatrix[unit].m[8] = s_plane[2]; 806 rmesa->TexGenMatrix[unit].m[12] = s_plane[3]; 807 808 rmesa->TexGenMatrix[unit].m[1] = t_plane[0]; 809 rmesa->TexGenMatrix[unit].m[5] = t_plane[1]; 810 rmesa->TexGenMatrix[unit].m[9] = t_plane[2]; 811 rmesa->TexGenMatrix[unit].m[13] = t_plane[3]; 812 813 /* NOTE: r_plane goes in the 4th row, not 3rd! */ 814 rmesa->TexGenMatrix[unit].m[3] = r_plane[0]; 815 rmesa->TexGenMatrix[unit].m[7] = r_plane[1]; 816 rmesa->TexGenMatrix[unit].m[11] = r_plane[2]; 817 rmesa->TexGenMatrix[unit].m[15] = r_plane[3]; 818 819 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; 820 } 821} 822 823/* Need this special matrix to get correct reflection map coords */ 824static void 825set_texgen_reflection_matrix( r200ContextPtr rmesa, GLuint unit ) 826{ 827 static const GLfloat m[16] = { 828 -1, 0, 0, 0, 829 0, -1, 0, 0, 830 0, 0, 0, -1, 831 0, 0, -1, 0 }; 832 _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m); 833 _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) ); 834 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit; 835} 836 837/* Need this special matrix to get correct normal map coords */ 838static void 839set_texgen_normal_map_matrix( r200ContextPtr rmesa, GLuint unit ) 840{ 841 static const GLfloat m[16] = { 842 1, 0, 0, 0, 843 0, 1, 0, 0, 844 0, 0, 0, 1, 845 0, 0, 1, 0 }; 846 _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m); 847 _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) ); 848 rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit; 849} 850 851 852/* Ignoring the Q texcoord for now. 853 * 854 * Returns GL_FALSE if fallback required. 855 */ 856static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit ) 857{ 858 r200ContextPtr rmesa = R200_CONTEXT(ctx); 859 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 860 GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4; 861 GLuint tmp = rmesa->TexGenEnabled; 862 863 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit); 864 rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit); 865 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit); 866 rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift); 867 rmesa->TexGenNeedNormals[unit] = 0; 868 869 if (0) 870 fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit); 871 872 if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT)) == 0) { 873 /* Disabled, no fallback: 874 */ 875 rmesa->TexGenInputs |= 876 (R200_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; 877 return GL_TRUE; 878 } 879 else if (texUnit->TexGenEnabled & Q_BIT) { 880 /* Very easy to do this, in fact would remove a fallback case 881 * elsewhere, but I haven't done it yet... Fallback: 882 */ 883 /*fprintf(stderr, "fallback Q_BIT\n");*/ 884 return GL_FALSE; 885 } 886 else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) && 887 texUnit->GenModeS == texUnit->GenModeT) { 888 /* OK */ 889 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit; 890 /* continue */ 891 } 892 else if (texUnit->TexGenEnabled == (S_BIT|T_BIT|R_BIT) && 893 texUnit->GenModeS == texUnit->GenModeT && 894 texUnit->GenModeT == texUnit->GenModeR) { 895 /* OK */ 896 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit; 897 /* continue */ 898 } 899 else { 900 /* Mixed modes, fallback: 901 */ 902 /* fprintf(stderr, "fallback mixed texgen\n"); */ 903 return GL_FALSE; 904 } 905 906 rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit; 907 908 switch (texUnit->GenModeS) { 909 case GL_OBJECT_LINEAR: 910 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_OBJ << inputshift; 911 set_texgen_matrix( rmesa, unit, 912 texUnit->ObjectPlaneS, 913 texUnit->ObjectPlaneT, 914 texUnit->ObjectPlaneR); 915 break; 916 917 case GL_EYE_LINEAR: 918 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE << inputshift; 919 set_texgen_matrix( rmesa, unit, 920 texUnit->EyePlaneS, 921 texUnit->EyePlaneT, 922 texUnit->EyePlaneR); 923 break; 924 925 case GL_REFLECTION_MAP_NV: 926 rmesa->TexGenNeedNormals[unit] = GL_TRUE; 927 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE_REFLECT<<inputshift; 928 set_texgen_reflection_matrix(rmesa, unit); 929 break; 930 931 case GL_NORMAL_MAP_NV: 932 rmesa->TexGenNeedNormals[unit] = GL_TRUE; 933 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift; 934 set_texgen_normal_map_matrix(rmesa, unit); 935 break; 936 937 case GL_SPHERE_MAP: 938 rmesa->TexGenNeedNormals[unit] = GL_TRUE; 939 rmesa->TexGenInputs |= R200_TEXGEN_INPUT_SPHERE<<inputshift; 940 break; 941 942 default: 943 /* Unsupported mode, fallback: 944 */ 945 /* fprintf(stderr, "fallback unsupported texgen\n"); */ 946 return GL_FALSE; 947 } 948 949 rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit; 950 951 if (tmp != rmesa->TexGenEnabled) { 952 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; 953 } 954 955 return GL_TRUE; 956} 957 958 959static void disable_tex( GLcontext *ctx, int unit ) 960{ 961 r200ContextPtr rmesa = R200_CONTEXT(ctx); 962 963 if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit)) { 964 /* Texture unit disabled */ 965 if ( rmesa->state.texture.unit[unit].texobj != NULL ) { 966 /* The old texture is no longer bound to this texture unit. 967 * Mark it as such. 968 */ 969 970 rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit); 971 rmesa->state.texture.unit[unit].texobj = NULL; 972 } 973 974 R200_STATECHANGE( rmesa, ctx ); 975 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((R200_TEX_0_ENABLE | 976 R200_TEX_BLEND_0_ENABLE) << unit); 977 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_BLEND_0_ENABLE; 978 979 R200_STATECHANGE( rmesa, tcl ); 980 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3)); 981 982 if (rmesa->TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) { 983 TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE); 984 } 985 986 /* Actually want to keep all units less than max active texture 987 * enabled, right? Fix this for >2 texunits. 988 */ 989 /* FIXME: What should happen here if r200UpdateTextureEnv fails? */ 990 if (unit == 0) 991 r200UpdateTextureEnv( ctx, unit ); 992 993 994 { 995 GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4; 996 GLuint tmp = rmesa->TexGenEnabled; 997 998 rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit); 999 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit); 1000 rmesa->TexGenEnabled &= ~(R200_TEXGEN_INPUT_MASK<<inputshift); 1001 rmesa->TexGenNeedNormals[unit] = 0; 1002 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit); 1003 rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift); 1004 1005 if (tmp != rmesa->TexGenEnabled) { 1006 rmesa->recheck_texgen[unit] = GL_TRUE; 1007 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; 1008 } 1009 } 1010 } 1011} 1012 1013static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) 1014{ 1015 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1016 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1017 struct gl_texture_object *tObj = texUnit->_Current; 1018 r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; 1019 1020 /* Need to load the 2d images associated with this unit. 1021 */ 1022 if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { 1023 t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; 1024 t->base.dirty_images[0] = ~0; 1025 } 1026 1027 ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D); 1028 1029 if ( t->base.dirty_images[0] ) { 1030 R200_FIREVERTICES( rmesa ); 1031 r200SetTexImages( rmesa, tObj ); 1032 r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); 1033 if ( !t->base.memBlock ) 1034 return GL_FALSE; 1035 } 1036 1037 return GL_TRUE; 1038} 1039 1040#if ENABLE_HW_3D_TEXTURE 1041static GLboolean enable_tex_3d( GLcontext *ctx, int unit ) 1042{ 1043 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1044 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1045 struct gl_texture_object *tObj = texUnit->_Current; 1046 r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; 1047 1048 /* Need to load the 3d images associated with this unit. 1049 */ 1050 if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { 1051 t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; 1052 t->base.dirty_images[0] = ~0; 1053 } 1054 1055 ASSERT(tObj->Target == GL_TEXTURE_3D); 1056 1057 /* R100 & R200 do not support mipmaps for 3D textures. 1058 */ 1059 if ( (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR) ) { 1060 return GL_FALSE; 1061 } 1062 1063 if ( t->base.dirty_images[0] ) { 1064 R200_FIREVERTICES( rmesa ); 1065 r200SetTexImages( rmesa, tObj ); 1066 r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); 1067 if ( !t->base.memBlock ) 1068 return GL_FALSE; 1069 } 1070 1071 return GL_TRUE; 1072} 1073#endif 1074 1075static GLboolean enable_tex_cube( GLcontext *ctx, int unit ) 1076{ 1077 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1078 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1079 struct gl_texture_object *tObj = texUnit->_Current; 1080 r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; 1081 GLuint face; 1082 1083 /* Need to load the 2d images associated with this unit. 1084 */ 1085 if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) { 1086 t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2; 1087 for (face = 0; face < 6; face++) 1088 t->base.dirty_images[face] = ~0; 1089 } 1090 1091 ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP); 1092 1093 if ( t->base.dirty_images[0] || t->base.dirty_images[1] || 1094 t->base.dirty_images[2] || t->base.dirty_images[3] || 1095 t->base.dirty_images[4] || t->base.dirty_images[5] ) { 1096 /* flush */ 1097 R200_FIREVERTICES( rmesa ); 1098 /* layout memory space, once for all faces */ 1099 r200SetTexImages( rmesa, tObj ); 1100 } 1101 1102 /* upload (per face) */ 1103 for (face = 0; face < 6; face++) { 1104 if (t->base.dirty_images[face]) { 1105 r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, face ); 1106 } 1107 } 1108 1109 if ( !t->base.memBlock ) { 1110 /* texmem alloc failed, use s/w fallback */ 1111 return GL_FALSE; 1112 } 1113 1114 return GL_TRUE; 1115} 1116 1117static GLboolean enable_tex_rect( GLcontext *ctx, int unit ) 1118{ 1119 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1120 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1121 struct gl_texture_object *tObj = texUnit->_Current; 1122 r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; 1123 1124 if (!(t->pp_txformat & R200_TXFORMAT_NON_POWER2)) { 1125 t->pp_txformat |= R200_TXFORMAT_NON_POWER2; 1126 t->base.dirty_images[0] = ~0; 1127 } 1128 1129 ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV); 1130 1131 if ( t->base.dirty_images[0] ) { 1132 R200_FIREVERTICES( rmesa ); 1133 r200SetTexImages( rmesa, tObj ); 1134 r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 ); 1135 if ( !t->base.memBlock && !rmesa->prefer_gart_client_texturing ) 1136 return GL_FALSE; 1137 } 1138 1139 return GL_TRUE; 1140} 1141 1142 1143static GLboolean update_tex_common( GLcontext *ctx, int unit ) 1144{ 1145 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1146 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1147 struct gl_texture_object *tObj = texUnit->_Current; 1148 r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData; 1149 GLenum format; 1150 1151 /* Fallback if there's a texture border */ 1152 if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) 1153 return GL_FALSE; 1154 1155 /* Update state if this is a different texture object to last 1156 * time. 1157 */ 1158 if ( rmesa->state.texture.unit[unit].texobj != t ) { 1159 if ( rmesa->state.texture.unit[unit].texobj != NULL ) { 1160 /* The old texture is no longer bound to this texture unit. 1161 * Mark it as such. 1162 */ 1163 1164 rmesa->state.texture.unit[unit].texobj->base.bound &= 1165 ~(1UL << unit); 1166 } 1167 1168 rmesa->state.texture.unit[unit].texobj = t; 1169 t->base.bound |= (1UL << unit); 1170 t->dirty_state |= 1<<unit; 1171 driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */ 1172 } 1173 1174 1175 /* Newly enabled? 1176 */ 1177 if ( 1|| !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit))) { 1178 R200_STATECHANGE( rmesa, ctx ); 1179 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_0_ENABLE | 1180 R200_TEX_BLEND_0_ENABLE) << unit; 1181 1182 R200_STATECHANGE( rmesa, vtx ); 1183 rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3); 1184 1185 rmesa->recheck_texgen[unit] = GL_TRUE; 1186 } 1187 1188 if (t->dirty_state & (1<<unit)) { 1189 import_tex_obj_state( rmesa, unit, t ); 1190 } 1191 1192 if (rmesa->recheck_texgen[unit]) { 1193 GLboolean fallback = !r200_validate_texgen( ctx, unit ); 1194 TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback); 1195 rmesa->recheck_texgen[unit] = 0; 1196 rmesa->NewGLState |= _NEW_TEXTURE_MATRIX; 1197 } 1198 1199 format = tObj->Image[0][tObj->BaseLevel]->Format; 1200 if ( rmesa->state.texture.unit[unit].format != format || 1201 rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) { 1202 rmesa->state.texture.unit[unit].format = format; 1203 rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode; 1204 if ( ! r200UpdateTextureEnv( ctx, unit ) ) { 1205 return GL_FALSE; 1206 } 1207 } 1208 1209 FALLBACK( rmesa, R200_FALLBACK_BORDER_MODE, t->border_fallback ); 1210 return !t->border_fallback; 1211} 1212 1213 1214 1215static GLboolean r200UpdateTextureUnit( GLcontext *ctx, int unit ) 1216{ 1217 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1218 1219 if ( texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT) ) { 1220 return (enable_tex_rect( ctx, unit ) && 1221 update_tex_common( ctx, unit )); 1222 } 1223 else if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) { 1224 return (enable_tex_2d( ctx, unit ) && 1225 update_tex_common( ctx, unit )); 1226 } 1227#if ENABLE_HW_3D_TEXTURE 1228 else if ( texUnit->_ReallyEnabled & (TEXTURE_3D_BIT) ) { 1229 return (enable_tex_3d( ctx, unit ) && 1230 update_tex_common( ctx, unit )); 1231 } 1232#endif 1233 else if ( texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT) ) { 1234 return (enable_tex_cube( ctx, unit ) && 1235 update_tex_common( ctx, unit )); 1236 } 1237 else if ( texUnit->_ReallyEnabled ) { 1238 return GL_FALSE; 1239 } 1240 else { 1241 disable_tex( ctx, unit ); 1242 return GL_TRUE; 1243 } 1244} 1245 1246 1247void r200UpdateTextureState( GLcontext *ctx ) 1248{ 1249 r200ContextPtr rmesa = R200_CONTEXT(ctx); 1250 GLboolean ok; 1251 GLuint dbg; 1252 1253 ok = (r200UpdateTextureUnit( ctx, 0 ) && 1254 r200UpdateTextureUnit( ctx, 1 )); 1255 1256 FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok ); 1257 1258 if (rmesa->TclFallback) 1259 r200ChooseVertexState( ctx ); 1260 1261 /* 1262 * T0 hang workaround ------------- 1263 */ 1264#if 1 1265 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) == R200_TEX_0_ENABLE && 1266 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) { 1267 1268 R200_STATECHANGE(rmesa, ctx); 1269 R200_STATECHANGE(rmesa, tex[1]); 1270 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE; 1271 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; 1272 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= 0x08000000; 1273 } 1274 else { 1275 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) && 1276 (rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) { 1277 R200_STATECHANGE(rmesa, tex[1]); 1278 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000; 1279 } 1280 } 1281#endif 1282 1283#if 1 1284 /* 1285 * Texture cache LRU hang workaround ------------- 1286 */ 1287 dbg = 0x0; 1288 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_0_ENABLE) && 1289 ((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 1290 0x04) == 0))) 1291 { 1292 dbg |= 0x02; 1293 } 1294 1295 if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) && 1296 ((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 1297 0x04) == 0))) 1298 { 1299 dbg |= 0x04; 1300 } 1301 1302 if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) { 1303 R200_STATECHANGE( rmesa, tam ); 1304 rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg; 1305 if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg); 1306 } 1307#endif 1308} 1309 1310/* 1311 also tests for higher texunits: 1312 1313 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) && 1314 ((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0)) || 1315 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) && 1316 ((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0))) 1317 1318 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) && 1319 ((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0)) || 1320 ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) && 1321 ((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0))) 1322 1323*/ 1324