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