texobj.c revision 7ec681f3
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 <stdio.h> 32#include "bufferobj.h" 33#include "context.h" 34#include "enums.h" 35#include "fbobject.h" 36#include "formats.h" 37#include "hash.h" 38 39#include "macros.h" 40#include "shaderimage.h" 41#include "teximage.h" 42#include "texobj.h" 43#include "texstate.h" 44#include "mtypes.h" 45#include "program/prog_instruction.h" 46#include "texturebindless.h" 47#include "util/u_memory.h" 48 49 50 51/**********************************************************************/ 52/** \name Internal functions */ 53/*@{*/ 54 55/** 56 * This function checks for all valid combinations of Min and Mag filters for 57 * Float types, when extensions like OES_texture_float and 58 * OES_texture_float_linear are supported. OES_texture_float mentions support 59 * for NEAREST, NEAREST_MIPMAP_NEAREST magnification and minification filters. 60 * Mag filters like LINEAR and min filters like NEAREST_MIPMAP_LINEAR, 61 * LINEAR_MIPMAP_NEAREST and LINEAR_MIPMAP_LINEAR are only valid in case 62 * OES_texture_float_linear is supported. 63 * 64 * Returns true in case the filter is valid for given Float type else false. 65 */ 66static bool 67valid_filter_for_float(const struct gl_context *ctx, 68 const struct gl_texture_object *obj) 69{ 70 switch (obj->Sampler.Attrib.MagFilter) { 71 case GL_LINEAR: 72 if (obj->_IsHalfFloat && !ctx->Extensions.OES_texture_half_float_linear) { 73 return false; 74 } else if (obj->_IsFloat && !ctx->Extensions.OES_texture_float_linear) { 75 return false; 76 } 77 FALLTHROUGH; 78 case GL_NEAREST: 79 case GL_NEAREST_MIPMAP_NEAREST: 80 break; 81 default: 82 unreachable("Invalid mag filter"); 83 } 84 85 switch (obj->Sampler.Attrib.MinFilter) { 86 case GL_LINEAR: 87 case GL_NEAREST_MIPMAP_LINEAR: 88 case GL_LINEAR_MIPMAP_NEAREST: 89 case GL_LINEAR_MIPMAP_LINEAR: 90 if (obj->_IsHalfFloat && !ctx->Extensions.OES_texture_half_float_linear) { 91 return false; 92 } else if (obj->_IsFloat && !ctx->Extensions.OES_texture_float_linear) { 93 return false; 94 } 95 FALLTHROUGH; 96 case GL_NEAREST: 97 case GL_NEAREST_MIPMAP_NEAREST: 98 break; 99 default: 100 unreachable("Invalid min filter"); 101 } 102 103 return true; 104} 105 106/** 107 * Return the gl_texture_object for a given ID. 108 */ 109struct gl_texture_object * 110_mesa_lookup_texture(struct gl_context *ctx, GLuint id) 111{ 112 return (struct gl_texture_object *) 113 _mesa_HashLookup(ctx->Shared->TexObjects, id); 114} 115 116/** 117 * Wrapper around _mesa_lookup_texture that throws GL_INVALID_OPERATION if id 118 * is not in the hash table. After calling _mesa_error, it returns NULL. 119 */ 120struct gl_texture_object * 121_mesa_lookup_texture_err(struct gl_context *ctx, GLuint id, const char* func) 122{ 123 struct gl_texture_object *texObj = NULL; 124 125 if (id > 0) 126 texObj = _mesa_lookup_texture(ctx, id); /* Returns NULL if not found. */ 127 128 if (!texObj) 129 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture)", func); 130 131 return texObj; 132} 133 134 135struct gl_texture_object * 136_mesa_lookup_texture_locked(struct gl_context *ctx, GLuint id) 137{ 138 return (struct gl_texture_object *) 139 _mesa_HashLookupLocked(ctx->Shared->TexObjects, id); 140} 141 142/** 143 * Return a pointer to the current texture object for the given target 144 * on the current texture unit. 145 * Note: all <target> error checking should have been done by this point. 146 */ 147struct gl_texture_object * 148_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) 149{ 150 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); 151 const GLboolean arrayTex = ctx->Extensions.EXT_texture_array; 152 153 switch (target) { 154 case GL_TEXTURE_1D: 155 return texUnit->CurrentTex[TEXTURE_1D_INDEX]; 156 case GL_PROXY_TEXTURE_1D: 157 return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; 158 case GL_TEXTURE_2D: 159 return texUnit->CurrentTex[TEXTURE_2D_INDEX]; 160 case GL_PROXY_TEXTURE_2D: 161 return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; 162 case GL_TEXTURE_3D: 163 return texUnit->CurrentTex[TEXTURE_3D_INDEX]; 164 case GL_PROXY_TEXTURE_3D: 165 return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; 166 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 167 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 168 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 169 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 170 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 171 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 172 case GL_TEXTURE_CUBE_MAP: 173 return ctx->Extensions.ARB_texture_cube_map 174 ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL; 175 case GL_PROXY_TEXTURE_CUBE_MAP: 176 return ctx->Extensions.ARB_texture_cube_map 177 ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; 178 case GL_TEXTURE_CUBE_MAP_ARRAY: 179 return _mesa_has_texture_cube_map_array(ctx) 180 ? texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; 181 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 182 return _mesa_has_texture_cube_map_array(ctx) 183 ? ctx->Texture.ProxyTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; 184 case GL_TEXTURE_RECTANGLE_NV: 185 return ctx->Extensions.NV_texture_rectangle 186 ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL; 187 case GL_PROXY_TEXTURE_RECTANGLE_NV: 188 return ctx->Extensions.NV_texture_rectangle 189 ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL; 190 case GL_TEXTURE_1D_ARRAY_EXT: 191 return arrayTex ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL; 192 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 193 return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL; 194 case GL_TEXTURE_2D_ARRAY_EXT: 195 return arrayTex ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL; 196 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 197 return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL; 198 case GL_TEXTURE_BUFFER: 199 return (_mesa_has_ARB_texture_buffer_object(ctx) || 200 _mesa_has_OES_texture_buffer(ctx)) ? 201 texUnit->CurrentTex[TEXTURE_BUFFER_INDEX] : NULL; 202 case GL_TEXTURE_EXTERNAL_OES: 203 return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external 204 ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL; 205 case GL_TEXTURE_2D_MULTISAMPLE: 206 return ctx->Extensions.ARB_texture_multisample 207 ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL; 208 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 209 return ctx->Extensions.ARB_texture_multisample 210 ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL; 211 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 212 return ctx->Extensions.ARB_texture_multisample 213 ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL; 214 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 215 return ctx->Extensions.ARB_texture_multisample 216 ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL; 217 default: 218 _mesa_problem(NULL, "bad target in _mesa_get_current_tex_object()"); 219 return NULL; 220 } 221} 222 223 224/** 225 * Get the texture object for given target and texunit 226 * Proxy targets are accepted only allowProxyTarget is true. 227 * Return NULL if any error (and record the error). 228 */ 229struct gl_texture_object * 230_mesa_get_texobj_by_target_and_texunit(struct gl_context *ctx, GLenum target, 231 GLuint texunit, bool allowProxyTarget, 232 const char* caller) 233{ 234 struct gl_texture_unit *texUnit; 235 int targetIndex; 236 237 if (_mesa_is_proxy_texture(target) && allowProxyTarget) { 238 return _mesa_get_current_tex_object(ctx, target); 239 } 240 241 if (texunit >= ctx->Const.MaxCombinedTextureImageUnits) { 242 _mesa_error(ctx, GL_INVALID_OPERATION, 243 "%s(texunit=%d)", caller, texunit); 244 return NULL; 245 } 246 247 texUnit = _mesa_get_tex_unit(ctx, texunit); 248 249 targetIndex = _mesa_tex_target_to_index(ctx, target); 250 if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) { 251 _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", caller); 252 return NULL; 253 } 254 assert(targetIndex < NUM_TEXTURE_TARGETS); 255 256 return texUnit->CurrentTex[targetIndex]; 257} 258 259 260/** 261 * Allocate and initialize a new texture object. But don't put it into the 262 * texture object hash table. 263 * 264 * Called via ctx->Driver.NewTextureObject, unless overridden by a device 265 * driver. 266 * 267 * \param shared the shared GL state structure to contain the texture object 268 * \param name integer name for the texture object 269 * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, 270 * GL_TEXTURE_CUBE_MAP or GL_TEXTURE_RECTANGLE_NV. zero is ok for the sake 271 * of GenTextures() 272 * 273 * \return pointer to new texture object. 274 */ 275struct gl_texture_object * 276_mesa_new_texture_object(struct gl_context *ctx, GLuint name, GLenum target) 277{ 278 struct gl_texture_object *obj; 279 280 obj = MALLOC_STRUCT(gl_texture_object); 281 if (!obj) 282 return NULL; 283 284 _mesa_initialize_texture_object(ctx, obj, name, target); 285 return obj; 286} 287 288 289/** 290 * Initialize a new texture object to default values. 291 * \param obj the texture object 292 * \param name the texture name 293 * \param target the texture target 294 */ 295void 296_mesa_initialize_texture_object( struct gl_context *ctx, 297 struct gl_texture_object *obj, 298 GLuint name, GLenum target ) 299{ 300 assert(target == 0 || 301 target == GL_TEXTURE_1D || 302 target == GL_TEXTURE_2D || 303 target == GL_TEXTURE_3D || 304 target == GL_TEXTURE_CUBE_MAP || 305 target == GL_TEXTURE_RECTANGLE_NV || 306 target == GL_TEXTURE_1D_ARRAY_EXT || 307 target == GL_TEXTURE_2D_ARRAY_EXT || 308 target == GL_TEXTURE_EXTERNAL_OES || 309 target == GL_TEXTURE_CUBE_MAP_ARRAY || 310 target == GL_TEXTURE_BUFFER || 311 target == GL_TEXTURE_2D_MULTISAMPLE || 312 target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY); 313 314 memset(obj, 0, sizeof(*obj)); 315 /* init the non-zero fields */ 316 obj->RefCount = 1; 317 obj->Name = name; 318 obj->Target = target; 319 if (target != 0) { 320 obj->TargetIndex = _mesa_tex_target_to_index(ctx, target); 321 } 322 else { 323 obj->TargetIndex = NUM_TEXTURE_TARGETS; /* invalid/error value */ 324 } 325 obj->Attrib.Priority = 1.0F; 326 obj->Attrib.BaseLevel = 0; 327 obj->Attrib.MaxLevel = 1000; 328 329 /* must be one; no support for (YUV) planes in separate buffers */ 330 obj->RequiredTextureImageUnits = 1; 331 332 /* sampler state */ 333 if (target == GL_TEXTURE_RECTANGLE_NV || 334 target == GL_TEXTURE_EXTERNAL_OES) { 335 obj->Sampler.Attrib.WrapS = GL_CLAMP_TO_EDGE; 336 obj->Sampler.Attrib.WrapT = GL_CLAMP_TO_EDGE; 337 obj->Sampler.Attrib.WrapR = GL_CLAMP_TO_EDGE; 338 obj->Sampler.Attrib.MinFilter = GL_LINEAR; 339 obj->Sampler.Attrib.state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 340 obj->Sampler.Attrib.state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 341 obj->Sampler.Attrib.state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 342 obj->Sampler.Attrib.state.min_img_filter = PIPE_TEX_FILTER_LINEAR; 343 obj->Sampler.Attrib.state.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 344 } 345 else { 346 obj->Sampler.Attrib.WrapS = GL_REPEAT; 347 obj->Sampler.Attrib.WrapT = GL_REPEAT; 348 obj->Sampler.Attrib.WrapR = GL_REPEAT; 349 obj->Sampler.Attrib.MinFilter = GL_NEAREST_MIPMAP_LINEAR; 350 obj->Sampler.Attrib.state.wrap_s = PIPE_TEX_WRAP_REPEAT; 351 obj->Sampler.Attrib.state.wrap_t = PIPE_TEX_WRAP_REPEAT; 352 obj->Sampler.Attrib.state.wrap_r = PIPE_TEX_WRAP_REPEAT; 353 obj->Sampler.Attrib.state.min_img_filter = PIPE_TEX_FILTER_NEAREST; 354 obj->Sampler.Attrib.state.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR; 355 } 356 obj->Sampler.Attrib.MagFilter = GL_LINEAR; 357 obj->Sampler.Attrib.state.mag_img_filter = PIPE_TEX_FILTER_LINEAR; 358 obj->Sampler.Attrib.MinLod = -1000.0; 359 obj->Sampler.Attrib.MaxLod = 1000.0; 360 obj->Sampler.Attrib.state.min_lod = 0; /* no negative numbers */ 361 obj->Sampler.Attrib.state.max_lod = 1000; 362 obj->Sampler.Attrib.LodBias = 0.0; 363 obj->Sampler.Attrib.state.lod_bias = 0; 364 obj->Sampler.Attrib.MaxAnisotropy = 1.0; 365 obj->Sampler.Attrib.state.max_anisotropy = 0; /* gallium sets 0 instead of 1 */ 366 obj->Sampler.Attrib.CompareMode = GL_NONE; /* ARB_shadow */ 367 obj->Sampler.Attrib.CompareFunc = GL_LEQUAL; /* ARB_shadow */ 368 obj->Sampler.Attrib.state.compare_mode = PIPE_TEX_COMPARE_NONE; 369 obj->Sampler.Attrib.state.compare_func = PIPE_FUNC_LEQUAL; 370 obj->Attrib.DepthMode = ctx->API == API_OPENGL_CORE ? GL_RED : GL_LUMINANCE; 371 obj->StencilSampling = false; 372 obj->Sampler.Attrib.CubeMapSeamless = GL_FALSE; 373 obj->Sampler.Attrib.state.seamless_cube_map = false; 374 obj->Sampler.HandleAllocated = GL_FALSE; 375 obj->Attrib.Swizzle[0] = GL_RED; 376 obj->Attrib.Swizzle[1] = GL_GREEN; 377 obj->Attrib.Swizzle[2] = GL_BLUE; 378 obj->Attrib.Swizzle[3] = GL_ALPHA; 379 obj->Attrib._Swizzle = SWIZZLE_NOOP; 380 obj->Sampler.Attrib.sRGBDecode = GL_DECODE_EXT; 381 obj->Sampler.Attrib.ReductionMode = GL_WEIGHTED_AVERAGE_EXT; 382 obj->Sampler.Attrib.state.reduction_mode = PIPE_TEX_REDUCTION_WEIGHTED_AVERAGE; 383 obj->BufferObjectFormat = ctx->API == API_OPENGL_COMPAT ? GL_LUMINANCE8 : GL_R8; 384 obj->_BufferObjectFormat = ctx->API == API_OPENGL_COMPAT 385 ? MESA_FORMAT_L_UNORM8 : MESA_FORMAT_R_UNORM8; 386 obj->Attrib.ImageFormatCompatibilityType = GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE; 387 388 /* GL_ARB_bindless_texture */ 389 _mesa_init_texture_handles(obj); 390} 391 392 393/** 394 * Some texture initialization can't be finished until we know which 395 * target it's getting bound to (GL_TEXTURE_1D/2D/etc). 396 */ 397static void 398finish_texture_init(struct gl_context *ctx, GLenum target, 399 struct gl_texture_object *obj, int targetIndex) 400{ 401 GLenum filter = GL_LINEAR; 402 assert(obj->Target == 0); 403 404 obj->Target = target; 405 obj->TargetIndex = targetIndex; 406 assert(obj->TargetIndex < NUM_TEXTURE_TARGETS); 407 408 switch (target) { 409 case GL_TEXTURE_2D_MULTISAMPLE: 410 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 411 filter = GL_NEAREST; 412 FALLTHROUGH; 413 414 case GL_TEXTURE_RECTANGLE_NV: 415 case GL_TEXTURE_EXTERNAL_OES: 416 /* have to init wrap and filter state here - kind of klunky */ 417 obj->Sampler.Attrib.WrapS = GL_CLAMP_TO_EDGE; 418 obj->Sampler.Attrib.WrapT = GL_CLAMP_TO_EDGE; 419 obj->Sampler.Attrib.WrapR = GL_CLAMP_TO_EDGE; 420 obj->Sampler.Attrib.state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 421 obj->Sampler.Attrib.state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 422 obj->Sampler.Attrib.state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 423 obj->Sampler.Attrib.MinFilter = filter; 424 obj->Sampler.Attrib.MagFilter = filter; 425 obj->Sampler.Attrib.state.min_img_filter = filter_to_gallium(filter); 426 obj->Sampler.Attrib.state.min_mip_filter = mipfilter_to_gallium(filter); 427 obj->Sampler.Attrib.state.mag_img_filter = filter_to_gallium(filter); 428 if (ctx->Driver.TexParameter) { 429 /* XXX we probably don't need to make all these calls */ 430 ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_WRAP_S); 431 ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_WRAP_T); 432 ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_WRAP_R); 433 ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_MIN_FILTER); 434 ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_MAG_FILTER); 435 } 436 break; 437 438 default: 439 /* nothing needs done */ 440 break; 441 } 442} 443 444 445/** 446 * Deallocate a texture object struct. It should have already been 447 * removed from the texture object pool. 448 * Called via ctx->Driver.DeleteTexture() if not overriden by a driver. 449 * 450 * \param shared the shared GL state to which the object belongs. 451 * \param texObj the texture object to delete. 452 */ 453void 454_mesa_delete_texture_object(struct gl_context *ctx, 455 struct gl_texture_object *texObj) 456{ 457 GLuint i, face; 458 459 /* Set Target to an invalid value. With some assertions elsewhere 460 * we can try to detect possible use of deleted textures. 461 */ 462 texObj->Target = 0x99; 463 464 /* free the texture images */ 465 for (face = 0; face < 6; face++) { 466 for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { 467 if (texObj->Image[face][i]) { 468 ctx->Driver.DeleteTextureImage(ctx, texObj->Image[face][i]); 469 } 470 } 471 } 472 473 /* Delete all texture/image handles. */ 474 _mesa_delete_texture_handles(ctx, texObj); 475 476 _mesa_reference_buffer_object_shared(ctx, &texObj->BufferObject, NULL); 477 free(texObj->Label); 478 479 /* free this object */ 480 free(texObj); 481} 482 483 484/** 485 * Free all texture images of the given texture objectm, except for 486 * \p retainTexImage. 487 * 488 * \param ctx GL context. 489 * \param texObj texture object. 490 * \param retainTexImage a texture image that will \em not be freed. 491 * 492 * \sa _mesa_clear_texture_image(). 493 */ 494void 495_mesa_clear_texture_object(struct gl_context *ctx, 496 struct gl_texture_object *texObj, 497 struct gl_texture_image *retainTexImage) 498{ 499 GLuint i, j; 500 501 if (texObj->Target == 0) 502 return; 503 504 for (i = 0; i < MAX_FACES; i++) { 505 for (j = 0; j < MAX_TEXTURE_LEVELS; j++) { 506 struct gl_texture_image *texImage = texObj->Image[i][j]; 507 if (texImage && texImage != retainTexImage) 508 _mesa_clear_texture_image(ctx, texImage); 509 } 510 } 511} 512 513 514/** 515 * Check if the given texture object is valid by examining its Target field. 516 * For debugging only. 517 */ 518static GLboolean 519valid_texture_object(const struct gl_texture_object *tex) 520{ 521 switch (tex->Target) { 522 case 0: 523 case GL_TEXTURE_1D: 524 case GL_TEXTURE_2D: 525 case GL_TEXTURE_3D: 526 case GL_TEXTURE_CUBE_MAP: 527 case GL_TEXTURE_RECTANGLE_NV: 528 case GL_TEXTURE_1D_ARRAY_EXT: 529 case GL_TEXTURE_2D_ARRAY_EXT: 530 case GL_TEXTURE_BUFFER: 531 case GL_TEXTURE_EXTERNAL_OES: 532 case GL_TEXTURE_CUBE_MAP_ARRAY: 533 case GL_TEXTURE_2D_MULTISAMPLE: 534 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 535 return GL_TRUE; 536 case 0x99: 537 _mesa_problem(NULL, "invalid reference to a deleted texture object"); 538 return GL_FALSE; 539 default: 540 _mesa_problem(NULL, "invalid texture object Target 0x%x, Id = %u", 541 tex->Target, tex->Name); 542 return GL_FALSE; 543 } 544} 545 546 547/** 548 * Reference (or unreference) a texture object. 549 * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero). 550 * If 'tex' is non-null, increment its refcount. 551 * This is normally only called from the _mesa_reference_texobj() macro 552 * when there's a real pointer change. 553 */ 554void 555_mesa_reference_texobj_(struct gl_texture_object **ptr, 556 struct gl_texture_object *tex) 557{ 558 assert(ptr); 559 560 if (*ptr) { 561 /* Unreference the old texture */ 562 struct gl_texture_object *oldTex = *ptr; 563 564 assert(valid_texture_object(oldTex)); 565 (void) valid_texture_object; /* silence warning in release builds */ 566 567 assert(oldTex->RefCount > 0); 568 569 if (p_atomic_dec_zero(&oldTex->RefCount)) { 570 /* Passing in the context drastically changes the driver code for 571 * framebuffer deletion. 572 */ 573 GET_CURRENT_CONTEXT(ctx); 574 if (ctx) 575 ctx->Driver.DeleteTexture(ctx, oldTex); 576 else 577 _mesa_problem(NULL, "Unable to delete texture, no context"); 578 } 579 } 580 581 if (tex) { 582 /* reference new texture */ 583 assert(valid_texture_object(tex)); 584 assert(tex->RefCount > 0); 585 586 p_atomic_inc(&tex->RefCount); 587 } 588 589 *ptr = tex; 590} 591 592 593enum base_mipmap { BASE, MIPMAP }; 594 595 596/** 597 * Mark a texture object as incomplete. There are actually three kinds of 598 * (in)completeness: 599 * 1. "base incomplete": the base level of the texture is invalid so no 600 * texturing is possible. 601 * 2. "mipmap incomplete": a non-base level of the texture is invalid so 602 * mipmap filtering isn't possible, but non-mipmap filtering is. 603 * 3. "texture incompleteness": some combination of texture state and 604 * sampler state renders the texture incomplete. 605 * 606 * \param t texture object 607 * \param bm either BASE or MIPMAP to indicate what's incomplete 608 * \param fmt... string describing why it's incomplete (for debugging). 609 */ 610static void 611incomplete(struct gl_texture_object *t, enum base_mipmap bm, 612 const char *fmt, ...) 613{ 614 if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_TEXTURE) { 615 va_list args; 616 char s[100]; 617 618 va_start(args, fmt); 619 vsnprintf(s, sizeof(s), fmt, args); 620 va_end(args); 621 622 _mesa_debug(NULL, "Texture Obj %d incomplete because: %s\n", t->Name, s); 623 } 624 625 if (bm == BASE) 626 t->_BaseComplete = GL_FALSE; 627 t->_MipmapComplete = GL_FALSE; 628} 629 630 631/** 632 * Examine a texture object to determine if it is complete. 633 * 634 * The gl_texture_object::Complete flag will be set to GL_TRUE or GL_FALSE 635 * accordingly. 636 * 637 * \param ctx GL context. 638 * \param t texture object. 639 * 640 * According to the texture target, verifies that each of the mipmaps is 641 * present and has the expected size. 642 */ 643void 644_mesa_test_texobj_completeness( const struct gl_context *ctx, 645 struct gl_texture_object *t ) 646{ 647 const GLint baseLevel = t->Attrib.BaseLevel; 648 const struct gl_texture_image *baseImage; 649 GLint maxLevels = 0; 650 651 /* We'll set these to FALSE if tests fail below */ 652 t->_BaseComplete = GL_TRUE; 653 t->_MipmapComplete = GL_TRUE; 654 655 if (t->Target == GL_TEXTURE_BUFFER) { 656 /* Buffer textures are always considered complete. The obvious case where 657 * they would be incomplete (no BO attached) is actually specced to be 658 * undefined rendering results. 659 */ 660 return; 661 } 662 663 /* Detect cases where the application set the base level to an invalid 664 * value. 665 */ 666 if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) { 667 incomplete(t, BASE, "base level = %d is invalid", baseLevel); 668 return; 669 } 670 671 if (t->Attrib.MaxLevel < baseLevel) { 672 incomplete(t, MIPMAP, "MAX_LEVEL (%d) < BASE_LEVEL (%d)", 673 t->Attrib.MaxLevel, baseLevel); 674 return; 675 } 676 677 baseImage = t->Image[0][baseLevel]; 678 679 /* Always need the base level image */ 680 if (!baseImage) { 681 incomplete(t, BASE, "Image[baseLevel=%d] == NULL", baseLevel); 682 return; 683 } 684 685 /* Check width/height/depth for zero */ 686 if (baseImage->Width == 0 || 687 baseImage->Height == 0 || 688 baseImage->Depth == 0) { 689 incomplete(t, BASE, "texture width or height or depth = 0"); 690 return; 691 } 692 693 /* Check if the texture values are integer */ 694 { 695 GLenum datatype = _mesa_get_format_datatype(baseImage->TexFormat); 696 t->_IsIntegerFormat = datatype == GL_INT || datatype == GL_UNSIGNED_INT; 697 } 698 699 /* Check if the texture type is Float or HalfFloatOES and ensure Min and Mag 700 * filters are supported in this case. 701 */ 702 if (_mesa_is_gles(ctx) && !valid_filter_for_float(ctx, t)) { 703 incomplete(t, BASE, "Filter is not supported with Float types."); 704 return; 705 } 706 707 maxLevels = _mesa_max_texture_levels(ctx, t->Target); 708 if (maxLevels == 0) { 709 _mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness"); 710 return; 711 } 712 713 assert(maxLevels > 0); 714 715 t->_MaxLevel = MIN3(t->Attrib.MaxLevel, 716 /* 'p' in the GL spec */ 717 (int) (baseLevel + baseImage->MaxNumLevels - 1), 718 /* 'q' in the GL spec */ 719 maxLevels - 1); 720 721 if (t->Immutable) { 722 /* Adjust max level for views: the data store may have more levels than 723 * the view exposes. 724 */ 725 t->_MaxLevel = MAX2(MIN2(t->_MaxLevel, t->Attrib.NumLevels - 1), 0); 726 } 727 728 /* Compute _MaxLambda = q - p in the spec used during mipmapping */ 729 t->_MaxLambda = (GLfloat) (t->_MaxLevel - baseLevel); 730 731 if (t->Immutable) { 732 /* This texture object was created with glTexStorage1/2/3D() so we 733 * know that all the mipmap levels are the right size and all cube 734 * map faces are the same size. 735 * We don't need to do any of the additional checks below. 736 */ 737 return; 738 } 739 740 if (t->Target == GL_TEXTURE_CUBE_MAP) { 741 /* Make sure that all six cube map level 0 images are the same size and 742 * format. 743 * Note: we know that the image's width==height (we enforce that 744 * at glTexImage time) so we only need to test the width here. 745 */ 746 GLuint face; 747 assert(baseImage->Width2 == baseImage->Height); 748 for (face = 1; face < 6; face++) { 749 assert(t->Image[face][baseLevel] == NULL || 750 t->Image[face][baseLevel]->Width2 == 751 t->Image[face][baseLevel]->Height2); 752 if (t->Image[face][baseLevel] == NULL || 753 t->Image[face][baseLevel]->Width2 != baseImage->Width2) { 754 incomplete(t, BASE, "Cube face missing or mismatched size"); 755 return; 756 } 757 if (t->Image[face][baseLevel]->InternalFormat != 758 baseImage->InternalFormat) { 759 incomplete(t, BASE, "Cube face format mismatch"); 760 return; 761 } 762 if (t->Image[face][baseLevel]->Border != baseImage->Border) { 763 incomplete(t, BASE, "Cube face border size mismatch"); 764 return; 765 } 766 } 767 } 768 769 /* 770 * Do mipmap consistency checking. 771 * Note: we don't care about the current texture sampler state here. 772 * To determine texture completeness we'll either look at _BaseComplete 773 * or _MipmapComplete depending on the current minification filter mode. 774 */ 775 { 776 GLint i; 777 const GLint minLevel = baseLevel; 778 const GLint maxLevel = t->_MaxLevel; 779 const GLuint numFaces = _mesa_num_tex_faces(t->Target); 780 GLuint width, height, depth, face; 781 782 if (minLevel > maxLevel) { 783 incomplete(t, MIPMAP, "minLevel > maxLevel"); 784 return; 785 } 786 787 /* Get the base image's dimensions */ 788 width = baseImage->Width2; 789 height = baseImage->Height2; 790 depth = baseImage->Depth2; 791 792 /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL, 793 * MULTISAMPLE and MULTISAMPLE_ARRAY textures 794 */ 795 for (i = baseLevel + 1; i < maxLevels; i++) { 796 /* Compute the expected size of image at level[i] */ 797 if (width > 1) { 798 width /= 2; 799 } 800 if (height > 1 && t->Target != GL_TEXTURE_1D_ARRAY) { 801 height /= 2; 802 } 803 if (depth > 1 && t->Target != GL_TEXTURE_2D_ARRAY 804 && t->Target != GL_TEXTURE_CUBE_MAP_ARRAY) { 805 depth /= 2; 806 } 807 808 /* loop over cube faces (or single face otherwise) */ 809 for (face = 0; face < numFaces; face++) { 810 if (i >= minLevel && i <= maxLevel) { 811 const struct gl_texture_image *img = t->Image[face][i]; 812 813 if (!img) { 814 incomplete(t, MIPMAP, "TexImage[%d] is missing", i); 815 return; 816 } 817 if (img->InternalFormat != baseImage->InternalFormat) { 818 incomplete(t, MIPMAP, "Format[i] != Format[baseLevel]"); 819 return; 820 } 821 if (img->Border != baseImage->Border) { 822 incomplete(t, MIPMAP, "Border[i] != Border[baseLevel]"); 823 return; 824 } 825 if (img->Width2 != width) { 826 incomplete(t, MIPMAP, "TexImage[%d] bad width %u", i, 827 img->Width2); 828 return; 829 } 830 if (img->Height2 != height) { 831 incomplete(t, MIPMAP, "TexImage[%d] bad height %u", i, 832 img->Height2); 833 return; 834 } 835 if (img->Depth2 != depth) { 836 incomplete(t, MIPMAP, "TexImage[%d] bad depth %u", i, 837 img->Depth2); 838 return; 839 } 840 } 841 } 842 843 if (width == 1 && height == 1 && depth == 1) { 844 return; /* found smallest needed mipmap, all done! */ 845 } 846 } 847 } 848} 849 850 851GLboolean 852_mesa_cube_level_complete(const struct gl_texture_object *texObj, 853 const GLint level) 854{ 855 const struct gl_texture_image *img0, *img; 856 GLuint face; 857 858 if (texObj->Target != GL_TEXTURE_CUBE_MAP) 859 return GL_FALSE; 860 861 if ((level < 0) || (level >= MAX_TEXTURE_LEVELS)) 862 return GL_FALSE; 863 864 /* check first face */ 865 img0 = texObj->Image[0][level]; 866 if (!img0 || 867 img0->Width < 1 || 868 img0->Width != img0->Height) 869 return GL_FALSE; 870 871 /* check remaining faces vs. first face */ 872 for (face = 1; face < 6; face++) { 873 img = texObj->Image[face][level]; 874 if (!img || 875 img->Width != img0->Width || 876 img->Height != img0->Height || 877 img->TexFormat != img0->TexFormat) 878 return GL_FALSE; 879 } 880 881 return GL_TRUE; 882} 883 884/** 885 * Check if the given cube map texture is "cube complete" as defined in 886 * the OpenGL specification. 887 */ 888GLboolean 889_mesa_cube_complete(const struct gl_texture_object *texObj) 890{ 891 return _mesa_cube_level_complete(texObj, texObj->Attrib.BaseLevel); 892} 893 894/** 895 * Mark a texture object dirty. It forces the object to be incomplete 896 * and forces the context to re-validate its state. 897 * 898 * \param ctx GL context. 899 * \param texObj texture object. 900 */ 901void 902_mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj) 903{ 904 texObj->_BaseComplete = GL_FALSE; 905 texObj->_MipmapComplete = GL_FALSE; 906 ctx->NewState |= _NEW_TEXTURE_OBJECT; 907 ctx->PopAttribState |= GL_TEXTURE_BIT; 908} 909 910 911/** 912 * Return pointer to a default/fallback texture of the given type/target. 913 * The texture is an RGBA texture with all texels = (0,0,0,1). 914 * That's the value a GLSL sampler should get when sampling from an 915 * incomplete texture. 916 */ 917struct gl_texture_object * 918_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex) 919{ 920 if (!ctx->Shared->FallbackTex[tex]) { 921 /* create fallback texture now */ 922 const GLsizei width = 1, height = 1; 923 GLsizei depth = 1; 924 GLubyte texel[24]; 925 struct gl_texture_object *texObj; 926 struct gl_texture_image *texImage; 927 mesa_format texFormat; 928 GLuint dims, face, numFaces = 1; 929 GLenum target; 930 931 for (face = 0; face < 6; face++) { 932 texel[4*face + 0] = 933 texel[4*face + 1] = 934 texel[4*face + 2] = 0x0; 935 texel[4*face + 3] = 0xff; 936 } 937 938 switch (tex) { 939 case TEXTURE_2D_ARRAY_INDEX: 940 dims = 3; 941 target = GL_TEXTURE_2D_ARRAY; 942 break; 943 case TEXTURE_1D_ARRAY_INDEX: 944 dims = 2; 945 target = GL_TEXTURE_1D_ARRAY; 946 break; 947 case TEXTURE_CUBE_INDEX: 948 dims = 2; 949 target = GL_TEXTURE_CUBE_MAP; 950 numFaces = 6; 951 break; 952 case TEXTURE_3D_INDEX: 953 dims = 3; 954 target = GL_TEXTURE_3D; 955 break; 956 case TEXTURE_RECT_INDEX: 957 dims = 2; 958 target = GL_TEXTURE_RECTANGLE; 959 break; 960 case TEXTURE_2D_INDEX: 961 dims = 2; 962 target = GL_TEXTURE_2D; 963 break; 964 case TEXTURE_1D_INDEX: 965 dims = 1; 966 target = GL_TEXTURE_1D; 967 break; 968 case TEXTURE_BUFFER_INDEX: 969 dims = 0; 970 target = GL_TEXTURE_BUFFER; 971 break; 972 case TEXTURE_CUBE_ARRAY_INDEX: 973 dims = 3; 974 target = GL_TEXTURE_CUBE_MAP_ARRAY; 975 depth = 6; 976 break; 977 case TEXTURE_EXTERNAL_INDEX: 978 dims = 2; 979 target = GL_TEXTURE_EXTERNAL_OES; 980 break; 981 case TEXTURE_2D_MULTISAMPLE_INDEX: 982 dims = 2; 983 target = GL_TEXTURE_2D_MULTISAMPLE; 984 break; 985 case TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: 986 dims = 3; 987 target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY; 988 break; 989 default: 990 /* no-op */ 991 return NULL; 992 } 993 994 /* create texture object */ 995 texObj = ctx->Driver.NewTextureObject(ctx, 0, target); 996 if (!texObj) 997 return NULL; 998 999 assert(texObj->RefCount == 1); 1000 texObj->Sampler.Attrib.MinFilter = GL_NEAREST; 1001 texObj->Sampler.Attrib.MagFilter = GL_NEAREST; 1002 texObj->Sampler.Attrib.state.min_img_filter = PIPE_TEX_FILTER_NEAREST; 1003 texObj->Sampler.Attrib.state.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 1004 texObj->Sampler.Attrib.state.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 1005 1006 texFormat = ctx->Driver.ChooseTextureFormat(ctx, target, 1007 GL_RGBA, GL_RGBA, 1008 GL_UNSIGNED_BYTE); 1009 1010 /* need a loop here just for cube maps */ 1011 for (face = 0; face < numFaces; face++) { 1012 const GLenum faceTarget = _mesa_cube_face_target(target, face); 1013 1014 /* initialize level[0] texture image */ 1015 texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, 0); 1016 1017 _mesa_init_teximage_fields(ctx, texImage, 1018 width, 1019 (dims > 1) ? height : 1, 1020 (dims > 2) ? depth : 1, 1021 0, /* border */ 1022 GL_RGBA, texFormat); 1023 1024 ctx->Driver.TexImage(ctx, dims, texImage, 1025 GL_RGBA, GL_UNSIGNED_BYTE, texel, 1026 &ctx->DefaultPacking); 1027 } 1028 1029 _mesa_test_texobj_completeness(ctx, texObj); 1030 assert(texObj->_BaseComplete); 1031 assert(texObj->_MipmapComplete); 1032 1033 ctx->Shared->FallbackTex[tex] = texObj; 1034 1035 /* Complete the driver's operation in case another context will also 1036 * use the same fallback texture. */ 1037 if (ctx->Driver.Finish) 1038 ctx->Driver.Finish(ctx); 1039 } 1040 return ctx->Shared->FallbackTex[tex]; 1041} 1042 1043 1044/** 1045 * Compute the size of the given texture object, in bytes. 1046 */ 1047static GLuint 1048texture_size(const struct gl_texture_object *texObj) 1049{ 1050 const GLuint numFaces = _mesa_num_tex_faces(texObj->Target); 1051 GLuint face, level, size = 0; 1052 1053 for (face = 0; face < numFaces; face++) { 1054 for (level = 0; level < MAX_TEXTURE_LEVELS; level++) { 1055 const struct gl_texture_image *img = texObj->Image[face][level]; 1056 if (img) { 1057 GLuint sz = _mesa_format_image_size(img->TexFormat, img->Width, 1058 img->Height, img->Depth); 1059 size += sz; 1060 } 1061 } 1062 } 1063 1064 return size; 1065} 1066 1067 1068/** 1069 * Callback called from _mesa_HashWalk() 1070 */ 1071static void 1072count_tex_size(void *data, void *userData) 1073{ 1074 const struct gl_texture_object *texObj = 1075 (const struct gl_texture_object *) data; 1076 GLuint *total = (GLuint *) userData; 1077 1078 *total = *total + texture_size(texObj); 1079} 1080 1081 1082/** 1083 * Compute total size (in bytes) of all textures for the given context. 1084 * For debugging purposes. 1085 */ 1086GLuint 1087_mesa_total_texture_memory(struct gl_context *ctx) 1088{ 1089 GLuint tgt, total = 0; 1090 1091 _mesa_HashWalk(ctx->Shared->TexObjects, count_tex_size, &total); 1092 1093 /* plus, the default texture objects */ 1094 for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { 1095 total += texture_size(ctx->Shared->DefaultTex[tgt]); 1096 } 1097 1098 return total; 1099} 1100 1101 1102/** 1103 * Return the base format for the given texture object by looking 1104 * at the base texture image. 1105 * \return base format (such as GL_RGBA) or GL_NONE if it can't be determined 1106 */ 1107GLenum 1108_mesa_texture_base_format(const struct gl_texture_object *texObj) 1109{ 1110 const struct gl_texture_image *texImage = _mesa_base_tex_image(texObj); 1111 1112 return texImage ? texImage->_BaseFormat : GL_NONE; 1113} 1114 1115 1116static struct gl_texture_object * 1117invalidate_tex_image_error_check(struct gl_context *ctx, GLuint texture, 1118 GLint level, const char *name) 1119{ 1120 /* The GL_ARB_invalidate_subdata spec says: 1121 * 1122 * "If <texture> is zero or is not the name of a texture, the error 1123 * INVALID_VALUE is generated." 1124 * 1125 * This performs the error check in a different order than listed in the 1126 * spec. We have to get the texture object before we can validate the 1127 * other parameters against values in the texture object. 1128 */ 1129 struct gl_texture_object *const t = _mesa_lookup_texture(ctx, texture); 1130 if (texture == 0 || t == NULL) { 1131 _mesa_error(ctx, GL_INVALID_VALUE, "%s(texture)", name); 1132 return NULL; 1133 } 1134 1135 /* The GL_ARB_invalidate_subdata spec says: 1136 * 1137 * "If <level> is less than zero or greater than the base 2 logarithm 1138 * of the maximum texture width, height, or depth, the error 1139 * INVALID_VALUE is generated." 1140 */ 1141 if (level < 0 || level > t->Attrib.MaxLevel) { 1142 _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name); 1143 return NULL; 1144 } 1145 1146 /* The GL_ARB_invalidate_subdata spec says: 1147 * 1148 * "If the target of <texture> is TEXTURE_RECTANGLE, TEXTURE_BUFFER, 1149 * TEXTURE_2D_MULTISAMPLE, or TEXTURE_2D_MULTISAMPLE_ARRAY, and <level> 1150 * is not zero, the error INVALID_VALUE is generated." 1151 */ 1152 if (level != 0) { 1153 switch (t->Target) { 1154 case GL_TEXTURE_RECTANGLE: 1155 case GL_TEXTURE_BUFFER: 1156 case GL_TEXTURE_2D_MULTISAMPLE: 1157 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1158 _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name); 1159 return NULL; 1160 1161 default: 1162 break; 1163 } 1164 } 1165 1166 return t; 1167} 1168 1169 1170/** 1171 * Helper function for glCreateTextures and glGenTextures. Need this because 1172 * glCreateTextures should throw errors if target = 0. This is not exposed to 1173 * the rest of Mesa to encourage Mesa internals to use nameless textures, 1174 * which do not require expensive hash lookups. 1175 * \param target either 0 or a valid / error-checked texture target enum 1176 */ 1177static void 1178create_textures(struct gl_context *ctx, GLenum target, 1179 GLsizei n, GLuint *textures, const char *caller) 1180{ 1181 GLint i; 1182 1183 if (!textures) 1184 return; 1185 1186 /* 1187 * This must be atomic (generation and allocation of texture IDs) 1188 */ 1189 _mesa_HashLockMutex(ctx->Shared->TexObjects); 1190 1191 _mesa_HashFindFreeKeys(ctx->Shared->TexObjects, textures, n); 1192 1193 /* Allocate new, empty texture objects */ 1194 for (i = 0; i < n; i++) { 1195 struct gl_texture_object *texObj; 1196 texObj = ctx->Driver.NewTextureObject(ctx, textures[i], target); 1197 if (!texObj) { 1198 _mesa_HashUnlockMutex(ctx->Shared->TexObjects); 1199 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); 1200 return; 1201 } 1202 1203 /* insert into hash table */ 1204 _mesa_HashInsertLocked(ctx->Shared->TexObjects, texObj->Name, texObj, true); 1205 } 1206 1207 _mesa_HashUnlockMutex(ctx->Shared->TexObjects); 1208} 1209 1210 1211static void 1212create_textures_err(struct gl_context *ctx, GLenum target, 1213 GLsizei n, GLuint *textures, const char *caller) 1214{ 1215 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1216 _mesa_debug(ctx, "%s %d\n", caller, n); 1217 1218 if (n < 0) { 1219 _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", caller); 1220 return; 1221 } 1222 1223 create_textures(ctx, target, n, textures, caller); 1224} 1225 1226/*@}*/ 1227 1228 1229/***********************************************************************/ 1230/** \name API functions */ 1231/*@{*/ 1232 1233 1234/** 1235 * Generate texture names. 1236 * 1237 * \param n number of texture names to be generated. 1238 * \param textures an array in which will hold the generated texture names. 1239 * 1240 * \sa glGenTextures(), glCreateTextures(). 1241 * 1242 * Calls _mesa_HashFindFreeKeys() to find a block of free texture 1243 * IDs which are stored in \p textures. Corresponding empty texture 1244 * objects are also generated. 1245 */ 1246void GLAPIENTRY 1247_mesa_GenTextures_no_error(GLsizei n, GLuint *textures) 1248{ 1249 GET_CURRENT_CONTEXT(ctx); 1250 create_textures(ctx, 0, n, textures, "glGenTextures"); 1251} 1252 1253 1254void GLAPIENTRY 1255_mesa_GenTextures(GLsizei n, GLuint *textures) 1256{ 1257 GET_CURRENT_CONTEXT(ctx); 1258 create_textures_err(ctx, 0, n, textures, "glGenTextures"); 1259} 1260 1261/** 1262 * Create texture objects. 1263 * 1264 * \param target the texture target for each name to be generated. 1265 * \param n number of texture names to be generated. 1266 * \param textures an array in which will hold the generated texture names. 1267 * 1268 * \sa glCreateTextures(), glGenTextures(). 1269 * 1270 * Calls _mesa_HashFindFreeKeys() to find a block of free texture 1271 * IDs which are stored in \p textures. Corresponding empty texture 1272 * objects are also generated. 1273 */ 1274void GLAPIENTRY 1275_mesa_CreateTextures_no_error(GLenum target, GLsizei n, GLuint *textures) 1276{ 1277 GET_CURRENT_CONTEXT(ctx); 1278 create_textures(ctx, target, n, textures, "glCreateTextures"); 1279} 1280 1281 1282void GLAPIENTRY 1283_mesa_CreateTextures(GLenum target, GLsizei n, GLuint *textures) 1284{ 1285 GLint targetIndex; 1286 GET_CURRENT_CONTEXT(ctx); 1287 1288 /* 1289 * The 4.5 core profile spec (30.10.2014) doesn't specify what 1290 * glCreateTextures should do with invalid targets, which was probably an 1291 * oversight. This conforms to the spec for glBindTexture. 1292 */ 1293 targetIndex = _mesa_tex_target_to_index(ctx, target); 1294 if (targetIndex < 0) { 1295 _mesa_error(ctx, GL_INVALID_ENUM, "glCreateTextures(target)"); 1296 return; 1297 } 1298 1299 create_textures_err(ctx, target, n, textures, "glCreateTextures"); 1300} 1301 1302/** 1303 * Check if the given texture object is bound to the current draw or 1304 * read framebuffer. If so, Unbind it. 1305 */ 1306static void 1307unbind_texobj_from_fbo(struct gl_context *ctx, 1308 struct gl_texture_object *texObj) 1309{ 1310 bool progress = false; 1311 1312 /* Section 4.4.2 (Attaching Images to Framebuffer Objects), subsection 1313 * "Attaching Texture Images to a Framebuffer," of the OpenGL 3.1 spec 1314 * says: 1315 * 1316 * "If a texture object is deleted while its image is attached to one 1317 * or more attachment points in the currently bound framebuffer, then 1318 * it is as if FramebufferTexture* had been called, with a texture of 1319 * zero, for each attachment point to which this image was attached in 1320 * the currently bound framebuffer. In other words, this texture image 1321 * is first detached from all attachment points in the currently bound 1322 * framebuffer. Note that the texture image is specifically not 1323 * detached from any other framebuffer objects. Detaching the texture 1324 * image from any other framebuffer objects is the responsibility of 1325 * the application." 1326 */ 1327 if (_mesa_is_user_fbo(ctx->DrawBuffer)) { 1328 progress = _mesa_detach_renderbuffer(ctx, ctx->DrawBuffer, texObj); 1329 } 1330 if (_mesa_is_user_fbo(ctx->ReadBuffer) 1331 && ctx->ReadBuffer != ctx->DrawBuffer) { 1332 progress = _mesa_detach_renderbuffer(ctx, ctx->ReadBuffer, texObj) 1333 || progress; 1334 } 1335 1336 if (progress) 1337 /* Vertices are already flushed by _mesa_DeleteTextures */ 1338 ctx->NewState |= _NEW_BUFFERS; 1339} 1340 1341 1342/** 1343 * Check if the given texture object is bound to any texture image units and 1344 * unbind it if so (revert to default textures). 1345 */ 1346static void 1347unbind_texobj_from_texunits(struct gl_context *ctx, 1348 struct gl_texture_object *texObj) 1349{ 1350 const gl_texture_index index = texObj->TargetIndex; 1351 GLuint u; 1352 1353 if (texObj->Target == 0) { 1354 /* texture was never bound */ 1355 return; 1356 } 1357 1358 assert(index < NUM_TEXTURE_TARGETS); 1359 1360 for (u = 0; u < ctx->Texture.NumCurrentTexUsed; u++) { 1361 struct gl_texture_unit *unit = &ctx->Texture.Unit[u]; 1362 1363 if (texObj == unit->CurrentTex[index]) { 1364 /* Bind the default texture for this unit/target */ 1365 _mesa_reference_texobj(&unit->CurrentTex[index], 1366 ctx->Shared->DefaultTex[index]); 1367 unit->_BoundTextures &= ~(1 << index); 1368 } 1369 } 1370} 1371 1372 1373/** 1374 * Check if the given texture object is bound to any shader image unit 1375 * and unbind it if that's the case. 1376 */ 1377static void 1378unbind_texobj_from_image_units(struct gl_context *ctx, 1379 struct gl_texture_object *texObj) 1380{ 1381 GLuint i; 1382 1383 for (i = 0; i < ctx->Const.MaxImageUnits; i++) { 1384 struct gl_image_unit *unit = &ctx->ImageUnits[i]; 1385 1386 if (texObj == unit->TexObj) { 1387 _mesa_reference_texobj(&unit->TexObj, NULL); 1388 *unit = _mesa_default_image_unit(ctx); 1389 } 1390 } 1391} 1392 1393 1394/** 1395 * Unbinds all textures bound to the given texture image unit. 1396 */ 1397static void 1398unbind_textures_from_unit(struct gl_context *ctx, GLuint unit) 1399{ 1400 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 1401 1402 while (texUnit->_BoundTextures) { 1403 const GLuint index = ffs(texUnit->_BoundTextures) - 1; 1404 struct gl_texture_object *texObj = ctx->Shared->DefaultTex[index]; 1405 1406 _mesa_reference_texobj(&texUnit->CurrentTex[index], texObj); 1407 1408 /* Pass BindTexture call to device driver */ 1409 if (ctx->Driver.BindTexture) 1410 ctx->Driver.BindTexture(ctx, unit, 0, texObj); 1411 1412 texUnit->_BoundTextures &= ~(1 << index); 1413 ctx->NewState |= _NEW_TEXTURE_OBJECT; 1414 ctx->PopAttribState |= GL_TEXTURE_BIT; 1415 } 1416} 1417 1418 1419/** 1420 * Delete named textures. 1421 * 1422 * \param n number of textures to be deleted. 1423 * \param textures array of texture IDs to be deleted. 1424 * 1425 * \sa glDeleteTextures(). 1426 * 1427 * If we're about to delete a texture that's currently bound to any 1428 * texture unit, unbind the texture first. Decrement the reference 1429 * count on the texture object and delete it if it's zero. 1430 * Recall that texture objects can be shared among several rendering 1431 * contexts. 1432 */ 1433static void 1434delete_textures(struct gl_context *ctx, GLsizei n, const GLuint *textures) 1435{ 1436 FLUSH_VERTICES(ctx, 0, 0); /* too complex */ 1437 1438 if (!textures) 1439 return; 1440 1441 for (GLsizei i = 0; i < n; i++) { 1442 if (textures[i] > 0) { 1443 struct gl_texture_object *delObj 1444 = _mesa_lookup_texture(ctx, textures[i]); 1445 1446 if (delObj) { 1447 _mesa_lock_texture(ctx, delObj); 1448 1449 /* Check if texture is bound to any framebuffer objects. 1450 * If so, unbind. 1451 * See section 4.4.2.3 of GL_EXT_framebuffer_object. 1452 */ 1453 unbind_texobj_from_fbo(ctx, delObj); 1454 1455 /* Check if this texture is currently bound to any texture units. 1456 * If so, unbind it. 1457 */ 1458 unbind_texobj_from_texunits(ctx, delObj); 1459 1460 /* Check if this texture is currently bound to any shader 1461 * image unit. If so, unbind it. 1462 * See section 3.9.X of GL_ARB_shader_image_load_store. 1463 */ 1464 unbind_texobj_from_image_units(ctx, delObj); 1465 1466 /* Make all handles that reference this texture object non-resident 1467 * in the current context. 1468 */ 1469 _mesa_make_texture_handles_non_resident(ctx, delObj); 1470 1471 _mesa_unlock_texture(ctx, delObj); 1472 1473 ctx->NewState |= _NEW_TEXTURE_OBJECT; 1474 ctx->PopAttribState |= GL_TEXTURE_BIT; 1475 1476 /* The texture _name_ is now free for re-use. 1477 * Remove it from the hash table now. 1478 */ 1479 _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name); 1480 1481 if (ctx->Driver.TextureRemovedFromShared) { 1482 ctx->Driver.TextureRemovedFromShared(ctx, delObj); 1483 } 1484 1485 /* Unreference the texobj. If refcount hits zero, the texture 1486 * will be deleted. 1487 */ 1488 _mesa_reference_texobj(&delObj, NULL); 1489 } 1490 } 1491 } 1492} 1493 1494/** 1495 * This deletes a texObj without altering the hash table. 1496 */ 1497void 1498_mesa_delete_nameless_texture(struct gl_context *ctx, 1499 struct gl_texture_object *texObj) 1500{ 1501 if (!texObj) 1502 return; 1503 1504 FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT); 1505 1506 _mesa_lock_texture(ctx, texObj); 1507 { 1508 /* Check if texture is bound to any framebuffer objects. 1509 * If so, unbind. 1510 * See section 4.4.2.3 of GL_EXT_framebuffer_object. 1511 */ 1512 unbind_texobj_from_fbo(ctx, texObj); 1513 1514 /* Check if this texture is currently bound to any texture units. 1515 * If so, unbind it. 1516 */ 1517 unbind_texobj_from_texunits(ctx, texObj); 1518 1519 /* Check if this texture is currently bound to any shader 1520 * image unit. If so, unbind it. 1521 * See section 3.9.X of GL_ARB_shader_image_load_store. 1522 */ 1523 unbind_texobj_from_image_units(ctx, texObj); 1524 } 1525 _mesa_unlock_texture(ctx, texObj); 1526 1527 /* Unreference the texobj. If refcount hits zero, the texture 1528 * will be deleted. 1529 */ 1530 _mesa_reference_texobj(&texObj, NULL); 1531} 1532 1533 1534void GLAPIENTRY 1535_mesa_DeleteTextures_no_error(GLsizei n, const GLuint *textures) 1536{ 1537 GET_CURRENT_CONTEXT(ctx); 1538 delete_textures(ctx, n, textures); 1539} 1540 1541 1542void GLAPIENTRY 1543_mesa_DeleteTextures(GLsizei n, const GLuint *textures) 1544{ 1545 GET_CURRENT_CONTEXT(ctx); 1546 1547 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1548 _mesa_debug(ctx, "glDeleteTextures %d\n", n); 1549 1550 if (n < 0) { 1551 _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteTextures(n < 0)"); 1552 return; 1553 } 1554 1555 delete_textures(ctx, n, textures); 1556} 1557 1558 1559/** 1560 * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D 1561 * into the corresponding Mesa texture target index. 1562 * Note that proxy targets are not valid here. 1563 * \return TEXTURE_x_INDEX or -1 if target is invalid 1564 */ 1565int 1566_mesa_tex_target_to_index(const struct gl_context *ctx, GLenum target) 1567{ 1568 switch (target) { 1569 case GL_TEXTURE_1D: 1570 return _mesa_is_desktop_gl(ctx) ? TEXTURE_1D_INDEX : -1; 1571 case GL_TEXTURE_2D: 1572 return TEXTURE_2D_INDEX; 1573 case GL_TEXTURE_3D: 1574 return ctx->API != API_OPENGLES ? TEXTURE_3D_INDEX : -1; 1575 case GL_TEXTURE_CUBE_MAP: 1576 return ctx->Extensions.ARB_texture_cube_map 1577 ? TEXTURE_CUBE_INDEX : -1; 1578 case GL_TEXTURE_RECTANGLE: 1579 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle 1580 ? TEXTURE_RECT_INDEX : -1; 1581 case GL_TEXTURE_1D_ARRAY: 1582 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array 1583 ? TEXTURE_1D_ARRAY_INDEX : -1; 1584 case GL_TEXTURE_2D_ARRAY: 1585 return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) 1586 || _mesa_is_gles3(ctx) 1587 ? TEXTURE_2D_ARRAY_INDEX : -1; 1588 case GL_TEXTURE_BUFFER: 1589 return (_mesa_has_ARB_texture_buffer_object(ctx) || 1590 _mesa_has_OES_texture_buffer(ctx)) ? 1591 TEXTURE_BUFFER_INDEX : -1; 1592 case GL_TEXTURE_EXTERNAL_OES: 1593 return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external 1594 ? TEXTURE_EXTERNAL_INDEX : -1; 1595 case GL_TEXTURE_CUBE_MAP_ARRAY: 1596 return _mesa_has_texture_cube_map_array(ctx) 1597 ? TEXTURE_CUBE_ARRAY_INDEX : -1; 1598 case GL_TEXTURE_2D_MULTISAMPLE: 1599 return ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample) || 1600 _mesa_is_gles31(ctx)) ? TEXTURE_2D_MULTISAMPLE_INDEX: -1; 1601 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1602 return ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample) || 1603 _mesa_is_gles31(ctx)) 1604 ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: -1; 1605 default: 1606 return -1; 1607 } 1608} 1609 1610 1611/** 1612 * Do actual texture binding. All error checking should have been done prior 1613 * to calling this function. Note that the texture target (1D, 2D, etc) is 1614 * always specified by the texObj->TargetIndex. 1615 * 1616 * \param unit index of texture unit to update 1617 * \param texObj the new texture object (cannot be NULL) 1618 */ 1619static void 1620bind_texture_object(struct gl_context *ctx, unsigned unit, 1621 struct gl_texture_object *texObj) 1622{ 1623 struct gl_texture_unit *texUnit; 1624 int targetIndex; 1625 1626 assert(unit < ARRAY_SIZE(ctx->Texture.Unit)); 1627 texUnit = &ctx->Texture.Unit[unit]; 1628 1629 assert(texObj); 1630 assert(valid_texture_object(texObj)); 1631 1632 targetIndex = texObj->TargetIndex; 1633 assert(targetIndex >= 0); 1634 assert(targetIndex < NUM_TEXTURE_TARGETS); 1635 1636 /* Check if this texture is only used by this context and is already bound. 1637 * If so, just return. For GL_OES_image_external, rebinding the texture 1638 * always must invalidate cached resources. 1639 */ 1640 if (targetIndex != TEXTURE_EXTERNAL_INDEX && 1641 ctx->Shared->RefCount == 1 && 1642 texObj == texUnit->CurrentTex[targetIndex]) 1643 return; 1644 1645 /* Flush before changing binding. 1646 * 1647 * Note: Multisample textures don't need to flag GL_TEXTURE_BIT because 1648 * they are not restored by glPopAttrib according to the GL 4.6 1649 * Compatibility Profile specification. We set GL_TEXTURE_BIT anyway 1650 * to simplify the code. This has no effect on behavior. 1651 */ 1652 FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT); 1653 1654 /* If the refcount on the previously bound texture is decremented to 1655 * zero, it'll be deleted here. 1656 */ 1657 _mesa_reference_texobj(&texUnit->CurrentTex[targetIndex], texObj); 1658 1659 ctx->Texture.NumCurrentTexUsed = MAX2(ctx->Texture.NumCurrentTexUsed, 1660 unit + 1); 1661 1662 if (texObj->Name != 0) 1663 texUnit->_BoundTextures |= (1 << targetIndex); 1664 else 1665 texUnit->_BoundTextures &= ~(1 << targetIndex); 1666 1667 /* Pass BindTexture call to device driver */ 1668 if (ctx->Driver.BindTexture) { 1669 ctx->Driver.BindTexture(ctx, unit, texObj->Target, texObj); 1670 } 1671} 1672 1673/** 1674 * Light-weight bind texture for internal users 1675 * 1676 * This is really just \c finish_texture_init plus \c bind_texture_object. 1677 * This is intended to be used by internal Mesa functions that use 1678 * \c _mesa_CreateTexture and need to bind textures (e.g., meta). 1679 */ 1680void 1681_mesa_bind_texture(struct gl_context *ctx, GLenum target, 1682 struct gl_texture_object *tex_obj) 1683{ 1684 const GLint targetIndex = _mesa_tex_target_to_index(ctx, target); 1685 1686 assert(targetIndex >= 0 && targetIndex < NUM_TEXTURE_TARGETS); 1687 1688 if (tex_obj->Target == 0) 1689 finish_texture_init(ctx, target, tex_obj, targetIndex); 1690 1691 assert(tex_obj->Target == target); 1692 assert(tex_obj->TargetIndex == targetIndex); 1693 1694 bind_texture_object(ctx, ctx->Texture.CurrentUnit, tex_obj); 1695} 1696 1697struct gl_texture_object * 1698_mesa_lookup_or_create_texture(struct gl_context *ctx, GLenum target, 1699 GLuint texName, bool no_error, bool is_ext_dsa, 1700 const char *caller) 1701{ 1702 struct gl_texture_object *newTexObj = NULL; 1703 int targetIndex; 1704 1705 if (is_ext_dsa) { 1706 if (_mesa_is_proxy_texture(target)) { 1707 /* EXT_dsa allows proxy targets only when texName is 0 */ 1708 if (texName != 0) { 1709 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target = %s)", caller, 1710 _mesa_enum_to_string(target)); 1711 return NULL; 1712 } 1713 return _mesa_get_current_tex_object(ctx, target); 1714 } 1715 if (GL_TEXTURE_CUBE_MAP_POSITIVE_X <= target && 1716 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) { 1717 target = GL_TEXTURE_CUBE_MAP; 1718 } 1719 } 1720 1721 targetIndex = _mesa_tex_target_to_index(ctx, target); 1722 if (!no_error && targetIndex < 0) { 1723 _mesa_error(ctx, GL_INVALID_ENUM, "%s(target = %s)", caller, 1724 _mesa_enum_to_string(target)); 1725 return NULL; 1726 } 1727 assert(targetIndex < NUM_TEXTURE_TARGETS); 1728 1729 /* 1730 * Get pointer to new texture object (newTexObj) 1731 */ 1732 if (texName == 0) { 1733 /* Use a default texture object */ 1734 newTexObj = ctx->Shared->DefaultTex[targetIndex]; 1735 } else { 1736 /* non-default texture object */ 1737 newTexObj = _mesa_lookup_texture(ctx, texName); 1738 if (newTexObj) { 1739 /* error checking */ 1740 if (!no_error && 1741 newTexObj->Target != 0 && newTexObj->Target != target) { 1742 /* The named texture object's target doesn't match the 1743 * given target 1744 */ 1745 _mesa_error(ctx, GL_INVALID_OPERATION, 1746 "%s(target mismatch)", caller); 1747 return NULL; 1748 } 1749 if (newTexObj->Target == 0) { 1750 finish_texture_init(ctx, target, newTexObj, targetIndex); 1751 } 1752 } else { 1753 if (!no_error && ctx->API == API_OPENGL_CORE) { 1754 _mesa_error(ctx, GL_INVALID_OPERATION, 1755 "%s(non-gen name)", caller); 1756 return NULL; 1757 } 1758 1759 /* if this is a new texture id, allocate a texture object now */ 1760 newTexObj = ctx->Driver.NewTextureObject(ctx, texName, target); 1761 if (!newTexObj) { 1762 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); 1763 return NULL; 1764 } 1765 1766 /* and insert it into hash table */ 1767 _mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj, false); 1768 } 1769 } 1770 1771 assert(newTexObj->Target == target); 1772 assert(newTexObj->TargetIndex == targetIndex); 1773 1774 return newTexObj; 1775} 1776 1777/** 1778 * Implement glBindTexture(). Do error checking, look-up or create a new 1779 * texture object, then bind it in the current texture unit. 1780 * 1781 * \param target texture target. 1782 * \param texName texture name. 1783 * \param texunit texture unit. 1784 */ 1785static ALWAYS_INLINE void 1786bind_texture(struct gl_context *ctx, GLenum target, GLuint texName, 1787 GLenum texunit, bool no_error, const char *caller) 1788{ 1789 struct gl_texture_object *newTexObj = 1790 _mesa_lookup_or_create_texture(ctx, target, texName, no_error, false, 1791 caller); 1792 if (!newTexObj) 1793 return; 1794 1795 bind_texture_object(ctx, texunit, newTexObj); 1796} 1797 1798void GLAPIENTRY 1799_mesa_BindTexture_no_error(GLenum target, GLuint texName) 1800{ 1801 GET_CURRENT_CONTEXT(ctx); 1802 bind_texture(ctx, target, texName, ctx->Texture.CurrentUnit, true, 1803 "glBindTexture"); 1804} 1805 1806 1807void GLAPIENTRY 1808_mesa_BindTexture(GLenum target, GLuint texName) 1809{ 1810 GET_CURRENT_CONTEXT(ctx); 1811 1812 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1813 _mesa_debug(ctx, "glBindTexture %s %d\n", 1814 _mesa_enum_to_string(target), (GLint) texName); 1815 1816 bind_texture(ctx, target, texName, ctx->Texture.CurrentUnit, false, 1817 "glBindTexture"); 1818} 1819 1820 1821void GLAPIENTRY 1822_mesa_BindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture) 1823{ 1824 GET_CURRENT_CONTEXT(ctx); 1825 1826 unsigned unit = texunit - GL_TEXTURE0; 1827 1828 if (texunit < GL_TEXTURE0 || unit >= _mesa_max_tex_unit(ctx)) { 1829 _mesa_error(ctx, GL_INVALID_ENUM, "glBindMultiTextureEXT(texunit=%s)", 1830 _mesa_enum_to_string(texunit)); 1831 return; 1832 } 1833 1834 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1835 _mesa_debug(ctx, "glBindMultiTextureEXT %s %d\n", 1836 _mesa_enum_to_string(texunit), (GLint) texture); 1837 1838 bind_texture(ctx, target, texture, unit, false, "glBindMultiTextureEXT"); 1839} 1840 1841 1842/** 1843 * OpenGL 4.5 / GL_ARB_direct_state_access glBindTextureUnit(). 1844 * 1845 * \param unit texture unit. 1846 * \param texture texture name. 1847 * 1848 * \sa glBindTexture(). 1849 * 1850 * If the named texture is 0, this will reset each target for the specified 1851 * texture unit to its default texture. 1852 * If the named texture is not 0 or a recognized texture name, this throws 1853 * GL_INVALID_OPERATION. 1854 */ 1855static ALWAYS_INLINE void 1856bind_texture_unit(struct gl_context *ctx, GLuint unit, GLuint texture, 1857 bool no_error) 1858{ 1859 struct gl_texture_object *texObj; 1860 1861 /* Section 8.1 (Texture Objects) of the OpenGL 4.5 core profile spec 1862 * (20141030) says: 1863 * "When texture is zero, each of the targets enumerated at the 1864 * beginning of this section is reset to its default texture for the 1865 * corresponding texture image unit." 1866 */ 1867 if (texture == 0) { 1868 unbind_textures_from_unit(ctx, unit); 1869 return; 1870 } 1871 1872 /* Get the non-default texture object */ 1873 texObj = _mesa_lookup_texture(ctx, texture); 1874 if (!no_error) { 1875 /* Error checking */ 1876 if (!texObj) { 1877 _mesa_error(ctx, GL_INVALID_OPERATION, 1878 "glBindTextureUnit(non-gen name)"); 1879 return; 1880 } 1881 1882 if (texObj->Target == 0) { 1883 /* Texture object was gen'd but never bound so the target is not set */ 1884 _mesa_error(ctx, GL_INVALID_OPERATION, "glBindTextureUnit(target)"); 1885 return; 1886 } 1887 } 1888 1889 assert(valid_texture_object(texObj)); 1890 1891 bind_texture_object(ctx, unit, texObj); 1892} 1893 1894 1895void GLAPIENTRY 1896_mesa_BindTextureUnit_no_error(GLuint unit, GLuint texture) 1897{ 1898 GET_CURRENT_CONTEXT(ctx); 1899 bind_texture_unit(ctx, unit, texture, true); 1900} 1901 1902 1903void GLAPIENTRY 1904_mesa_BindTextureUnit(GLuint unit, GLuint texture) 1905{ 1906 GET_CURRENT_CONTEXT(ctx); 1907 1908 if (unit >= _mesa_max_tex_unit(ctx)) { 1909 _mesa_error(ctx, GL_INVALID_VALUE, "glBindTextureUnit(unit=%u)", unit); 1910 return; 1911 } 1912 1913 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 1914 _mesa_debug(ctx, "glBindTextureUnit %s %d\n", 1915 _mesa_enum_to_string(GL_TEXTURE0+unit), (GLint) texture); 1916 1917 bind_texture_unit(ctx, unit, texture, false); 1918} 1919 1920 1921/** 1922 * OpenGL 4.4 / GL_ARB_multi_bind glBindTextures(). 1923 */ 1924static ALWAYS_INLINE void 1925bind_textures(struct gl_context *ctx, GLuint first, GLsizei count, 1926 const GLuint *textures, bool no_error) 1927{ 1928 GLsizei i; 1929 1930 if (textures) { 1931 /* Note that the error semantics for multi-bind commands differ from 1932 * those of other GL commands. 1933 * 1934 * The issues section in the ARB_multi_bind spec says: 1935 * 1936 * "(11) Typically, OpenGL specifies that if an error is generated by 1937 * a command, that command has no effect. This is somewhat 1938 * unfortunate for multi-bind commands, because it would require 1939 * a first pass to scan the entire list of bound objects for 1940 * errors and then a second pass to actually perform the 1941 * bindings. Should we have different error semantics? 1942 * 1943 * RESOLVED: Yes. In this specification, when the parameters for 1944 * one of the <count> binding points are invalid, that binding 1945 * point is not updated and an error will be generated. However, 1946 * other binding points in the same command will be updated if 1947 * their parameters are valid and no other error occurs." 1948 */ 1949 1950 _mesa_HashLockMutex(ctx->Shared->TexObjects); 1951 1952 for (i = 0; i < count; i++) { 1953 if (textures[i] != 0) { 1954 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[first + i]; 1955 struct gl_texture_object *current = texUnit->_Current; 1956 struct gl_texture_object *texObj; 1957 1958 if (current && current->Name == textures[i]) 1959 texObj = current; 1960 else 1961 texObj = _mesa_lookup_texture_locked(ctx, textures[i]); 1962 1963 if (texObj && texObj->Target != 0) { 1964 bind_texture_object(ctx, first + i, texObj); 1965 } else if (!no_error) { 1966 /* The ARB_multi_bind spec says: 1967 * 1968 * "An INVALID_OPERATION error is generated if any value 1969 * in <textures> is not zero or the name of an existing 1970 * texture object (per binding)." 1971 */ 1972 _mesa_error(ctx, GL_INVALID_OPERATION, 1973 "glBindTextures(textures[%d]=%u is not zero " 1974 "or the name of an existing texture object)", 1975 i, textures[i]); 1976 } 1977 } else { 1978 unbind_textures_from_unit(ctx, first + i); 1979 } 1980 } 1981 1982 _mesa_HashUnlockMutex(ctx->Shared->TexObjects); 1983 } else { 1984 /* Unbind all textures in the range <first> through <first>+<count>-1 */ 1985 for (i = 0; i < count; i++) 1986 unbind_textures_from_unit(ctx, first + i); 1987 } 1988} 1989 1990 1991void GLAPIENTRY 1992_mesa_BindTextures_no_error(GLuint first, GLsizei count, const GLuint *textures) 1993{ 1994 GET_CURRENT_CONTEXT(ctx); 1995 bind_textures(ctx, first, count, textures, true); 1996} 1997 1998 1999void GLAPIENTRY 2000_mesa_BindTextures(GLuint first, GLsizei count, const GLuint *textures) 2001{ 2002 GET_CURRENT_CONTEXT(ctx); 2003 2004 /* The ARB_multi_bind spec says: 2005 * 2006 * "An INVALID_OPERATION error is generated if <first> + <count> 2007 * is greater than the number of texture image units supported 2008 * by the implementation." 2009 */ 2010 if (first + count > ctx->Const.MaxCombinedTextureImageUnits) { 2011 _mesa_error(ctx, GL_INVALID_OPERATION, 2012 "glBindTextures(first=%u + count=%d > the value of " 2013 "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS=%u)", 2014 first, count, ctx->Const.MaxCombinedTextureImageUnits); 2015 return; 2016 } 2017 2018 bind_textures(ctx, first, count, textures, false); 2019} 2020 2021 2022/** 2023 * Set texture priorities. 2024 * 2025 * \param n number of textures. 2026 * \param texName texture names. 2027 * \param priorities corresponding texture priorities. 2028 * 2029 * \sa glPrioritizeTextures(). 2030 * 2031 * Looks up each texture in the hash, clamps the corresponding priority between 2032 * 0.0 and 1.0, and calls dd_function_table::PrioritizeTexture. 2033 */ 2034void GLAPIENTRY 2035_mesa_PrioritizeTextures( GLsizei n, const GLuint *texName, 2036 const GLclampf *priorities ) 2037{ 2038 GET_CURRENT_CONTEXT(ctx); 2039 GLint i; 2040 2041 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2042 _mesa_debug(ctx, "glPrioritizeTextures %d\n", n); 2043 2044 2045 if (n < 0) { 2046 _mesa_error( ctx, GL_INVALID_VALUE, "glPrioritizeTextures" ); 2047 return; 2048 } 2049 2050 if (!priorities) 2051 return; 2052 2053 FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT); 2054 2055 for (i = 0; i < n; i++) { 2056 if (texName[i] > 0) { 2057 struct gl_texture_object *t = _mesa_lookup_texture(ctx, texName[i]); 2058 if (t) { 2059 t->Attrib.Priority = CLAMP( priorities[i], 0.0F, 1.0F ); 2060 } 2061 } 2062 } 2063} 2064 2065 2066 2067/** 2068 * See if textures are loaded in texture memory. 2069 * 2070 * \param n number of textures to query. 2071 * \param texName array with the texture names. 2072 * \param residences array which will hold the residence status. 2073 * 2074 * \return GL_TRUE if all textures are resident and 2075 * residences is left unchanged, 2076 * 2077 * Note: we assume all textures are always resident 2078 */ 2079GLboolean GLAPIENTRY 2080_mesa_AreTexturesResident(GLsizei n, const GLuint *texName, 2081 GLboolean *residences) 2082{ 2083 GET_CURRENT_CONTEXT(ctx); 2084 GLboolean allResident = GL_TRUE; 2085 GLint i; 2086 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 2087 2088 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2089 _mesa_debug(ctx, "glAreTexturesResident %d\n", n); 2090 2091 if (n < 0) { 2092 _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)"); 2093 return GL_FALSE; 2094 } 2095 2096 if (!texName || !residences) 2097 return GL_FALSE; 2098 2099 /* We only do error checking on the texture names */ 2100 for (i = 0; i < n; i++) { 2101 struct gl_texture_object *t; 2102 if (texName[i] == 0) { 2103 _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident"); 2104 return GL_FALSE; 2105 } 2106 t = _mesa_lookup_texture(ctx, texName[i]); 2107 if (!t) { 2108 _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident"); 2109 return GL_FALSE; 2110 } 2111 } 2112 2113 return allResident; 2114} 2115 2116 2117/** 2118 * See if a name corresponds to a texture. 2119 * 2120 * \param texture texture name. 2121 * 2122 * \return GL_TRUE if texture name corresponds to a texture, or GL_FALSE 2123 * otherwise. 2124 * 2125 * \sa glIsTexture(). 2126 * 2127 * Calls _mesa_HashLookup(). 2128 */ 2129GLboolean GLAPIENTRY 2130_mesa_IsTexture( GLuint texture ) 2131{ 2132 struct gl_texture_object *t; 2133 GET_CURRENT_CONTEXT(ctx); 2134 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); 2135 2136 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2137 _mesa_debug(ctx, "glIsTexture %d\n", texture); 2138 2139 if (!texture) 2140 return GL_FALSE; 2141 2142 t = _mesa_lookup_texture(ctx, texture); 2143 2144 /* IsTexture is true only after object has been bound once. */ 2145 return t && t->Target; 2146} 2147 2148 2149/** 2150 * Simplest implementation of texture locking: grab the shared tex 2151 * mutex. Examine the shared context state timestamp and if there has 2152 * been a change, set the appropriate bits in ctx->NewState. 2153 * 2154 * This is used to deal with synchronizing things when a texture object 2155 * is used/modified by different contexts (or threads) which are sharing 2156 * the texture. 2157 * 2158 * See also _mesa_lock/unlock_texture() in teximage.h 2159 */ 2160void 2161_mesa_lock_context_textures( struct gl_context *ctx ) 2162{ 2163 if (!ctx->TexturesLocked) 2164 mtx_lock(&ctx->Shared->TexMutex); 2165 2166 if (ctx->Shared->TextureStateStamp != ctx->TextureStateTimestamp) { 2167 ctx->NewState |= _NEW_TEXTURE_OBJECT; 2168 ctx->PopAttribState |= GL_TEXTURE_BIT; 2169 ctx->TextureStateTimestamp = ctx->Shared->TextureStateStamp; 2170 } 2171} 2172 2173 2174void 2175_mesa_unlock_context_textures( struct gl_context *ctx ) 2176{ 2177 assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp); 2178 if (!ctx->TexturesLocked) 2179 mtx_unlock(&ctx->Shared->TexMutex); 2180} 2181 2182 2183void GLAPIENTRY 2184_mesa_InvalidateTexSubImage_no_error(GLuint texture, GLint level, GLint xoffset, 2185 GLint yoffset, GLint zoffset, 2186 GLsizei width, GLsizei height, 2187 GLsizei depth) 2188{ 2189 /* no-op */ 2190} 2191 2192 2193void GLAPIENTRY 2194_mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, 2195 GLint yoffset, GLint zoffset, GLsizei width, 2196 GLsizei height, GLsizei depth) 2197{ 2198 struct gl_texture_object *t; 2199 struct gl_texture_image *image; 2200 GET_CURRENT_CONTEXT(ctx); 2201 2202 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2203 _mesa_debug(ctx, "glInvalidateTexSubImage %d\n", texture); 2204 2205 t = invalidate_tex_image_error_check(ctx, texture, level, 2206 "glInvalidateTexSubImage"); 2207 2208 /* The GL_ARB_invalidate_subdata spec says: 2209 * 2210 * "...the specified subregion must be between -<b> and <dim>+<b> where 2211 * <dim> is the size of the dimension of the texture image, and <b> is 2212 * the size of the border of that texture image, otherwise 2213 * INVALID_VALUE is generated (border is not applied to dimensions that 2214 * don't exist in a given texture target)." 2215 */ 2216 image = t->Image[0][level]; 2217 if (image) { 2218 int xBorder; 2219 int yBorder; 2220 int zBorder; 2221 int imageWidth; 2222 int imageHeight; 2223 int imageDepth; 2224 2225 /* The GL_ARB_invalidate_subdata spec says: 2226 * 2227 * "For texture targets that don't have certain dimensions, this 2228 * command treats those dimensions as having a size of 1. For 2229 * example, to invalidate a portion of a two-dimensional texture, 2230 * the application would use <zoffset> equal to zero and <depth> 2231 * equal to one." 2232 */ 2233 switch (t->Target) { 2234 case GL_TEXTURE_BUFFER: 2235 xBorder = 0; 2236 yBorder = 0; 2237 zBorder = 0; 2238 imageWidth = 1; 2239 imageHeight = 1; 2240 imageDepth = 1; 2241 break; 2242 case GL_TEXTURE_1D: 2243 xBorder = image->Border; 2244 yBorder = 0; 2245 zBorder = 0; 2246 imageWidth = image->Width; 2247 imageHeight = 1; 2248 imageDepth = 1; 2249 break; 2250 case GL_TEXTURE_1D_ARRAY: 2251 xBorder = image->Border; 2252 yBorder = 0; 2253 zBorder = 0; 2254 imageWidth = image->Width; 2255 imageHeight = image->Height; 2256 imageDepth = 1; 2257 break; 2258 case GL_TEXTURE_2D: 2259 case GL_TEXTURE_CUBE_MAP: 2260 case GL_TEXTURE_RECTANGLE: 2261 case GL_TEXTURE_2D_MULTISAMPLE: 2262 xBorder = image->Border; 2263 yBorder = image->Border; 2264 zBorder = 0; 2265 imageWidth = image->Width; 2266 imageHeight = image->Height; 2267 imageDepth = 1; 2268 break; 2269 case GL_TEXTURE_2D_ARRAY: 2270 case GL_TEXTURE_CUBE_MAP_ARRAY: 2271 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 2272 xBorder = image->Border; 2273 yBorder = image->Border; 2274 zBorder = 0; 2275 imageWidth = image->Width; 2276 imageHeight = image->Height; 2277 imageDepth = image->Depth; 2278 break; 2279 case GL_TEXTURE_3D: 2280 xBorder = image->Border; 2281 yBorder = image->Border; 2282 zBorder = image->Border; 2283 imageWidth = image->Width; 2284 imageHeight = image->Height; 2285 imageDepth = image->Depth; 2286 break; 2287 default: 2288 assert(!"Should not get here."); 2289 xBorder = 0; 2290 yBorder = 0; 2291 zBorder = 0; 2292 imageWidth = 0; 2293 imageHeight = 0; 2294 imageDepth = 0; 2295 break; 2296 } 2297 2298 if (xoffset < -xBorder) { 2299 _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(xoffset)"); 2300 return; 2301 } 2302 2303 if (xoffset + width > imageWidth + xBorder) { 2304 _mesa_error(ctx, GL_INVALID_VALUE, 2305 "glInvalidateSubTexImage(xoffset+width)"); 2306 return; 2307 } 2308 2309 if (yoffset < -yBorder) { 2310 _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(yoffset)"); 2311 return; 2312 } 2313 2314 if (yoffset + height > imageHeight + yBorder) { 2315 _mesa_error(ctx, GL_INVALID_VALUE, 2316 "glInvalidateSubTexImage(yoffset+height)"); 2317 return; 2318 } 2319 2320 if (zoffset < -zBorder) { 2321 _mesa_error(ctx, GL_INVALID_VALUE, 2322 "glInvalidateSubTexImage(zoffset)"); 2323 return; 2324 } 2325 2326 if (zoffset + depth > imageDepth + zBorder) { 2327 _mesa_error(ctx, GL_INVALID_VALUE, 2328 "glInvalidateSubTexImage(zoffset+depth)"); 2329 return; 2330 } 2331 } 2332 2333 /* We don't actually do anything for this yet. Just return after 2334 * validating the parameters and generating the required errors. 2335 */ 2336 return; 2337} 2338 2339 2340void GLAPIENTRY 2341_mesa_InvalidateTexImage_no_error(GLuint texture, GLint level) 2342{ 2343 /* no-op */ 2344} 2345 2346 2347void GLAPIENTRY 2348_mesa_InvalidateTexImage(GLuint texture, GLint level) 2349{ 2350 GET_CURRENT_CONTEXT(ctx); 2351 2352 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2353 _mesa_debug(ctx, "glInvalidateTexImage(%d, %d)\n", texture, level); 2354 2355 invalidate_tex_image_error_check(ctx, texture, level, 2356 "glInvalidateTexImage"); 2357 2358 /* We don't actually do anything for this yet. Just return after 2359 * validating the parameters and generating the required errors. 2360 */ 2361 return; 2362} 2363 2364/*@}*/ 2365