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#include "api_exec_decl.h" 44 45#include "state_tracker/st_cb_texture.h" 46 47/** 48 * Check if the given texture target is a legal texture object target 49 * for a glTexStorage() command. 50 * This is a bit different than legal_teximage_target() when it comes 51 * to cube maps. 52 */ 53bool 54_mesa_is_legal_tex_storage_target(const struct gl_context *ctx, 55 GLuint dims, GLenum target) 56{ 57 if (dims < 1 || dims > 3) { 58 _mesa_problem(ctx, "invalid dims=%u in _mesa_is_legal_tex_storage_target()", dims); 59 return false; 60 } 61 62 switch (dims) { 63 case 2: 64 switch (target) { 65 case GL_TEXTURE_2D: 66 case GL_TEXTURE_CUBE_MAP: 67 return true; 68 } 69 break; 70 case 3: 71 switch (target) { 72 case GL_TEXTURE_3D: 73 return true; 74 case GL_TEXTURE_2D_ARRAY: 75 return ctx->Extensions.EXT_texture_array; 76 case GL_TEXTURE_CUBE_MAP_ARRAY: 77 return _mesa_has_texture_cube_map_array(ctx); 78 } 79 break; 80 } 81 82 if (!_mesa_is_desktop_gl(ctx)) 83 return false; 84 85 switch (dims) { 86 case 1: 87 switch (target) { 88 case GL_TEXTURE_1D: 89 case GL_PROXY_TEXTURE_1D: 90 return true; 91 default: 92 return false; 93 } 94 case 2: 95 switch (target) { 96 case GL_PROXY_TEXTURE_2D: 97 case GL_PROXY_TEXTURE_CUBE_MAP: 98 return true; 99 case GL_TEXTURE_RECTANGLE: 100 case GL_PROXY_TEXTURE_RECTANGLE: 101 return ctx->Extensions.NV_texture_rectangle; 102 case GL_TEXTURE_1D_ARRAY: 103 case GL_PROXY_TEXTURE_1D_ARRAY: 104 return ctx->Extensions.EXT_texture_array; 105 default: 106 return false; 107 } 108 case 3: 109 switch (target) { 110 case GL_PROXY_TEXTURE_3D: 111 return true; 112 case GL_PROXY_TEXTURE_2D_ARRAY: 113 return ctx->Extensions.EXT_texture_array; 114 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 115 return ctx->Extensions.ARB_texture_cube_map_array; 116 default: 117 return false; 118 } 119 default: 120 unreachable("impossible dimensions"); 121 } 122} 123 124 125/** Helper to get a particular texture image in a texture object */ 126static struct gl_texture_image * 127get_tex_image(struct gl_context *ctx, 128 struct gl_texture_object *texObj, 129 GLuint face, GLuint level) 130{ 131 const GLenum faceTarget = 132 (texObj->Target == GL_TEXTURE_CUBE_MAP || 133 texObj->Target == GL_PROXY_TEXTURE_CUBE_MAP) 134 ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : texObj->Target; 135 return _mesa_get_tex_image(ctx, texObj, faceTarget, level); 136} 137 138 139 140static GLboolean 141initialize_texture_fields(struct gl_context *ctx, 142 struct gl_texture_object *texObj, 143 GLint levels, 144 GLsizei width, GLsizei height, GLsizei depth, 145 GLenum internalFormat, mesa_format texFormat) 146{ 147 const GLenum target = texObj->Target; 148 const GLuint numFaces = _mesa_num_tex_faces(target); 149 GLint level, levelWidth = width, levelHeight = height, levelDepth = depth; 150 GLuint face; 151 152 /* Set up all the texture object's gl_texture_images */ 153 for (level = 0; level < levels; level++) { 154 for (face = 0; face < numFaces; face++) { 155 struct gl_texture_image *texImage = 156 get_tex_image(ctx, texObj, face, level); 157 158 if (!texImage) { 159 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage"); 160 return GL_FALSE; 161 } 162 163 _mesa_init_teximage_fields(ctx, texImage, 164 levelWidth, levelHeight, levelDepth, 165 0, internalFormat, texFormat); 166 } 167 168 _mesa_next_mipmap_level_size(target, 0, 169 levelWidth, levelHeight, levelDepth, 170 &levelWidth, &levelHeight, &levelDepth); 171 } 172 return GL_TRUE; 173} 174 175 176/** 177 * Clear all fields of texture object to zeros. Used for proxy texture tests 178 * and to clean up when a texture memory allocation fails. 179 */ 180static void 181clear_texture_fields(struct gl_context *ctx, 182 struct gl_texture_object *texObj) 183{ 184 const GLenum target = texObj->Target; 185 const GLuint numFaces = _mesa_num_tex_faces(target); 186 GLint level; 187 GLuint face; 188 189 for (level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) { 190 for (face = 0; face < numFaces; face++) { 191 struct gl_texture_image *texImage = 192 get_tex_image(ctx, texObj, face, level); 193 194 if (!texImage) { 195 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage"); 196 return; 197 } 198 199 _mesa_clear_texture_image(ctx, texImage); 200 } 201 } 202} 203 204 205/** 206 * Update/re-validate framebuffer object. 207 */ 208static void 209update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj) 210{ 211 const unsigned numFaces = _mesa_num_tex_faces(texObj->Target); 212 for (int level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) { 213 for (unsigned face = 0; face < numFaces; face++) 214 _mesa_update_fbo_texture(ctx, texObj, face, level); 215 } 216} 217 218 219GLboolean 220_mesa_is_legal_tex_storage_format(const struct gl_context *ctx, 221 GLenum internalformat) 222{ 223 /* check internal format - note that only sized formats are allowed */ 224 switch (internalformat) { 225 case GL_ALPHA: 226 case GL_LUMINANCE: 227 case GL_LUMINANCE_ALPHA: 228 case GL_INTENSITY: 229 case GL_RED: 230 case GL_RG: 231 case GL_RGB: 232 case GL_RGBA: 233 case GL_BGRA: 234 case GL_DEPTH_COMPONENT: 235 case GL_DEPTH_STENCIL: 236 case GL_COMPRESSED_ALPHA: 237 case GL_COMPRESSED_LUMINANCE_ALPHA: 238 case GL_COMPRESSED_LUMINANCE: 239 case GL_COMPRESSED_INTENSITY: 240 case GL_COMPRESSED_RGB: 241 case GL_COMPRESSED_RGBA: 242 case GL_COMPRESSED_SRGB: 243 case GL_COMPRESSED_SRGB_ALPHA: 244 case GL_COMPRESSED_SLUMINANCE: 245 case GL_COMPRESSED_SLUMINANCE_ALPHA: 246 case GL_RED_INTEGER: 247 case GL_GREEN_INTEGER: 248 case GL_BLUE_INTEGER: 249 case GL_ALPHA_INTEGER: 250 case GL_RGB_INTEGER: 251 case GL_RGBA_INTEGER: 252 case GL_BGR_INTEGER: 253 case GL_BGRA_INTEGER: 254 case GL_LUMINANCE_INTEGER_EXT: 255 case GL_LUMINANCE_ALPHA_INTEGER_EXT: 256 /* these unsized formats are illegal */ 257 return GL_FALSE; 258 default: 259 return _mesa_base_tex_format(ctx, internalformat) > 0; 260 } 261} 262 263 264/** 265 * Do error checking for calls to glTexStorage1/2/3D(). 266 * If an error is found, record it with _mesa_error(), unless the target 267 * is a proxy texture. 268 * \return GL_TRUE if any error, GL_FALSE otherwise. 269 */ 270static GLboolean 271tex_storage_error_check(struct gl_context *ctx, 272 struct gl_texture_object *texObj, 273 struct gl_memory_object *memObj, 274 GLuint dims, GLenum target, 275 GLsizei levels, GLenum internalformat, 276 GLsizei width, GLsizei height, GLsizei depth, 277 bool dsa) 278{ 279 const char* suffix = dsa ? (memObj ? "tureMem" : "ture") : 280 (memObj ? "Mem" : ""); 281 282 /* Legal format checking has been moved to texstorage and texturestorage in 283 * order to allow meta functions to use legacy formats. */ 284 285 /* size check */ 286 if (!_mesa_valid_tex_storage_dim(width, height, depth)) { 287 _mesa_error(ctx, GL_INVALID_VALUE, 288 "glTex%sStorage%uD(width, height or depth < 1)", 289 suffix, dims); 290 return GL_TRUE; 291 } 292 293 if (_mesa_is_compressed_format(ctx, internalformat)) { 294 GLenum err; 295 if (!_mesa_target_can_be_compressed(ctx, target, internalformat, &err)) { 296 _mesa_error(ctx, err, 297 "glTex%sStorage%dD(internalformat = %s)", suffix, dims, 298 _mesa_enum_to_string(internalformat)); 299 return GL_TRUE; 300 } 301 } 302 303 /* levels check */ 304 if (levels < 1) { 305 _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)", 306 suffix, dims); 307 return GL_TRUE; 308 } 309 310 /* check levels against maximum (note different error than above) */ 311 if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) { 312 _mesa_error(ctx, GL_INVALID_OPERATION, 313 "glTex%sStorage%uD(levels too large)", 314 suffix, dims); 315 return GL_TRUE; 316 } 317 318 /* check levels against width/height/depth */ 319 if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) { 320 _mesa_error(ctx, GL_INVALID_OPERATION, 321 "glTex%sStorage%uD(too many levels" 322 " for max texture dimension)", 323 suffix, dims); 324 return GL_TRUE; 325 } 326 327 /* non-default texture object check */ 328 if (!_mesa_is_proxy_texture(target) && (!texObj || (texObj->Name == 0))) { 329 _mesa_error(ctx, GL_INVALID_OPERATION, 330 "glTex%sStorage%uD(texture object 0)", 331 suffix, dims); 332 return GL_TRUE; 333 } 334 335 /* Check if texObj->Immutable is set */ 336 if (!_mesa_is_proxy_texture(target) && texObj->Immutable) { 337 _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(immutable)", 338 suffix, dims); 339 return GL_TRUE; 340 } 341 342 /* additional checks for depth textures */ 343 if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat)) { 344 _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(bad target for texture)", 345 suffix, dims); 346 return GL_TRUE; 347 } 348 349 return GL_FALSE; 350} 351 352GLboolean 353_mesa_sparse_texture_error_check(struct gl_context *ctx, GLuint dims, 354 struct gl_texture_object *texObj, 355 mesa_format format, GLenum target, GLsizei levels, 356 GLsizei width, GLsizei height, GLsizei depth, 357 const char *func) 358{ 359 int px, py, pz; 360 int index = texObj->VirtualPageSizeIndex; 361 if (!st_GetSparseTextureVirtualPageSize(ctx, target, format, index, 362 &px, &py, &pz)) { 363 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(sparse index = %d)", 364 func, index); 365 return GL_TRUE; 366 } 367 368 if (target == GL_TEXTURE_3D) { 369 if (width > ctx->Const.MaxSparse3DTextureSize || 370 height > ctx->Const.MaxSparse3DTextureSize || 371 depth > ctx->Const.MaxSparse3DTextureSize) 372 goto exceed_max_size; 373 } else { 374 if (width > ctx->Const.MaxSparseTextureSize || 375 height > ctx->Const.MaxSparseTextureSize) 376 goto exceed_max_size; 377 378 if (target == GL_TEXTURE_2D_ARRAY || 379 target == GL_TEXTURE_CUBE_MAP_ARRAY) { 380 if (depth > ctx->Const.MaxSparseArrayTextureLayers) 381 goto exceed_max_size; 382 } else if (target == GL_TEXTURE_1D_ARRAY) { 383 if (height > ctx->Const.MaxSparseArrayTextureLayers) 384 goto exceed_max_size; 385 } 386 } 387 388 /* ARB_sparse_texture2 allow non-page-aligned base texture size. */ 389 if (!_mesa_has_ARB_sparse_texture2(ctx) && 390 (width % px || height % py || depth % pz)) { 391 _mesa_error(ctx, GL_INVALID_VALUE, "%s(sparse page size)", func); 392 return GL_TRUE; 393 } 394 395 /* ARB_sparse_texture spec: 396 * 397 * If the value of SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB is FALSE, 398 * then TexStorage* will generate an INVALID_OPERATION error if 399 * * the texture's TEXTURE_SPARSE_ARB parameter is TRUE, 400 * * <target> is one of TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, 401 * TEXTURE_CUBE_MAP, or TEXTURE_CUBE_MAP_ARRAY, and 402 * * for the virtual page size corresponding to the 403 * VIRTUAL_PAGE_SIZE_INDEX_ARB parameter, either of the following is 404 * true: 405 * - <width> is not a multiple of VIRTUAL_PAGE_SIZE_X_ARB * 406 * 2^(<levels>-1), or 407 * - <height> is not a multiple of VIRTUAL_PAGE_SIZE_Y_ARB * 408 * 2^(<levels>-1). 409 * 410 * This make sure all allocated mipmap level size is multiple of virtual 411 * page size when SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB is FALSE. 412 */ 413 if (!ctx->Const.SparseTextureFullArrayCubeMipmaps && 414 (target == GL_TEXTURE_1D_ARRAY || 415 target == GL_TEXTURE_2D_ARRAY || 416 target == GL_TEXTURE_CUBE_MAP || 417 target == GL_TEXTURE_CUBE_MAP_ARRAY) && 418 (width % (px << (levels - 1)) || 419 height % (py << (levels - 1)))) { 420 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(sparse array align)", func); 421 return GL_TRUE; 422 } 423 424 return GL_FALSE; 425 426exceed_max_size: 427 _mesa_error(ctx, GL_INVALID_VALUE, "%s(exceed max sparse size)", func); 428 return GL_TRUE; 429} 430 431/** 432 * Helper that does the storage allocation for _mesa_TexStorage1/2/3D() 433 * and _mesa_TextureStorage1/2/3D(). 434 */ 435static ALWAYS_INLINE void 436texture_storage(struct gl_context *ctx, GLuint dims, 437 struct gl_texture_object *texObj, 438 struct gl_memory_object *memObj, GLenum target, 439 GLsizei levels, GLenum internalformat, GLsizei width, 440 GLsizei height, GLsizei depth, GLuint64 offset, bool dsa, 441 bool no_error) 442{ 443 GLboolean sizeOK = GL_TRUE, dimensionsOK = GL_TRUE; 444 mesa_format texFormat; 445 const char* suffix = dsa ? (memObj ? "tureMem" : "ture") : 446 (memObj ? "Mem" : ""); 447 448 assert(texObj); 449 450 if (!no_error) { 451 if (tex_storage_error_check(ctx, texObj, memObj, dims, target, levels, 452 internalformat, width, height, depth, dsa)) { 453 return; /* error was recorded */ 454 } 455 } 456 457 texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, 458 internalformat, GL_NONE, GL_NONE); 459 460 if (!no_error) { 461 /* check that width, height, depth are legal for the mipmap level */ 462 dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, 463 width, height, depth, 0); 464 465 sizeOK = st_TestProxyTexImage(ctx, target, levels, 0, texFormat, 466 1, width, height, depth); 467 } 468 469 if (_mesa_is_proxy_texture(target)) { 470 if (dimensionsOK && sizeOK) { 471 initialize_texture_fields(ctx, texObj, levels, width, height, depth, 472 internalformat, texFormat); 473 } 474 else { 475 /* clear all image fields for [levels] */ 476 clear_texture_fields(ctx, texObj); 477 } 478 } 479 else { 480 if (!no_error) { 481 if (!dimensionsOK) { 482 _mesa_error(ctx, GL_INVALID_VALUE, 483 "glTex%sStorage%uD(invalid width, height or depth)", 484 suffix, dims); 485 return; 486 } 487 488 if (!sizeOK) { 489 _mesa_error(ctx, GL_OUT_OF_MEMORY, 490 "glTex%sStorage%uD(texture too large)", 491 suffix, dims); 492 return; 493 } 494 495 if (texObj->IsSparse) { 496 char func[32]; 497 snprintf(func, 32, "glTex%sStorage%uD", suffix, dims); 498 if (_mesa_sparse_texture_error_check(ctx, dims, texObj, texFormat, target, 499 levels, width, height, depth, func)) 500 return; /* error was recorded */ 501 } 502 } 503 504 assert(levels > 0); 505 assert(width > 0); 506 assert(height > 0); 507 assert(depth > 0); 508 509 if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth, 510 internalformat, texFormat)) { 511 return; 512 } 513 514 /* Setup the backing memory */ 515 if (memObj) { 516 if (!st_SetTextureStorageForMemoryObject(ctx, texObj, memObj, 517 levels, 518 width, height, depth, 519 offset)) { 520 521 clear_texture_fields(ctx, texObj); 522 return; 523 } 524 } 525 else { 526 if (!st_AllocTextureStorage(ctx, texObj, levels, 527 width, height, depth)) { 528 /* Reset the texture images' info to zeros. 529 * Strictly speaking, we probably don't have to do this since 530 * generating GL_OUT_OF_MEMORY can leave things in an undefined 531 * state but this puts things in a consistent state. 532 */ 533 clear_texture_fields(ctx, texObj); 534 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD", 535 suffix, dims); 536 return; 537 } 538 } 539 540 _mesa_set_texture_view_state(ctx, texObj, target, levels); 541 542 update_fbo_texture(ctx, texObj); 543 } 544} 545 546 547static void 548texture_storage_error(struct gl_context *ctx, GLuint dims, 549 struct gl_texture_object *texObj, 550 GLenum target, GLsizei levels, 551 GLenum internalformat, GLsizei width, 552 GLsizei height, GLsizei depth, bool dsa) 553{ 554 texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat, 555 width, height, depth, dsa, 0, false); 556} 557 558 559static void 560texture_storage_no_error(struct gl_context *ctx, GLuint dims, 561 struct gl_texture_object *texObj, 562 GLenum target, GLsizei levels, 563 GLenum internalformat, GLsizei width, 564 GLsizei height, GLsizei depth, bool dsa) 565{ 566 texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat, 567 width, height, depth, dsa, 0, true); 568} 569 570 571/** 572 * Helper used by _mesa_TexStorage1/2/3D(). 573 */ 574static void 575texstorage_error(GLuint dims, GLenum target, GLsizei levels, 576 GLenum internalformat, GLsizei width, GLsizei height, 577 GLsizei depth, const char *caller) 578{ 579 struct gl_texture_object *texObj; 580 GET_CURRENT_CONTEXT(ctx); 581 582 /* Check target. This is done here so that texture_storage 583 * can receive unsized formats. 584 */ 585 if (!_mesa_is_legal_tex_storage_target(ctx, dims, target)) { 586 _mesa_error(ctx, GL_INVALID_ENUM, 587 "%s(illegal target=%s)", 588 caller, _mesa_enum_to_string(target)); 589 return; 590 } 591 592 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 593 _mesa_debug(ctx, "%s %s %d %s %d %d %d\n", caller, 594 _mesa_enum_to_string(target), levels, 595 _mesa_enum_to_string(internalformat), 596 width, height, depth); 597 598 /* Check the format to make sure it is sized. */ 599 if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { 600 _mesa_error(ctx, GL_INVALID_ENUM, 601 "%s(internalformat = %s)", caller, 602 _mesa_enum_to_string(internalformat)); 603 return; 604 } 605 606 texObj = _mesa_get_current_tex_object(ctx, target); 607 if (!texObj) 608 return; 609 610 texture_storage_error(ctx, dims, texObj, target, levels, 611 internalformat, width, height, depth, false); 612} 613 614 615static void 616texstorage_no_error(GLuint dims, GLenum target, GLsizei levels, 617 GLenum internalformat, GLsizei width, GLsizei height, 618 GLsizei depth) 619{ 620 GET_CURRENT_CONTEXT(ctx); 621 622 struct gl_texture_object *texObj = _mesa_get_current_tex_object(ctx, target); 623 texture_storage_no_error(ctx, dims, texObj, target, levels, 624 internalformat, width, height, depth, false); 625} 626 627 628/** 629 * Helper used by _mesa_TextureStorage1/2/3D(). 630 */ 631static void 632texturestorage_error(GLuint dims, GLuint texture, GLsizei levels, 633 GLenum internalformat, GLsizei width, GLsizei height, 634 GLsizei depth, const char *caller) 635{ 636 struct gl_texture_object *texObj; 637 GET_CURRENT_CONTEXT(ctx); 638 639 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 640 _mesa_debug(ctx, "%s %d %d %s %d %d %d\n", 641 caller, texture, levels, 642 _mesa_enum_to_string(internalformat), 643 width, height, depth); 644 645 /* Check the format to make sure it is sized. */ 646 if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) { 647 _mesa_error(ctx, GL_INVALID_ENUM, 648 "%s(internalformat = %s)", caller, 649 _mesa_enum_to_string(internalformat)); 650 return; 651 } 652 653 texObj = _mesa_lookup_texture_err(ctx, texture, caller); 654 if (!texObj) 655 return; 656 657 /* Check target. This is done here so that texture_storage 658 * can receive unsized formats. 659 */ 660 if (!_mesa_is_legal_tex_storage_target(ctx, dims, texObj->Target)) { 661 _mesa_error(ctx, GL_INVALID_OPERATION, 662 "%s(illegal target=%s)", caller, 663 _mesa_enum_to_string(texObj->Target)); 664 return; 665 } 666 667 texture_storage_error(ctx, dims, texObj, texObj->Target, 668 levels, internalformat, width, height, depth, true); 669} 670 671 672static void 673texturestorage_no_error(GLuint dims, GLuint texture, GLsizei levels, 674 GLenum internalformat, GLsizei width, GLsizei height, 675 GLsizei depth) 676{ 677 GET_CURRENT_CONTEXT(ctx); 678 679 struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, texture); 680 texture_storage_no_error(ctx, dims, texObj, texObj->Target, 681 levels, internalformat, width, height, depth, true); 682} 683 684 685void GLAPIENTRY 686_mesa_TexStorage1D_no_error(GLenum target, GLsizei levels, 687 GLenum internalformat, GLsizei width) 688{ 689 texstorage_no_error(1, target, levels, internalformat, width, 1, 1); 690} 691 692 693void GLAPIENTRY 694_mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, 695 GLsizei width) 696{ 697 texstorage_error(1, target, levels, internalformat, width, 1, 1, 698 "glTexStorage1D"); 699} 700 701 702void GLAPIENTRY 703_mesa_TexStorage2D_no_error(GLenum target, GLsizei levels, 704 GLenum internalformat, GLsizei width, 705 GLsizei height) 706{ 707 texstorage_no_error(2, target, levels, internalformat, width, height, 1); 708} 709 710 711void GLAPIENTRY 712_mesa_TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, 713 GLsizei width, GLsizei height) 714{ 715 texstorage_error(2, target, levels, internalformat, width, height, 1, 716 "glTexStorage2D"); 717} 718 719 720void GLAPIENTRY 721_mesa_TexStorage3D_no_error(GLenum target, GLsizei levels, 722 GLenum internalformat, GLsizei width, 723 GLsizei height, GLsizei depth) 724{ 725 texstorage_no_error(3, target, levels, internalformat, width, height, depth); 726} 727 728 729void GLAPIENTRY 730_mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, 731 GLsizei width, GLsizei height, GLsizei depth) 732{ 733 texstorage_error(3, target, levels, internalformat, width, height, depth, 734 "glTexStorage3D"); 735} 736 737 738void GLAPIENTRY 739_mesa_TextureStorage1D_no_error(GLuint texture, GLsizei levels, 740 GLenum internalformat, GLsizei width) 741{ 742 texturestorage_no_error(1, texture, levels, internalformat, width, 1, 1); 743} 744 745 746void GLAPIENTRY 747_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, 748 GLsizei width) 749{ 750 texturestorage_error(1, texture, levels, internalformat, width, 1, 1, 751 "glTextureStorage1D"); 752} 753 754 755void GLAPIENTRY 756_mesa_TextureStorage2D_no_error(GLuint texture, GLsizei levels, 757 GLenum internalformat, 758 GLsizei width, GLsizei height) 759{ 760 texturestorage_no_error(2, texture, levels, internalformat, width, height, 1); 761} 762 763 764void GLAPIENTRY 765_mesa_TextureStorage2D(GLuint texture, GLsizei levels, 766 GLenum internalformat, 767 GLsizei width, GLsizei height) 768{ 769 texturestorage_error(2, texture, levels, internalformat, width, height, 1, 770 "glTextureStorage2D"); 771} 772 773 774void GLAPIENTRY 775_mesa_TextureStorage3D_no_error(GLuint texture, GLsizei levels, 776 GLenum internalformat, GLsizei width, 777 GLsizei height, GLsizei depth) 778{ 779 texturestorage_no_error(3, texture, levels, internalformat, width, height, 780 depth); 781} 782 783 784void GLAPIENTRY 785_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, 786 GLsizei width, GLsizei height, GLsizei depth) 787{ 788 texturestorage_error(3, texture, levels, internalformat, width, height, depth, 789 "glTextureStorage3D"); 790} 791 792 793void GLAPIENTRY 794_mesa_TextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, 795 GLenum internalformat, 796 GLsizei width) 797{ 798 GET_CURRENT_CONTEXT(ctx); 799 /* 'texture' must always be initialized, even if the call to 800 * glTextureStorage1DEXT will generate an error. 801 */ 802 if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true, 803 "glTextureStorage1DEXT")) 804 return; 805 texturestorage_error(1, texture, levels, internalformat, width, 1, 1, 806 "glTextureStorage1DEXT"); 807} 808 809 810void GLAPIENTRY 811_mesa_TextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels, 812 GLenum internalformat, 813 GLsizei width, GLsizei height) 814{ 815 GET_CURRENT_CONTEXT(ctx); 816 /* 'texture' must always be initialized, even if the call to 817 * glTextureStorage2DEXT will generate an error. 818 */ 819 if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true, 820 "glTextureStorage2DEXT")) 821 return; 822 texturestorage_error(2, texture, levels, internalformat, width, height, 1, 823 "glTextureStorage2DEXT"); 824} 825 826 827void GLAPIENTRY 828_mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, 829 GLenum internalformat, 830 GLsizei width, GLsizei height, GLsizei depth) 831{ 832 GET_CURRENT_CONTEXT(ctx); 833 /* 'texture' must always be initialized, even if the call to 834 * glTextureStorage3DEXT will generate an error. 835 */ 836 if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true, 837 "glTextureStorage3DEXT")) 838 return; 839 texturestorage_error(3, texture, levels, internalformat, width, height, depth, 840 "glTextureStorage3DEXT"); 841} 842 843 844void 845_mesa_texture_storage_memory(struct gl_context *ctx, GLuint dims, 846 struct gl_texture_object *texObj, 847 struct gl_memory_object *memObj, 848 GLenum target, GLsizei levels, 849 GLenum internalformat, GLsizei width, 850 GLsizei height, GLsizei depth, 851 GLuint64 offset, bool dsa) 852{ 853 assert(memObj); 854 855 texture_storage(ctx, dims, texObj, memObj, target, levels, internalformat, 856 width, height, depth, offset, dsa, false); 857} 858