1 /************************************************************************** 2 3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and 4 VA Linux Systems Inc., Fremont, California. 5 6 All Rights Reserved. 7 8 Permission is hereby granted, free of charge, to any person obtaining 9 a copy of this software and associated documentation files (the 10 "Software"), to deal in the Software without restriction, including 11 without limitation the rights to use, copy, modify, merge, publish, 12 distribute, sublicense, and/or sell copies of the Software, and to 13 permit persons to whom the Software is furnished to do so, subject to 14 the following conditions: 15 16 The above copyright notice and this permission notice (including the 17 next paragraph) shall be included in all copies or substantial 18 portions of the Software. 19 20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 28 **************************************************************************/ 29 30 /* 31 * Authors: 32 * Kevin E. Martin <martin (at) valinux.com> 33 * Gareth Hughes <gareth (at) valinux.com> 34 */ 35 36 #include "main/glheader.h" 37 #include "main/imports.h" 38 #include "main/context.h" 39 #include "main/macros.h" 40 #include "main/teximage.h" 41 #include "main/texstate.h" 42 #include "main/texobj.h" 43 #include "main/enums.h" 44 #include "main/samplerobj.h" 45 46 #include "radeon_context.h" 47 #include "radeon_mipmap_tree.h" 48 #include "radeon_state.h" 49 #include "radeon_ioctl.h" 50 #include "radeon_swtcl.h" 51 #include "radeon_tex.h" 52 #include "radeon_tcl.h" 53 54 55 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \ 56 && (tx_table[f].format != 0xffffffff) ) 57 58 /* ================================================================ 59 * Texture combine functions 60 */ 61 62 /* GL_ARB_texture_env_combine support 63 */ 64 65 /* The color tables have combine functions for GL_SRC_COLOR, 66 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. 67 */ 68 static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] = 69 { 70 { 71 RADEON_COLOR_ARG_A_T0_COLOR, 72 RADEON_COLOR_ARG_A_T1_COLOR, 73 RADEON_COLOR_ARG_A_T2_COLOR 74 }, 75 { 76 RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A, 77 RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A, 78 RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A 79 }, 80 { 81 RADEON_COLOR_ARG_A_T0_ALPHA, 82 RADEON_COLOR_ARG_A_T1_ALPHA, 83 RADEON_COLOR_ARG_A_T2_ALPHA 84 }, 85 { 86 RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A, 87 RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A, 88 RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A 89 }, 90 }; 91 92 static GLuint radeon_tfactor_color[] = 93 { 94 RADEON_COLOR_ARG_A_TFACTOR_COLOR, 95 RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A, 96 RADEON_COLOR_ARG_A_TFACTOR_ALPHA, 97 RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A 98 }; 99 100 static GLuint radeon_primary_color[] = 101 { 102 RADEON_COLOR_ARG_A_DIFFUSE_COLOR, 103 RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A, 104 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA, 105 RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A 106 }; 107 108 static GLuint radeon_previous_color[] = 109 { 110 RADEON_COLOR_ARG_A_CURRENT_COLOR, 111 RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A, 112 RADEON_COLOR_ARG_A_CURRENT_ALPHA, 113 RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A 114 }; 115 116 /* GL_ZERO table - indices 0-3 117 * GL_ONE table - indices 1-4 118 */ 119 static GLuint radeon_zero_color[] = 120 { 121 RADEON_COLOR_ARG_A_ZERO, 122 RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A, 123 RADEON_COLOR_ARG_A_ZERO, 124 RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A, 125 RADEON_COLOR_ARG_A_ZERO 126 }; 127 128 129 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. 130 */ 131 static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] = 132 { 133 { 134 RADEON_ALPHA_ARG_A_T0_ALPHA, 135 RADEON_ALPHA_ARG_A_T1_ALPHA, 136 RADEON_ALPHA_ARG_A_T2_ALPHA 137 }, 138 { 139 RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A, 140 RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A, 141 RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A 142 }, 143 }; 144 145 static GLuint radeon_tfactor_alpha[] = 146 { 147 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA, 148 RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A 149 }; 150 151 static GLuint radeon_primary_alpha[] = 152 { 153 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA, 154 RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A 155 }; 156 157 static GLuint radeon_previous_alpha[] = 158 { 159 RADEON_ALPHA_ARG_A_CURRENT_ALPHA, 160 RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A 161 }; 162 163 /* GL_ZERO table - indices 0-1 164 * GL_ONE table - indices 1-2 165 */ 166 static GLuint radeon_zero_alpha[] = 167 { 168 RADEON_ALPHA_ARG_A_ZERO, 169 RADEON_ALPHA_ARG_A_ZERO | RADEON_COMP_ARG_A, 170 RADEON_ALPHA_ARG_A_ZERO 171 }; 172 173 174 /* Extract the arg from slot A, shift it into the correct argument slot 175 * and set the corresponding complement bit. 176 */ 177 #define RADEON_COLOR_ARG( n, arg ) \ 178 do { \ 179 color_combine |= \ 180 ((color_arg[n] & RADEON_COLOR_ARG_MASK) \ 181 << RADEON_COLOR_ARG_##arg##_SHIFT); \ 182 color_combine |= \ 183 ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \ 184 << RADEON_COMP_ARG_##arg##_SHIFT); \ 185 } while (0) 186 187 #define RADEON_ALPHA_ARG( n, arg ) \ 188 do { \ 189 alpha_combine |= \ 190 ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \ 191 << RADEON_ALPHA_ARG_##arg##_SHIFT); \ 192 alpha_combine |= \ 193 ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \ 194 << RADEON_COMP_ARG_##arg##_SHIFT); \ 195 } while (0) 196 197 198 /* ================================================================ 199 * Texture unit state management 200 */ 201 202 static GLenum 203 texture_base_format(const struct gl_texture_object *t) 204 { 205 return t->Image[0][t->BaseLevel]->_BaseFormat; 206 } 207 208 static GLboolean radeonUpdateTextureEnv( struct gl_context *ctx, int unit ) 209 { 210 r100ContextPtr rmesa = R100_CONTEXT(ctx); 211 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 212 GLuint color_combine, alpha_combine; 213 const GLuint color_combine0 = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO 214 | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD 215 | RADEON_SCALE_1X | RADEON_CLAMP_TX; 216 const GLuint alpha_combine0 = RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO 217 | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD 218 | RADEON_SCALE_1X | RADEON_CLAMP_TX; 219 220 221 if ( RADEON_DEBUG & RADEON_TEXTURE ) { 222 fprintf( stderr, "%s( %p, %d )\n", __func__, (void *)ctx, unit ); 223 } 224 225 /* Set the texture environment state. Isn't this nice and clean? 226 * The chip will automagically set the texture alpha to 0xff when 227 * the texture format does not include an alpha component. This 228 * reduces the amount of special-casing we have to do, alpha-only 229 * textures being a notable exception. Doesn't work for luminance 230 * textures realized with I8 and ALPHA_IN_MAP not set neither (on r100). 231 */ 232 /* Don't cache these results. 233 */ 234 rmesa->state.texture.unit[unit].format = 0; 235 rmesa->state.texture.unit[unit].envMode = 0; 236 237 if ( !texUnit->_Current ) { 238 color_combine = color_combine0; 239 alpha_combine = alpha_combine0; 240 } 241 else { 242 GLuint color_arg[3], alpha_arg[3]; 243 GLuint i; 244 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB; 245 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA; 246 GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB; 247 GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA; 248 249 250 /* Step 1: 251 * Extract the color and alpha combine function arguments. 252 */ 253 for ( i = 0 ; i < numColorArgs ; i++ ) { 254 const GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR; 255 const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i]; 256 assert(op >= 0); 257 assert(op <= 3); 258 switch ( srcRGBi ) { 259 case GL_TEXTURE: 260 if (texture_base_format(texUnit->_Current) == GL_ALPHA) 261 color_arg[i] = radeon_zero_color[op]; 262 else 263 color_arg[i] = radeon_texture_color[op][unit]; 264 break; 265 case GL_CONSTANT: 266 color_arg[i] = radeon_tfactor_color[op]; 267 break; 268 case GL_PRIMARY_COLOR: 269 color_arg[i] = radeon_primary_color[op]; 270 break; 271 case GL_PREVIOUS: 272 color_arg[i] = radeon_previous_color[op]; 273 break; 274 case GL_ZERO: 275 color_arg[i] = radeon_zero_color[op]; 276 break; 277 case GL_ONE: 278 color_arg[i] = radeon_zero_color[op+1]; 279 break; 280 case GL_TEXTURE0: 281 case GL_TEXTURE1: 282 case GL_TEXTURE2: { 283 GLuint txunit = srcRGBi - GL_TEXTURE0; 284 if (texture_base_format(ctx->Texture.Unit[txunit]._Current) == GL_ALPHA) 285 color_arg[i] = radeon_zero_color[op]; 286 else 287 /* implement ogl 1.4/1.5 core spec here, not specification of 288 * GL_ARB_texture_env_crossbar (which would require disabling blending 289 * instead of undefined results when referencing not enabled texunit) */ 290 color_arg[i] = radeon_texture_color[op][txunit]; 291 } 292 break; 293 default: 294 return GL_FALSE; 295 } 296 } 297 298 for ( i = 0 ; i < numAlphaArgs ; i++ ) { 299 const GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA; 300 const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i]; 301 assert(op >= 0); 302 assert(op <= 1); 303 switch ( srcAi ) { 304 case GL_TEXTURE: 305 if (texture_base_format(texUnit->_Current) == GL_LUMINANCE) 306 alpha_arg[i] = radeon_zero_alpha[op+1]; 307 else 308 alpha_arg[i] = radeon_texture_alpha[op][unit]; 309 break; 310 case GL_CONSTANT: 311 alpha_arg[i] = radeon_tfactor_alpha[op]; 312 break; 313 case GL_PRIMARY_COLOR: 314 alpha_arg[i] = radeon_primary_alpha[op]; 315 break; 316 case GL_PREVIOUS: 317 alpha_arg[i] = radeon_previous_alpha[op]; 318 break; 319 case GL_ZERO: 320 alpha_arg[i] = radeon_zero_alpha[op]; 321 break; 322 case GL_ONE: 323 alpha_arg[i] = radeon_zero_alpha[op+1]; 324 break; 325 case GL_TEXTURE0: 326 case GL_TEXTURE1: 327 case GL_TEXTURE2: { 328 GLuint txunit = srcAi - GL_TEXTURE0; 329 if (texture_base_format(ctx->Texture.Unit[txunit]._Current) == GL_LUMINANCE) 330 alpha_arg[i] = radeon_zero_alpha[op+1]; 331 else 332 alpha_arg[i] = radeon_texture_alpha[op][txunit]; 333 } 334 break; 335 default: 336 return GL_FALSE; 337 } 338 } 339 340 /* Step 2: 341 * Build up the color and alpha combine functions. 342 */ 343 switch ( texUnit->_CurrentCombine->ModeRGB ) { 344 case GL_REPLACE: 345 color_combine = (RADEON_COLOR_ARG_A_ZERO | 346 RADEON_COLOR_ARG_B_ZERO | 347 RADEON_BLEND_CTL_ADD | 348 RADEON_CLAMP_TX); 349 RADEON_COLOR_ARG( 0, C ); 350 break; 351 case GL_MODULATE: 352 color_combine = (RADEON_COLOR_ARG_C_ZERO | 353 RADEON_BLEND_CTL_ADD | 354 RADEON_CLAMP_TX); 355 RADEON_COLOR_ARG( 0, A ); 356 RADEON_COLOR_ARG( 1, B ); 357 break; 358 case GL_ADD: 359 color_combine = (RADEON_COLOR_ARG_B_ZERO | 360 RADEON_COMP_ARG_B | 361 RADEON_BLEND_CTL_ADD | 362 RADEON_CLAMP_TX); 363 RADEON_COLOR_ARG( 0, A ); 364 RADEON_COLOR_ARG( 1, C ); 365 break; 366 case GL_ADD_SIGNED: 367 color_combine = (RADEON_COLOR_ARG_B_ZERO | 368 RADEON_COMP_ARG_B | 369 RADEON_BLEND_CTL_ADDSIGNED | 370 RADEON_CLAMP_TX); 371 RADEON_COLOR_ARG( 0, A ); 372 RADEON_COLOR_ARG( 1, C ); 373 break; 374 case GL_SUBTRACT: 375 color_combine = (RADEON_COLOR_ARG_B_ZERO | 376 RADEON_COMP_ARG_B | 377 RADEON_BLEND_CTL_SUBTRACT | 378 RADEON_CLAMP_TX); 379 RADEON_COLOR_ARG( 0, A ); 380 RADEON_COLOR_ARG( 1, C ); 381 break; 382 case GL_INTERPOLATE: 383 color_combine = (RADEON_BLEND_CTL_BLEND | 384 RADEON_CLAMP_TX); 385 RADEON_COLOR_ARG( 0, B ); 386 RADEON_COLOR_ARG( 1, A ); 387 RADEON_COLOR_ARG( 2, C ); 388 break; 389 390 case GL_DOT3_RGB_EXT: 391 case GL_DOT3_RGBA_EXT: 392 /* The EXT version of the DOT3 extension does not support the 393 * scale factor, but the ARB version (and the version in OpenGL 394 * 1.3) does. 395 */ 396 RGBshift = 0; 397 /* FALLTHROUGH */ 398 399 case GL_DOT3_RGB: 400 case GL_DOT3_RGBA: 401 /* The R100 / RV200 only support a 1X multiplier in hardware 402 * w/the ARB version. 403 */ 404 if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) { 405 return GL_FALSE; 406 } 407 408 RGBshift += 2; 409 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT) 410 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) { 411 /* is it necessary to set this or will it be ignored anyway? */ 412 Ashift = RGBshift; 413 } 414 415 color_combine = (RADEON_COLOR_ARG_C_ZERO | 416 RADEON_BLEND_CTL_DOT3 | 417 RADEON_CLAMP_TX); 418 RADEON_COLOR_ARG( 0, A ); 419 RADEON_COLOR_ARG( 1, B ); 420 break; 421 422 case GL_MODULATE_ADD_ATI: 423 color_combine = (RADEON_BLEND_CTL_ADD | 424 RADEON_CLAMP_TX); 425 RADEON_COLOR_ARG( 0, A ); 426 RADEON_COLOR_ARG( 1, C ); 427 RADEON_COLOR_ARG( 2, B ); 428 break; 429 case GL_MODULATE_SIGNED_ADD_ATI: 430 color_combine = (RADEON_BLEND_CTL_ADDSIGNED | 431 RADEON_CLAMP_TX); 432 RADEON_COLOR_ARG( 0, A ); 433 RADEON_COLOR_ARG( 1, C ); 434 RADEON_COLOR_ARG( 2, B ); 435 break; 436 case GL_MODULATE_SUBTRACT_ATI: 437 color_combine = (RADEON_BLEND_CTL_SUBTRACT | 438 RADEON_CLAMP_TX); 439 RADEON_COLOR_ARG( 0, A ); 440 RADEON_COLOR_ARG( 1, C ); 441 RADEON_COLOR_ARG( 2, B ); 442 break; 443 default: 444 return GL_FALSE; 445 } 446 447 switch ( texUnit->_CurrentCombine->ModeA ) { 448 case GL_REPLACE: 449 alpha_combine = (RADEON_ALPHA_ARG_A_ZERO | 450 RADEON_ALPHA_ARG_B_ZERO | 451 RADEON_BLEND_CTL_ADD | 452 RADEON_CLAMP_TX); 453 RADEON_ALPHA_ARG( 0, C ); 454 break; 455 case GL_MODULATE: 456 alpha_combine = (RADEON_ALPHA_ARG_C_ZERO | 457 RADEON_BLEND_CTL_ADD | 458 RADEON_CLAMP_TX); 459 RADEON_ALPHA_ARG( 0, A ); 460 RADEON_ALPHA_ARG( 1, B ); 461 break; 462 case GL_ADD: 463 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | 464 RADEON_COMP_ARG_B | 465 RADEON_BLEND_CTL_ADD | 466 RADEON_CLAMP_TX); 467 RADEON_ALPHA_ARG( 0, A ); 468 RADEON_ALPHA_ARG( 1, C ); 469 break; 470 case GL_ADD_SIGNED: 471 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | 472 RADEON_COMP_ARG_B | 473 RADEON_BLEND_CTL_ADDSIGNED | 474 RADEON_CLAMP_TX); 475 RADEON_ALPHA_ARG( 0, A ); 476 RADEON_ALPHA_ARG( 1, C ); 477 break; 478 case GL_SUBTRACT: 479 alpha_combine = (RADEON_COLOR_ARG_B_ZERO | 480 RADEON_COMP_ARG_B | 481 RADEON_BLEND_CTL_SUBTRACT | 482 RADEON_CLAMP_TX); 483 RADEON_ALPHA_ARG( 0, A ); 484 RADEON_ALPHA_ARG( 1, C ); 485 break; 486 case GL_INTERPOLATE: 487 alpha_combine = (RADEON_BLEND_CTL_BLEND | 488 RADEON_CLAMP_TX); 489 RADEON_ALPHA_ARG( 0, B ); 490 RADEON_ALPHA_ARG( 1, A ); 491 RADEON_ALPHA_ARG( 2, C ); 492 break; 493 494 case GL_MODULATE_ADD_ATI: 495 alpha_combine = (RADEON_BLEND_CTL_ADD | 496 RADEON_CLAMP_TX); 497 RADEON_ALPHA_ARG( 0, A ); 498 RADEON_ALPHA_ARG( 1, C ); 499 RADEON_ALPHA_ARG( 2, B ); 500 break; 501 case GL_MODULATE_SIGNED_ADD_ATI: 502 alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED | 503 RADEON_CLAMP_TX); 504 RADEON_ALPHA_ARG( 0, A ); 505 RADEON_ALPHA_ARG( 1, C ); 506 RADEON_ALPHA_ARG( 2, B ); 507 break; 508 case GL_MODULATE_SUBTRACT_ATI: 509 alpha_combine = (RADEON_BLEND_CTL_SUBTRACT | 510 RADEON_CLAMP_TX); 511 RADEON_ALPHA_ARG( 0, A ); 512 RADEON_ALPHA_ARG( 1, C ); 513 RADEON_ALPHA_ARG( 2, B ); 514 break; 515 default: 516 return GL_FALSE; 517 } 518 519 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB_EXT) 520 || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB) ) { 521 alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE; 522 } 523 524 /* Step 3: 525 * Apply the scale factor. 526 */ 527 color_combine |= (RGBshift << RADEON_SCALE_SHIFT); 528 alpha_combine |= (Ashift << RADEON_SCALE_SHIFT); 529 530 /* All done! 531 */ 532 } 533 534 if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine || 535 rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] != alpha_combine ) { 536 RADEON_STATECHANGE( rmesa, tex[unit] ); 537 rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] = color_combine; 538 rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] = alpha_combine; 539 } 540 541 return GL_TRUE; 542 } 543 544 void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format, 545 __DRIdrawable *dPriv) 546 { 547 struct gl_texture_object *texObj; 548 struct gl_texture_image *texImage; 549 struct radeon_renderbuffer *rb; 550 radeon_texture_image *rImage; 551 radeonContextPtr radeon; 552 struct radeon_framebuffer *rfb; 553 radeonTexObjPtr t; 554 uint32_t pitch_val; 555 mesa_format texFormat; 556 557 radeon = pDRICtx->driverPrivate; 558 559 rfb = dPriv->driverPrivate; 560 texObj = _mesa_get_current_tex_object(&radeon->glCtx, target); 561 texImage = _mesa_get_tex_image(&radeon->glCtx, texObj, target, 0); 562 563 rImage = get_radeon_texture_image(texImage); 564 t = radeon_tex_obj(texObj); 565 if (t == NULL) { 566 return; 567 } 568 569 radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE); 570 rb = rfb->color_rb[0]; 571 if (rb->bo == NULL) { 572 /* Failed to BO for the buffer */ 573 return; 574 } 575 576 _mesa_lock_texture(&radeon->glCtx, texObj); 577 if (t->bo) { 578 radeon_bo_unref(t->bo); 579 t->bo = NULL; 580 } 581 if (rImage->bo) { 582 radeon_bo_unref(rImage->bo); 583 rImage->bo = NULL; 584 } 585 586 radeon_miptree_unreference(&t->mt); 587 radeon_miptree_unreference(&rImage->mt); 588 589 rImage->bo = rb->bo; 590 radeon_bo_ref(rImage->bo); 591 t->bo = rb->bo; 592 radeon_bo_ref(t->bo); 593 t->tile_bits = 0; 594 t->image_override = GL_TRUE; 595 t->override_offset = 0; 596 switch (rb->cpp) { 597 case 4: 598 if (texture_format == __DRI_TEXTURE_FORMAT_RGB) { 599 t->pp_txformat = tx_table[MESA_FORMAT_BGR_UNORM8].format; 600 texFormat = MESA_FORMAT_BGR_UNORM8; 601 } 602 else { 603 t->pp_txformat = tx_table[MESA_FORMAT_B8G8R8A8_UNORM].format; 604 texFormat = MESA_FORMAT_B8G8R8A8_UNORM; 605 } 606 t->pp_txfilter |= tx_table[MESA_FORMAT_B8G8R8A8_UNORM].filter; 607 break; 608 case 3: 609 default: 610 texFormat = MESA_FORMAT_BGR_UNORM8; 611 t->pp_txformat = tx_table[MESA_FORMAT_BGR_UNORM8].format; 612 t->pp_txfilter |= tx_table[MESA_FORMAT_BGR_UNORM8].filter; 613 break; 614 case 2: 615 texFormat = MESA_FORMAT_B5G6R5_UNORM; 616 t->pp_txformat = tx_table[MESA_FORMAT_B5G6R5_UNORM].format; 617 t->pp_txfilter |= tx_table[MESA_FORMAT_B5G6R5_UNORM].filter; 618 break; 619 } 620 621 _mesa_init_teximage_fields(&radeon->glCtx, texImage, 622 rb->base.Base.Width, rb->base.Base.Height, 623 1, 0, 624 rb->cpp, texFormat); 625 rImage->base.RowStride = rb->pitch / rb->cpp; 626 627 t->pp_txpitch &= (1 << 13) -1; 628 pitch_val = rb->pitch; 629 630 t->pp_txsize = ((rb->base.Base.Width - 1) << RADEON_TEX_USIZE_SHIFT) 631 | ((rb->base.Base.Height - 1) << RADEON_TEX_VSIZE_SHIFT); 632 if (target == GL_TEXTURE_RECTANGLE_NV) { 633 t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2; 634 t->pp_txpitch = pitch_val; 635 t->pp_txpitch -= 32; 636 } else { 637 t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK | 638 RADEON_TXFORMAT_HEIGHT_MASK | 639 RADEON_TXFORMAT_CUBIC_MAP_ENABLE | 640 RADEON_TXFORMAT_F5_WIDTH_MASK | 641 RADEON_TXFORMAT_F5_HEIGHT_MASK); 642 t->pp_txformat |= ((texImage->WidthLog2 << RADEON_TXFORMAT_WIDTH_SHIFT) | 643 (texImage->HeightLog2 << RADEON_TXFORMAT_HEIGHT_SHIFT)); 644 } 645 t->validated = GL_TRUE; 646 _mesa_unlock_texture(&radeon->glCtx, texObj); 647 return; 648 } 649 650 651 void radeonSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) 652 { 653 radeonSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv); 654 } 655 656 657 #define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \ 658 RADEON_MIN_FILTER_MASK | \ 659 RADEON_MAG_FILTER_MASK | \ 660 RADEON_MAX_ANISO_MASK | \ 661 RADEON_YUV_TO_RGB | \ 662 RADEON_YUV_TEMPERATURE_MASK | \ 663 RADEON_CLAMP_S_MASK | \ 664 RADEON_CLAMP_T_MASK | \ 665 RADEON_BORDER_MODE_D3D ) 666 667 #define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK | \ 668 RADEON_TXFORMAT_HEIGHT_MASK | \ 669 RADEON_TXFORMAT_FORMAT_MASK | \ 670 RADEON_TXFORMAT_F5_WIDTH_MASK | \ 671 RADEON_TXFORMAT_F5_HEIGHT_MASK | \ 672 RADEON_TXFORMAT_ALPHA_IN_MAP | \ 673 RADEON_TXFORMAT_CUBIC_MAP_ENABLE | \ 674 RADEON_TXFORMAT_NON_POWER2) 675 676 677 static void disable_tex_obj_state( r100ContextPtr rmesa, 678 int unit ) 679 { 680 RADEON_STATECHANGE( rmesa, tex[unit] ); 681 682 RADEON_STATECHANGE( rmesa, tcl ); 683 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_ST_BIT(unit) | 684 RADEON_Q_BIT(unit)); 685 686 if (rmesa->radeon.TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) { 687 TCL_FALLBACK( &rmesa->radeon.glCtx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE); 688 rmesa->recheck_texgen[unit] = GL_TRUE; 689 } 690 691 if (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) { 692 /* this seems to be a genuine (r100 only?) hw bug. Need to remove the 693 cubic_map bit on unit 2 when the unit is disabled, otherwise every 694 2nd (2d) mipmap on unit 0 will be broken (may not be needed for other 695 units, better be safe than sorry though).*/ 696 RADEON_STATECHANGE( rmesa, tex[unit] ); 697 rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &= ~RADEON_TXFORMAT_CUBIC_MAP_ENABLE; 698 } 699 700 { 701 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4; 702 GLuint tmp = rmesa->TexGenEnabled; 703 704 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit); 705 rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit); 706 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift); 707 rmesa->TexGenNeedNormals[unit] = 0; 708 rmesa->TexGenEnabled |= 709 (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift; 710 711 if (tmp != rmesa->TexGenEnabled) { 712 rmesa->recheck_texgen[unit] = GL_TRUE; 713 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; 714 } 715 } 716 } 717 718 static void import_tex_obj_state( r100ContextPtr rmesa, 719 int unit, 720 radeonTexObjPtr texobj ) 721 { 722 /* do not use RADEON_DB_STATE to avoid stale texture caches */ 723 uint32_t *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0]; 724 GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT]; 725 726 RADEON_STATECHANGE( rmesa, tex[unit] ); 727 728 cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK; 729 cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK; 730 cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; 731 cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK; 732 cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color; 733 734 if (texobj->pp_txformat & RADEON_TXFORMAT_NON_POWER2) { 735 uint32_t *txr_cmd = &rmesa->hw.txr[unit].cmd[TXR_CMD_0]; 736 txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */ 737 txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */ 738 RADEON_STATECHANGE( rmesa, txr[unit] ); 739 } 740 741 if (texobj->base.Target == GL_TEXTURE_RECTANGLE_NV) { 742 se_coord_fmt |= RADEON_VTX_ST0_NONPARAMETRIC << unit; 743 } 744 else { 745 se_coord_fmt &= ~(RADEON_VTX_ST0_NONPARAMETRIC << unit); 746 747 if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) { 748 uint32_t *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0]; 749 750 RADEON_STATECHANGE( rmesa, cube[unit] ); 751 cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces; 752 /* state filled out in the cube_emit */ 753 } 754 } 755 756 if (se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT]) { 757 RADEON_STATECHANGE( rmesa, set ); 758 rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt; 759 } 760 761 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; 762 } 763 764 765 static void set_texgen_matrix( r100ContextPtr rmesa, 766 GLuint unit, 767 const GLfloat *s_plane, 768 const GLfloat *t_plane, 769 const GLfloat *r_plane, 770 const GLfloat *q_plane ) 771 { 772 rmesa->TexGenMatrix[unit].m[0] = s_plane[0]; 773 rmesa->TexGenMatrix[unit].m[4] = s_plane[1]; 774 rmesa->TexGenMatrix[unit].m[8] = s_plane[2]; 775 rmesa->TexGenMatrix[unit].m[12] = s_plane[3]; 776 777 rmesa->TexGenMatrix[unit].m[1] = t_plane[0]; 778 rmesa->TexGenMatrix[unit].m[5] = t_plane[1]; 779 rmesa->TexGenMatrix[unit].m[9] = t_plane[2]; 780 rmesa->TexGenMatrix[unit].m[13] = t_plane[3]; 781 782 rmesa->TexGenMatrix[unit].m[2] = r_plane[0]; 783 rmesa->TexGenMatrix[unit].m[6] = r_plane[1]; 784 rmesa->TexGenMatrix[unit].m[10] = r_plane[2]; 785 rmesa->TexGenMatrix[unit].m[14] = r_plane[3]; 786 787 rmesa->TexGenMatrix[unit].m[3] = q_plane[0]; 788 rmesa->TexGenMatrix[unit].m[7] = q_plane[1]; 789 rmesa->TexGenMatrix[unit].m[11] = q_plane[2]; 790 rmesa->TexGenMatrix[unit].m[15] = q_plane[3]; 791 792 rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE << unit; 793 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; 794 } 795 796 /* Returns GL_FALSE if fallback required. 797 */ 798 static GLboolean radeon_validate_texgen( struct gl_context *ctx, GLuint unit ) 799 { 800 r100ContextPtr rmesa = R100_CONTEXT(ctx); 801 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 802 GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4; 803 GLuint tmp = rmesa->TexGenEnabled; 804 static const GLfloat reflect[16] = { 805 -1, 0, 0, 0, 806 0, -1, 0, 0, 807 0, 0, -1, 0, 808 0, 0, 0, 1 }; 809 810 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE << unit); 811 rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE << unit); 812 rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK << inputshift); 813 rmesa->TexGenNeedNormals[unit] = 0; 814 815 if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT|Q_BIT)) == 0) { 816 /* Disabled, no fallback: 817 */ 818 rmesa->TexGenEnabled |= 819 (RADEON_TEXGEN_INPUT_TEXCOORD_0 + unit) << inputshift; 820 return GL_TRUE; 821 } 822 /* the r100 cannot do texgen for some coords and not for others 823 * we do not detect such cases (certainly can't do it here) and just 824 * ASSUME that when S and T are texgen enabled we do not need other 825 * non-texgen enabled coords, no matter if the R and Q bits are texgen 826 * enabled. Still check for mixed mode texgen for all coords. 827 */ 828 else if ( (texUnit->TexGenEnabled & S_BIT) && 829 (texUnit->TexGenEnabled & T_BIT) && 830 (texUnit->GenS.Mode == texUnit->GenT.Mode) ) { 831 if ( ((texUnit->TexGenEnabled & R_BIT) && 832 (texUnit->GenS.Mode != texUnit->GenR.Mode)) || 833 ((texUnit->TexGenEnabled & Q_BIT) && 834 (texUnit->GenS.Mode != texUnit->GenQ.Mode)) ) { 835 /* Mixed modes, fallback: 836 */ 837 if (RADEON_DEBUG & RADEON_FALLBACKS) 838 fprintf(stderr, "fallback mixed texgen\n"); 839 return GL_FALSE; 840 } 841 rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit; 842 } 843 else { 844 /* some texgen mode not including both S and T bits */ 845 if (RADEON_DEBUG & RADEON_FALLBACKS) 846 fprintf(stderr, "fallback mixed texgen/nontexgen\n"); 847 return GL_FALSE; 848 } 849 850 if ((texUnit->TexGenEnabled & (R_BIT | Q_BIT)) != 0) { 851 /* need this here for vtxfmt presumably. Argh we need to set 852 this from way too many places, would be much easier if we could leave 853 tcl q coord always enabled as on r200) */ 854 RADEON_STATECHANGE( rmesa, tcl ); 855 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_Q_BIT(unit); 856 } 857 858 switch (texUnit->GenS.Mode) { 859 case GL_OBJECT_LINEAR: 860 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift; 861 set_texgen_matrix( rmesa, unit, 862 texUnit->GenS.ObjectPlane, 863 texUnit->GenT.ObjectPlane, 864 texUnit->GenR.ObjectPlane, 865 texUnit->GenQ.ObjectPlane); 866 break; 867 868 case GL_EYE_LINEAR: 869 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift; 870 set_texgen_matrix( rmesa, unit, 871 texUnit->GenS.EyePlane, 872 texUnit->GenT.EyePlane, 873 texUnit->GenR.EyePlane, 874 texUnit->GenQ.EyePlane); 875 break; 876 877 case GL_REFLECTION_MAP_NV: 878 rmesa->TexGenNeedNormals[unit] = GL_TRUE; 879 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT << inputshift; 880 /* TODO: unknown if this is needed/correct */ 881 set_texgen_matrix( rmesa, unit, reflect, reflect + 4, 882 reflect + 8, reflect + 12 ); 883 break; 884 885 case GL_NORMAL_MAP_NV: 886 rmesa->TexGenNeedNormals[unit] = GL_TRUE; 887 rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL << inputshift; 888 break; 889 890 case GL_SPHERE_MAP: 891 /* the mode which everyone uses :-( */ 892 default: 893 /* Unsupported mode, fallback: 894 */ 895 if (RADEON_DEBUG & RADEON_FALLBACKS) 896 fprintf(stderr, "fallback GL_SPHERE_MAP\n"); 897 return GL_FALSE; 898 } 899 900 if (tmp != rmesa->TexGenEnabled) { 901 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; 902 } 903 904 return GL_TRUE; 905 } 906 907 /** 908 * Compute the cached hardware register values for the given texture object. 909 * 910 * \param rmesa Context pointer 911 * \param t the r300 texture object 912 */ 913 static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int unit) 914 { 915 const struct gl_texture_image *firstImage; 916 GLint log2Width, log2Height, texelBytes; 917 918 if ( t->bo ) { 919 return GL_TRUE; 920 } 921 922 firstImage = t->base.Image[0][t->minLod]; 923 924 log2Width = firstImage->WidthLog2; 925 log2Height = firstImage->HeightLog2; 926 texelBytes = _mesa_get_format_bytes(firstImage->TexFormat); 927 928 if (!t->image_override) { 929 if (VALID_FORMAT(firstImage->TexFormat)) { 930 const struct tx_table *table = tx_table; 931 932 t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK | 933 RADEON_TXFORMAT_ALPHA_IN_MAP); 934 t->pp_txfilter &= ~RADEON_YUV_TO_RGB; 935 936 t->pp_txformat |= table[ firstImage->TexFormat ].format; 937 t->pp_txfilter |= table[ firstImage->TexFormat ].filter; 938 } else { 939 _mesa_problem(NULL, "unexpected texture format in %s", 940 __func__); 941 return GL_FALSE; 942 } 943 } 944 945 t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK; 946 t->pp_txfilter |= (t->maxLod - t->minLod) << RADEON_MAX_MIP_LEVEL_SHIFT; 947 948 t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK | 949 RADEON_TXFORMAT_HEIGHT_MASK | 950 RADEON_TXFORMAT_CUBIC_MAP_ENABLE | 951 RADEON_TXFORMAT_F5_WIDTH_MASK | 952 RADEON_TXFORMAT_F5_HEIGHT_MASK); 953 t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) | 954 (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT)); 955 956 t->tile_bits = 0; 957 958 if (t->base.Target == GL_TEXTURE_CUBE_MAP) { 959 assert(log2Width == log2Height); 960 t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) | 961 (log2Height << RADEON_TXFORMAT_F5_HEIGHT_SHIFT) | 962 /* don't think we need this bit, if it exists at all - fglrx does not set it */ 963 (RADEON_TXFORMAT_CUBIC_MAP_ENABLE)); 964 t->pp_cubic_faces = ((log2Width << RADEON_FACE_WIDTH_1_SHIFT) | 965 (log2Height << RADEON_FACE_HEIGHT_1_SHIFT) | 966 (log2Width << RADEON_FACE_WIDTH_2_SHIFT) | 967 (log2Height << RADEON_FACE_HEIGHT_2_SHIFT) | 968 (log2Width << RADEON_FACE_WIDTH_3_SHIFT) | 969 (log2Height << RADEON_FACE_HEIGHT_3_SHIFT) | 970 (log2Width << RADEON_FACE_WIDTH_4_SHIFT) | 971 (log2Height << RADEON_FACE_HEIGHT_4_SHIFT)); 972 } 973 974 t->pp_txsize = (((firstImage->Width - 1) << RADEON_TEX_USIZE_SHIFT) 975 | ((firstImage->Height - 1) << RADEON_TEX_VSIZE_SHIFT)); 976 977 if ( !t->image_override ) { 978 if (_mesa_is_format_compressed(firstImage->TexFormat)) 979 t->pp_txpitch = (firstImage->Width + 63) & ~(63); 980 else 981 t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63); 982 t->pp_txpitch -= 32; 983 } 984 985 if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) { 986 t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2; 987 } 988 989 return GL_TRUE; 990 } 991 992 static GLboolean radeon_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit) 993 { 994 r100ContextPtr rmesa = R100_CONTEXT(ctx); 995 radeonTexObj *t = radeon_tex_obj(texObj); 996 int ret; 997 998 if (!radeon_validate_texture_miptree(ctx, _mesa_get_samplerobj(ctx, unit), texObj)) 999 return GL_FALSE; 1000 1001 ret = setup_hardware_state(rmesa, t, unit); 1002 if (ret == GL_FALSE) 1003 return GL_FALSE; 1004 1005 /* yuv conversion only works in first unit */ 1006 if (unit != 0 && (t->pp_txfilter & RADEON_YUV_TO_RGB)) 1007 return GL_FALSE; 1008 1009 RADEON_STATECHANGE( rmesa, ctx ); 1010 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= 1011 (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit; 1012 RADEON_STATECHANGE( rmesa, tcl ); 1013 rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit); 1014 1015 rmesa->recheck_texgen[unit] = GL_TRUE; 1016 1017 radeonTexUpdateParameters(ctx, unit); 1018 import_tex_obj_state( rmesa, unit, t ); 1019 1020 if (rmesa->recheck_texgen[unit]) { 1021 GLboolean fallback = !radeon_validate_texgen( ctx, unit ); 1022 TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback); 1023 rmesa->recheck_texgen[unit] = 0; 1024 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX; 1025 } 1026 1027 if ( ! radeonUpdateTextureEnv( ctx, unit ) ) { 1028 return GL_FALSE; 1029 } 1030 FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback ); 1031 1032 t->validated = GL_TRUE; 1033 return !t->border_fallback; 1034 } 1035 1036 static GLboolean radeonUpdateTextureUnit( struct gl_context *ctx, int unit ) 1037 { 1038 r100ContextPtr rmesa = R100_CONTEXT(ctx); 1039 1040 if (ctx->Texture.Unit[unit]._Current && 1041 ctx->Texture.Unit[unit]._Current->Target == GL_TEXTURE_3D) { 1042 disable_tex_obj_state(rmesa, unit); 1043 rmesa->state.texture.unit[unit].texobj = NULL; 1044 return GL_FALSE; 1045 } 1046 1047 if (!ctx->Texture.Unit[unit]._Current) { 1048 /* disable the unit */ 1049 disable_tex_obj_state(rmesa, unit); 1050 rmesa->state.texture.unit[unit].texobj = NULL; 1051 return GL_TRUE; 1052 } 1053 1054 if (!radeon_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) { 1055 _mesa_warning(ctx, 1056 "failed to validate texture for unit %d.\n", 1057 unit); 1058 rmesa->state.texture.unit[unit].texobj = NULL; 1059 return GL_FALSE; 1060 } 1061 rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current); 1062 return GL_TRUE; 1063 } 1064 1065 void radeonUpdateTextureState( struct gl_context *ctx ) 1066 { 1067 r100ContextPtr rmesa = R100_CONTEXT(ctx); 1068 GLboolean ok; 1069 1070 /* set the ctx all textures off */ 1071 RADEON_STATECHANGE( rmesa, ctx ); 1072 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((RADEON_TEX_ENABLE_MASK) | (RADEON_TEX_BLEND_ENABLE_MASK)); 1073 1074 ok = (radeonUpdateTextureUnit( ctx, 0 ) && 1075 radeonUpdateTextureUnit( ctx, 1 ) && 1076 radeonUpdateTextureUnit( ctx, 2 )); 1077 1078 FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok ); 1079 1080 if (rmesa->radeon.TclFallback) 1081 radeonChooseVertexState( ctx ); 1082 } 1083