1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/** 26 * \file texstate.c 27 * 28 * Texture state handling. 29 */ 30 31#include <stdio.h> 32#include "glheader.h" 33#include "bufferobj.h" 34#include "context.h" 35#include "enums.h" 36#include "macros.h" 37#include "texobj.h" 38#include "teximage.h" 39#include "texstate.h" 40#include "mtypes.h" 41#include "state.h" 42#include "util/bitscan.h" 43#include "util/bitset.h" 44 45 46/** 47 * Default texture combine environment state. This is used to initialize 48 * a context's texture units and as the basis for converting "classic" 49 * texture environmnets to ARB_texture_env_combine style values. 50 */ 51static const struct gl_tex_env_combine_state default_combine_state = { 52 GL_MODULATE, GL_MODULATE, 53 { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT }, 54 { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT }, 55 { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA, GL_SRC_ALPHA }, 56 { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA }, 57 0, 0, 58 2, 2 59}; 60 61 62 63/** 64 * Used by glXCopyContext to copy texture state from one context to another. 65 */ 66void 67_mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst ) 68{ 69 GLuint u, tex; 70 71 assert(src); 72 assert(dst); 73 74 dst->Texture.CurrentUnit = src->Texture.CurrentUnit; 75 76 /* per-unit state */ 77 for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) { 78 dst->Texture.Unit[u].LodBias = src->Texture.Unit[u].LodBias; 79 dst->Texture.Unit[u].LodBiasQuantized = src->Texture.Unit[u].LodBiasQuantized; 80 81 /* 82 * XXX strictly speaking, we should compare texture names/ids and 83 * bind textures in the dest context according to id. For now, only 84 * copy bindings if the contexts share the same pool of textures to 85 * avoid refcounting bugs. 86 */ 87 if (dst->Shared == src->Shared) { 88 /* copy texture object bindings, not contents of texture objects */ 89 _mesa_lock_context_textures(dst); 90 91 for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 92 _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex], 93 src->Texture.Unit[u].CurrentTex[tex]); 94 if (src->Texture.Unit[u].CurrentTex[tex]) { 95 dst->Texture.NumCurrentTexUsed = 96 MAX2(dst->Texture.NumCurrentTexUsed, u + 1); 97 } 98 } 99 dst->Texture.Unit[u]._BoundTextures = src->Texture.Unit[u]._BoundTextures; 100 _mesa_unlock_context_textures(dst); 101 } 102 } 103 104 for (u = 0; u < src->Const.MaxTextureCoordUnits; u++) { 105 dst->Texture.FixedFuncUnit[u].Enabled = src->Texture.FixedFuncUnit[u].Enabled; 106 dst->Texture.FixedFuncUnit[u].EnvMode = src->Texture.FixedFuncUnit[u].EnvMode; 107 COPY_4V(dst->Texture.FixedFuncUnit[u].EnvColor, src->Texture.FixedFuncUnit[u].EnvColor); 108 dst->Texture.FixedFuncUnit[u].TexGenEnabled = src->Texture.FixedFuncUnit[u].TexGenEnabled; 109 dst->Texture.FixedFuncUnit[u].GenS = src->Texture.FixedFuncUnit[u].GenS; 110 dst->Texture.FixedFuncUnit[u].GenT = src->Texture.FixedFuncUnit[u].GenT; 111 dst->Texture.FixedFuncUnit[u].GenR = src->Texture.FixedFuncUnit[u].GenR; 112 dst->Texture.FixedFuncUnit[u].GenQ = src->Texture.FixedFuncUnit[u].GenQ; 113 memcpy(dst->Texture.FixedFuncUnit[u].ObjectPlane, 114 src->Texture.FixedFuncUnit[u].ObjectPlane, 115 sizeof(src->Texture.FixedFuncUnit[u].ObjectPlane)); 116 memcpy(dst->Texture.FixedFuncUnit[u].EyePlane, 117 src->Texture.FixedFuncUnit[u].EyePlane, 118 sizeof(src->Texture.FixedFuncUnit[u].EyePlane)); 119 120 /* GL_EXT_texture_env_combine */ 121 dst->Texture.FixedFuncUnit[u].Combine = src->Texture.FixedFuncUnit[u].Combine; 122 } 123} 124 125 126/* 127 * For debugging 128 */ 129void 130_mesa_print_texunit_state( struct gl_context *ctx, GLuint unit ) 131{ 132 const struct gl_fixedfunc_texture_unit *texUnit = ctx->Texture.FixedFuncUnit + unit; 133 printf("Texture Unit %d\n", unit); 134 printf(" GL_TEXTURE_ENV_MODE = %s\n", _mesa_enum_to_string(texUnit->EnvMode)); 135 printf(" GL_COMBINE_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeRGB)); 136 printf(" GL_COMBINE_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeA)); 137 printf(" GL_SOURCE0_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[0])); 138 printf(" GL_SOURCE1_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[1])); 139 printf(" GL_SOURCE2_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[2])); 140 printf(" GL_SOURCE0_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[0])); 141 printf(" GL_SOURCE1_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[1])); 142 printf(" GL_SOURCE2_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[2])); 143 printf(" GL_OPERAND0_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[0])); 144 printf(" GL_OPERAND1_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[1])); 145 printf(" GL_OPERAND2_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[2])); 146 printf(" GL_OPERAND0_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[0])); 147 printf(" GL_OPERAND1_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[1])); 148 printf(" GL_OPERAND2_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[2])); 149 printf(" GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB); 150 printf(" GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA); 151 printf(" GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]); 152} 153 154 155 156/**********************************************************************/ 157/* Texture Environment */ 158/**********************************************************************/ 159 160/** 161 * Convert "classic" texture environment to ARB_texture_env_combine style 162 * environments. 163 * 164 * \param state texture_env_combine state vector to be filled-in. 165 * \param mode Classic texture environment mode (i.e., \c GL_REPLACE, 166 * \c GL_BLEND, \c GL_DECAL, etc.). 167 * \param texBaseFormat Base format of the texture associated with the 168 * texture unit. 169 */ 170static void 171calculate_derived_texenv( struct gl_tex_env_combine_state *state, 172 GLenum mode, GLenum texBaseFormat ) 173{ 174 GLenum mode_rgb; 175 GLenum mode_a; 176 177 *state = default_combine_state; 178 179 switch (texBaseFormat) { 180 case GL_ALPHA: 181 state->SourceRGB[0] = GL_PREVIOUS; 182 break; 183 184 case GL_LUMINANCE_ALPHA: 185 case GL_INTENSITY: 186 case GL_RGBA: 187 break; 188 189 case GL_LUMINANCE: 190 case GL_RED: 191 case GL_RG: 192 case GL_RGB: 193 case GL_YCBCR_MESA: 194 state->SourceA[0] = GL_PREVIOUS; 195 break; 196 197 default: 198 _mesa_problem(NULL, 199 "Invalid texBaseFormat 0x%x in calculate_derived_texenv", 200 texBaseFormat); 201 return; 202 } 203 204 if (mode == GL_REPLACE_EXT) 205 mode = GL_REPLACE; 206 207 switch (mode) { 208 case GL_REPLACE: 209 case GL_MODULATE: 210 mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode; 211 mode_a = mode; 212 break; 213 214 case GL_DECAL: 215 mode_rgb = GL_INTERPOLATE; 216 mode_a = GL_REPLACE; 217 218 state->SourceA[0] = GL_PREVIOUS; 219 220 /* Having alpha / luminance / intensity textures replace using the 221 * incoming fragment color matches the definition in NV_texture_shader. 222 * The 1.5 spec simply marks these as "undefined". 223 */ 224 switch (texBaseFormat) { 225 case GL_ALPHA: 226 case GL_LUMINANCE: 227 case GL_LUMINANCE_ALPHA: 228 case GL_INTENSITY: 229 state->SourceRGB[0] = GL_PREVIOUS; 230 break; 231 case GL_RED: 232 case GL_RG: 233 case GL_RGB: 234 case GL_YCBCR_MESA: 235 mode_rgb = GL_REPLACE; 236 break; 237 case GL_RGBA: 238 state->SourceRGB[2] = GL_TEXTURE; 239 break; 240 } 241 break; 242 243 case GL_BLEND: 244 mode_rgb = GL_INTERPOLATE; 245 mode_a = GL_MODULATE; 246 247 switch (texBaseFormat) { 248 case GL_ALPHA: 249 mode_rgb = GL_REPLACE; 250 break; 251 case GL_INTENSITY: 252 mode_a = GL_INTERPOLATE; 253 state->SourceA[0] = GL_CONSTANT; 254 state->OperandA[2] = GL_SRC_ALPHA; 255 FALLTHROUGH; 256 case GL_LUMINANCE: 257 case GL_RED: 258 case GL_RG: 259 case GL_RGB: 260 case GL_LUMINANCE_ALPHA: 261 case GL_RGBA: 262 case GL_YCBCR_MESA: 263 state->SourceRGB[2] = GL_TEXTURE; 264 state->SourceA[2] = GL_TEXTURE; 265 state->SourceRGB[0] = GL_CONSTANT; 266 state->OperandRGB[2] = GL_SRC_COLOR; 267 break; 268 } 269 break; 270 271 case GL_ADD: 272 mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD; 273 mode_a = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE; 274 break; 275 276 default: 277 _mesa_problem(NULL, 278 "Invalid texture env mode 0x%x in calculate_derived_texenv", 279 mode); 280 return; 281 } 282 283 state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS) 284 ? mode_rgb : GL_REPLACE; 285 state->ModeA = (state->SourceA[0] != GL_PREVIOUS) 286 ? mode_a : GL_REPLACE; 287} 288 289 290/* GL_ARB_multitexture */ 291static ALWAYS_INLINE void 292active_texture(GLenum texture, bool no_error) 293{ 294 const GLuint texUnit = texture - GL_TEXTURE0; 295 296 GET_CURRENT_CONTEXT(ctx); 297 298 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 299 _mesa_debug(ctx, "glActiveTexture %s\n", 300 _mesa_enum_to_string(texture)); 301 302 if (ctx->Texture.CurrentUnit == texUnit) 303 return; 304 305 if (!no_error) { 306 GLuint k = _mesa_max_tex_unit(ctx); 307 308 assert(k <= ARRAY_SIZE(ctx->Texture.Unit)); 309 310 if (texUnit >= k) { 311 _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)", 312 _mesa_enum_to_string(texture)); 313 return; 314 } 315 } 316 317 318 /* The below flush call seems useless because 319 * gl_context::Texture::CurrentUnit is not used by 320 * _mesa_update_texture_state() and friends. 321 * 322 * However removing the flush 323 * introduced some blinking textures in UT2004. More investigation is 324 * needed to find the root cause. 325 * 326 * https://bugs.freedesktop.org/show_bug.cgi?id=105436 327 */ 328 FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT); 329 330 ctx->Texture.CurrentUnit = texUnit; 331 if (ctx->Transform.MatrixMode == GL_TEXTURE) { 332 /* update current stack pointer */ 333 ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit]; 334 } 335} 336 337 338void GLAPIENTRY 339_mesa_ActiveTexture_no_error(GLenum texture) 340{ 341 active_texture(texture, true); 342} 343 344 345void GLAPIENTRY 346_mesa_ActiveTexture(GLenum texture) 347{ 348 active_texture(texture, false); 349} 350 351 352/* GL_ARB_multitexture */ 353void GLAPIENTRY 354_mesa_ClientActiveTexture(GLenum texture) 355{ 356 GET_CURRENT_CONTEXT(ctx); 357 GLuint texUnit = texture - GL_TEXTURE0; 358 359 if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) 360 _mesa_debug(ctx, "glClientActiveTexture %s\n", 361 _mesa_enum_to_string(texture)); 362 363 if (ctx->Array.ActiveTexture == texUnit) 364 return; 365 366 if (texUnit >= ctx->Const.MaxTextureCoordUnits) { 367 _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture=%s)", 368 _mesa_enum_to_string(texture)); 369 return; 370 } 371 372 /* Don't flush vertices. This is a "latched" state. */ 373 ctx->Array.ActiveTexture = texUnit; 374} 375 376 377 378/**********************************************************************/ 379/***** State management *****/ 380/**********************************************************************/ 381 382 383/** 384 * \note This routine refers to derived texture attribute values to 385 * compute the ENABLE_TEXMAT flags, but is only called on 386 * _NEW_TEXTURE_MATRIX. On changes to _NEW_TEXTURE_OBJECT/STATE, 387 * the ENABLE_TEXMAT flags are updated by _mesa_update_textures(), below. 388 * 389 * \param ctx GL context. 390 */ 391GLbitfield 392_mesa_update_texture_matrices(struct gl_context *ctx) 393{ 394 GLuint u; 395 GLbitfield old_texmat_enabled = ctx->Texture._TexMatEnabled; 396 397 ctx->Texture._TexMatEnabled = 0x0; 398 399 for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { 400 assert(u < ARRAY_SIZE(ctx->TextureMatrixStack)); 401 if (_math_matrix_is_dirty(ctx->TextureMatrixStack[u].Top)) { 402 _math_matrix_analyse( ctx->TextureMatrixStack[u].Top ); 403 404 if (ctx->Texture.Unit[u]._Current && 405 ctx->TextureMatrixStack[u].Top->type != MATRIX_IDENTITY) 406 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(u); 407 } 408 } 409 410 if (old_texmat_enabled != ctx->Texture._TexMatEnabled) 411 return _NEW_FF_VERT_PROGRAM | _NEW_FF_FRAG_PROGRAM; 412 413 return 0; 414} 415 416 417/** 418 * Translate GL combiner state into a MODE_x value 419 */ 420static uint32_t 421tex_combine_translate_mode(GLenum envMode, GLenum mode) 422{ 423 switch (mode) { 424 case GL_REPLACE: return TEXENV_MODE_REPLACE; 425 case GL_MODULATE: return TEXENV_MODE_MODULATE; 426 case GL_ADD: 427 if (envMode == GL_COMBINE4_NV) 428 return TEXENV_MODE_ADD_PRODUCTS_NV; 429 else 430 return TEXENV_MODE_ADD; 431 case GL_ADD_SIGNED: 432 if (envMode == GL_COMBINE4_NV) 433 return TEXENV_MODE_ADD_PRODUCTS_SIGNED_NV; 434 else 435 return TEXENV_MODE_ADD_SIGNED; 436 case GL_INTERPOLATE: return TEXENV_MODE_INTERPOLATE; 437 case GL_SUBTRACT: return TEXENV_MODE_SUBTRACT; 438 case GL_DOT3_RGB: return TEXENV_MODE_DOT3_RGB; 439 case GL_DOT3_RGB_EXT: return TEXENV_MODE_DOT3_RGB_EXT; 440 case GL_DOT3_RGBA: return TEXENV_MODE_DOT3_RGBA; 441 case GL_DOT3_RGBA_EXT: return TEXENV_MODE_DOT3_RGBA_EXT; 442 case GL_MODULATE_ADD_ATI: return TEXENV_MODE_MODULATE_ADD_ATI; 443 case GL_MODULATE_SIGNED_ADD_ATI: return TEXENV_MODE_MODULATE_SIGNED_ADD_ATI; 444 case GL_MODULATE_SUBTRACT_ATI: return TEXENV_MODE_MODULATE_SUBTRACT_ATI; 445 default: 446 unreachable("Invalid TexEnv Combine mode"); 447 } 448} 449 450 451static uint8_t 452tex_combine_translate_source(GLenum src) 453{ 454 switch (src) { 455 case GL_TEXTURE0: 456 case GL_TEXTURE1: 457 case GL_TEXTURE2: 458 case GL_TEXTURE3: 459 case GL_TEXTURE4: 460 case GL_TEXTURE5: 461 case GL_TEXTURE6: 462 case GL_TEXTURE7: return TEXENV_SRC_TEXTURE0 + (src - GL_TEXTURE0); 463 case GL_TEXTURE: return TEXENV_SRC_TEXTURE; 464 case GL_PREVIOUS: return TEXENV_SRC_PREVIOUS; 465 case GL_PRIMARY_COLOR: return TEXENV_SRC_PRIMARY_COLOR; 466 case GL_CONSTANT: return TEXENV_SRC_CONSTANT; 467 case GL_ZERO: return TEXENV_SRC_ZERO; 468 case GL_ONE: return TEXENV_SRC_ONE; 469 default: 470 unreachable("Invalid TexEnv Combine argument source"); 471 } 472} 473 474 475static uint8_t 476tex_combine_translate_operand(GLenum operand) 477{ 478 switch (operand) { 479 case GL_SRC_COLOR: return TEXENV_OPR_COLOR; 480 case GL_ONE_MINUS_SRC_COLOR: return TEXENV_OPR_ONE_MINUS_COLOR; 481 case GL_SRC_ALPHA: return TEXENV_OPR_ALPHA; 482 case GL_ONE_MINUS_SRC_ALPHA: return TEXENV_OPR_ONE_MINUS_ALPHA; 483 default: 484 unreachable("Invalid TexEnv Combine argument source"); 485 } 486} 487 488 489static void 490pack_tex_combine(struct gl_fixedfunc_texture_unit *texUnit) 491{ 492 struct gl_tex_env_combine_state *state = texUnit->_CurrentCombine; 493 struct gl_tex_env_combine_packed *packed = &texUnit->_CurrentCombinePacked; 494 495 memset(packed, 0, sizeof *packed); 496 497 packed->ModeRGB = tex_combine_translate_mode(texUnit->EnvMode, state->ModeRGB); 498 packed->ModeA = tex_combine_translate_mode(texUnit->EnvMode, state->ModeA); 499 packed->ScaleShiftRGB = state->ScaleShiftRGB; 500 packed->ScaleShiftA = state->ScaleShiftA; 501 packed->NumArgsRGB = state->_NumArgsRGB; 502 packed->NumArgsA = state->_NumArgsA; 503 504 for (int i = 0; i < state->_NumArgsRGB; ++i) 505 { 506 packed->ArgsRGB[i].Source = tex_combine_translate_source(state->SourceRGB[i]); 507 packed->ArgsRGB[i].Operand = tex_combine_translate_operand(state->OperandRGB[i]); 508 } 509 510 for (int i = 0; i < state->_NumArgsA; ++i) 511 { 512 packed->ArgsA[i].Source = tex_combine_translate_source(state->SourceA[i]); 513 packed->ArgsA[i].Operand = tex_combine_translate_operand(state->OperandA[i]); 514 } 515} 516 517 518/** 519 * Examine texture unit's combine/env state to update derived state. 520 */ 521static void 522update_tex_combine(struct gl_context *ctx, 523 struct gl_texture_unit *texUnit, 524 struct gl_fixedfunc_texture_unit *fftexUnit) 525{ 526 struct gl_tex_env_combine_state *combine; 527 528 /* No combiners will apply to this. */ 529 if (texUnit->_Current->Target == GL_TEXTURE_BUFFER) 530 return; 531 532 /* Set the texUnit->_CurrentCombine field to point to the user's combiner 533 * state, or the combiner state which is derived from traditional texenv 534 * mode. 535 */ 536 if (fftexUnit->EnvMode == GL_COMBINE || 537 fftexUnit->EnvMode == GL_COMBINE4_NV) { 538 fftexUnit->_CurrentCombine = & fftexUnit->Combine; 539 } 540 else { 541 const struct gl_texture_object *texObj = texUnit->_Current; 542 GLenum format = texObj->Image[0][texObj->Attrib.BaseLevel]->_BaseFormat; 543 544 if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) { 545 format = texObj->Attrib.DepthMode; 546 } 547 calculate_derived_texenv(&fftexUnit->_EnvMode, fftexUnit->EnvMode, format); 548 fftexUnit->_CurrentCombine = & fftexUnit->_EnvMode; 549 } 550 551 combine = fftexUnit->_CurrentCombine; 552 553 /* Determine number of source RGB terms in the combiner function */ 554 switch (combine->ModeRGB) { 555 case GL_REPLACE: 556 combine->_NumArgsRGB = 1; 557 break; 558 case GL_ADD: 559 case GL_ADD_SIGNED: 560 if (fftexUnit->EnvMode == GL_COMBINE4_NV) 561 combine->_NumArgsRGB = 4; 562 else 563 combine->_NumArgsRGB = 2; 564 break; 565 case GL_MODULATE: 566 case GL_SUBTRACT: 567 case GL_DOT3_RGB: 568 case GL_DOT3_RGBA: 569 case GL_DOT3_RGB_EXT: 570 case GL_DOT3_RGBA_EXT: 571 combine->_NumArgsRGB = 2; 572 break; 573 case GL_INTERPOLATE: 574 case GL_MODULATE_ADD_ATI: 575 case GL_MODULATE_SIGNED_ADD_ATI: 576 case GL_MODULATE_SUBTRACT_ATI: 577 combine->_NumArgsRGB = 3; 578 break; 579 default: 580 combine->_NumArgsRGB = 0; 581 _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state"); 582 return; 583 } 584 585 /* Determine number of source Alpha terms in the combiner function */ 586 switch (combine->ModeA) { 587 case GL_REPLACE: 588 combine->_NumArgsA = 1; 589 break; 590 case GL_ADD: 591 case GL_ADD_SIGNED: 592 if (fftexUnit->EnvMode == GL_COMBINE4_NV) 593 combine->_NumArgsA = 4; 594 else 595 combine->_NumArgsA = 2; 596 break; 597 case GL_MODULATE: 598 case GL_SUBTRACT: 599 combine->_NumArgsA = 2; 600 break; 601 case GL_INTERPOLATE: 602 case GL_MODULATE_ADD_ATI: 603 case GL_MODULATE_SIGNED_ADD_ATI: 604 case GL_MODULATE_SUBTRACT_ATI: 605 combine->_NumArgsA = 3; 606 break; 607 default: 608 combine->_NumArgsA = 0; 609 _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state"); 610 break; 611 } 612 613 pack_tex_combine(fftexUnit); 614} 615 616static void 617update_texgen(struct gl_context *ctx) 618{ 619 GLuint unit; 620 621 /* Setup texgen for those texture coordinate sets that are in use */ 622 for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) { 623 struct gl_fixedfunc_texture_unit *texUnit = 624 &ctx->Texture.FixedFuncUnit[unit]; 625 626 texUnit->_GenFlags = 0x0; 627 628 if (!(ctx->Texture._EnabledCoordUnits & (1 << unit))) 629 continue; 630 631 if (texUnit->TexGenEnabled) { 632 if (texUnit->TexGenEnabled & S_BIT) { 633 texUnit->_GenFlags |= texUnit->GenS._ModeBit; 634 } 635 if (texUnit->TexGenEnabled & T_BIT) { 636 texUnit->_GenFlags |= texUnit->GenT._ModeBit; 637 } 638 if (texUnit->TexGenEnabled & R_BIT) { 639 texUnit->_GenFlags |= texUnit->GenR._ModeBit; 640 } 641 if (texUnit->TexGenEnabled & Q_BIT) { 642 texUnit->_GenFlags |= texUnit->GenQ._ModeBit; 643 } 644 645 ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit); 646 ctx->Texture._GenFlags |= texUnit->_GenFlags; 647 } 648 649 assert(unit < ARRAY_SIZE(ctx->TextureMatrixStack)); 650 if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) 651 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit); 652 } 653} 654 655static struct gl_texture_object * 656update_single_program_texture(struct gl_context *ctx, struct gl_program *prog, 657 int unit) 658{ 659 gl_texture_index target_index; 660 struct gl_texture_unit *texUnit; 661 struct gl_texture_object *texObj; 662 struct gl_sampler_object *sampler; 663 664 texUnit = &ctx->Texture.Unit[unit]; 665 666 /* Note: If more than one bit was set in TexturesUsed[unit], then we should 667 * have had the draw call rejected already. From the GL 4.4 specification, 668 * section 7.10 ("Samplers"): 669 * 670 * "It is not allowed to have variables of different sampler types 671 * pointing to the same texture image unit within a program 672 * object. This situation can only be detected at the next rendering 673 * command issued which triggers shader invocations, and an 674 * INVALID_OPERATION error will then be generated." 675 */ 676 target_index = ffs(prog->TexturesUsed[unit]) - 1; 677 texObj = texUnit->CurrentTex[target_index]; 678 679 sampler = texUnit->Sampler ? 680 texUnit->Sampler : &texObj->Sampler; 681 682 if (likely(texObj)) { 683 if (_mesa_is_texture_complete(texObj, sampler, 684 ctx->Const.ForceIntegerTexNearest)) 685 return texObj; 686 687 _mesa_test_texobj_completeness(ctx, texObj); 688 if (_mesa_is_texture_complete(texObj, sampler, 689 ctx->Const.ForceIntegerTexNearest)) 690 return texObj; 691 } 692 693 /* If we've reached this point, we didn't find a complete texture of the 694 * shader's target. From the GL 4.4 core specification, section 11.1.3.5 695 * ("Texture Access"): 696 * 697 * "If a sampler is used in a shader and the sampler’s associated 698 * texture is not complete, as defined in section 8.17, (0, 0, 0, 1) 699 * will be returned for a non-shadow sampler and 0 for a shadow 700 * sampler." 701 * 702 * Mesa implements this by creating a hidden texture object with a pixel of 703 * that value. 704 */ 705 texObj = _mesa_get_fallback_texture(ctx, target_index); 706 assert(texObj); 707 708 return texObj; 709} 710 711static inline void 712update_single_program_texture_state(struct gl_context *ctx, 713 struct gl_program *prog, 714 int unit, 715 BITSET_WORD *enabled_texture_units) 716{ 717 struct gl_texture_object *texObj; 718 719 texObj = update_single_program_texture(ctx, prog, unit); 720 721 _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj); 722 BITSET_SET(enabled_texture_units, unit); 723 ctx->Texture._MaxEnabledTexImageUnit = 724 MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit); 725} 726 727static void 728update_program_texture_state(struct gl_context *ctx, struct gl_program **prog, 729 BITSET_WORD *enabled_texture_units) 730{ 731 int i; 732 733 for (i = 0; i < MESA_SHADER_STAGES; i++) { 734 GLbitfield mask; 735 GLuint s; 736 737 if (!prog[i]) 738 continue; 739 740 mask = prog[i]->SamplersUsed; 741 742 while (mask) { 743 s = u_bit_scan(&mask); 744 745 update_single_program_texture_state(ctx, prog[i], 746 prog[i]->SamplerUnits[s], 747 enabled_texture_units); 748 } 749 750 if (unlikely(prog[i]->sh.HasBoundBindlessSampler)) { 751 /* Loop over bindless samplers bound to texture units. 752 */ 753 for (s = 0; s < prog[i]->sh.NumBindlessSamplers; s++) { 754 struct gl_bindless_sampler *sampler = 755 &prog[i]->sh.BindlessSamplers[s]; 756 757 if (!sampler->bound) 758 continue; 759 760 update_single_program_texture_state(ctx, prog[i], sampler->unit, 761 enabled_texture_units); 762 } 763 } 764 } 765 766 if (prog[MESA_SHADER_FRAGMENT]) { 767 const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1; 768 ctx->Texture._EnabledCoordUnits |= 769 (prog[MESA_SHADER_FRAGMENT]->info.inputs_read >> VARYING_SLOT_TEX0) & 770 coordMask; 771 } 772} 773 774static void 775update_ff_texture_state(struct gl_context *ctx, 776 BITSET_WORD *enabled_texture_units) 777{ 778 int unit; 779 780 for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 781 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 782 struct gl_fixedfunc_texture_unit *fftexUnit = 783 &ctx->Texture.FixedFuncUnit[unit]; 784 GLbitfield mask; 785 bool complete; 786 787 if (fftexUnit->Enabled == 0x0) 788 continue; 789 790 /* If a shader already dictated what texture target was used for this 791 * unit, just go along with it. 792 */ 793 if (BITSET_TEST(enabled_texture_units, unit)) 794 continue; 795 796 /* From the GL 4.4 compat specification, section 16.2 ("Texture Application"): 797 * 798 * "Texturing is enabled or disabled using the generic Enable and 799 * Disable commands, respectively, with the symbolic constants 800 * TEXTURE_1D, TEXTURE_2D, TEXTURE_RECTANGLE, TEXTURE_3D, or 801 * TEXTURE_CUBE_MAP to enable the one-, two-, rectangular, 802 * three-dimensional, or cube map texture, respectively. If more 803 * than one of these textures is enabled, the first one enabled 804 * from the following list is used: 805 * 806 * • cube map texture 807 * • three-dimensional texture 808 * • rectangular texture 809 * • two-dimensional texture 810 * • one-dimensional texture" 811 * 812 * Note that the TEXTURE_x_INDEX values are in high to low priority. 813 * Also: 814 * 815 * "If a texture unit is disabled or has an invalid or incomplete 816 * texture (as defined in section 8.17) bound to it, then blending 817 * is disabled for that texture unit. If the texture environment 818 * for a given enabled texture unit references a disabled texture 819 * unit, or an invalid or incomplete texture that is bound to 820 * another unit, then the results of texture blending are 821 * undefined." 822 */ 823 complete = false; 824 mask = fftexUnit->Enabled; 825 while (mask) { 826 const int texIndex = u_bit_scan(&mask); 827 struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex]; 828 struct gl_sampler_object *sampler = texUnit->Sampler ? 829 texUnit->Sampler : &texObj->Sampler; 830 831 if (!_mesa_is_texture_complete(texObj, sampler, 832 ctx->Const.ForceIntegerTexNearest)) { 833 _mesa_test_texobj_completeness(ctx, texObj); 834 } 835 if (_mesa_is_texture_complete(texObj, sampler, 836 ctx->Const.ForceIntegerTexNearest)) { 837 _mesa_reference_texobj(&texUnit->_Current, texObj); 838 complete = true; 839 break; 840 } 841 } 842 843 if (!complete) 844 continue; 845 846 /* if we get here, we know this texture unit is enabled */ 847 BITSET_SET(enabled_texture_units, unit); 848 ctx->Texture._MaxEnabledTexImageUnit = 849 MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit); 850 851 ctx->Texture._EnabledCoordUnits |= 1 << unit; 852 853 update_tex_combine(ctx, texUnit, fftexUnit); 854 } 855} 856 857static void 858fix_missing_textures_for_atifs(struct gl_context *ctx, 859 struct gl_program *prog, 860 BITSET_WORD *enabled_texture_units) 861{ 862 GLbitfield mask = prog->SamplersUsed; 863 864 while (mask) { 865 const int s = u_bit_scan(&mask); 866 const int unit = prog->SamplerUnits[s]; 867 const gl_texture_index target_index = ffs(prog->TexturesUsed[unit]) - 1; 868 869 if (!ctx->Texture.Unit[unit]._Current) { 870 struct gl_texture_object *texObj = 871 _mesa_get_fallback_texture(ctx, target_index); 872 _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj); 873 BITSET_SET(enabled_texture_units, unit); 874 ctx->Texture._MaxEnabledTexImageUnit = 875 MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit); 876 } 877 } 878} 879 880/** 881 * \note This routine refers to derived texture matrix values to 882 * compute the ENABLE_TEXMAT flags, but is only called on 883 * _NEW_TEXTURE_OBJECT/STATE. On changes to _NEW_TEXTURE_MATRIX, 884 * the ENABLE_TEXMAT flags are updated by _mesa_update_texture_matrices, 885 * above. 886 * 887 * \param ctx GL context. 888 */ 889GLbitfield 890_mesa_update_texture_state(struct gl_context *ctx) 891{ 892 struct gl_program *prog[MESA_SHADER_STAGES]; 893 int i; 894 int old_max_unit = ctx->Texture._MaxEnabledTexImageUnit; 895 BITSET_DECLARE(enabled_texture_units, MAX_COMBINED_TEXTURE_IMAGE_UNITS); 896 897 memcpy(prog, ctx->_Shader->CurrentProgram, sizeof(prog)); 898 899 if (prog[MESA_SHADER_FRAGMENT] == NULL && 900 _mesa_arb_fragment_program_enabled(ctx)) { 901 prog[MESA_SHADER_FRAGMENT] = ctx->FragmentProgram.Current; 902 } 903 904 /* TODO: only set this if there are actual changes */ 905 ctx->NewState |= _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE; 906 907 GLbitfield old_genflags = ctx->Texture._GenFlags; 908 GLbitfield old_enabled_coord_units = ctx->Texture._EnabledCoordUnits; 909 GLbitfield old_texgen_enabled = ctx->Texture._TexGenEnabled; 910 GLbitfield old_texmat_enabled = ctx->Texture._TexMatEnabled; 911 912 ctx->Texture._GenFlags = 0x0; 913 ctx->Texture._TexMatEnabled = 0x0; 914 ctx->Texture._TexGenEnabled = 0x0; 915 ctx->Texture._MaxEnabledTexImageUnit = -1; 916 ctx->Texture._EnabledCoordUnits = 0x0; 917 918 memset(&enabled_texture_units, 0, sizeof(enabled_texture_units)); 919 920 /* First, walk over our programs pulling in all the textures for them. 921 * Programs dictate specific texture targets to be enabled, and for a draw 922 * call to be valid they can't conflict about which texture targets are 923 * used. 924 */ 925 update_program_texture_state(ctx, prog, enabled_texture_units); 926 927 /* Also pull in any textures necessary for fixed function fragment shading. 928 */ 929 if (!prog[MESA_SHADER_FRAGMENT]) 930 update_ff_texture_state(ctx, enabled_texture_units); 931 932 /* Now, clear out the _Current of any disabled texture units. */ 933 for (i = 0; i <= ctx->Texture._MaxEnabledTexImageUnit; i++) { 934 if (!BITSET_TEST(enabled_texture_units, i)) 935 _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL); 936 } 937 for (i = ctx->Texture._MaxEnabledTexImageUnit + 1; i <= old_max_unit; i++) { 938 _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL); 939 } 940 941 /* add fallback texture for SampleMapATI if there is nothing */ 942 if (_mesa_ati_fragment_shader_enabled(ctx) && 943 ctx->ATIFragmentShader.Current->Program) 944 fix_missing_textures_for_atifs(ctx, 945 ctx->ATIFragmentShader.Current->Program, 946 enabled_texture_units); 947 948 if (!prog[MESA_SHADER_FRAGMENT] || !prog[MESA_SHADER_VERTEX]) 949 update_texgen(ctx); 950 951 GLbitfield new_state = 0; 952 953 if (old_enabled_coord_units != ctx->Texture._EnabledCoordUnits || 954 old_texgen_enabled != ctx->Texture._TexGenEnabled || 955 old_texmat_enabled != ctx->Texture._TexMatEnabled) { 956 new_state |= _NEW_FF_VERT_PROGRAM | _NEW_FF_FRAG_PROGRAM; 957 } 958 959 if (old_genflags != ctx->Texture._GenFlags) 960 new_state |= _NEW_TNL_SPACES; 961 962 return new_state; 963} 964 965 966/**********************************************************************/ 967/***** Initialization *****/ 968/**********************************************************************/ 969 970/** 971 * Allocate the proxy textures for the given context. 972 * 973 * \param ctx the context to allocate proxies for. 974 * 975 * \return GL_TRUE on success, or GL_FALSE on failure 976 * 977 * If run out of memory part way through the allocations, clean up and return 978 * GL_FALSE. 979 */ 980static GLboolean 981alloc_proxy_textures( struct gl_context *ctx ) 982{ 983 /* NOTE: these values must be in the same order as the TEXTURE_x_INDEX 984 * values! 985 */ 986 static const GLenum targets[] = { 987 GL_TEXTURE_2D_MULTISAMPLE, 988 GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 989 GL_TEXTURE_CUBE_MAP_ARRAY, 990 GL_TEXTURE_BUFFER, 991 GL_TEXTURE_2D_ARRAY_EXT, 992 GL_TEXTURE_1D_ARRAY_EXT, 993 GL_TEXTURE_EXTERNAL_OES, 994 GL_TEXTURE_CUBE_MAP, 995 GL_TEXTURE_3D, 996 GL_TEXTURE_RECTANGLE_NV, 997 GL_TEXTURE_2D, 998 GL_TEXTURE_1D, 999 }; 1000 GLint tgt; 1001 1002 STATIC_ASSERT(ARRAY_SIZE(targets) == NUM_TEXTURE_TARGETS); 1003 assert(targets[TEXTURE_2D_INDEX] == GL_TEXTURE_2D); 1004 assert(targets[TEXTURE_CUBE_INDEX] == GL_TEXTURE_CUBE_MAP); 1005 1006 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 1007 if (!(ctx->Texture.ProxyTex[tgt] 1008 = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) { 1009 /* out of memory, free what we did allocate */ 1010 while (--tgt >= 0) { 1011 ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); 1012 } 1013 return GL_FALSE; 1014 } 1015 } 1016 1017 assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */ 1018 return GL_TRUE; 1019} 1020 1021 1022/** 1023 * Initialize texture state for the given context. 1024 */ 1025GLboolean 1026_mesa_init_texture(struct gl_context *ctx) 1027{ 1028 GLuint u; 1029 1030 /* Texture group */ 1031 ctx->Texture.CurrentUnit = 0; /* multitexture */ 1032 1033 /* Appendix F.2 of the OpenGL ES 3.0 spec says: 1034 * 1035 * "OpenGL ES 3.0 requires that all cube map filtering be 1036 * seamless. OpenGL ES 2.0 specified that a single cube map face be 1037 * selected and used for filtering." 1038 * 1039 * Unfortunatley, a call to _mesa_is_gles3 below will only work if 1040 * the driver has already computed and set ctx->Version, however drivers 1041 * seem to call _mesa_initialize_context (which calls this) early 1042 * in the CreateContext hook and _mesa_compute_version much later (since 1043 * it needs information about available extensions). So, we will 1044 * enable seamless cubemaps by default since GLES2. This should work 1045 * for most implementations and drivers that don't support seamless 1046 * cubemaps for GLES2 can still disable it. 1047 */ 1048 ctx->Texture.CubeMapSeamless = ctx->API == API_OPENGLES2; 1049 1050 for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) { 1051 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u]; 1052 GLuint tex; 1053 1054 /* initialize current texture object ptrs to the shared default objects */ 1055 for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 1056 _mesa_reference_texobj(&texUnit->CurrentTex[tex], 1057 ctx->Shared->DefaultTex[tex]); 1058 } 1059 1060 texUnit->_BoundTextures = 0; 1061 } 1062 1063 for (u = 0; u < ARRAY_SIZE(ctx->Texture.FixedFuncUnit); u++) { 1064 struct gl_fixedfunc_texture_unit *texUnit = 1065 &ctx->Texture.FixedFuncUnit[u]; 1066 1067 texUnit->EnvMode = GL_MODULATE; 1068 ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 ); 1069 1070 texUnit->Combine = default_combine_state; 1071 texUnit->_EnvMode = default_combine_state; 1072 texUnit->_CurrentCombine = & texUnit->_EnvMode; 1073 1074 texUnit->TexGenEnabled = 0x0; 1075 texUnit->GenS.Mode = GL_EYE_LINEAR; 1076 texUnit->GenT.Mode = GL_EYE_LINEAR; 1077 texUnit->GenR.Mode = GL_EYE_LINEAR; 1078 texUnit->GenQ.Mode = GL_EYE_LINEAR; 1079 texUnit->GenS._ModeBit = TEXGEN_EYE_LINEAR; 1080 texUnit->GenT._ModeBit = TEXGEN_EYE_LINEAR; 1081 texUnit->GenR._ModeBit = TEXGEN_EYE_LINEAR; 1082 texUnit->GenQ._ModeBit = TEXGEN_EYE_LINEAR; 1083 1084 /* Yes, these plane coefficients are correct! */ 1085 ASSIGN_4V( texUnit->ObjectPlane[GEN_S], 1.0, 0.0, 0.0, 0.0 ); 1086 ASSIGN_4V( texUnit->ObjectPlane[GEN_T], 0.0, 1.0, 0.0, 0.0 ); 1087 ASSIGN_4V( texUnit->ObjectPlane[GEN_R], 0.0, 0.0, 0.0, 0.0 ); 1088 ASSIGN_4V( texUnit->ObjectPlane[GEN_Q], 0.0, 0.0, 0.0, 0.0 ); 1089 ASSIGN_4V( texUnit->EyePlane[GEN_S], 1.0, 0.0, 0.0, 0.0 ); 1090 ASSIGN_4V( texUnit->EyePlane[GEN_T], 0.0, 1.0, 0.0, 0.0 ); 1091 ASSIGN_4V( texUnit->EyePlane[GEN_R], 0.0, 0.0, 0.0, 0.0 ); 1092 ASSIGN_4V( texUnit->EyePlane[GEN_Q], 0.0, 0.0, 0.0, 0.0 ); 1093 } 1094 1095 /* After we're done initializing the context's texture state the default 1096 * texture objects' refcounts should be at least 1097 * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1. 1098 */ 1099 assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount 1100 >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1); 1101 1102 /* Allocate proxy textures */ 1103 if (!alloc_proxy_textures( ctx )) 1104 return GL_FALSE; 1105 1106 /* GL_ARB_texture_buffer_object */ 1107 _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL); 1108 1109 ctx->Texture.NumCurrentTexUsed = 0; 1110 1111 return GL_TRUE; 1112} 1113 1114 1115/** 1116 * Free dynamically-allocted texture data attached to the given context. 1117 */ 1118void 1119_mesa_free_texture_data(struct gl_context *ctx) 1120{ 1121 GLuint u, tgt; 1122 1123 /* unreference current textures */ 1124 for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) { 1125 /* The _Current texture could account for another reference */ 1126 _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL); 1127 1128 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 1129 _mesa_reference_texobj(&ctx->Texture.Unit[u].CurrentTex[tgt], NULL); 1130 } 1131 } 1132 1133 /* Free proxy texture objects */ 1134 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) 1135 ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); 1136 1137 /* GL_ARB_texture_buffer_object */ 1138 _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL); 1139 1140 for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) { 1141 _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[u].Sampler, NULL); 1142 } 1143} 1144 1145 1146/** 1147 * Update the default texture objects in the given context to reference those 1148 * specified in the shared state and release those referencing the old 1149 * shared state. 1150 */ 1151void 1152_mesa_update_default_objects_texture(struct gl_context *ctx) 1153{ 1154 GLuint u, tex; 1155 1156 for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) { 1157 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u]; 1158 for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { 1159 _mesa_reference_texobj(&texUnit->CurrentTex[tex], 1160 ctx->Shared->DefaultTex[tex]); 1161 } 1162 } 1163} 1164