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