texobj.c revision 848b8605
1/** 2 * \file texobj.c 3 * Texture object management. 4 */ 5 6/* 7 * Mesa 3-D graphics library 8 * 9 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 10 * 11 * Permission is hereby granted, free of charge, to any person obtaining a 12 * copy of this software and associated documentation files (the "Software"), 13 * to deal in the Software without restriction, including without limitation 14 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 15 * and/or sell copies of the Software, and to permit persons to whom the 16 * Software is furnished to do so, subject to the following conditions: 17 * 18 * The above copyright notice and this permission notice shall be included 19 * in all copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 25 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 26 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27 * OTHER DEALINGS IN THE SOFTWARE. 28 */ 29 30 31#include "bufferobj.h" 32#include "colortab.h" 33#include "context.h" 34#include "enums.h" 35#include "fbobject.h" 36#include "formats.h" 37#include "hash.h" 38#include "imports.h" 39#include "macros.h" 40#include "teximage.h" 41#include "texobj.h" 42#include "texstate.h" 43#include "mtypes.h" 44#include "program/prog_instruction.h" 45 46 47 48/**********************************************************************/ 49/** \name Internal functions */ 50/*@{*/ 51 52 53/** 54 * Return the gl_texture_object for a given ID. 55 */ 56struct gl_texture_object * 57_mesa_lookup_texture(struct gl_context *ctx, GLuint id) 58{ 59 return (struct gl_texture_object *) 60 _mesa_HashLookup(ctx->Shared->TexObjects, id); 61} 62 63 64void 65_mesa_begin_texture_lookups(struct gl_context *ctx) 66{ 67 _mesa_HashLockMutex(ctx->Shared->TexObjects); 68} 69 70 71void 72_mesa_end_texture_lookups(struct gl_context *ctx) 73{ 74 _mesa_HashUnlockMutex(ctx->Shared->TexObjects); 75} 76 77 78struct gl_texture_object * 79_mesa_lookup_texture_locked(struct gl_context *ctx, GLuint id) 80{ 81 return (struct gl_texture_object *) 82 _mesa_HashLookupLocked(ctx->Shared->TexObjects, id); 83} 84 85 86/** 87 * Allocate and initialize a new texture object. But don't put it into the 88 * texture object hash table. 89 * 90 * Called via ctx->Driver.NewTextureObject, unless overridden by a device 91 * driver. 92 * 93 * \param shared the shared GL state structure to contain the texture object 94 * \param name integer name for the texture object 95 * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, 96 * GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV. zero is ok for the sake 97 * of GenTextures() 98 * 99 * \return pointer to new texture object. 100 */ 101struct gl_texture_object * 102_mesa_new_texture_object( struct gl_context *ctx, GLuint name, GLenum target ) 103{ 104 struct gl_texture_object *obj; 105 (void) ctx; 106 obj = MALLOC_STRUCT(gl_texture_object); 107 _mesa_initialize_texture_object(ctx, obj, name, target); 108 return obj; 109} 110 111 112/** 113 * Initialize a new texture object to default values. 114 * \param obj the texture object 115 * \param name the texture name 116 * \param target the texture target 117 */ 118void 119_mesa_initialize_texture_object( struct gl_context *ctx, 120 struct gl_texture_object *obj, 121 GLuint name, GLenum target ) 122{ 123 ASSERT(target == 0 || 124 target == GL_TEXTURE_1D || 125 target == GL_TEXTURE_2D || 126 target == GL_TEXTURE_3D || 127 target == GL_TEXTURE_CUBE_MAP_ARB || 128 target == GL_TEXTURE_RECTANGLE_NV || 129 target == GL_TEXTURE_1D_ARRAY_EXT || 130 target == GL_TEXTURE_2D_ARRAY_EXT || 131 target == GL_TEXTURE_EXTERNAL_OES || 132 target == GL_TEXTURE_CUBE_MAP_ARRAY || 133 target == GL_TEXTURE_BUFFER || 134 target == GL_TEXTURE_2D_MULTISAMPLE || 135 target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 136 137 memset(obj, 0, sizeof(*obj)); 138 /* init the non-zero fields */ 139 mtx_init(&obj->Mutex, mtx_plain); 140 obj->RefCount = 1; 141 obj->Name = name; 142 obj->Target = target; 143 obj->Priority = 1.0F; 144 obj->BaseLevel = 0; 145 obj->MaxLevel = 1000; 146 147 /* must be one; no support for (YUV) planes in separate buffers */ 148 obj->RequiredTextureImageUnits = 1; 149 150 /* sampler state */ 151 if (target == GL_TEXTURE_RECTANGLE_NV || 152 target == GL_TEXTURE_EXTERNAL_OES) { 153 obj->Sampler.WrapS = GL_CLAMP_TO_EDGE; 154 obj->Sampler.WrapT = GL_CLAMP_TO_EDGE; 155 obj->Sampler.WrapR = GL_CLAMP_TO_EDGE; 156 obj->Sampler.MinFilter = GL_LINEAR; 157 } 158 else { 159 obj->Sampler.WrapS = GL_REPEAT; 160 obj->Sampler.WrapT = GL_REPEAT; 161 obj->Sampler.WrapR = GL_REPEAT; 162 obj->Sampler.MinFilter = GL_NEAREST_MIPMAP_LINEAR; 163 } 164 obj->Sampler.MagFilter = GL_LINEAR; 165 obj->Sampler.MinLod = -1000.0; 166 obj->Sampler.MaxLod = 1000.0; 167 obj->Sampler.LodBias = 0.0; 168 obj->Sampler.MaxAnisotropy = 1.0; 169 obj->Sampler.CompareMode = GL_NONE; /* ARB_shadow */ 170 obj->Sampler.CompareFunc = GL_LEQUAL; /* ARB_shadow */ 171 obj->DepthMode = ctx->API == API_OPENGL_CORE ? GL_RED : GL_LUMINANCE; 172 obj->StencilSampling = false; 173 obj->Sampler.CubeMapSeamless = GL_FALSE; 174 obj->Swizzle[0] = GL_RED; 175 obj->Swizzle[1] = GL_GREEN; 176 obj->Swizzle[2] = GL_BLUE; 177 obj->Swizzle[3] = GL_ALPHA; 178 obj->_Swizzle = SWIZZLE_NOOP; 179 obj->Sampler.sRGBDecode = GL_DECODE_EXT; 180 obj->BufferObjectFormat = GL_R8; 181 obj->_BufferObjectFormat = MESA_FORMAT_R_UNORM8; 182 obj->ImageFormatCompatibilityType = GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE; 183} 184 185 186/** 187 * Some texture initialization can't be finished until we know which 188 * target it's getting bound to (GL_TEXTURE_1D/2D/etc). 189 */ 190static void 191finish_texture_init(struct gl_context *ctx, GLenum target, 192 struct gl_texture_object *obj) 193{ 194 GLenum filter = GL_LINEAR; 195 assert(obj->Target == 0); 196 197 switch (target) { 198 case GL_TEXTURE_2D_MULTISAMPLE: 199 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 200 filter = GL_NEAREST; 201 /* fallthrough */ 202 203 case GL_TEXTURE_RECTANGLE_NV: 204 case GL_TEXTURE_EXTERNAL_OES: 205 /* have to init wrap and filter state here - kind of klunky */ 206 obj->Sampler.WrapS = GL_CLAMP_TO_EDGE; 207 obj->Sampler.WrapT = GL_CLAMP_TO_EDGE; 208 obj->Sampler.WrapR = GL_CLAMP_TO_EDGE; 209 obj->Sampler.MinFilter = filter; 210 obj->Sampler.MagFilter = filter; 211 if (ctx->Driver.TexParameter) { 212 static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE}; 213 const GLfloat fparam_filter[1] = {(GLfloat) filter}; 214 ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_WRAP_S, fparam_wrap); 215 ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_WRAP_T, fparam_wrap); 216 ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_WRAP_R, fparam_wrap); 217 ctx->Driver.TexParameter(ctx, obj, 218 GL_TEXTURE_MIN_FILTER, fparam_filter); 219 ctx->Driver.TexParameter(ctx, obj, 220 GL_TEXTURE_MAG_FILTER, fparam_filter); 221 } 222 break; 223 224 default: 225 /* nothing needs done */ 226 break; 227 } 228} 229 230 231/** 232 * Deallocate a texture object struct. It should have already been 233 * removed from the texture object pool. 234 * Called via ctx->Driver.DeleteTexture() if not overriden by a driver. 235 * 236 * \param shared the shared GL state to which the object belongs. 237 * \param texObj the texture object to delete. 238 */ 239void 240_mesa_delete_texture_object(struct gl_context *ctx, 241 struct gl_texture_object *texObj) 242{ 243 GLuint i, face; 244 245 /* Set Target to an invalid value. With some assertions elsewhere 246 * we can try to detect possible use of deleted textures. 247 */ 248 texObj->Target = 0x99; 249 250 /* free the texture images */ 251 for (face = 0; face < 6; face++) { 252 for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { 253 if (texObj->Image[face][i]) { 254 ctx->Driver.DeleteTextureImage(ctx, texObj->Image[face][i]); 255 } 256 } 257 } 258 259 _mesa_reference_buffer_object(ctx, &texObj->BufferObject, NULL); 260 261 /* destroy the mutex -- it may have allocated memory (eg on bsd) */ 262 mtx_destroy(&texObj->Mutex); 263 264 free(texObj->Label); 265 266 /* free this object */ 267 free(texObj); 268} 269 270 271 272/** 273 * Copy texture object state from one texture object to another. 274 * Use for glPush/PopAttrib. 275 * 276 * \param dest destination texture object. 277 * \param src source texture object. 278 */ 279void 280_mesa_copy_texture_object( struct gl_texture_object *dest, 281 const struct gl_texture_object *src ) 282{ 283 dest->Target = src->Target; 284 dest->TargetIndex = src->TargetIndex; 285 dest->Name = src->Name; 286 dest->Priority = src->Priority; 287 dest->Sampler.BorderColor.f[0] = src->Sampler.BorderColor.f[0]; 288 dest->Sampler.BorderColor.f[1] = src->Sampler.BorderColor.f[1]; 289 dest->Sampler.BorderColor.f[2] = src->Sampler.BorderColor.f[2]; 290 dest->Sampler.BorderColor.f[3] = src->Sampler.BorderColor.f[3]; 291 dest->Sampler.WrapS = src->Sampler.WrapS; 292 dest->Sampler.WrapT = src->Sampler.WrapT; 293 dest->Sampler.WrapR = src->Sampler.WrapR; 294 dest->Sampler.MinFilter = src->Sampler.MinFilter; 295 dest->Sampler.MagFilter = src->Sampler.MagFilter; 296 dest->Sampler.MinLod = src->Sampler.MinLod; 297 dest->Sampler.MaxLod = src->Sampler.MaxLod; 298 dest->Sampler.LodBias = src->Sampler.LodBias; 299 dest->BaseLevel = src->BaseLevel; 300 dest->MaxLevel = src->MaxLevel; 301 dest->Sampler.MaxAnisotropy = src->Sampler.MaxAnisotropy; 302 dest->Sampler.CompareMode = src->Sampler.CompareMode; 303 dest->Sampler.CompareFunc = src->Sampler.CompareFunc; 304 dest->Sampler.CubeMapSeamless = src->Sampler.CubeMapSeamless; 305 dest->DepthMode = src->DepthMode; 306 dest->StencilSampling = src->StencilSampling; 307 dest->Sampler.sRGBDecode = src->Sampler.sRGBDecode; 308 dest->_MaxLevel = src->_MaxLevel; 309 dest->_MaxLambda = src->_MaxLambda; 310 dest->GenerateMipmap = src->GenerateMipmap; 311 dest->_BaseComplete = src->_BaseComplete; 312 dest->_MipmapComplete = src->_MipmapComplete; 313 COPY_4V(dest->Swizzle, src->Swizzle); 314 dest->_Swizzle = src->_Swizzle; 315 316 dest->RequiredTextureImageUnits = src->RequiredTextureImageUnits; 317} 318 319 320/** 321 * Free all texture images of the given texture object. 322 * 323 * \param ctx GL context. 324 * \param t texture object. 325 * 326 * \sa _mesa_clear_texture_image(). 327 */ 328void 329_mesa_clear_texture_object(struct gl_context *ctx, 330 struct gl_texture_object *texObj) 331{ 332 GLuint i, j; 333 334 if (texObj->Target == 0) 335 return; 336 337 for (i = 0; i < MAX_FACES; i++) { 338 for (j = 0; j < MAX_TEXTURE_LEVELS; j++) { 339 struct gl_texture_image *texImage = texObj->Image[i][j]; 340 if (texImage) 341 _mesa_clear_texture_image(ctx, texImage); 342 } 343 } 344} 345 346 347/** 348 * Check if the given texture object is valid by examining its Target field. 349 * For debugging only. 350 */ 351static GLboolean 352valid_texture_object(const struct gl_texture_object *tex) 353{ 354 switch (tex->Target) { 355 case 0: 356 case GL_TEXTURE_1D: 357 case GL_TEXTURE_2D: 358 case GL_TEXTURE_3D: 359 case GL_TEXTURE_CUBE_MAP_ARB: 360 case GL_TEXTURE_RECTANGLE_NV: 361 case GL_TEXTURE_1D_ARRAY_EXT: 362 case GL_TEXTURE_2D_ARRAY_EXT: 363 case GL_TEXTURE_BUFFER: 364 case GL_TEXTURE_EXTERNAL_OES: 365 case GL_TEXTURE_CUBE_MAP_ARRAY: 366 case GL_TEXTURE_2D_MULTISAMPLE: 367 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 368 return GL_TRUE; 369 case 0x99: 370 _mesa_problem(NULL, "invalid reference to a deleted texture object"); 371 return GL_FALSE; 372 default: 373 _mesa_problem(NULL, "invalid texture object Target 0x%x, Id = %u", 374 tex->Target, tex->Name); 375 return GL_FALSE; 376 } 377} 378 379 380/** 381 * Reference (or unreference) a texture object. 382 * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero). 383 * If 'tex' is non-null, increment its refcount. 384 * This is normally only called from the _mesa_reference_texobj() macro 385 * when there's a real pointer change. 386 */ 387void 388_mesa_reference_texobj_(struct gl_texture_object **ptr, 389 struct gl_texture_object *tex) 390{ 391 assert(ptr); 392 393 if (*ptr) { 394 /* Unreference the old texture */ 395 GLboolean deleteFlag = GL_FALSE; 396 struct gl_texture_object *oldTex = *ptr; 397 398 ASSERT(valid_texture_object(oldTex)); 399 (void) valid_texture_object; /* silence warning in release builds */ 400 401 mtx_lock(&oldTex->Mutex); 402 ASSERT(oldTex->RefCount > 0); 403 oldTex->RefCount--; 404 405 deleteFlag = (oldTex->RefCount == 0); 406 mtx_unlock(&oldTex->Mutex); 407 408 if (deleteFlag) { 409 GET_CURRENT_CONTEXT(ctx); 410 if (ctx) 411 ctx->Driver.DeleteTexture(ctx, oldTex); 412 else 413 _mesa_problem(NULL, "Unable to delete texture, no context"); 414 } 415 416 *ptr = NULL; 417 } 418 assert(!*ptr); 419 420 if (tex) { 421 /* reference new texture */ 422 ASSERT(valid_texture_object(tex)); 423 mtx_lock(&tex->Mutex); 424 if (tex->RefCount == 0) { 425 /* this texture's being deleted (look just above) */ 426 /* Not sure this can every really happen. Warn if it does. */ 427 _mesa_problem(NULL, "referencing deleted texture object"); 428 *ptr = NULL; 429 } 430 else { 431 tex->RefCount++; 432 *ptr = tex; 433 } 434 mtx_unlock(&tex->Mutex); 435 } 436} 437 438 439enum base_mipmap { BASE, MIPMAP }; 440 441 442/** 443 * Mark a texture object as incomplete. There are actually three kinds of 444 * (in)completeness: 445 * 1. "base incomplete": the base level of the texture is invalid so no 446 * texturing is possible. 447 * 2. "mipmap incomplete": a non-base level of the texture is invalid so 448 * mipmap filtering isn't possible, but non-mipmap filtering is. 449 * 3. "texture incompleteness": some combination of texture state and 450 * sampler state renders the texture incomplete. 451 * 452 * \param t texture object 453 * \param bm either BASE or MIPMAP to indicate what's incomplete 454 * \param fmt... string describing why it's incomplete (for debugging). 455 */ 456static void 457incomplete(struct gl_texture_object *t, enum base_mipmap bm, 458 const char *fmt, ...) 459{ 460 if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_TEXTURE) { 461 va_list args; 462 char s[100]; 463 464 va_start(args, fmt); 465 vsnprintf(s, sizeof(s), fmt, args); 466 va_end(args); 467 468 _mesa_debug(NULL, "Texture Obj %d incomplete because: %s\n", t->Name, s); 469 } 470 471 if (bm == BASE) 472 t->_BaseComplete = GL_FALSE; 473 t->_MipmapComplete = GL_FALSE; 474} 475 476 477/** 478 * Examine a texture object to determine if it is complete. 479 * 480 * The gl_texture_object::Complete flag will be set to GL_TRUE or GL_FALSE 481 * accordingly. 482 * 483 * \param ctx GL context. 484 * \param t texture object. 485 * 486 * According to the texture target, verifies that each of the mipmaps is 487 * present and has the expected size. 488 */ 489void 490_mesa_test_texobj_completeness( const struct gl_context *ctx, 491 struct gl_texture_object *t ) 492{ 493 const GLint baseLevel = t->BaseLevel; 494 const struct gl_texture_image *baseImage; 495 GLint maxLevels = 0; 496 497 /* We'll set these to FALSE if tests fail below */ 498 t->_BaseComplete = GL_TRUE; 499 t->_MipmapComplete = GL_TRUE; 500 501 if (t->Target == GL_TEXTURE_BUFFER) { 502 /* Buffer textures are always considered complete. The obvious case where 503 * they would be incomplete (no BO attached) is actually specced to be 504 * undefined rendering results. 505 */ 506 return; 507 } 508 509 /* Detect cases where the application set the base level to an invalid 510 * value. 511 */ 512 if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) { 513 incomplete(t, BASE, "base level = %d is invalid", baseLevel); 514 return; 515 } 516 517 if (t->MaxLevel < baseLevel) { 518 incomplete(t, MIPMAP, "MAX_LEVEL (%d) < BASE_LEVEL (%d)", 519 t->MaxLevel, baseLevel); 520 return; 521 } 522 523 baseImage = t->Image[0][baseLevel]; 524 525 /* Always need the base level image */ 526 if (!baseImage) { 527 incomplete(t, BASE, "Image[baseLevel=%d] == NULL", baseLevel); 528 return; 529 } 530 531 /* Check width/height/depth for zero */ 532 if (baseImage->Width == 0 || 533 baseImage->Height == 0 || 534 baseImage->Depth == 0) { 535 incomplete(t, BASE, "texture width or height or depth = 0"); 536 return; 537 } 538 539 /* Check if the texture values are integer */ 540 { 541 GLenum datatype = _mesa_get_format_datatype(baseImage->TexFormat); 542 t->_IsIntegerFormat = datatype == GL_INT || datatype == GL_UNSIGNED_INT; 543 } 544 545 /* Compute _MaxLevel (the maximum mipmap level we'll sample from given the 546 * mipmap image sizes and GL_TEXTURE_MAX_LEVEL state). 547 */ 548 switch (t->Target) { 549 case GL_TEXTURE_1D: 550 case GL_TEXTURE_1D_ARRAY_EXT: 551 maxLevels = ctx->Const.MaxTextureLevels; 552 break; 553 case GL_TEXTURE_2D: 554 case GL_TEXTURE_2D_ARRAY_EXT: 555 maxLevels = ctx->Const.MaxTextureLevels; 556 break; 557 case GL_TEXTURE_3D: 558 maxLevels = ctx->Const.Max3DTextureLevels; 559 break; 560 case GL_TEXTURE_CUBE_MAP_ARB: 561 case GL_TEXTURE_CUBE_MAP_ARRAY: 562 maxLevels = ctx->Const.MaxCubeTextureLevels; 563 break; 564 case GL_TEXTURE_RECTANGLE_NV: 565 case GL_TEXTURE_BUFFER: 566 case GL_TEXTURE_EXTERNAL_OES: 567 case GL_TEXTURE_2D_MULTISAMPLE: 568 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 569 maxLevels = 1; /* no mipmapping */ 570 break; 571 default: 572 _mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness"); 573 return; 574 } 575 576 ASSERT(maxLevels > 0); 577 578 t->_MaxLevel = MIN3(t->MaxLevel, 579 /* 'p' in the GL spec */ 580 (int) (baseLevel + baseImage->MaxNumLevels - 1), 581 /* 'q' in the GL spec */ 582 maxLevels - 1); 583 584 if (t->Immutable) { 585 /* Adjust max level for views: the data store may have more levels than 586 * the view exposes. 587 */ 588 t->_MaxLevel = MIN2(t->_MaxLevel, t->NumLevels - 1); 589 } 590 591 /* Compute _MaxLambda = q - p in the spec used during mipmapping */ 592 t->_MaxLambda = (GLfloat) (t->_MaxLevel - baseLevel); 593 594 if (t->Immutable) { 595 /* This texture object was created with glTexStorage1/2/3D() so we 596 * know that all the mipmap levels are the right size and all cube 597 * map faces are the same size. 598 * We don't need to do any of the additional checks below. 599 */ 600 return; 601 } 602 603 if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) { 604 /* Make sure that all six cube map level 0 images are the same size. 605 * Note: we know that the image's width==height (we enforce that 606 * at glTexImage time) so we only need to test the width here. 607 */ 608 GLuint face; 609 assert(baseImage->Width2 == baseImage->Height); 610 for (face = 1; face < 6; face++) { 611 assert(t->Image[face][baseLevel] == NULL || 612 t->Image[face][baseLevel]->Width2 == 613 t->Image[face][baseLevel]->Height2); 614 if (t->Image[face][baseLevel] == NULL || 615 t->Image[face][baseLevel]->Width2 != baseImage->Width2) { 616 incomplete(t, BASE, "Cube face missing or mismatched size"); 617 return; 618 } 619 } 620 } 621 622 /* 623 * Do mipmap consistency checking. 624 * Note: we don't care about the current texture sampler state here. 625 * To determine texture completeness we'll either look at _BaseComplete 626 * or _MipmapComplete depending on the current minification filter mode. 627 */ 628 { 629 GLint i; 630 const GLint minLevel = baseLevel; 631 const GLint maxLevel = t->_MaxLevel; 632 const GLuint numFaces = _mesa_num_tex_faces(t->Target); 633 GLuint width, height, depth, face; 634 635 if (minLevel > maxLevel) { 636 incomplete(t, MIPMAP, "minLevel > maxLevel"); 637 return; 638 } 639 640 /* Get the base image's dimensions */ 641 width = baseImage->Width2; 642 height = baseImage->Height2; 643 depth = baseImage->Depth2; 644 645 /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL, 646 * MULTISAMPLE and MULTISAMPLE_ARRAY textures 647 */ 648 for (i = baseLevel + 1; i < maxLevels; i++) { 649 /* Compute the expected size of image at level[i] */ 650 if (width > 1) { 651 width /= 2; 652 } 653 if (height > 1 && t->Target != GL_TEXTURE_1D_ARRAY) { 654 height /= 2; 655 } 656 if (depth > 1 && t->Target != GL_TEXTURE_2D_ARRAY && t->Target != GL_TEXTURE_CUBE_MAP_ARRAY) { 657 depth /= 2; 658 } 659 660 /* loop over cube faces (or single face otherwise) */ 661 for (face = 0; face < numFaces; face++) { 662 if (i >= minLevel && i <= maxLevel) { 663 const struct gl_texture_image *img = t->Image[face][i]; 664 665 if (!img) { 666 incomplete(t, MIPMAP, "TexImage[%d] is missing", i); 667 return; 668 } 669 if (img->TexFormat != baseImage->TexFormat) { 670 incomplete(t, MIPMAP, "Format[i] != Format[baseLevel]"); 671 return; 672 } 673 if (img->Border != baseImage->Border) { 674 incomplete(t, MIPMAP, "Border[i] != Border[baseLevel]"); 675 return; 676 } 677 if (img->Width2 != width) { 678 incomplete(t, MIPMAP, "TexImage[%d] bad width %u", i, img->Width2); 679 return; 680 } 681 if (img->Height2 != height) { 682 incomplete(t, MIPMAP, "TexImage[%d] bad height %u", i, img->Height2); 683 return; 684 } 685 if (img->Depth2 != depth) { 686 incomplete(t, MIPMAP, "TexImage[%d] bad depth %u", i, img->Depth2); 687 return; 688 } 689 690 /* Extra checks for cube textures */ 691 if (face > 0) { 692 /* check that cube faces are the same size */ 693 if (img->Width2 != t->Image[0][i]->Width2 || 694 img->Height2 != t->Image[0][i]->Height2) { 695 incomplete(t, MIPMAP, "CubeMap Image[n][i] bad size"); 696 return; 697 } 698 } 699 } 700 } 701 702 if (width == 1 && height == 1 && depth == 1) { 703 return; /* found smallest needed mipmap, all done! */ 704 } 705 } 706 } 707} 708 709 710/** 711 * Check if the given cube map texture is "cube complete" as defined in 712 * the OpenGL specification. 713 */ 714GLboolean 715_mesa_cube_complete(const struct gl_texture_object *texObj) 716{ 717 const GLint baseLevel = texObj->BaseLevel; 718 const struct gl_texture_image *img0, *img; 719 GLuint face; 720 721 if (texObj->Target != GL_TEXTURE_CUBE_MAP) 722 return GL_FALSE; 723 724 if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) 725 return GL_FALSE; 726 727 /* check first face */ 728 img0 = texObj->Image[0][baseLevel]; 729 if (!img0 || 730 img0->Width < 1 || 731 img0->Width != img0->Height) 732 return GL_FALSE; 733 734 /* check remaining faces vs. first face */ 735 for (face = 1; face < 6; face++) { 736 img = texObj->Image[face][baseLevel]; 737 if (!img || 738 img->Width != img0->Width || 739 img->Height != img0->Height || 740 img->TexFormat != img0->TexFormat) 741 return GL_FALSE; 742 } 743 744 return GL_TRUE; 745} 746 747 748/** 749 * Mark a texture object dirty. It forces the object to be incomplete 750 * and forces the context to re-validate its state. 751 * 752 * \param ctx GL context. 753 * \param texObj texture object. 754 */ 755void 756_mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj) 757{ 758 texObj->_BaseComplete = GL_FALSE; 759 texObj->_MipmapComplete = GL_FALSE; 760 ctx->NewState |= _NEW_TEXTURE; 761} 762 763 764/** 765 * Return pointer to a default/fallback texture of the given type/target. 766 * The texture is an RGBA texture with all texels = (0,0,0,1). 767 * That's the value a GLSL sampler should get when sampling from an 768 * incomplete texture. 769 */ 770struct gl_texture_object * 771_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex) 772{ 773 if (!ctx->Shared->FallbackTex[tex]) { 774 /* create fallback texture now */ 775 const GLsizei width = 1, height = 1, depth = 1; 776 GLubyte texel[4]; 777 struct gl_texture_object *texObj; 778 struct gl_texture_image *texImage; 779 mesa_format texFormat; 780 GLuint dims, face, numFaces = 1; 781 GLenum target; 782 783 texel[0] = 784 texel[1] = 785 texel[2] = 0x0; 786 texel[3] = 0xff; 787 788 switch (tex) { 789 case TEXTURE_2D_ARRAY_INDEX: 790 dims = 3; 791 target = GL_TEXTURE_2D_ARRAY; 792 break; 793 case TEXTURE_1D_ARRAY_INDEX: 794 dims = 2; 795 target = GL_TEXTURE_1D_ARRAY; 796 break; 797 case TEXTURE_CUBE_INDEX: 798 dims = 2; 799 target = GL_TEXTURE_CUBE_MAP; 800 numFaces = 6; 801 break; 802 case TEXTURE_3D_INDEX: 803 dims = 3; 804 target = GL_TEXTURE_3D; 805 break; 806 case TEXTURE_RECT_INDEX: 807 dims = 2; 808 target = GL_TEXTURE_RECTANGLE; 809 break; 810 case TEXTURE_2D_INDEX: 811 dims = 2; 812 target = GL_TEXTURE_2D; 813 break; 814 case TEXTURE_1D_INDEX: 815 dims = 1; 816 target = GL_TEXTURE_1D; 817 break; 818 case TEXTURE_BUFFER_INDEX: 819 dims = 0; 820 target = GL_TEXTURE_BUFFER; 821 break; 822 case TEXTURE_CUBE_ARRAY_INDEX: 823 dims = 3; 824 target = GL_TEXTURE_CUBE_MAP_ARRAY; 825 break; 826 case TEXTURE_EXTERNAL_INDEX: 827 dims = 2; 828 target = GL_TEXTURE_EXTERNAL_OES; 829 break; 830 case TEXTURE_2D_MULTISAMPLE_INDEX: 831 dims = 2; 832 target = GL_TEXTURE_2D_MULTISAMPLE; 833 break; 834 case TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: 835 dims = 3; 836 target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY; 837 break; 838 default: 839 /* no-op */ 840 return NULL; 841 } 842 843 /* create texture object */ 844 texObj = ctx->Driver.NewTextureObject(ctx, 0, target); 845 if (!texObj) 846 return NULL; 847 848 assert(texObj->RefCount == 1); 849 texObj->Sampler.MinFilter = GL_NEAREST; 850 texObj->Sampler.MagFilter = GL_NEAREST; 851 852 texFormat = ctx->Driver.ChooseTextureFormat(ctx, target, 853 GL_RGBA, GL_RGBA, 854 GL_UNSIGNED_BYTE); 855 856 /* need a loop here just for cube maps */ 857 for (face = 0; face < numFaces; face++) { 858 GLenum faceTarget; 859 860 if (target == GL_TEXTURE_CUBE_MAP) 861 faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; 862 else 863 faceTarget = target; 864 865 /* initialize level[0] texture image */ 866 texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, 0); 867 868 _mesa_init_teximage_fields(ctx, texImage, 869 width, 870 (dims > 1) ? height : 1, 871 (dims > 2) ? depth : 1, 872 0, /* border */ 873 GL_RGBA, texFormat); 874 875 ctx->Driver.TexImage(ctx, dims, texImage, 876 GL_RGBA, GL_UNSIGNED_BYTE, texel, 877 &ctx->DefaultPacking); 878 } 879 880 _mesa_test_texobj_completeness(ctx, texObj); 881 assert(texObj->_BaseComplete); 882 assert(texObj->_MipmapComplete); 883 884 ctx->Shared->FallbackTex[tex] = texObj; 885 } 886 return ctx->Shared->FallbackTex[tex]; 887} 888 889 890/** 891 * Compute the size of the given texture object, in bytes. 892 */ 893static GLuint 894texture_size(const struct gl_texture_object *texObj) 895{ 896 const GLuint numFaces = _mesa_num_tex_faces(texObj->Target); 897 GLuint face, level, size = 0; 898 899 for (face = 0; face < numFaces; face++) { 900 for (level = 0; level < MAX_TEXTURE_LEVELS; level++) { 901 const struct gl_texture_image *img = texObj->Image[face][level]; 902 if (img) { 903 GLuint sz = _mesa_format_image_size(img->TexFormat, img->Width, 904 img->Height, img->Depth); 905 size += sz; 906 } 907 } 908 } 909 910 return size; 911} 912 913 914/** 915 * Callback called from _mesa_HashWalk() 916 */ 917static void 918count_tex_size(GLuint key, void *data, void *userData) 919{ 920 const struct gl_texture_object *texObj = 921 (const struct gl_texture_object *) data; 922 GLuint *total = (GLuint *) userData; 923 924 (void) key; 925 926 *total = *total + texture_size(texObj); 927} 928 929 930/** 931 * Compute total size (in bytes) of all textures for the given context. 932 * For debugging purposes. 933 */ 934GLuint 935_mesa_total_texture_memory(struct gl_context *ctx) 936{ 937 GLuint tgt, total = 0; 938 939 _mesa_HashWalk(ctx->Shared->TexObjects, count_tex_size, &total); 940 941 /* plus, the default texture objects */ 942 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 943 total += texture_size(ctx->Shared->DefaultTex[tgt]); 944 } 945 946 return total; 947} 948 949static struct gl_texture_object * 950invalidate_tex_image_error_check(struct gl_context *ctx, GLuint texture, 951 GLint level, const char *name) 952{ 953 /* The GL_ARB_invalidate_subdata spec says: 954 * 955 * "If <texture> is zero or is not the name of a texture, the error 956 * INVALID_VALUE is generated." 957 * 958 * This performs the error check in a different order than listed in the 959 * spec. We have to get the texture object before we can validate the 960 * other parameters against values in the texture object. 961 */ 962 struct gl_texture_object *const t = _mesa_lookup_texture(ctx, texture); 963 if (texture == 0 || t == NULL) { 964 _mesa_error(ctx, GL_INVALID_VALUE, "%s(texture)", name); 965 return NULL; 966 } 967 968 /* The GL_ARB_invalidate_subdata spec says: 969 * 970 * "If <level> is less than zero or greater than the base 2 logarithm 971 * of the maximum texture width, height, or depth, the error 972 * INVALID_VALUE is generated." 973 */ 974 if (level < 0 || level > t->MaxLevel) { 975 _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name); 976 return NULL; 977 } 978 979 /* The GL_ARB_invalidate_subdata spec says: 980 * 981 * "If the target of <texture> is TEXTURE_RECTANGLE, TEXTURE_BUFFER, 982 * TEXTURE_2D_MULTISAMPLE, or TEXTURE_2D_MULTISAMPLE_ARRAY, and <level> 983 * is not zero, the error INVALID_VALUE is generated." 984 */ 985 if (level != 0) { 986 switch (t->Target) { 987 case GL_TEXTURE_RECTANGLE: 988 case GL_TEXTURE_BUFFER: 989 case GL_TEXTURE_2D_MULTISAMPLE: 990 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 991 _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name); 992 return NULL; 993 994 default: 995 break; 996 } 997 } 998 999 return t; 1000} 1001 1002/*@}*/ 1003 1004 1005/***********************************************************************/ 1006/** \name API functions */ 1007/*@{*/ 1008 1009 1010/** 1011 * Generate texture names. 1012 * 1013 * \param n number of texture names to be generated. 1014 * \param textures an array in which will hold the generated texture names. 1015 * 1016 * \sa glGenTextures(). 1017 * 1018 * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture 1019 * IDs which are stored in \p textures. Corresponding empty texture 1020 * objects are also generated. 1021 */ 1022void GLAPIENTRY 1023_mesa_GenTextures( GLsizei n, GLuint *textures ) 1024{ 1025 GET_CURRENT_CONTEXT(ctx); 1026 GLuint first; 1027 GLint i; 1028 1029 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1030 _mesa_debug(ctx, "glGenTextures %d\n", n); 1031 1032 if (n < 0) { 1033 _mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" ); 1034 return; 1035 } 1036 1037 if (!textures) 1038 return; 1039 1040 /* 1041 * This must be atomic (generation and allocation of texture IDs) 1042 */ 1043 mtx_lock(&ctx->Shared->Mutex); 1044 1045 first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n); 1046 1047 /* Allocate new, empty texture objects */ 1048 for (i = 0; i < n; i++) { 1049 struct gl_texture_object *texObj; 1050 GLuint name = first + i; 1051 GLenum target = 0; 1052 texObj = ctx->Driver.NewTextureObject(ctx, name, target); 1053 if (!texObj) { 1054 mtx_unlock(&ctx->Shared->Mutex); 1055 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures"); 1056 return; 1057 } 1058 1059 /* insert into hash table */ 1060 _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj); 1061 1062 textures[i] = name; 1063 } 1064 1065 mtx_unlock(&ctx->Shared->Mutex); 1066} 1067 1068 1069/** 1070 * Check if the given texture object is bound to the current draw or 1071 * read framebuffer. If so, Unbind it. 1072 */ 1073static void 1074unbind_texobj_from_fbo(struct gl_context *ctx, 1075 struct gl_texture_object *texObj) 1076{ 1077 bool progress = false; 1078 1079 /* Section 4.4.2 (Attaching Images to Framebuffer Objects), subsection 1080 * "Attaching Texture Images to a Framebuffer," of the OpenGL 3.1 spec 1081 * says: 1082 * 1083 * "If a texture object is deleted while its image is attached to one 1084 * or more attachment points in the currently bound framebuffer, then 1085 * it is as if FramebufferTexture* had been called, with a texture of 1086 * zero, for each attachment point to which this image was attached in 1087 * the currently bound framebuffer. In other words, this texture image 1088 * is first detached from all attachment points in the currently bound 1089 * framebuffer. Note that the texture image is specifically not 1090 * detached from any other framebuffer objects. Detaching the texture 1091 * image from any other framebuffer objects is the responsibility of 1092 * the application." 1093 */ 1094 if (_mesa_is_user_fbo(ctx->DrawBuffer)) { 1095 progress = _mesa_detach_renderbuffer(ctx, ctx->DrawBuffer, texObj); 1096 } 1097 if (_mesa_is_user_fbo(ctx->ReadBuffer) 1098 && ctx->ReadBuffer != ctx->DrawBuffer) { 1099 progress = _mesa_detach_renderbuffer(ctx, ctx->ReadBuffer, texObj) 1100 || progress; 1101 } 1102 1103 if (progress) 1104 /* Vertices are already flushed by _mesa_DeleteTextures */ 1105 ctx->NewState |= _NEW_BUFFERS; 1106} 1107 1108 1109/** 1110 * Check if the given texture object is bound to any texture image units and 1111 * unbind it if so (revert to default textures). 1112 */ 1113static void 1114unbind_texobj_from_texunits(struct gl_context *ctx, 1115 struct gl_texture_object *texObj) 1116{ 1117 const gl_texture_index index = texObj->TargetIndex; 1118 GLuint u; 1119 1120 if (texObj->Target == 0) 1121 return; 1122 1123 for (u = 0; u < ctx->Texture.NumCurrentTexUsed; u++) { 1124 struct gl_texture_unit *unit = &ctx->Texture.Unit[u]; 1125 1126 if (texObj == unit->CurrentTex[index]) { 1127 /* Bind the default texture for this unit/target */ 1128 _mesa_reference_texobj(&unit->CurrentTex[index], 1129 ctx->Shared->DefaultTex[index]); 1130 unit->_BoundTextures &= ~(1 << index); 1131 } 1132 } 1133} 1134 1135 1136/** 1137 * Check if the given texture object is bound to any shader image unit 1138 * and unbind it if that's the case. 1139 */ 1140static void 1141unbind_texobj_from_image_units(struct gl_context *ctx, 1142 struct gl_texture_object *texObj) 1143{ 1144 GLuint i; 1145 1146 for (i = 0; i < ctx->Const.MaxImageUnits; i++) { 1147 struct gl_image_unit *unit = &ctx->ImageUnits[i]; 1148 1149 if (texObj == unit->TexObj) 1150 _mesa_reference_texobj(&unit->TexObj, NULL); 1151 } 1152} 1153 1154/** 1155 * Unbinds all textures bound to the given texture image unit. 1156 */ 1157static void 1158unbind_textures_from_unit(struct gl_context *ctx, GLuint unit) 1159{ 1160 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1161 1162 while (texUnit->_BoundTextures) { 1163 const GLuint index = ffs(texUnit->_BoundTextures) - 1; 1164 struct gl_texture_object *texObj = ctx->Shared->DefaultTex[index]; 1165 1166 _mesa_reference_texobj(&texUnit->CurrentTex[index], texObj); 1167 1168 /* Pass BindTexture call to device driver */ 1169 if (ctx->Driver.BindTexture) 1170 ctx->Driver.BindTexture(ctx, unit, 0, texObj); 1171 1172 texUnit->_BoundTextures &= ~(1 << index); 1173 ctx->NewState |= _NEW_TEXTURE; 1174 } 1175} 1176 1177/** 1178 * Delete named textures. 1179 * 1180 * \param n number of textures to be deleted. 1181 * \param textures array of texture IDs to be deleted. 1182 * 1183 * \sa glDeleteTextures(). 1184 * 1185 * If we're about to delete a texture that's currently bound to any 1186 * texture unit, unbind the texture first. Decrement the reference 1187 * count on the texture object and delete it if it's zero. 1188 * Recall that texture objects can be shared among several rendering 1189 * contexts. 1190 */ 1191void GLAPIENTRY 1192_mesa_DeleteTextures( GLsizei n, const GLuint *textures) 1193{ 1194 GET_CURRENT_CONTEXT(ctx); 1195 GLint i; 1196 1197 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1198 _mesa_debug(ctx, "glDeleteTextures %d\n", n); 1199 1200 FLUSH_VERTICES(ctx, 0); /* too complex */ 1201 1202 if (!textures) 1203 return; 1204 1205 for (i = 0; i < n; i++) { 1206 if (textures[i] > 0) { 1207 struct gl_texture_object *delObj 1208 = _mesa_lookup_texture(ctx, textures[i]); 1209 1210 if (delObj) { 1211 _mesa_lock_texture(ctx, delObj); 1212 1213 /* Check if texture is bound to any framebuffer objects. 1214 * If so, unbind. 1215 * See section 4.4.2.3 of GL_EXT_framebuffer_object. 1216 */ 1217 unbind_texobj_from_fbo(ctx, delObj); 1218 1219 /* Check if this texture is currently bound to any texture units. 1220 * If so, unbind it. 1221 */ 1222 unbind_texobj_from_texunits(ctx, delObj); 1223 1224 /* Check if this texture is currently bound to any shader 1225 * image unit. If so, unbind it. 1226 * See section 3.9.X of GL_ARB_shader_image_load_store. 1227 */ 1228 unbind_texobj_from_image_units(ctx, delObj); 1229 1230 _mesa_unlock_texture(ctx, delObj); 1231 1232 ctx->NewState |= _NEW_TEXTURE; 1233 1234 /* The texture _name_ is now free for re-use. 1235 * Remove it from the hash table now. 1236 */ 1237 mtx_lock(&ctx->Shared->Mutex); 1238 _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name); 1239 mtx_unlock(&ctx->Shared->Mutex); 1240 1241 /* Unreference the texobj. If refcount hits zero, the texture 1242 * will be deleted. 1243 */ 1244 _mesa_reference_texobj(&delObj, NULL); 1245 } 1246 } 1247 } 1248} 1249 1250 1251/** 1252 * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D 1253 * into the corresponding Mesa texture target index. 1254 * Note that proxy targets are not valid here. 1255 * \return TEXTURE_x_INDEX or -1 if target is invalid 1256 */ 1257int 1258_mesa_tex_target_to_index(const struct gl_context *ctx, GLenum target) 1259{ 1260 switch (target) { 1261 case GL_TEXTURE_1D: 1262 return _mesa_is_desktop_gl(ctx) ? TEXTURE_1D_INDEX : -1; 1263 case GL_TEXTURE_2D: 1264 return TEXTURE_2D_INDEX; 1265 case GL_TEXTURE_3D: 1266 return ctx->API != API_OPENGLES ? TEXTURE_3D_INDEX : -1; 1267 case GL_TEXTURE_CUBE_MAP: 1268 return ctx->Extensions.ARB_texture_cube_map 1269 ? TEXTURE_CUBE_INDEX : -1; 1270 case GL_TEXTURE_RECTANGLE: 1271 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle 1272 ? TEXTURE_RECT_INDEX : -1; 1273 case GL_TEXTURE_1D_ARRAY: 1274 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array 1275 ? TEXTURE_1D_ARRAY_INDEX : -1; 1276 case GL_TEXTURE_2D_ARRAY: 1277 return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) 1278 || _mesa_is_gles3(ctx) 1279 ? TEXTURE_2D_ARRAY_INDEX : -1; 1280 case GL_TEXTURE_BUFFER: 1281 return ctx->API == API_OPENGL_CORE && 1282 ctx->Extensions.ARB_texture_buffer_object ? 1283 TEXTURE_BUFFER_INDEX : -1; 1284 case GL_TEXTURE_EXTERNAL_OES: 1285 return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external 1286 ? TEXTURE_EXTERNAL_INDEX : -1; 1287 case GL_TEXTURE_CUBE_MAP_ARRAY: 1288 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_cube_map_array 1289 ? TEXTURE_CUBE_ARRAY_INDEX : -1; 1290 case GL_TEXTURE_2D_MULTISAMPLE: 1291 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample 1292 ? TEXTURE_2D_MULTISAMPLE_INDEX: -1; 1293 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1294 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample 1295 ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: -1; 1296 default: 1297 return -1; 1298 } 1299} 1300 1301 1302/** 1303 * Bind a named texture to a texturing target. 1304 * 1305 * \param target texture target. 1306 * \param texName texture name. 1307 * 1308 * \sa glBindTexture(). 1309 * 1310 * Determines the old texture object bound and returns immediately if rebinding 1311 * the same texture. Get the current texture which is either a default texture 1312 * if name is null, a named texture from the hash, or a new texture if the 1313 * given texture name is new. Increments its reference count, binds it, and 1314 * calls dd_function_table::BindTexture. Decrements the old texture reference 1315 * count and deletes it if it reaches zero. 1316 */ 1317void GLAPIENTRY 1318_mesa_BindTexture( GLenum target, GLuint texName ) 1319{ 1320 GET_CURRENT_CONTEXT(ctx); 1321 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); 1322 struct gl_texture_object *newTexObj = NULL; 1323 GLint targetIndex; 1324 1325 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1326 _mesa_debug(ctx, "glBindTexture %s %d\n", 1327 _mesa_lookup_enum_by_nr(target), (GLint) texName); 1328 1329 targetIndex = _mesa_tex_target_to_index(ctx, target); 1330 if (targetIndex < 0) { 1331 _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)"); 1332 return; 1333 } 1334 assert(targetIndex < NUM_TEXTURE_TARGETS); 1335 1336 /* 1337 * Get pointer to new texture object (newTexObj) 1338 */ 1339 if (texName == 0) { 1340 /* Use a default texture object */ 1341 newTexObj = ctx->Shared->DefaultTex[targetIndex]; 1342 } 1343 else { 1344 /* non-default texture object */ 1345 newTexObj = _mesa_lookup_texture(ctx, texName); 1346 if (newTexObj) { 1347 /* error checking */ 1348 if (newTexObj->Target != 0 && newTexObj->Target != target) { 1349 /* the named texture object's target doesn't match the given target */ 1350 _mesa_error( ctx, GL_INVALID_OPERATION, 1351 "glBindTexture(target mismatch)" ); 1352 return; 1353 } 1354 if (newTexObj->Target == 0) { 1355 finish_texture_init(ctx, target, newTexObj); 1356 } 1357 } 1358 else { 1359 if (ctx->API == API_OPENGL_CORE) { 1360 _mesa_error(ctx, GL_INVALID_OPERATION, "glBindTexture(non-gen name)"); 1361 return; 1362 } 1363 1364 /* if this is a new texture id, allocate a texture object now */ 1365 newTexObj = ctx->Driver.NewTextureObject(ctx, texName, target); 1366 if (!newTexObj) { 1367 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture"); 1368 return; 1369 } 1370 1371 /* and insert it into hash table */ 1372 mtx_lock(&ctx->Shared->Mutex); 1373 _mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj); 1374 mtx_unlock(&ctx->Shared->Mutex); 1375 } 1376 newTexObj->Target = target; 1377 newTexObj->TargetIndex = targetIndex; 1378 } 1379 1380 assert(valid_texture_object(newTexObj)); 1381 1382 /* Check if this texture is only used by this context and is already bound. 1383 * If so, just return. 1384 */ 1385 { 1386 GLboolean early_out; 1387 mtx_lock(&ctx->Shared->Mutex); 1388 early_out = ((ctx->Shared->RefCount == 1) 1389 && (newTexObj == texUnit->CurrentTex[targetIndex])); 1390 mtx_unlock(&ctx->Shared->Mutex); 1391 if (early_out) { 1392 return; 1393 } 1394 } 1395 1396 /* flush before changing binding */ 1397 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1398 1399 /* Do the actual binding. The refcount on the previously bound 1400 * texture object will be decremented. It'll be deleted if the 1401 * count hits zero. 1402 */ 1403 _mesa_reference_texobj(&texUnit->CurrentTex[targetIndex], newTexObj); 1404 ctx->Texture.NumCurrentTexUsed = MAX2(ctx->Texture.NumCurrentTexUsed, 1405 ctx->Texture.CurrentUnit + 1); 1406 ASSERT(texUnit->CurrentTex[targetIndex]); 1407 1408 if (texName != 0) 1409 texUnit->_BoundTextures |= (1 << targetIndex); 1410 else 1411 texUnit->_BoundTextures &= ~(1 << targetIndex); 1412 1413 /* Pass BindTexture call to device driver */ 1414 if (ctx->Driver.BindTexture) 1415 ctx->Driver.BindTexture(ctx, ctx->Texture.CurrentUnit, target, newTexObj); 1416} 1417 1418 1419void GLAPIENTRY 1420_mesa_BindTextures(GLuint first, GLsizei count, const GLuint *textures) 1421{ 1422 GET_CURRENT_CONTEXT(ctx); 1423 GLint i; 1424 1425 /* The ARB_multi_bind spec says: 1426 * 1427 * "An INVALID_OPERATION error is generated if <first> + <count> 1428 * is greater than the number of texture image units supported 1429 * by the implementation." 1430 */ 1431 if (first + count > ctx->Const.MaxCombinedTextureImageUnits) { 1432 _mesa_error(ctx, GL_INVALID_OPERATION, 1433 "glBindTextures(first=%u + count=%d > the value of " 1434 "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS=%u)", 1435 first, count, ctx->Const.MaxCombinedTextureImageUnits); 1436 return; 1437 } 1438 1439 /* Flush before changing bindings */ 1440 FLUSH_VERTICES(ctx, 0); 1441 1442 ctx->Texture.NumCurrentTexUsed = MAX2(ctx->Texture.NumCurrentTexUsed, 1443 first + count); 1444 1445 if (textures) { 1446 /* Note that the error semantics for multi-bind commands differ from 1447 * those of other GL commands. 1448 * 1449 * The issues section in the ARB_multi_bind spec says: 1450 * 1451 * "(11) Typically, OpenGL specifies that if an error is generated by 1452 * a command, that command has no effect. This is somewhat 1453 * unfortunate for multi-bind commands, because it would require 1454 * a first pass to scan the entire list of bound objects for 1455 * errors and then a second pass to actually perform the 1456 * bindings. Should we have different error semantics? 1457 * 1458 * RESOLVED: Yes. In this specification, when the parameters for 1459 * one of the <count> binding points are invalid, that binding 1460 * point is not updated and an error will be generated. However, 1461 * other binding points in the same command will be updated if 1462 * their parameters are valid and no other error occurs." 1463 */ 1464 1465 _mesa_begin_texture_lookups(ctx); 1466 1467 for (i = 0; i < count; i++) { 1468 if (textures[i] != 0) { 1469 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[first + i]; 1470 struct gl_texture_object *current = texUnit->_Current; 1471 struct gl_texture_object *texObj; 1472 1473 if (current && current->Name == textures[i]) 1474 texObj = current; 1475 else 1476 texObj = _mesa_lookup_texture_locked(ctx, textures[i]); 1477 1478 if (texObj && texObj->Target != 0) { 1479 const gl_texture_index targetIndex = texObj->TargetIndex; 1480 1481 if (texUnit->CurrentTex[targetIndex] != texObj) { 1482 /* Do the actual binding. The refcount on the previously 1483 * bound texture object will be decremented. It will be 1484 * deleted if the count hits zero. 1485 */ 1486 _mesa_reference_texobj(&texUnit->CurrentTex[targetIndex], 1487 texObj); 1488 1489 texUnit->_BoundTextures |= (1 << targetIndex); 1490 ctx->NewState |= _NEW_TEXTURE; 1491 1492 /* Pass the BindTexture call to the device driver */ 1493 if (ctx->Driver.BindTexture) 1494 ctx->Driver.BindTexture(ctx, first + i, 1495 texObj->Target, texObj); 1496 } 1497 } else { 1498 /* The ARB_multi_bind spec says: 1499 * 1500 * "An INVALID_OPERATION error is generated if any value 1501 * in <textures> is not zero or the name of an existing 1502 * texture object (per binding)." 1503 */ 1504 _mesa_error(ctx, GL_INVALID_OPERATION, 1505 "glBindTextures(textures[%d]=%u is not zero " 1506 "or the name of an existing texture object)", 1507 i, textures[i]); 1508 } 1509 } else { 1510 unbind_textures_from_unit(ctx, first + i); 1511 } 1512 } 1513 1514 _mesa_end_texture_lookups(ctx); 1515 } else { 1516 /* Unbind all textures in the range <first> through <first>+<count>-1 */ 1517 for (i = 0; i < count; i++) 1518 unbind_textures_from_unit(ctx, first + i); 1519 } 1520} 1521 1522 1523/** 1524 * Set texture priorities. 1525 * 1526 * \param n number of textures. 1527 * \param texName texture names. 1528 * \param priorities corresponding texture priorities. 1529 * 1530 * \sa glPrioritizeTextures(). 1531 * 1532 * Looks up each texture in the hash, clamps the corresponding priority between 1533 * 0.0 and 1.0, and calls dd_function_table::PrioritizeTexture. 1534 */ 1535void GLAPIENTRY 1536_mesa_PrioritizeTextures( GLsizei n, const GLuint *texName, 1537 const GLclampf *priorities ) 1538{ 1539 GET_CURRENT_CONTEXT(ctx); 1540 GLint i; 1541 1542 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1543 _mesa_debug(ctx, "glPrioritizeTextures %d\n", n); 1544 1545 FLUSH_VERTICES(ctx, 0); 1546 1547 if (n < 0) { 1548 _mesa_error( ctx, GL_INVALID_VALUE, "glPrioritizeTextures" ); 1549 return; 1550 } 1551 1552 if (!priorities) 1553 return; 1554 1555 for (i = 0; i < n; i++) { 1556 if (texName[i] > 0) { 1557 struct gl_texture_object *t = _mesa_lookup_texture(ctx, texName[i]); 1558 if (t) { 1559 t->Priority = CLAMP( priorities[i], 0.0F, 1.0F ); 1560 } 1561 } 1562 } 1563 1564 ctx->NewState |= _NEW_TEXTURE; 1565} 1566 1567 1568 1569/** 1570 * See if textures are loaded in texture memory. 1571 * 1572 * \param n number of textures to query. 1573 * \param texName array with the texture names. 1574 * \param residences array which will hold the residence status. 1575 * 1576 * \return GL_TRUE if all textures are resident and \p residences is left unchanged, 1577 * 1578 * Note: we assume all textures are always resident 1579 */ 1580GLboolean GLAPIENTRY 1581_mesa_AreTexturesResident(GLsizei n, const GLuint *texName, 1582 GLboolean *residences) 1583{ 1584 GET_CURRENT_CONTEXT(ctx); 1585 GLboolean allResident = GL_TRUE; 1586 GLint i; 1587 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 1588 1589 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1590 _mesa_debug(ctx, "glAreTexturesResident %d\n", n); 1591 1592 if (n < 0) { 1593 _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)"); 1594 return GL_FALSE; 1595 } 1596 1597 if (!texName || !residences) 1598 return GL_FALSE; 1599 1600 /* We only do error checking on the texture names */ 1601 for (i = 0; i < n; i++) { 1602 struct gl_texture_object *t; 1603 if (texName[i] == 0) { 1604 _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident"); 1605 return GL_FALSE; 1606 } 1607 t = _mesa_lookup_texture(ctx, texName[i]); 1608 if (!t) { 1609 _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident"); 1610 return GL_FALSE; 1611 } 1612 } 1613 1614 return allResident; 1615} 1616 1617 1618/** 1619 * See if a name corresponds to a texture. 1620 * 1621 * \param texture texture name. 1622 * 1623 * \return GL_TRUE if texture name corresponds to a texture, or GL_FALSE 1624 * otherwise. 1625 * 1626 * \sa glIsTexture(). 1627 * 1628 * Calls _mesa_HashLookup(). 1629 */ 1630GLboolean GLAPIENTRY 1631_mesa_IsTexture( GLuint texture ) 1632{ 1633 struct gl_texture_object *t; 1634 GET_CURRENT_CONTEXT(ctx); 1635 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 1636 1637 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1638 _mesa_debug(ctx, "glIsTexture %d\n", texture); 1639 1640 if (!texture) 1641 return GL_FALSE; 1642 1643 t = _mesa_lookup_texture(ctx, texture); 1644 1645 /* IsTexture is true only after object has been bound once. */ 1646 return t && t->Target; 1647} 1648 1649 1650/** 1651 * Simplest implementation of texture locking: grab the shared tex 1652 * mutex. Examine the shared context state timestamp and if there has 1653 * been a change, set the appropriate bits in ctx->NewState. 1654 * 1655 * This is used to deal with synchronizing things when a texture object 1656 * is used/modified by different contexts (or threads) which are sharing 1657 * the texture. 1658 * 1659 * See also _mesa_lock/unlock_texture() in teximage.h 1660 */ 1661void 1662_mesa_lock_context_textures( struct gl_context *ctx ) 1663{ 1664 mtx_lock(&ctx->Shared->TexMutex); 1665 1666 if (ctx->Shared->TextureStateStamp != ctx->TextureStateTimestamp) { 1667 ctx->NewState |= _NEW_TEXTURE; 1668 ctx->TextureStateTimestamp = ctx->Shared->TextureStateStamp; 1669 } 1670} 1671 1672 1673void 1674_mesa_unlock_context_textures( struct gl_context *ctx ) 1675{ 1676 assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp); 1677 mtx_unlock(&ctx->Shared->TexMutex); 1678} 1679 1680void GLAPIENTRY 1681_mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, 1682 GLint yoffset, GLint zoffset, GLsizei width, 1683 GLsizei height, GLsizei depth) 1684{ 1685 struct gl_texture_object *t; 1686 struct gl_texture_image *image; 1687 GET_CURRENT_CONTEXT(ctx); 1688 1689 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1690 _mesa_debug(ctx, "glInvalidateTexSubImage %d\n", texture); 1691 1692 t = invalidate_tex_image_error_check(ctx, texture, level, 1693 "glInvalidateTexSubImage"); 1694 1695 /* The GL_ARB_invalidate_subdata spec says: 1696 * 1697 * "...the specified subregion must be between -<b> and <dim>+<b> where 1698 * <dim> is the size of the dimension of the texture image, and <b> is 1699 * the size of the border of that texture image, otherwise 1700 * INVALID_VALUE is generated (border is not applied to dimensions that 1701 * don't exist in a given texture target)." 1702 */ 1703 image = t->Image[0][level]; 1704 if (image) { 1705 int xBorder; 1706 int yBorder; 1707 int zBorder; 1708 int imageWidth; 1709 int imageHeight; 1710 int imageDepth; 1711 1712 /* The GL_ARB_invalidate_subdata spec says: 1713 * 1714 * "For texture targets that don't have certain dimensions, this 1715 * command treats those dimensions as having a size of 1. For 1716 * example, to invalidate a portion of a two-dimensional texture, 1717 * the application would use <zoffset> equal to zero and <depth> 1718 * equal to one." 1719 */ 1720 switch (t->Target) { 1721 case GL_TEXTURE_BUFFER: 1722 xBorder = 0; 1723 yBorder = 0; 1724 zBorder = 0; 1725 imageWidth = 1; 1726 imageHeight = 1; 1727 imageDepth = 1; 1728 break; 1729 case GL_TEXTURE_1D: 1730 xBorder = image->Border; 1731 yBorder = 0; 1732 zBorder = 0; 1733 imageWidth = image->Width; 1734 imageHeight = 1; 1735 imageDepth = 1; 1736 break; 1737 case GL_TEXTURE_1D_ARRAY: 1738 xBorder = image->Border; 1739 yBorder = 0; 1740 zBorder = 0; 1741 imageWidth = image->Width; 1742 imageHeight = image->Height; 1743 imageDepth = 1; 1744 break; 1745 case GL_TEXTURE_2D: 1746 case GL_TEXTURE_CUBE_MAP: 1747 case GL_TEXTURE_RECTANGLE: 1748 case GL_TEXTURE_2D_MULTISAMPLE: 1749 xBorder = image->Border; 1750 yBorder = image->Border; 1751 zBorder = 0; 1752 imageWidth = image->Width; 1753 imageHeight = image->Height; 1754 imageDepth = 1; 1755 break; 1756 case GL_TEXTURE_2D_ARRAY: 1757 case GL_TEXTURE_CUBE_MAP_ARRAY: 1758 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1759 xBorder = image->Border; 1760 yBorder = image->Border; 1761 zBorder = 0; 1762 imageWidth = image->Width; 1763 imageHeight = image->Height; 1764 imageDepth = image->Depth; 1765 break; 1766 case GL_TEXTURE_3D: 1767 xBorder = image->Border; 1768 yBorder = image->Border; 1769 zBorder = image->Border; 1770 imageWidth = image->Width; 1771 imageHeight = image->Height; 1772 imageDepth = image->Depth; 1773 break; 1774 default: 1775 assert(!"Should not get here."); 1776 xBorder = 0; 1777 yBorder = 0; 1778 zBorder = 0; 1779 imageWidth = 0; 1780 imageHeight = 0; 1781 imageDepth = 0; 1782 break; 1783 } 1784 1785 if (xoffset < -xBorder) { 1786 _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(xoffset)"); 1787 return; 1788 } 1789 1790 if (xoffset + width > imageWidth + xBorder) { 1791 _mesa_error(ctx, GL_INVALID_VALUE, 1792 "glInvalidateSubTexImage(xoffset+width)"); 1793 return; 1794 } 1795 1796 if (yoffset < -yBorder) { 1797 _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(yoffset)"); 1798 return; 1799 } 1800 1801 if (yoffset + height > imageHeight + yBorder) { 1802 _mesa_error(ctx, GL_INVALID_VALUE, 1803 "glInvalidateSubTexImage(yoffset+height)"); 1804 return; 1805 } 1806 1807 if (zoffset < -zBorder) { 1808 _mesa_error(ctx, GL_INVALID_VALUE, 1809 "glInvalidateSubTexImage(zoffset)"); 1810 return; 1811 } 1812 1813 if (zoffset + depth > imageDepth + zBorder) { 1814 _mesa_error(ctx, GL_INVALID_VALUE, 1815 "glInvalidateSubTexImage(zoffset+depth)"); 1816 return; 1817 } 1818 } 1819 1820 /* We don't actually do anything for this yet. Just return after 1821 * validating the parameters and generating the required errors. 1822 */ 1823 return; 1824} 1825 1826void GLAPIENTRY 1827_mesa_InvalidateTexImage(GLuint texture, GLint level) 1828{ 1829 GET_CURRENT_CONTEXT(ctx); 1830 1831 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1832 _mesa_debug(ctx, "glInvalidateTexImage(%d, %d)\n", texture, level); 1833 1834 invalidate_tex_image_error_check(ctx, texture, level, 1835 "glInvalidateTexImage"); 1836 1837 /* We don't actually do anything for this yet. Just return after 1838 * validating the parameters and generating the required errors. 1839 */ 1840 return; 1841} 1842 1843/*@}*/ 1844