1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2011 VMware, Inc. All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/** 26 * \file texstorage.c 27 * GL_ARB_texture_storage functions 28 */ 29 30#include "glheader.h" 31#include "context.h" 32#include "enums.h" 33 34#include "macros.h" 35#include "teximage.h" 36#include "texobj.h" 37#include "mipmap.h" 38#include "texstorage.h" 39#include "textureview.h" 40#include "mtypes.h" 41#include "glformats.h" 42#include "hash.h" 43 44 45/** 46 * Check if the given texture target is a legal texture object target 47 * for a glTexStorage() command. 48 * This is a bit different than legal_teximage_target() when it comes 49 * to cube maps. 50 */ 51static bool 52legal_texobj_target(const struct gl_context *ctx, GLuint dims, GLenum target) 53{ 54 if (dims < 1 || dims > 3) { 55 _mesa_problem(ctx, "invalid dims=%u in legal_texobj_target()", dims); 56 return false; 57 } 58 59 switch (dims) { 60 case 2: 61 switch (target) { 62 case GL_TEXTURE_2D: 63 return true; 64 case GL_TEXTURE_CUBE_MAP: 65 return ctx->Extensions.ARB_texture_cube_map; 66 } 67 break; 68 case 3: 69 switch (target) { 70 case GL_TEXTURE_3D: 71 return true; 72 case GL_TEXTURE_2D_ARRAY: 73 return ctx->Extensions.EXT_texture_array; 74 case GL_TEXTURE_CUBE_MAP_ARRAY: 75 return _mesa_has_texture_cube_map_array(ctx); 76 } 77 break; 78 } 79 80 if (!_mesa_is_desktop_gl(ctx)) 81 return false; 82 83 switch (dims) { 84 case 1: 85 switch (target) { 86 case GL_TEXTURE_1D: 87 case GL_PROXY_TEXTURE_1D: 88 return true; 89 default: 90 return false; 91 } 92 case 2: 93 switch (target) { 94 case GL_PROXY_TEXTURE_2D: 95 return true; 96 case GL_PROXY_TEXTURE_CUBE_MAP: 97 return ctx->Extensions.ARB_texture_cube_map; 98 case GL_TEXTURE_RECTANGLE: 99 case GL_PROXY_TEXTURE_RECTANGLE: 100 return ctx->Extensions.NV_texture_rectangle; 101 case GL_TEXTURE_1D_ARRAY: 102 case GL_PROXY_TEXTURE_1D_ARRAY: 103 return ctx->Extensions.EXT_texture_array; 104 default: 105 return false; 106 } 107 case 3: 108 switch (target) { 109 case GL_PROXY_TEXTURE_3D: 110 return true; 111 case GL_PROXY_TEXTURE_2D_ARRAY: 112 return ctx->Extensions.EXT_texture_array; 113 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 114 return ctx->Extensions.ARB_texture_cube_map_array; 115 default: 116 return false; 117 } 118 default: 119 unreachable("impossible dimensions"); 120 } 121} 122 123 124/** Helper to get a particular texture image in a texture object */ 125static struct gl_texture_image * 126get_tex_image(struct gl_context *ctx, 127 struct gl_texture_object *texObj, 128 GLuint face, GLuint level) 129{ 130 const GLenum faceTarget = 131 (texObj->Target == GL_TEXTURE_CUBE_MAP || 132 texObj->Target == GL_PROXY_TEXTURE_CUBE_MAP) 133 ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : texObj->Target; 134 return _mesa_get_tex_image(ctx, texObj, faceTarget, level); 135} 136 137 138 139static GLboolean 140initialize_texture_fields(struct gl_context *ctx, 141 struct gl_texture_object *texObj, 142 GLint levels, 143 GLsizei width, GLsizei height, GLsizei depth, 144 GLenum internalFormat, mesa_format texFormat) 145{ 146 const GLenum target = texObj->Target; 147 const GLuint numFaces = _mesa_num_tex_faces(target); 148 GLint level, levelWidth = width, levelHeight = height, levelDepth = depth; 149 GLuint face; 150 151 /* Set up all the texture object's gl_texture_images */ 152 for (level = 0; level < levels; level++) { 153 for (face = 0; face < numFaces; face++) { 154 struct gl_texture_image *texImage = 155 get_tex_image(ctx, texObj, face, level); 156 157 if (!texImage) { 158 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage"); 159 return GL_FALSE; 160 } 161 162 _mesa_init_teximage_fields(ctx, texImage, 163 levelWidth, levelHeight, levelDepth, 164 0, internalFormat, texFormat); 165 } 166 167 _mesa_next_mipmap_level_size(target, 0, 168 levelWidth, levelHeight, levelDepth, 169 &levelWidth, &levelHeight, &levelDepth); 170 } 171 return GL_TRUE; 172} 173 174 175/** 176 * Clear all fields of texture object to zeros. Used for proxy texture tests 177 * and to clean up when a texture memory allocation fails. 178 */ 179static void 180clear_texture_fields(struct gl_context *ctx, 181 struct gl_texture_object *texObj) 182{ 183 const GLenum target = texObj->Target; 184 const GLuint numFaces = _mesa_num_tex_faces(target); 185 GLint level; 186 GLuint face; 187 188 for (level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) { 189 for (face = 0; face < numFaces; face++) { 190 struct gl_texture_image *texImage = 191 get_tex_image(ctx, texObj, face, level); 192 193 if (!texImage) { 194 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage"); 195 return; 196 } 197 198 _mesa_clear_texture_image(ctx, texImage); 199 } 200 } 201} 202 203 204/** 205 * Update/re-validate framebuffer object. 206 */ 207static void 208update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj) 209{ 210 const unsigned numFaces = _mesa_num_tex_faces(texObj->Target); 211 for (int level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) { 212 for (unsigned face = 0; face < numFaces; face++) 213 _mesa_update_fbo_texture(ctx, texObj, face, level); 214 } 215} 216 217 218GLboolean 219_mesa_is_legal_tex_storage_format(const struct gl_context *ctx, 220 GLenum internalformat) 221{ 222 /* check internal format - note that only sized formats are allowed */ 223 switch (internalformat) { 224 case GL_ALPHA: 225 case GL_LUMINANCE: 226 case GL_LUMINANCE_ALPHA: 227 case GL_INTENSITY: 228 case GL_RED: 229 case GL_RG: 230 case GL_RGB: 231 case GL_RGBA: 232 case GL_BGRA: 233 case GL_DEPTH_COMPONENT: 234 case GL_DEPTH_STENCIL: 235 case GL_COMPRESSED_ALPHA: 236 case GL_COMPRESSED_LUMINANCE_ALPHA: 237 case GL_COMPRESSED_LUMINANCE: 238 case GL_COMPRESSED_INTENSITY: 239 case GL_COMPRESSED_RGB: 240 case GL_COMPRESSED_RGBA: 241 case GL_COMPRESSED_SRGB: 242 case GL_COMPRESSED_SRGB_ALPHA: 243 case GL_COMPRESSED_SLUMINANCE: 244 case GL_COMPRESSED_SLUMINANCE_ALPHA: 245 case GL_RED_INTEGER: 246 case GL_GREEN_INTEGER: 247 case GL_BLUE_INTEGER: 248 case GL_ALPHA_INTEGER: 249 case GL_RGB_INTEGER: 250 case GL_RGBA_INTEGER: 251 case GL_BGR_INTEGER: 252 case GL_BGRA_INTEGER: 253 case GL_LUMINANCE_INTEGER_EXT: 254 case GL_LUMINANCE_ALPHA_INTEGER_EXT: 255 /* these unsized formats are illegal */ 256 return GL_FALSE; 257 default: 258 return _mesa_base_tex_format(ctx, internalformat) > 0; 259 } 260} 261 262 263/** 264 * Default ctx->Driver.AllocTextureStorage() handler. 265 * 266 * The driver can override this with a more specific implementation if it 267 * desires, but this can be used to get the texture images allocated using the 268 * usual texture image handling code. The immutability of 269 * GL_ARB_texture_storage texture layouts is handled by texObj->Immutable 270 * checks at glTexImage* time. 271 */ 272GLboolean 273_mesa_AllocTextureStorage_sw(struct gl_context *ctx, 274 struct gl_texture_object *texObj, 275 GLsizei levels, GLsizei width, 276 GLsizei height, GLsizei depth) 277{ 278 const int numFaces = _mesa_num_tex_faces(texObj->Target); 279 int face; 280 int level; 281 282 (void) width; 283 (void) height; 284 (void) depth; 285 286 for (face = 0; face < numFaces; face++) { 287 for (level = 0; level < levels; level++) { 288 struct gl_texture_image *const texImage = texObj->Image[face][level]; 289 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) 290 return GL_FALSE; 291 } 292 } 293 294 return GL_TRUE; 295} 296 297 298/** 299 * Do error checking for calls to glTexStorage1/2/3D(). 300 * If an error is found, record it with _mesa_error(), unless the target 301 * is a proxy texture. 302 * \return GL_TRUE if any error, GL_FALSE otherwise. 303 */ 304static GLboolean 305tex_storage_error_check(struct gl_context *ctx, 306 struct gl_texture_object *texObj, 307 struct gl_memory_object *memObj, 308 GLuint dims, GLenum target, 309 GLsizei levels, GLenum internalformat, 310 GLsizei width, GLsizei height, GLsizei depth, 311 bool dsa) 312{ 313 const char* suffix = dsa ? (memObj ? "tureMem" : "ture") : 314 (memObj ? "Mem" : ""); 315 316 /* Legal format checking has been moved to texstorage and texturestorage in 317 * order to allow meta functions to use legacy formats. */ 318 319 /* size check */ 320 if (!_mesa_valid_tex_storage_dim(width, height, depth)) { 321 _mesa_error(ctx, GL_INVALID_VALUE, 322 "glTex%sStorage%uD(width, height or depth < 1)", 323 suffix, dims); 324 return GL_TRUE; 325 } 326 327 if (_mesa_is_compressed_format(ctx, internalformat)) { 328 GLenum err; 329 if (!_mesa_target_can_be_compressed(ctx, target, internalformat, &err)) { 330 _mesa_error(ctx, err, 331 "glTex%sStorage%dD(internalformat = %s)", suffix, dims, 332 _mesa_enum_to_string(internalformat)); 333 return GL_TRUE; 334 } 335 } 336 337 /* levels check */ 338 if (levels < 1) { 339 _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)", 340 suffix, dims); 341 return GL_TRUE; 342 } 343 344 /* check levels against maximum (note different error than above) */ 345 if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) { 346 _mesa_error(ctx, GL_INVALID_OPERATION, 347 "glTex%sStorage%uD(levels too large)", 348 suffix, dims); 349 return GL_TRUE; 350 } 351 352 /* check levels against width/height/depth */ 353 if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) { 354 _mesa_error(ctx, GL_INVALID_OPERATION, 355 "glTex%sStorage%uD(too many levels" 356 " for max texture dimension)", 357 suffix, dims); 358 return GL_TRUE; 359 } 360 361 /* non-default texture object check */ 362 if (!_mesa_is_proxy_texture(target) && (!texObj || (texObj->Name == 0))) { 363 _mesa_error(ctx, GL_INVALID_OPERATION, 364 "glTex%sStorage%uD(texture object 0)", 365 suffix, dims); 366 return GL_TRUE; 367 } 368 369 /* Check if texObj->Immutable is set */ 370 if (!_mesa_is_proxy_texture(target) && texObj->Immutable) { 371 _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(immutable)", 372 suffix, dims); 373 return GL_TRUE; 374 } 375 376 /* additional checks for depth textures */ 377 if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat)) { 378 _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(bad target for texture)", 379 suffix, dims); 380 return GL_TRUE; 381 } 382 383 return GL_FALSE; 384} 385 386 387/** 388 * Helper that does the storage allocation for _mesa_TexStorage1/2/3D() 389 * and _mesa_TextureStorage1/2/3D(). 390 */ 391static ALWAYS_INLINE void 392texture_storage(struct gl_context *ctx, GLuint dims, 393 struct gl_texture_object *texObj, 394 struct gl_memory_object *memObj, GLenum target, 395 GLsizei levels, GLenum internalformat, GLsizei width, 396 GLsizei height, GLsizei depth, GLuint64 offset, bool dsa, 397 bool no_error) 398{ 399 GLboolean sizeOK = GL_TRUE, dimensionsOK = GL_TRUE; 400 mesa_format texFormat; 401 const char* suffix = dsa ? (memObj ? "tureMem" : "ture") : 402 (memObj ? "Mem" : ""); 403 404 assert(texObj); 405 406 if (!no_error) { 407 if (tex_storage_error_check(ctx, texObj, memObj, dims, target, levels, 408 internalformat, width, height, depth, dsa)) { 409 return; /* error was recorded */ 410 } 411 } 412 413 texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, 414 internalformat, GL_NONE, GL_NONE); 415 416 if (!no_error) { 417 /* check that width, height, depth are legal for the mipmap level */ 418 dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, 419 width, height, depth, 0); 420 421 sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, levels, 0, texFormat, 422 1, width, height, depth); 423 } 424 425 if (_mesa_is_proxy_texture(target)) { 426 if (dimensionsOK && sizeOK) { 427 initialize_texture_fields(ctx, texObj, levels, width, height, depth, 428 internalformat, texFormat); 429 } 430 else { 431 /* clear all image fields for [levels] */ 432 clear_texture_fields(ctx, texObj); 433 } 434 } 435 else { 436 if (!no_error) { 437 if (!dimensionsOK) { 438 _mesa_error(ctx, GL_INVALID_VALUE, 439 "glTex%sStorage%uD(invalid width, height or depth)", 440 suffix, dims); 441 return; 442 } 443 444 if (!sizeOK) { 445 _mesa_error(ctx, GL_OUT_OF_MEMORY, 446 "glTex%sStorage%uD(texture too large)", 447 suffix, dims); 448 return; 449 } 450 } 451 452 assert(levels > 0); 453 assert(width > 0); 454 assert(height > 0); 455 assert(depth > 0); 456 457 if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth, 458 internalformat, texFormat)) { 459 return; 460 } 461 462 /* Setup the backing memory */ 463 if (memObj) { 464 if (!ctx->Driver.SetTextureStorageForMemoryObject(ctx, texObj, memObj, 465 levels, 466 width, height, depth, 467 offset)) { 468 469 clear_texture_fields(ctx, texObj); 470 return; 471 } 472 } 473 else { 474 if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels, 475 width, height, depth)) { 476 /* Reset the texture images' info to zeros. 477 * Strictly speaking, we probably don't have to do this since 478 * generating GL_OUT_OF_MEMORY can leave things in an undefined 479 * state but this puts things in a consistent state. 480 */ 481 clear_texture_fields(ctx, texObj); 482 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD", 483 suffix, dims); 484 return; 485 } 486 } 487 488 _mesa_set_texture_view_state(ctx, texObj, target, levels); 489 490 update_fbo_texture(ctx, texObj); 491 } 492} 493 494 495static void 496texture_storage_error(struct gl_context *ctx, GLuint dims, 497 struct gl_texture_object *texObj, 498 GLenum target, GLsizei levels, 499 GLenum internalformat, GLsizei width, 500 GLsizei height, GLsizei depth, bool dsa) 501{ 502 texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat, 503 width, height, depth, dsa, 0, false); 504} 505 506 507static void 508texture_storage_no_error(struct gl_context *ctx, GLuint dims, 509 struct gl_texture_object *texObj, 510 GLenum target, GLsizei levels, 511 GLenum internalformat, GLsizei width, 512 GLsizei height, GLsizei depth, bool dsa) 513{ 514 texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat, 515 width, height, depth, dsa, 0, true); 516} 517 518 519/** 520 * Helper used by _mesa_TexStorage1/2/3D(). 521 */ 522static void 523texstorage_error(GLuint dims, GLenum target, GLsizei levels, 524 GLenum internalformat, GLsizei width, GLsizei height, 525 GLsizei depth, const char *caller) 526{ 527 struct gl_texture_object *texObj; 528 GET_CURRENT_CONTEXT(ctx); 529 530 /* Check target. This is done here so that texture_storage 531 * can receive unsized formats. 532 */ 533 if (!legal_texobj_target(ctx, dims, target)) { 534 _mesa_error(ctx, GL_INVALID_ENUM, 535 "%s(illegal target=%s)", 536 caller, _mesa_enum_to_string(target)); 537 return; 538 } 539 540 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 541 _mesa_debug(ctx, "%s %s %d %s %d %d %d\n", caller, 542 _mesa_enum_to_string(target), levels, 543 _mesa_enum_to_string(internalformat), 544 width, height, depth); 545 546 /* Check the format to make sure it is sized. */ 547 if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { 548 _mesa_error(ctx, GL_INVALID_ENUM, 549 "%s(internalformat = %s)", caller, 550 _mesa_enum_to_string(internalformat)); 551 return; 552 } 553 554 texObj = _mesa_get_current_tex_object(ctx, target); 555 if (!texObj) 556 return; 557 558 texture_storage_error(ctx, dims, texObj, target, levels, 559 internalformat, width, height, depth, false); 560} 561 562 563static void 564texstorage_no_error(GLuint dims, GLenum target, GLsizei levels, 565 GLenum internalformat, GLsizei width, GLsizei height, 566 GLsizei depth) 567{ 568 GET_CURRENT_CONTEXT(ctx); 569 570 struct gl_texture_object *texObj = _mesa_get_current_tex_object(ctx, target); 571 texture_storage_no_error(ctx, dims, texObj, target, levels, 572 internalformat, width, height, depth, false); 573} 574 575 576/** 577 * Helper used by _mesa_TextureStorage1/2/3D(). 578 */ 579static void 580texturestorage_error(GLuint dims, GLuint texture, GLsizei levels, 581 GLenum internalformat, GLsizei width, GLsizei height, 582 GLsizei depth, const char *caller) 583{ 584 struct gl_texture_object *texObj; 585 GET_CURRENT_CONTEXT(ctx); 586 587 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 588 _mesa_debug(ctx, "%s %d %d %s %d %d %d\n", 589 caller, texture, levels, 590 _mesa_enum_to_string(internalformat), 591 width, height, depth); 592 593 /* Check the format to make sure it is sized. */ 594 if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { 595 _mesa_error(ctx, GL_INVALID_ENUM, 596 "%s(internalformat = %s)", caller, 597 _mesa_enum_to_string(internalformat)); 598 return; 599 } 600 601 texObj = _mesa_lookup_texture_err(ctx, texture, caller); 602 if (!texObj) 603 return; 604 605 /* Check target. This is done here so that texture_storage 606 * can receive unsized formats. 607 */ 608 if (!legal_texobj_target(ctx, dims, texObj->Target)) { 609 _mesa_error(ctx, GL_INVALID_OPERATION, 610 "%s(illegal target=%s)", caller, 611 _mesa_enum_to_string(texObj->Target)); 612 return; 613 } 614 615 texture_storage_error(ctx, dims, texObj, texObj->Target, 616 levels, internalformat, width, height, depth, true); 617} 618 619 620static void 621texturestorage_no_error(GLuint dims, GLuint texture, GLsizei levels, 622 GLenum internalformat, GLsizei width, GLsizei height, 623 GLsizei depth) 624{ 625 GET_CURRENT_CONTEXT(ctx); 626 627 struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, texture); 628 texture_storage_no_error(ctx, dims, texObj, texObj->Target, 629 levels, internalformat, width, height, depth, true); 630} 631 632 633void GLAPIENTRY 634_mesa_TexStorage1D_no_error(GLenum target, GLsizei levels, 635 GLenum internalformat, GLsizei width) 636{ 637 texstorage_no_error(1, target, levels, internalformat, width, 1, 1); 638} 639 640 641void GLAPIENTRY 642_mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, 643 GLsizei width) 644{ 645 texstorage_error(1, target, levels, internalformat, width, 1, 1, 646 "glTexStorage1D"); 647} 648 649 650void GLAPIENTRY 651_mesa_TexStorage2D_no_error(GLenum target, GLsizei levels, 652 GLenum internalformat, GLsizei width, 653 GLsizei height) 654{ 655 texstorage_no_error(2, target, levels, internalformat, width, height, 1); 656} 657 658 659void GLAPIENTRY 660_mesa_TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, 661 GLsizei width, GLsizei height) 662{ 663 texstorage_error(2, target, levels, internalformat, width, height, 1, 664 "glTexStorage2D"); 665} 666 667 668void GLAPIENTRY 669_mesa_TexStorage3D_no_error(GLenum target, GLsizei levels, 670 GLenum internalformat, GLsizei width, 671 GLsizei height, GLsizei depth) 672{ 673 texstorage_no_error(3, target, levels, internalformat, width, height, depth); 674} 675 676 677void GLAPIENTRY 678_mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, 679 GLsizei width, GLsizei height, GLsizei depth) 680{ 681 texstorage_error(3, target, levels, internalformat, width, height, depth, 682 "glTexStorage3D"); 683} 684 685 686void GLAPIENTRY 687_mesa_TextureStorage1D_no_error(GLuint texture, GLsizei levels, 688 GLenum internalformat, GLsizei width) 689{ 690 texturestorage_no_error(1, texture, levels, internalformat, width, 1, 1); 691} 692 693 694void GLAPIENTRY 695_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, 696 GLsizei width) 697{ 698 texturestorage_error(1, texture, levels, internalformat, width, 1, 1, 699 "glTextureStorage1D"); 700} 701 702 703void GLAPIENTRY 704_mesa_TextureStorage2D_no_error(GLuint texture, GLsizei levels, 705 GLenum internalformat, 706 GLsizei width, GLsizei height) 707{ 708 texturestorage_no_error(2, texture, levels, internalformat, width, height, 1); 709} 710 711 712void GLAPIENTRY 713_mesa_TextureStorage2D(GLuint texture, GLsizei levels, 714 GLenum internalformat, 715 GLsizei width, GLsizei height) 716{ 717 texturestorage_error(2, texture, levels, internalformat, width, height, 1, 718 "glTextureStorage2D"); 719} 720 721 722void GLAPIENTRY 723_mesa_TextureStorage3D_no_error(GLuint texture, GLsizei levels, 724 GLenum internalformat, GLsizei width, 725 GLsizei height, GLsizei depth) 726{ 727 texturestorage_no_error(3, texture, levels, internalformat, width, height, 728 depth); 729} 730 731 732void GLAPIENTRY 733_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, 734 GLsizei width, GLsizei height, GLsizei depth) 735{ 736 texturestorage_error(3, texture, levels, internalformat, width, height, depth, 737 "glTextureStorage3D"); 738} 739 740 741void GLAPIENTRY 742_mesa_TextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, 743 GLenum internalformat, 744 GLsizei width) 745{ 746 GET_CURRENT_CONTEXT(ctx); 747 /* 'texture' must always be initialized, even if the call to 748 * glTextureStorage1DEXT will generate an error. 749 */ 750 if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true, 751 "glTextureStorage1DEXT")) 752 return; 753 texturestorage_error(1, texture, levels, internalformat, width, 1, 1, 754 "glTextureStorage1DEXT"); 755} 756 757 758void GLAPIENTRY 759_mesa_TextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels, 760 GLenum internalformat, 761 GLsizei width, GLsizei height) 762{ 763 GET_CURRENT_CONTEXT(ctx); 764 /* 'texture' must always be initialized, even if the call to 765 * glTextureStorage2DEXT will generate an error. 766 */ 767 if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true, 768 "glTextureStorage2DEXT")) 769 return; 770 texturestorage_error(2, texture, levels, internalformat, width, height, 1, 771 "glTextureStorage2DEXT"); 772} 773 774 775void GLAPIENTRY 776_mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, 777 GLenum internalformat, 778 GLsizei width, GLsizei height, GLsizei depth) 779{ 780 GET_CURRENT_CONTEXT(ctx); 781 /* 'texture' must always be initialized, even if the call to 782 * glTextureStorage3DEXT will generate an error. 783 */ 784 if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true, 785 "glTextureStorage3DEXT")) 786 return; 787 texturestorage_error(3, texture, levels, internalformat, width, height, depth, 788 "glTextureStorage3DEXT"); 789} 790 791 792void 793_mesa_texture_storage_memory(struct gl_context *ctx, GLuint dims, 794 struct gl_texture_object *texObj, 795 struct gl_memory_object *memObj, 796 GLenum target, GLsizei levels, 797 GLenum internalformat, GLsizei width, 798 GLsizei height, GLsizei depth, 799 GLuint64 offset, bool dsa) 800{ 801 assert(memObj); 802 803 texture_storage(ctx, dims, texObj, memObj, target, levels, internalformat, 804 width, height, depth, offset, dsa, false); 805} 806