1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27/** 28 * \file teximage.c 29 * Texture image-related functions. 30 */ 31 32#include <stdbool.h> 33#include "glheader.h" 34#include "bufferobj.h" 35#include "context.h" 36#include "enums.h" 37#include "fbobject.h" 38#include "framebuffer.h" 39#include "hash.h" 40#include "image.h" 41 42#include "macros.h" 43#include "mipmap.h" 44#include "multisample.h" 45#include "pixel.h" 46#include "pixelstore.h" 47#include "state.h" 48#include "texcompress.h" 49#include "texcompress_cpal.h" 50#include "teximage.h" 51#include "texobj.h" 52#include "texstate.h" 53#include "texstorage.h" 54#include "textureview.h" 55#include "mtypes.h" 56#include "glformats.h" 57#include "texstore.h" 58#include "pbo.h" 59#include "api_exec_decl.h" 60 61#include "util/u_memory.h" 62 63#include "state_tracker/st_cb_texture.h" 64#include "state_tracker/st_context.h" 65#include "state_tracker/st_format.h" 66#include "state_tracker/st_gen_mipmap.h" 67#include "state_tracker/st_cb_eglimage.h" 68#include "state_tracker/st_sampler_view.h" 69 70/** 71 * Returns a corresponding internal floating point format for a given base 72 * format as specifed by OES_texture_float. In case of GL_FLOAT, the internal 73 * format needs to be a 32 bit component and in case of GL_HALF_FLOAT_OES it 74 * needs to be a 16 bit component. 75 * 76 * For example, given base format GL_RGBA, type GL_FLOAT return GL_RGBA32F_ARB. 77 */ 78static GLenum 79adjust_for_oes_float_texture(const struct gl_context *ctx, 80 GLenum format, GLenum type) 81{ 82 switch (type) { 83 case GL_FLOAT: 84 if (ctx->Extensions.OES_texture_float) { 85 switch (format) { 86 case GL_RGBA: 87 return GL_RGBA32F; 88 case GL_RGB: 89 return GL_RGB32F; 90 case GL_ALPHA: 91 return GL_ALPHA32F_ARB; 92 case GL_LUMINANCE: 93 return GL_LUMINANCE32F_ARB; 94 case GL_LUMINANCE_ALPHA: 95 return GL_LUMINANCE_ALPHA32F_ARB; 96 default: 97 break; 98 } 99 } 100 break; 101 102 case GL_HALF_FLOAT_OES: 103 if (ctx->Extensions.OES_texture_half_float) { 104 switch (format) { 105 case GL_RGBA: 106 return GL_RGBA16F; 107 case GL_RGB: 108 return GL_RGB16F; 109 case GL_ALPHA: 110 return GL_ALPHA16F_ARB; 111 case GL_LUMINANCE: 112 return GL_LUMINANCE16F_ARB; 113 case GL_LUMINANCE_ALPHA: 114 return GL_LUMINANCE_ALPHA16F_ARB; 115 default: 116 break; 117 } 118 } 119 break; 120 121 default: 122 break; 123 } 124 125 return format; 126} 127 128/** 129 * Returns a corresponding base format for a given internal floating point 130 * format as specifed by OES_texture_float. 131 */ 132static GLenum 133oes_float_internal_format(const struct gl_context *ctx, 134 GLenum format, GLenum type) 135{ 136 switch (type) { 137 case GL_FLOAT: 138 if (ctx->Extensions.OES_texture_float) { 139 switch (format) { 140 case GL_RGBA32F: 141 return GL_RGBA; 142 case GL_RGB32F: 143 return GL_RGB; 144 case GL_ALPHA32F_ARB: 145 return GL_ALPHA; 146 case GL_LUMINANCE32F_ARB: 147 return GL_LUMINANCE; 148 case GL_LUMINANCE_ALPHA32F_ARB: 149 return GL_LUMINANCE_ALPHA; 150 default: 151 break; 152 } 153 } 154 break; 155 156 case GL_HALF_FLOAT_OES: 157 if (ctx->Extensions.OES_texture_half_float) { 158 switch (format) { 159 case GL_RGBA16F: 160 return GL_RGBA; 161 case GL_RGB16F: 162 return GL_RGB; 163 case GL_ALPHA16F_ARB: 164 return GL_ALPHA; 165 case GL_LUMINANCE16F_ARB: 166 return GL_LUMINANCE; 167 case GL_LUMINANCE_ALPHA16F_ARB: 168 return GL_LUMINANCE_ALPHA; 169 default: 170 break; 171 } 172 } 173 break; 174 } 175 return format; 176} 177 178 179/** 180 * Install gl_texture_image in a gl_texture_object according to the target 181 * and level parameters. 182 * 183 * \param tObj texture object. 184 * \param target texture target. 185 * \param level image level. 186 * \param texImage texture image. 187 */ 188static void 189set_tex_image(struct gl_texture_object *tObj, 190 GLenum target, GLint level, 191 struct gl_texture_image *texImage) 192{ 193 const GLuint face = _mesa_tex_target_to_face(target); 194 195 assert(tObj); 196 assert(texImage); 197 if (target == GL_TEXTURE_RECTANGLE_NV || target == GL_TEXTURE_EXTERNAL_OES) 198 assert(level == 0); 199 200 tObj->Image[face][level] = texImage; 201 202 /* Set the 'back' pointer */ 203 texImage->TexObject = tObj; 204 texImage->Level = level; 205 texImage->Face = face; 206} 207 208 209/** 210 * Free a gl_texture_image and associated data. 211 * This function is a fallback. 212 * 213 * \param texImage texture image. 214 * 215 * Free the texture image structure and the associated image data. 216 */ 217void 218_mesa_delete_texture_image(struct gl_context *ctx, 219 struct gl_texture_image *texImage) 220{ 221 /* Free texImage->Data and/or any other driver-specific texture 222 * image storage. 223 */ 224 st_FreeTextureImageBuffer( ctx, texImage ); 225 FREE(texImage); 226} 227 228 229/** 230 * Test if a target is a proxy target. 231 * 232 * \param target texture target. 233 * 234 * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise. 235 */ 236GLboolean 237_mesa_is_proxy_texture(GLenum target) 238{ 239 unsigned i; 240 static const GLenum targets[] = { 241 GL_PROXY_TEXTURE_1D, 242 GL_PROXY_TEXTURE_2D, 243 GL_PROXY_TEXTURE_3D, 244 GL_PROXY_TEXTURE_CUBE_MAP, 245 GL_PROXY_TEXTURE_RECTANGLE, 246 GL_PROXY_TEXTURE_1D_ARRAY, 247 GL_PROXY_TEXTURE_2D_ARRAY, 248 GL_PROXY_TEXTURE_CUBE_MAP_ARRAY, 249 GL_PROXY_TEXTURE_2D_MULTISAMPLE, 250 GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 251 }; 252 /* 253 * NUM_TEXTURE_TARGETS should match number of terms above, except there's no 254 * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES. 255 */ 256 STATIC_ASSERT(NUM_TEXTURE_TARGETS == ARRAY_SIZE(targets) + 2); 257 258 for (i = 0; i < ARRAY_SIZE(targets); ++i) 259 if (target == targets[i]) 260 return GL_TRUE; 261 return GL_FALSE; 262} 263 264 265/** 266 * Test if a target is an array target. 267 * 268 * \param target texture target. 269 * 270 * \return true if the target is an array target, false otherwise. 271 */ 272bool 273_mesa_is_array_texture(GLenum target) 274{ 275 switch (target) { 276 case GL_TEXTURE_1D_ARRAY: 277 case GL_TEXTURE_2D_ARRAY: 278 case GL_TEXTURE_CUBE_MAP_ARRAY: 279 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 280 return true; 281 default: 282 return false; 283 }; 284} 285 286/** 287 * Test if a target is a cube map. 288 * 289 * \param target texture target. 290 * 291 * \return true if the target is a cube map, false otherwise. 292 */ 293bool 294_mesa_is_cube_map_texture(GLenum target) 295{ 296 switch(target) { 297 case GL_TEXTURE_CUBE_MAP: 298 case GL_TEXTURE_CUBE_MAP_ARRAY: 299 return true; 300 default: 301 return false; 302 } 303} 304 305/** 306 * Return the proxy target which corresponds to the given texture target 307 */ 308static GLenum 309proxy_target(GLenum target) 310{ 311 switch (target) { 312 case GL_TEXTURE_1D: 313 case GL_PROXY_TEXTURE_1D: 314 return GL_PROXY_TEXTURE_1D; 315 case GL_TEXTURE_2D: 316 case GL_PROXY_TEXTURE_2D: 317 return GL_PROXY_TEXTURE_2D; 318 case GL_TEXTURE_3D: 319 case GL_PROXY_TEXTURE_3D: 320 return GL_PROXY_TEXTURE_3D; 321 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 322 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 323 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 324 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 325 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 326 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 327 case GL_TEXTURE_CUBE_MAP: 328 case GL_PROXY_TEXTURE_CUBE_MAP: 329 return GL_PROXY_TEXTURE_CUBE_MAP; 330 case GL_TEXTURE_RECTANGLE_NV: 331 case GL_PROXY_TEXTURE_RECTANGLE_NV: 332 return GL_PROXY_TEXTURE_RECTANGLE_NV; 333 case GL_TEXTURE_1D_ARRAY_EXT: 334 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 335 return GL_PROXY_TEXTURE_1D_ARRAY_EXT; 336 case GL_TEXTURE_2D_ARRAY_EXT: 337 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 338 return GL_PROXY_TEXTURE_2D_ARRAY_EXT; 339 case GL_TEXTURE_CUBE_MAP_ARRAY: 340 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 341 return GL_PROXY_TEXTURE_CUBE_MAP_ARRAY; 342 case GL_TEXTURE_2D_MULTISAMPLE: 343 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 344 return GL_PROXY_TEXTURE_2D_MULTISAMPLE; 345 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 346 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 347 return GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY; 348 default: 349 _mesa_problem(NULL, "unexpected target in proxy_target()"); 350 return 0; 351 } 352} 353 354 355 356 357/** 358 * Get a texture image pointer from a texture object, given a texture 359 * target and mipmap level. The target and level parameters should 360 * have already been error-checked. 361 * 362 * \param texObj texture unit. 363 * \param target texture target. 364 * \param level image level. 365 * 366 * \return pointer to the texture image structure, or NULL on failure. 367 */ 368struct gl_texture_image * 369_mesa_select_tex_image(const struct gl_texture_object *texObj, 370 GLenum target, GLint level) 371{ 372 const GLuint face = _mesa_tex_target_to_face(target); 373 374 assert(texObj); 375 assert(level >= 0); 376 assert(level < MAX_TEXTURE_LEVELS); 377 378 return texObj->Image[face][level]; 379} 380 381 382/** 383 * Like _mesa_select_tex_image() but if the image doesn't exist, allocate 384 * it and install it. Only return NULL if passed a bad parameter or run 385 * out of memory. 386 */ 387struct gl_texture_image * 388_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, 389 GLenum target, GLint level) 390{ 391 struct gl_texture_image *texImage; 392 393 if (!texObj) 394 return NULL; 395 396 texImage = _mesa_select_tex_image(texObj, target, level); 397 if (!texImage) { 398 texImage = CALLOC_STRUCT(gl_texture_image); 399 if (!texImage) { 400 _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation"); 401 return NULL; 402 } 403 404 set_tex_image(texObj, target, level, texImage); 405 } 406 407 return texImage; 408} 409 410 411/** 412 * Return pointer to the specified proxy texture image. 413 * Note that proxy textures are per-context, not per-texture unit. 414 * \return pointer to texture image or NULL if invalid target, invalid 415 * level, or out of memory. 416 */ 417static struct gl_texture_image * 418get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level) 419{ 420 struct gl_texture_image *texImage; 421 GLuint texIndex; 422 423 if (level < 0) 424 return NULL; 425 426 switch (target) { 427 case GL_PROXY_TEXTURE_1D: 428 texIndex = TEXTURE_1D_INDEX; 429 break; 430 case GL_PROXY_TEXTURE_2D: 431 texIndex = TEXTURE_2D_INDEX; 432 break; 433 case GL_PROXY_TEXTURE_3D: 434 texIndex = TEXTURE_3D_INDEX; 435 break; 436 case GL_PROXY_TEXTURE_CUBE_MAP: 437 texIndex = TEXTURE_CUBE_INDEX; 438 break; 439 case GL_PROXY_TEXTURE_RECTANGLE_NV: 440 if (level > 0) 441 return NULL; 442 texIndex = TEXTURE_RECT_INDEX; 443 break; 444 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 445 texIndex = TEXTURE_1D_ARRAY_INDEX; 446 break; 447 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 448 texIndex = TEXTURE_2D_ARRAY_INDEX; 449 break; 450 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 451 texIndex = TEXTURE_CUBE_ARRAY_INDEX; 452 break; 453 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 454 texIndex = TEXTURE_2D_MULTISAMPLE_INDEX; 455 break; 456 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 457 texIndex = TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX; 458 break; 459 default: 460 return NULL; 461 } 462 463 texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level]; 464 if (!texImage) { 465 texImage = CALLOC_STRUCT(gl_texture_image); 466 if (!texImage) { 467 _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); 468 return NULL; 469 } 470 ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage; 471 /* Set the 'back' pointer */ 472 texImage->TexObject = ctx->Texture.ProxyTex[texIndex]; 473 } 474 return texImage; 475} 476 477 478/** 479 * Get the maximum number of allowed mipmap levels. 480 * 481 * \param ctx GL context. 482 * \param target texture target. 483 * 484 * \return the maximum number of allowed mipmap levels for the given 485 * texture target, or zero if passed a bad target. 486 * 487 * \sa gl_constants. 488 */ 489GLint 490_mesa_max_texture_levels(const struct gl_context *ctx, GLenum target) 491{ 492 switch (target) { 493 case GL_TEXTURE_1D: 494 case GL_PROXY_TEXTURE_1D: 495 case GL_TEXTURE_2D: 496 case GL_PROXY_TEXTURE_2D: 497 return ffs(util_next_power_of_two(ctx->Const.MaxTextureSize)); 498 case GL_TEXTURE_3D: 499 case GL_PROXY_TEXTURE_3D: 500 return !(ctx->API == API_OPENGLES2 && !ctx->Extensions.OES_texture_3D) 501 ? ctx->Const.Max3DTextureLevels : 0; 502 case GL_TEXTURE_CUBE_MAP: 503 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 504 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 505 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 506 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 507 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 508 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 509 case GL_PROXY_TEXTURE_CUBE_MAP: 510 return ctx->Const.MaxCubeTextureLevels; 511 case GL_TEXTURE_RECTANGLE_NV: 512 case GL_PROXY_TEXTURE_RECTANGLE_NV: 513 return ctx->Extensions.NV_texture_rectangle ? 1 : 0; 514 case GL_TEXTURE_1D_ARRAY_EXT: 515 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 516 case GL_TEXTURE_2D_ARRAY_EXT: 517 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 518 return ctx->Extensions.EXT_texture_array 519 ? ffs(util_next_power_of_two(ctx->Const.MaxTextureSize)) : 0; 520 case GL_TEXTURE_CUBE_MAP_ARRAY: 521 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 522 return _mesa_has_texture_cube_map_array(ctx) 523 ? ctx->Const.MaxCubeTextureLevels : 0; 524 case GL_TEXTURE_BUFFER: 525 return (_mesa_has_ARB_texture_buffer_object(ctx) || 526 _mesa_has_OES_texture_buffer(ctx)) ? 1 : 0; 527 case GL_TEXTURE_2D_MULTISAMPLE: 528 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 529 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 530 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 531 return (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) 532 && ctx->Extensions.ARB_texture_multisample 533 ? 1 : 0; 534 case GL_TEXTURE_EXTERNAL_OES: 535 return _mesa_has_OES_EGL_image_external(ctx) ? 1 : 0; 536 default: 537 return 0; /* bad target */ 538 } 539} 540 541 542/** 543 * Return number of dimensions per mipmap level for the given texture target. 544 */ 545GLint 546_mesa_get_texture_dimensions(GLenum target) 547{ 548 switch (target) { 549 case GL_TEXTURE_1D: 550 case GL_PROXY_TEXTURE_1D: 551 return 1; 552 case GL_TEXTURE_2D: 553 case GL_TEXTURE_RECTANGLE: 554 case GL_TEXTURE_CUBE_MAP: 555 case GL_PROXY_TEXTURE_2D: 556 case GL_PROXY_TEXTURE_RECTANGLE: 557 case GL_PROXY_TEXTURE_CUBE_MAP: 558 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 559 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 560 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 561 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 562 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 563 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 564 case GL_TEXTURE_1D_ARRAY: 565 case GL_PROXY_TEXTURE_1D_ARRAY: 566 case GL_TEXTURE_EXTERNAL_OES: 567 case GL_TEXTURE_2D_MULTISAMPLE: 568 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 569 return 2; 570 case GL_TEXTURE_3D: 571 case GL_PROXY_TEXTURE_3D: 572 case GL_TEXTURE_2D_ARRAY: 573 case GL_PROXY_TEXTURE_2D_ARRAY: 574 case GL_TEXTURE_CUBE_MAP_ARRAY: 575 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 576 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 577 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 578 return 3; 579 case GL_TEXTURE_BUFFER: 580 FALLTHROUGH; 581 default: 582 _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()", 583 target); 584 return 2; 585 } 586} 587 588 589/** 590 * Check if a texture target can have more than one layer. 591 */ 592GLboolean 593_mesa_tex_target_is_layered(GLenum target) 594{ 595 switch (target) { 596 case GL_TEXTURE_1D: 597 case GL_PROXY_TEXTURE_1D: 598 case GL_TEXTURE_2D: 599 case GL_PROXY_TEXTURE_2D: 600 case GL_TEXTURE_RECTANGLE: 601 case GL_PROXY_TEXTURE_RECTANGLE: 602 case GL_TEXTURE_2D_MULTISAMPLE: 603 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 604 case GL_TEXTURE_BUFFER: 605 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 606 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 607 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 608 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 609 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 610 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 611 case GL_TEXTURE_EXTERNAL_OES: 612 return GL_FALSE; 613 614 case GL_TEXTURE_3D: 615 case GL_PROXY_TEXTURE_3D: 616 case GL_TEXTURE_CUBE_MAP: 617 case GL_PROXY_TEXTURE_CUBE_MAP: 618 case GL_TEXTURE_1D_ARRAY: 619 case GL_PROXY_TEXTURE_1D_ARRAY: 620 case GL_TEXTURE_2D_ARRAY: 621 case GL_PROXY_TEXTURE_2D_ARRAY: 622 case GL_TEXTURE_CUBE_MAP_ARRAY: 623 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 624 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 625 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 626 return GL_TRUE; 627 628 default: 629 assert(!"Invalid texture target."); 630 return GL_FALSE; 631 } 632} 633 634 635/** 636 * Return the number of layers present in the given level of an array, 637 * cubemap or 3D texture. If the texture is not layered return zero. 638 */ 639GLuint 640_mesa_get_texture_layers(const struct gl_texture_object *texObj, GLint level) 641{ 642 assert(level >= 0 && level < MAX_TEXTURE_LEVELS); 643 644 switch (texObj->Target) { 645 case GL_TEXTURE_1D: 646 case GL_TEXTURE_2D: 647 case GL_TEXTURE_RECTANGLE: 648 case GL_TEXTURE_2D_MULTISAMPLE: 649 case GL_TEXTURE_BUFFER: 650 case GL_TEXTURE_EXTERNAL_OES: 651 return 0; 652 653 case GL_TEXTURE_CUBE_MAP: 654 return 6; 655 656 case GL_TEXTURE_1D_ARRAY: { 657 struct gl_texture_image *img = texObj->Image[0][level]; 658 return img ? img->Height : 0; 659 } 660 661 case GL_TEXTURE_3D: 662 case GL_TEXTURE_2D_ARRAY: 663 case GL_TEXTURE_CUBE_MAP_ARRAY: 664 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: { 665 struct gl_texture_image *img = texObj->Image[0][level]; 666 return img ? img->Depth : 0; 667 } 668 669 default: 670 assert(!"Invalid texture target."); 671 return 0; 672 } 673} 674 675 676/** 677 * Return the maximum number of mipmap levels for the given target 678 * and the dimensions. 679 * The dimensions are expected not to include the border. 680 */ 681GLsizei 682_mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height, 683 GLsizei depth) 684{ 685 GLsizei size; 686 687 switch (target) { 688 case GL_TEXTURE_1D: 689 case GL_TEXTURE_1D_ARRAY: 690 case GL_PROXY_TEXTURE_1D: 691 case GL_PROXY_TEXTURE_1D_ARRAY: 692 size = width; 693 break; 694 case GL_TEXTURE_CUBE_MAP: 695 case GL_TEXTURE_CUBE_MAP_ARRAY: 696 case GL_PROXY_TEXTURE_CUBE_MAP: 697 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 698 size = width; 699 break; 700 case GL_TEXTURE_2D: 701 case GL_TEXTURE_2D_ARRAY: 702 case GL_PROXY_TEXTURE_2D: 703 case GL_PROXY_TEXTURE_2D_ARRAY: 704 size = MAX2(width, height); 705 break; 706 case GL_TEXTURE_3D: 707 case GL_PROXY_TEXTURE_3D: 708 size = MAX3(width, height, depth); 709 break; 710 case GL_TEXTURE_RECTANGLE: 711 case GL_TEXTURE_EXTERNAL_OES: 712 case GL_TEXTURE_2D_MULTISAMPLE: 713 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 714 case GL_PROXY_TEXTURE_RECTANGLE: 715 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 716 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 717 return 1; 718 default: 719 assert(0); 720 return 1; 721 } 722 723 return util_logbase2(size) + 1; 724} 725 726 727#if 000 /* not used anymore */ 728/* 729 * glTexImage[123]D can accept a NULL image pointer. In this case we 730 * create a texture image with unspecified image contents per the OpenGL 731 * spec. 732 */ 733static GLubyte * 734make_null_texture(GLint width, GLint height, GLint depth, GLenum format) 735{ 736 const GLint components = _mesa_components_in_format(format); 737 const GLint numPixels = width * height * depth; 738 GLubyte *data = (GLubyte *) malloc(numPixels * components * sizeof(GLubyte)); 739 740#ifdef DEBUG 741 /* 742 * Let's see if anyone finds this. If glTexImage2D() is called with 743 * a NULL image pointer then load the texture image with something 744 * interesting instead of leaving it indeterminate. 745 */ 746 if (data) { 747 static const char message[8][32] = { 748 " X X XXXXX XXX X ", 749 " XX XX X X X X X ", 750 " X X X X X X X ", 751 " X X XXXX XXX XXXXX ", 752 " X X X X X X ", 753 " X X X X X X X ", 754 " X X XXXXX XXX X X ", 755 " " 756 }; 757 758 GLubyte *imgPtr = data; 759 GLint h, i, j, k; 760 for (h = 0; h < depth; h++) { 761 for (i = 0; i < height; i++) { 762 GLint srcRow = 7 - (i % 8); 763 for (j = 0; j < width; j++) { 764 GLint srcCol = j % 32; 765 GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70; 766 for (k = 0; k < components; k++) { 767 *imgPtr++ = texel; 768 } 769 } 770 } 771 } 772 } 773#endif 774 775 return data; 776} 777#endif 778 779 780 781/** 782 * Set the size and format-related fields of a gl_texture_image struct 783 * to zero. This is used when a proxy texture test fails. 784 */ 785static void 786clear_teximage_fields(struct gl_texture_image *img) 787{ 788 assert(img); 789 img->_BaseFormat = 0; 790 img->InternalFormat = 0; 791 img->Border = 0; 792 img->Width = 0; 793 img->Height = 0; 794 img->Depth = 0; 795 img->Width2 = 0; 796 img->Height2 = 0; 797 img->Depth2 = 0; 798 img->WidthLog2 = 0; 799 img->HeightLog2 = 0; 800 img->DepthLog2 = 0; 801 img->TexFormat = MESA_FORMAT_NONE; 802 img->NumSamples = 0; 803 img->FixedSampleLocations = GL_TRUE; 804} 805 806 807/** 808 * Initialize basic fields of the gl_texture_image struct. 809 * 810 * \param ctx GL context. 811 * \param img texture image structure to be initialized. 812 * \param width image width. 813 * \param height image height. 814 * \param depth image depth. 815 * \param border image border. 816 * \param internalFormat internal format. 817 * \param format the actual hardware format (one of MESA_FORMAT_*) 818 * \param numSamples number of samples per texel, or zero for non-MS. 819 * \param fixedSampleLocations are sample locations fixed? 820 * 821 * Fills in the fields of \p img with the given information. 822 * Note: width, height and depth include the border. 823 */ 824void 825_mesa_init_teximage_fields_ms(struct gl_context *ctx, 826 struct gl_texture_image *img, 827 GLsizei width, GLsizei height, GLsizei depth, 828 GLint border, GLenum internalFormat, 829 mesa_format format, 830 GLuint numSamples, GLboolean fixedSampleLocations) 831{ 832 const GLint base_format =_mesa_base_tex_format(ctx, internalFormat); 833 GLenum target; 834 assert(img); 835 assert(width >= 0); 836 assert(height >= 0); 837 assert(depth >= 0); 838 839 target = img->TexObject->Target; 840 assert(base_format != -1); 841 img->_BaseFormat = (GLenum16)base_format; 842 img->InternalFormat = internalFormat; 843 img->Border = border; 844 img->Width = width; 845 img->Height = height; 846 img->Depth = depth; 847 848 img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */ 849 img->WidthLog2 = util_logbase2(img->Width2); 850 851 switch(target) { 852 case GL_TEXTURE_1D: 853 case GL_TEXTURE_BUFFER: 854 case GL_PROXY_TEXTURE_1D: 855 if (height == 0) 856 img->Height2 = 0; 857 else 858 img->Height2 = 1; 859 img->HeightLog2 = 0; 860 if (depth == 0) 861 img->Depth2 = 0; 862 else 863 img->Depth2 = 1; 864 img->DepthLog2 = 0; 865 break; 866 case GL_TEXTURE_1D_ARRAY: 867 case GL_PROXY_TEXTURE_1D_ARRAY: 868 img->Height2 = height; /* no border */ 869 img->HeightLog2 = 0; /* not used */ 870 if (depth == 0) 871 img->Depth2 = 0; 872 else 873 img->Depth2 = 1; 874 img->DepthLog2 = 0; 875 break; 876 case GL_TEXTURE_2D: 877 case GL_TEXTURE_RECTANGLE: 878 case GL_TEXTURE_CUBE_MAP: 879 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 880 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 881 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 882 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 883 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 884 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 885 case GL_TEXTURE_EXTERNAL_OES: 886 case GL_PROXY_TEXTURE_2D: 887 case GL_PROXY_TEXTURE_RECTANGLE: 888 case GL_PROXY_TEXTURE_CUBE_MAP: 889 case GL_TEXTURE_2D_MULTISAMPLE: 890 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 891 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 892 img->HeightLog2 = util_logbase2(img->Height2); 893 if (depth == 0) 894 img->Depth2 = 0; 895 else 896 img->Depth2 = 1; 897 img->DepthLog2 = 0; 898 break; 899 case GL_TEXTURE_2D_ARRAY: 900 case GL_PROXY_TEXTURE_2D_ARRAY: 901 case GL_TEXTURE_CUBE_MAP_ARRAY: 902 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 903 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 904 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 905 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 906 img->HeightLog2 = util_logbase2(img->Height2); 907 img->Depth2 = depth; /* no border */ 908 img->DepthLog2 = 0; /* not used */ 909 break; 910 case GL_TEXTURE_3D: 911 case GL_PROXY_TEXTURE_3D: 912 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 913 img->HeightLog2 = util_logbase2(img->Height2); 914 img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ 915 img->DepthLog2 = util_logbase2(img->Depth2); 916 break; 917 default: 918 _mesa_problem(NULL, "invalid target 0x%x in _mesa_init_teximage_fields()", 919 target); 920 } 921 922 img->MaxNumLevels = 923 _mesa_get_tex_max_num_levels(target, 924 img->Width2, img->Height2, img->Depth2); 925 img->TexFormat = format; 926 img->NumSamples = numSamples; 927 img->FixedSampleLocations = fixedSampleLocations; 928} 929 930 931void 932_mesa_init_teximage_fields(struct gl_context *ctx, 933 struct gl_texture_image *img, 934 GLsizei width, GLsizei height, GLsizei depth, 935 GLint border, GLenum internalFormat, 936 mesa_format format) 937{ 938 _mesa_init_teximage_fields_ms(ctx, img, width, height, depth, border, 939 internalFormat, format, 0, GL_TRUE); 940} 941 942 943/** 944 * Free and clear fields of the gl_texture_image struct. 945 * 946 * \param ctx GL context. 947 * \param texImage texture image structure to be cleared. 948 * 949 * After the call, \p texImage will have no data associated with it. Its 950 * fields are cleared so that its parent object will test incomplete. 951 */ 952void 953_mesa_clear_texture_image(struct gl_context *ctx, 954 struct gl_texture_image *texImage) 955{ 956 st_FreeTextureImageBuffer(ctx, texImage); 957 clear_teximage_fields(texImage); 958} 959 960 961/** 962 * Check the width, height, depth and border of a texture image are legal. 963 * Used by all the glTexImage, glCompressedTexImage and glCopyTexImage 964 * functions. 965 * The target and level parameters will have already been validated. 966 * \return GL_TRUE if size is OK, GL_FALSE otherwise. 967 */ 968GLboolean 969_mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, 970 GLint level, GLint width, GLint height, 971 GLint depth, GLint border) 972{ 973 GLint maxSize; 974 975 switch (target) { 976 case GL_TEXTURE_1D: 977 case GL_PROXY_TEXTURE_1D: 978 maxSize = ctx->Const.MaxTextureSize >> level; 979 if (width < 2 * border || width > 2 * border + maxSize) 980 return GL_FALSE; 981 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 982 if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 983 return GL_FALSE; 984 } 985 return GL_TRUE; 986 987 case GL_TEXTURE_2D: 988 case GL_PROXY_TEXTURE_2D: 989 case GL_TEXTURE_2D_MULTISAMPLE: 990 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 991 maxSize = ctx->Const.MaxTextureSize >> level; 992 if (width < 2 * border || width > 2 * border + maxSize) 993 return GL_FALSE; 994 if (height < 2 * border || height > 2 * border + maxSize) 995 return GL_FALSE; 996 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 997 if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 998 return GL_FALSE; 999 if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border)) 1000 return GL_FALSE; 1001 } 1002 return GL_TRUE; 1003 1004 case GL_TEXTURE_3D: 1005 case GL_PROXY_TEXTURE_3D: 1006 maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); 1007 maxSize >>= level; 1008 if (width < 2 * border || width > 2 * border + maxSize) 1009 return GL_FALSE; 1010 if (height < 2 * border || height > 2 * border + maxSize) 1011 return GL_FALSE; 1012 if (depth < 2 * border || depth > 2 * border + maxSize) 1013 return GL_FALSE; 1014 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1015 if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 1016 return GL_FALSE; 1017 if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border)) 1018 return GL_FALSE; 1019 if (depth > 0 && !util_is_power_of_two_nonzero(depth - 2 * border)) 1020 return GL_FALSE; 1021 } 1022 return GL_TRUE; 1023 1024 case GL_TEXTURE_RECTANGLE_NV: 1025 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1026 if (level != 0) 1027 return GL_FALSE; 1028 maxSize = ctx->Const.MaxTextureRectSize; 1029 if (width < 0 || width > maxSize) 1030 return GL_FALSE; 1031 if (height < 0 || height > maxSize) 1032 return GL_FALSE; 1033 return GL_TRUE; 1034 1035 case GL_TEXTURE_CUBE_MAP: 1036 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1037 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1038 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1039 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1040 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1041 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1042 case GL_PROXY_TEXTURE_CUBE_MAP: 1043 maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); 1044 maxSize >>= level; 1045 if (width != height) 1046 return GL_FALSE; 1047 if (width < 2 * border || width > 2 * border + maxSize) 1048 return GL_FALSE; 1049 if (height < 2 * border || height > 2 * border + maxSize) 1050 return GL_FALSE; 1051 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1052 if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 1053 return GL_FALSE; 1054 if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border)) 1055 return GL_FALSE; 1056 } 1057 return GL_TRUE; 1058 1059 case GL_TEXTURE_1D_ARRAY_EXT: 1060 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1061 maxSize = ctx->Const.MaxTextureSize >> level; 1062 if (width < 2 * border || width > 2 * border + maxSize) 1063 return GL_FALSE; 1064 if (height < 0 || height > ctx->Const.MaxArrayTextureLayers) 1065 return GL_FALSE; 1066 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1067 if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 1068 return GL_FALSE; 1069 } 1070 return GL_TRUE; 1071 1072 case GL_TEXTURE_2D_ARRAY_EXT: 1073 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1074 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1075 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 1076 maxSize = ctx->Const.MaxTextureSize >> level; 1077 if (width < 2 * border || width > 2 * border + maxSize) 1078 return GL_FALSE; 1079 if (height < 2 * border || height > 2 * border + maxSize) 1080 return GL_FALSE; 1081 if (depth < 0 || depth > ctx->Const.MaxArrayTextureLayers) 1082 return GL_FALSE; 1083 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1084 if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 1085 return GL_FALSE; 1086 if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border)) 1087 return GL_FALSE; 1088 } 1089 return GL_TRUE; 1090 1091 case GL_TEXTURE_CUBE_MAP_ARRAY: 1092 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1093 maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); 1094 if (width < 2 * border || width > 2 * border + maxSize) 1095 return GL_FALSE; 1096 if (height < 2 * border || height > 2 * border + maxSize) 1097 return GL_FALSE; 1098 if (depth < 0 || depth > ctx->Const.MaxArrayTextureLayers || depth % 6) 1099 return GL_FALSE; 1100 if (width != height) 1101 return GL_FALSE; 1102 if (level >= ctx->Const.MaxCubeTextureLevels) 1103 return GL_FALSE; 1104 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1105 if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border)) 1106 return GL_FALSE; 1107 if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border)) 1108 return GL_FALSE; 1109 } 1110 return GL_TRUE; 1111 default: 1112 _mesa_problem(ctx, "Invalid target in _mesa_legal_texture_dimensions()"); 1113 return GL_FALSE; 1114 } 1115} 1116 1117static bool 1118error_check_subtexture_negative_dimensions(struct gl_context *ctx, 1119 GLuint dims, 1120 GLsizei subWidth, 1121 GLsizei subHeight, 1122 GLsizei subDepth, 1123 const char *func) 1124{ 1125 /* Check size */ 1126 if (subWidth < 0) { 1127 _mesa_error(ctx, GL_INVALID_VALUE, "%s(width=%d)", func, subWidth); 1128 return true; 1129 } 1130 1131 if (dims > 1 && subHeight < 0) { 1132 _mesa_error(ctx, GL_INVALID_VALUE, "%s(height=%d)", func, subHeight); 1133 return true; 1134 } 1135 1136 if (dims > 2 && subDepth < 0) { 1137 _mesa_error(ctx, GL_INVALID_VALUE, "%s(depth=%d)", func, subDepth); 1138 return true; 1139 } 1140 1141 return false; 1142} 1143 1144/** 1145 * Do error checking of xoffset, yoffset, zoffset, width, height and depth 1146 * for glTexSubImage, glCopyTexSubImage and glCompressedTexSubImage. 1147 * \param destImage the destination texture image. 1148 * \return GL_TRUE if error found, GL_FALSE otherwise. 1149 */ 1150static GLboolean 1151error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims, 1152 const struct gl_texture_image *destImage, 1153 GLint xoffset, GLint yoffset, GLint zoffset, 1154 GLsizei subWidth, GLsizei subHeight, 1155 GLsizei subDepth, const char *func) 1156{ 1157 const GLenum target = destImage->TexObject->Target; 1158 GLuint bw, bh, bd; 1159 1160 /* check xoffset and width */ 1161 if (xoffset < - (GLint) destImage->Border) { 1162 _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset)", func); 1163 return GL_TRUE; 1164 } 1165 1166 if (xoffset + subWidth > (GLint) destImage->Width) { 1167 _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset %d + width %d > %u)", func, 1168 xoffset, subWidth, destImage->Width); 1169 return GL_TRUE; 1170 } 1171 1172 /* check yoffset and height */ 1173 if (dims > 1) { 1174 GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destImage->Border; 1175 if (yoffset < -yBorder) { 1176 _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset)", func); 1177 return GL_TRUE; 1178 } 1179 if (yoffset + subHeight > (GLint) destImage->Height) { 1180 _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset %d + height %d > %u)", 1181 func, yoffset, subHeight, destImage->Height); 1182 return GL_TRUE; 1183 } 1184 } 1185 1186 /* check zoffset and depth */ 1187 if (dims > 2) { 1188 GLint depth; 1189 GLint zBorder = (target == GL_TEXTURE_2D_ARRAY || 1190 target == GL_TEXTURE_CUBE_MAP_ARRAY) ? 1191 0 : destImage->Border; 1192 1193 if (zoffset < -zBorder) { 1194 _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset)", func); 1195 return GL_TRUE; 1196 } 1197 1198 depth = (GLint) destImage->Depth; 1199 if (target == GL_TEXTURE_CUBE_MAP) 1200 depth = 6; 1201 if (zoffset + subDepth > depth) { 1202 _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset %d + depth %d > %u)", 1203 func, zoffset, subDepth, depth); 1204 return GL_TRUE; 1205 } 1206 } 1207 1208 /* 1209 * The OpenGL spec (and GL_ARB_texture_compression) says only whole 1210 * compressed texture images can be updated. But, that restriction may be 1211 * relaxed for particular compressed formats. At this time, all the 1212 * compressed formats supported by Mesa allow sub-textures to be updated 1213 * along compressed block boundaries. 1214 */ 1215 _mesa_get_format_block_size_3d(destImage->TexFormat, &bw, &bh, &bd); 1216 1217 if (bw != 1 || bh != 1 || bd != 1) { 1218 /* offset must be multiple of block size */ 1219 if ((xoffset % bw != 0) || (yoffset % bh != 0) || (zoffset % bd != 0)) { 1220 _mesa_error(ctx, GL_INVALID_OPERATION, 1221 "%s(xoffset = %d, yoffset = %d, zoffset = %d)", 1222 func, xoffset, yoffset, zoffset); 1223 return GL_TRUE; 1224 } 1225 1226 /* The size must be a multiple of bw x bh, or we must be using a 1227 * offset+size that exactly hits the edge of the image. This 1228 * is important for small mipmap levels (1x1, 2x1, etc) and for 1229 * NPOT textures. 1230 */ 1231 if ((subWidth % bw != 0) && 1232 (xoffset + subWidth != (GLint) destImage->Width)) { 1233 _mesa_error(ctx, GL_INVALID_OPERATION, 1234 "%s(width = %d)", func, subWidth); 1235 return GL_TRUE; 1236 } 1237 1238 if ((subHeight % bh != 0) && 1239 (yoffset + subHeight != (GLint) destImage->Height)) { 1240 _mesa_error(ctx, GL_INVALID_OPERATION, 1241 "%s(height = %d)", func, subHeight); 1242 return GL_TRUE; 1243 } 1244 1245 if ((subDepth % bd != 0) && 1246 (zoffset + subDepth != (GLint) destImage->Depth)) { 1247 _mesa_error(ctx, GL_INVALID_OPERATION, 1248 "%s(depth = %d)", func, subDepth); 1249 return GL_TRUE; 1250 } 1251 } 1252 1253 return GL_FALSE; 1254} 1255 1256 1257 1258 1259/** 1260 * This is the fallback for Driver.TestProxyTexImage() for doing device- 1261 * specific texture image size checks. 1262 * 1263 * A hardware driver might override this function if, for example, the 1264 * max 3D texture size is 512x512x64 (i.e. not a cube). 1265 * 1266 * Note that width, height, depth == 0 is not an error. However, a 1267 * texture with zero width/height/depth will be considered "incomplete" 1268 * and texturing will effectively be disabled. 1269 * 1270 * \param target any texture target/type 1271 * \param numLevels number of mipmap levels in the texture or 0 if not known 1272 * \param level as passed to glTexImage 1273 * \param format the MESA_FORMAT_x for the tex image 1274 * \param numSamples number of samples per texel 1275 * \param width as passed to glTexImage 1276 * \param height as passed to glTexImage 1277 * \param depth as passed to glTexImage 1278 * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable. 1279 */ 1280GLboolean 1281_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, 1282 GLuint numLevels, ASSERTED GLint level, 1283 mesa_format format, GLuint numSamples, 1284 GLint width, GLint height, GLint depth) 1285{ 1286 uint64_t bytes, mbytes; 1287 1288 if (numLevels > 0) { 1289 /* Compute total memory for a whole mipmap. This is the path 1290 * taken for glTexStorage(GL_PROXY_TEXTURE_x). 1291 */ 1292 unsigned l; 1293 1294 assert(level == 0); 1295 1296 bytes = 0; 1297 1298 for (l = 0; l < numLevels; l++) { 1299 GLint nextWidth, nextHeight, nextDepth; 1300 1301 bytes += _mesa_format_image_size64(format, width, height, depth); 1302 1303 if (_mesa_next_mipmap_level_size(target, 0, width, height, depth, 1304 &nextWidth, &nextHeight, 1305 &nextDepth)) { 1306 width = nextWidth; 1307 height = nextHeight; 1308 depth = nextDepth; 1309 } else { 1310 break; 1311 } 1312 } 1313 } else { 1314 /* We just compute the size of one mipmap level. This is the path 1315 * taken for glTexImage(GL_PROXY_TEXTURE_x). 1316 */ 1317 bytes = _mesa_format_image_size64(format, width, height, depth); 1318 } 1319 1320 bytes *= _mesa_num_tex_faces(target); 1321 bytes *= MAX2(1, numSamples); 1322 1323 mbytes = bytes / (1024 * 1024); /* convert to MB */ 1324 1325 /* We just check if the image size is less than MaxTextureMbytes. 1326 * Some drivers may do more specific checks. 1327 */ 1328 return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes; 1329} 1330 1331 1332/** 1333 * Return true if the format is only valid for glCompressedTexImage. 1334 */ 1335static bool 1336compressedteximage_only_format(GLenum format) 1337{ 1338 switch (format) { 1339 case GL_PALETTE4_RGB8_OES: 1340 case GL_PALETTE4_RGBA8_OES: 1341 case GL_PALETTE4_R5_G6_B5_OES: 1342 case GL_PALETTE4_RGBA4_OES: 1343 case GL_PALETTE4_RGB5_A1_OES: 1344 case GL_PALETTE8_RGB8_OES: 1345 case GL_PALETTE8_RGBA8_OES: 1346 case GL_PALETTE8_R5_G6_B5_OES: 1347 case GL_PALETTE8_RGBA4_OES: 1348 case GL_PALETTE8_RGB5_A1_OES: 1349 case GL_ATC_RGB_AMD: 1350 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD: 1351 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: 1352 return true; 1353 default: 1354 return false; 1355 } 1356} 1357 1358/** 1359 * Return true if the format doesn't support online compression. 1360 */ 1361bool 1362_mesa_format_no_online_compression(GLenum format) 1363{ 1364 return _mesa_is_astc_format(format) || 1365 _mesa_is_etc2_format(format) || 1366 compressedteximage_only_format(format); 1367} 1368 1369/* Writes to an GL error pointer if non-null and returns whether or not the 1370 * error is GL_NO_ERROR */ 1371static bool 1372write_error(GLenum *err_ptr, GLenum error) 1373{ 1374 if (err_ptr) 1375 *err_ptr = error; 1376 1377 return error == GL_NO_ERROR; 1378} 1379 1380/** 1381 * Helper function to determine whether a target and specific compression 1382 * format are supported. The error parameter returns GL_NO_ERROR if the 1383 * target can be compressed. Otherwise it returns either GL_INVALID_OPERATION 1384 * or GL_INVALID_ENUM, whichever is more appropriate. 1385 */ 1386GLboolean 1387_mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target, 1388 GLenum intFormat, GLenum *error) 1389{ 1390 GLboolean target_can_be_compresed = GL_FALSE; 1391 mesa_format format = _mesa_glenum_to_compressed_format(intFormat); 1392 enum mesa_format_layout layout = _mesa_get_format_layout(format); 1393 1394 switch (target) { 1395 case GL_TEXTURE_2D: 1396 case GL_PROXY_TEXTURE_2D: 1397 target_can_be_compresed = GL_TRUE; /* true for any compressed format so far */ 1398 break; 1399 case GL_PROXY_TEXTURE_CUBE_MAP: 1400 case GL_TEXTURE_CUBE_MAP: 1401 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1402 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1403 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1404 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1405 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1406 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1407 target_can_be_compresed = GL_TRUE; 1408 break; 1409 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1410 case GL_TEXTURE_2D_ARRAY_EXT: 1411 target_can_be_compresed = ctx->Extensions.EXT_texture_array; 1412 break; 1413 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1414 case GL_TEXTURE_CUBE_MAP_ARRAY: 1415 /* From the KHR_texture_compression_astc_hdr spec: 1416 * 1417 * Add a second new column "3D Tex." which is empty for all non-ASTC 1418 * formats. If only the LDR profile is supported by the 1419 * implementation, this column is also empty for all ASTC formats. If 1420 * both the LDR and HDR profiles are supported only, this column is 1421 * checked for all ASTC formats. 1422 * 1423 * Add a third new column "Cube Map Array Tex." which is empty for all 1424 * non-ASTC formats, and checked for all ASTC formats. 1425 * 1426 * and, 1427 * 1428 * 'An INVALID_OPERATION error is generated by CompressedTexImage3D 1429 * if <internalformat> is TEXTURE_CUBE_MAP_ARRAY and the 1430 * "Cube Map Array" column of table 8.19 is *not* checked, or if 1431 * <internalformat> is TEXTURE_3D and the "3D Tex." column of table 1432 * 8.19 is *not* checked' 1433 * 1434 * The instances of <internalformat> above should say <target>. 1435 * 1436 * ETC2/EAC formats are the only alternative in GLES and thus such errors 1437 * have already been handled by normal ETC2/EAC behavior. 1438 */ 1439 1440 /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec: 1441 * 1442 * "The ETC2/EAC texture compression algorithm supports only 1443 * two-dimensional images. If internalformat is an ETC2/EAC format, 1444 * glCompressedTexImage3D will generate an INVALID_OPERATION error if 1445 * target is not TEXTURE_2D_ARRAY." 1446 * 1447 * This should also be applicable for glTexStorage3D(). Other available 1448 * targets for these functions are: TEXTURE_3D and TEXTURE_CUBE_MAP_ARRAY. 1449 * 1450 * Section 8.7, page 179 of OpenGL ES 3.2 adds: 1451 * 1452 * An INVALID_OPERATION error is generated by CompressedTexImage3D 1453 * if internalformat is one of the the formats in table 8.17 and target is 1454 * not TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY or TEXTURE_3D. 1455 * 1456 * An INVALID_OPERATION error is generated by CompressedTexImage3D 1457 * if internalformat is TEXTURE_CUBE_MAP_ARRAY and the “Cube Map 1458 * Array” column of table 8.17 is not checked, or if internalformat 1459 * is TEXTURE_- 3D and the “3D Tex.” column of table 8.17 is not 1460 * checked. 1461 * 1462 * The instances of <internalformat> above should say <target>. 1463 * 1464 * Such table 8.17 has checked "Cube Map Array" column for all the 1465 * cases. So in practice, TEXTURE_CUBE_MAP_ARRAY is now valid for OpenGL ES 3.2 1466 */ 1467 if (layout == MESA_FORMAT_LAYOUT_ETC2 && _mesa_is_gles3(ctx) && 1468 !_mesa_is_gles32(ctx)) 1469 return write_error(error, GL_INVALID_OPERATION); 1470 target_can_be_compresed = _mesa_has_texture_cube_map_array(ctx); 1471 break; 1472 case GL_TEXTURE_3D: 1473 switch (layout) { 1474 case MESA_FORMAT_LAYOUT_ETC2: 1475 /* See ETC2/EAC comment in case GL_TEXTURE_CUBE_MAP_ARRAY. */ 1476 if (_mesa_is_gles3(ctx)) 1477 return write_error(error, GL_INVALID_OPERATION); 1478 break; 1479 case MESA_FORMAT_LAYOUT_BPTC: 1480 target_can_be_compresed = ctx->Extensions.ARB_texture_compression_bptc; 1481 break; 1482 case MESA_FORMAT_LAYOUT_ASTC: 1483 target_can_be_compresed = 1484 ctx->Extensions.KHR_texture_compression_astc_hdr || 1485 ctx->Extensions.KHR_texture_compression_astc_sliced_3d; 1486 1487 /* Throw an INVALID_OPERATION error if the target is TEXTURE_3D and 1488 * neither of the above extensions are supported. See comment in 1489 * switch case GL_TEXTURE_CUBE_MAP_ARRAY for more info. 1490 */ 1491 if (!target_can_be_compresed) 1492 return write_error(error, GL_INVALID_OPERATION); 1493 break; 1494 default: 1495 break; 1496 } 1497 FALLTHROUGH; 1498 default: 1499 break; 1500 } 1501 return write_error(error, 1502 target_can_be_compresed ? GL_NO_ERROR : GL_INVALID_ENUM); 1503} 1504 1505 1506/** 1507 * Check if the given texture target value is legal for a 1508 * glTexImage1/2/3D call. 1509 */ 1510static GLboolean 1511legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target) 1512{ 1513 switch (dims) { 1514 case 1: 1515 switch (target) { 1516 case GL_TEXTURE_1D: 1517 case GL_PROXY_TEXTURE_1D: 1518 return _mesa_is_desktop_gl(ctx); 1519 default: 1520 return GL_FALSE; 1521 } 1522 case 2: 1523 switch (target) { 1524 case GL_TEXTURE_2D: 1525 return GL_TRUE; 1526 case GL_PROXY_TEXTURE_2D: 1527 return _mesa_is_desktop_gl(ctx); 1528 case GL_PROXY_TEXTURE_CUBE_MAP: 1529 return _mesa_is_desktop_gl(ctx); 1530 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1531 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1532 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1533 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1534 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1535 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1536 return GL_TRUE; 1537 case GL_TEXTURE_RECTANGLE_NV: 1538 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1539 return _mesa_is_desktop_gl(ctx) 1540 && ctx->Extensions.NV_texture_rectangle; 1541 case GL_TEXTURE_1D_ARRAY_EXT: 1542 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1543 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array; 1544 default: 1545 return GL_FALSE; 1546 } 1547 case 3: 1548 switch (target) { 1549 case GL_TEXTURE_3D: 1550 return GL_TRUE; 1551 case GL_PROXY_TEXTURE_3D: 1552 return _mesa_is_desktop_gl(ctx); 1553 case GL_TEXTURE_2D_ARRAY_EXT: 1554 return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) 1555 || _mesa_is_gles3(ctx); 1556 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1557 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array; 1558 case GL_TEXTURE_CUBE_MAP_ARRAY: 1559 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1560 return _mesa_has_texture_cube_map_array(ctx); 1561 default: 1562 return GL_FALSE; 1563 } 1564 default: 1565 _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims); 1566 return GL_FALSE; 1567 } 1568} 1569 1570 1571/** 1572 * Check if the given texture target value is legal for a 1573 * glTexSubImage, glCopyTexSubImage or glCopyTexImage call. 1574 * The difference compared to legal_teximage_target() above is that 1575 * proxy targets are not supported. 1576 */ 1577static GLboolean 1578legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target, 1579 bool dsa) 1580{ 1581 switch (dims) { 1582 case 1: 1583 return _mesa_is_desktop_gl(ctx) && target == GL_TEXTURE_1D; 1584 case 2: 1585 switch (target) { 1586 case GL_TEXTURE_2D: 1587 return GL_TRUE; 1588 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1589 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1590 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1591 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1592 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1593 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1594 return GL_TRUE; 1595 case GL_TEXTURE_RECTANGLE_NV: 1596 return _mesa_is_desktop_gl(ctx) 1597 && ctx->Extensions.NV_texture_rectangle; 1598 case GL_TEXTURE_1D_ARRAY_EXT: 1599 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array; 1600 default: 1601 return GL_FALSE; 1602 } 1603 case 3: 1604 switch (target) { 1605 case GL_TEXTURE_3D: 1606 return GL_TRUE; 1607 case GL_TEXTURE_2D_ARRAY_EXT: 1608 return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) 1609 || _mesa_is_gles3(ctx); 1610 case GL_TEXTURE_CUBE_MAP_ARRAY: 1611 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1612 return _mesa_has_texture_cube_map_array(ctx); 1613 1614 /* Table 8.15 of the OpenGL 4.5 core profile spec 1615 * (20141030) says that TEXTURE_CUBE_MAP is valid for TextureSubImage3D 1616 * and CopyTextureSubImage3D. 1617 */ 1618 case GL_TEXTURE_CUBE_MAP: 1619 return dsa; 1620 default: 1621 return GL_FALSE; 1622 } 1623 default: 1624 _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()", 1625 dims); 1626 return GL_FALSE; 1627 } 1628} 1629 1630 1631/** 1632 * Helper function to determine if a texture object is mutable (in terms 1633 * of GL_ARB_texture_storage/GL_ARB_bindless_texture). 1634 */ 1635static GLboolean 1636mutable_tex_object(struct gl_texture_object *texObj) 1637{ 1638 if (!texObj) 1639 return GL_FALSE; 1640 1641 if (texObj->HandleAllocated) { 1642 /* The ARB_bindless_texture spec says: 1643 * 1644 * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*, 1645 * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other 1646 * functions defined in terms of these, if the texture object to be 1647 * modified is referenced by one or more texture or image handles." 1648 */ 1649 return GL_FALSE; 1650 } 1651 1652 return !texObj->Immutable; 1653} 1654 1655 1656/** 1657 * Return expected size of a compressed texture. 1658 */ 1659static GLuint 1660compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth, 1661 GLenum glformat) 1662{ 1663 mesa_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 1664 return _mesa_format_image_size(mesaFormat, width, height, depth); 1665} 1666 1667/** 1668 * Verify that a texture format is valid with a particular target 1669 * 1670 * In particular, textures with base format of \c GL_DEPTH_COMPONENT or 1671 * \c GL_DEPTH_STENCIL are only valid with certain, context dependent texture 1672 * targets. 1673 * 1674 * \param ctx GL context 1675 * \param target Texture target 1676 * \param internalFormat Internal format of the texture image 1677 * 1678 * \returns true if the combination is legal, false otherwise. 1679 */ 1680bool 1681_mesa_legal_texture_base_format_for_target(struct gl_context *ctx, 1682 GLenum target, GLenum internalFormat) 1683{ 1684 if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT 1685 || _mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_STENCIL 1686 || _mesa_base_tex_format(ctx, internalFormat) == GL_STENCIL_INDEX) { 1687 /* Section 3.8.3 (Texture Image Specification) of the OpenGL 3.3 Core 1688 * Profile spec says: 1689 * 1690 * "Textures with a base internal format of DEPTH_COMPONENT or 1691 * DEPTH_STENCIL are supported by texture image specification 1692 * commands only if target is TEXTURE_1D, TEXTURE_2D, 1693 * TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_RECTANGLE, 1694 * TEXTURE_CUBE_MAP, PROXY_TEXTURE_1D, PROXY_TEXTURE_2D, 1695 * PROXY_TEXTURE_1D_ARRAY, PROXY_TEXTURE_2D_ARRAY, 1696 * PROXY_TEXTURE_RECTANGLE, or PROXY_TEXTURE_CUBE_MAP. Using these 1697 * formats in conjunction with any other target will result in an 1698 * INVALID_OPERATION error." 1699 * 1700 * Cubemaps are only supported with desktop OpenGL version >= 3.0, 1701 * EXT_gpu_shader4, or, on OpenGL ES 2.0+, OES_depth_texture_cube_map. 1702 */ 1703 if (target != GL_TEXTURE_1D && 1704 target != GL_PROXY_TEXTURE_1D && 1705 target != GL_TEXTURE_2D && 1706 target != GL_PROXY_TEXTURE_2D && 1707 target != GL_TEXTURE_1D_ARRAY && 1708 target != GL_PROXY_TEXTURE_1D_ARRAY && 1709 target != GL_TEXTURE_2D_ARRAY && 1710 target != GL_PROXY_TEXTURE_2D_ARRAY && 1711 target != GL_TEXTURE_RECTANGLE_ARB && 1712 target != GL_PROXY_TEXTURE_RECTANGLE_ARB && 1713 !((_mesa_is_cube_face(target) || 1714 target == GL_TEXTURE_CUBE_MAP || 1715 target == GL_PROXY_TEXTURE_CUBE_MAP) && 1716 (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4 1717 || (ctx->API == API_OPENGLES2 && ctx->Extensions.OES_depth_texture_cube_map))) && 1718 !((target == GL_TEXTURE_CUBE_MAP_ARRAY || 1719 target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY) && 1720 _mesa_has_texture_cube_map_array(ctx))) { 1721 return false; 1722 } 1723 } 1724 1725 return true; 1726} 1727 1728static bool 1729texture_formats_agree(GLenum internalFormat, 1730 GLenum format) 1731{ 1732 GLboolean colorFormat; 1733 GLboolean is_format_depth_or_depthstencil; 1734 GLboolean is_internalFormat_depth_or_depthstencil; 1735 1736 /* Even though there are no color-index textures, we still have to support 1737 * uploading color-index data and remapping it to RGB via the 1738 * GL_PIXEL_MAP_I_TO_[RGBA] tables. 1739 */ 1740 const GLboolean indexFormat = (format == GL_COLOR_INDEX); 1741 1742 is_internalFormat_depth_or_depthstencil = 1743 _mesa_is_depth_format(internalFormat) || 1744 _mesa_is_depthstencil_format(internalFormat); 1745 1746 is_format_depth_or_depthstencil = 1747 _mesa_is_depth_format(format) || 1748 _mesa_is_depthstencil_format(format); 1749 1750 colorFormat = _mesa_is_color_format(format); 1751 1752 if (_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) 1753 return false; 1754 1755 if (is_internalFormat_depth_or_depthstencil != 1756 is_format_depth_or_depthstencil) 1757 return false; 1758 1759 if (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) 1760 return false; 1761 1762 return true; 1763} 1764 1765/** 1766 * Test the combination of format, type and internal format arguments of 1767 * different texture operations on GLES. 1768 * 1769 * \param ctx GL context. 1770 * \param format pixel data format given by the user. 1771 * \param type pixel data type given by the user. 1772 * \param internalFormat internal format given by the user. 1773 * \param callerName name of the caller function to print in the error message 1774 * 1775 * \return true if a error is found, false otherwise 1776 * 1777 * Currently, it is used by texture_error_check() and texsubimage_error_check(). 1778 */ 1779static bool 1780texture_format_error_check_gles(struct gl_context *ctx, GLenum format, 1781 GLenum type, GLenum internalFormat, const char *callerName) 1782{ 1783 GLenum err = _mesa_gles_error_check_format_and_type(ctx, format, type, 1784 internalFormat); 1785 if (err != GL_NO_ERROR) { 1786 _mesa_error(ctx, err, 1787 "%s(format = %s, type = %s, internalformat = %s)", 1788 callerName, _mesa_enum_to_string(format), 1789 _mesa_enum_to_string(type), 1790 _mesa_enum_to_string(internalFormat)); 1791 return true; 1792 } 1793 1794 return false; 1795} 1796 1797/** 1798 * Test the glTexImage[123]D() parameters for errors. 1799 * 1800 * \param ctx GL context. 1801 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1802 * \param target texture target given by the user (already validated). 1803 * \param level image level given by the user. 1804 * \param internalFormat internal format given by the user. 1805 * \param format pixel data format given by the user. 1806 * \param type pixel data type given by the user. 1807 * \param width image width given by the user. 1808 * \param height image height given by the user. 1809 * \param depth image depth given by the user. 1810 * \param border image border given by the user. 1811 * 1812 * \return GL_TRUE if a error is found, GL_FALSE otherwise 1813 * 1814 * Verifies each of the parameters against the constants specified in 1815 * __struct gl_contextRec::Const and the supported extensions, and according 1816 * to the OpenGL specification. 1817 * Note that we don't fully error-check the width, height, depth values 1818 * here. That's done in _mesa_legal_texture_dimensions() which is used 1819 * by several other GL entrypoints. Plus, texture dims have a special 1820 * interaction with proxy textures. 1821 */ 1822static GLboolean 1823texture_error_check( struct gl_context *ctx, 1824 GLuint dimensions, GLenum target, 1825 struct gl_texture_object* texObj, 1826 GLint level, GLint internalFormat, 1827 GLenum format, GLenum type, 1828 GLint width, GLint height, 1829 GLint depth, GLint border, 1830 const GLvoid *pixels ) 1831{ 1832 GLenum err; 1833 1834 /* Note: for proxy textures, some error conditions immediately generate 1835 * a GL error in the usual way. But others do not generate a GL error. 1836 * Instead, they cause the width, height, depth, format fields of the 1837 * texture image to be zeroed-out. The GL spec seems to indicate that the 1838 * zero-out behaviour is only used in cases related to memory allocation. 1839 */ 1840 1841 /* level check */ 1842 if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 1843 _mesa_error(ctx, GL_INVALID_VALUE, 1844 "glTexImage%dD(level=%d)", dimensions, level); 1845 return GL_TRUE; 1846 } 1847 1848 /* Check border */ 1849 if (border < 0 || border > 1 || 1850 ((ctx->API != API_OPENGL_COMPAT || 1851 target == GL_TEXTURE_RECTANGLE_NV || 1852 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 1853 _mesa_error(ctx, GL_INVALID_VALUE, 1854 "glTexImage%dD(border=%d)", dimensions, border); 1855 return GL_TRUE; 1856 } 1857 1858 if (width < 0 || height < 0 || depth < 0) { 1859 _mesa_error(ctx, GL_INVALID_VALUE, 1860 "glTexImage%dD(width, height or depth < 0)", dimensions); 1861 return GL_TRUE; 1862 } 1863 1864 /* Check incoming image format and type */ 1865 err = _mesa_error_check_format_and_type(ctx, format, type); 1866 if (err != GL_NO_ERROR) { 1867 /* Prior to OpenGL-ES 2.0, an INVALID_VALUE is expected instead of 1868 * INVALID_ENUM. From page 73 OpenGL ES 1.1 spec: 1869 * 1870 * "Specifying a value for internalformat that is not one of the 1871 * above (acceptable) values generates the error INVALID VALUE." 1872 */ 1873 if (err == GL_INVALID_ENUM && _mesa_is_gles(ctx) && ctx->Version < 20) 1874 err = GL_INVALID_VALUE; 1875 1876 _mesa_error(ctx, err, 1877 "glTexImage%dD(incompatible format = %s, type = %s)", 1878 dimensions, _mesa_enum_to_string(format), 1879 _mesa_enum_to_string(type)); 1880 return GL_TRUE; 1881 } 1882 1883 /* Check internalFormat */ 1884 if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 1885 _mesa_error(ctx, GL_INVALID_VALUE, 1886 "glTexImage%dD(internalFormat=%s)", 1887 dimensions, _mesa_enum_to_string(internalFormat)); 1888 return GL_TRUE; 1889 } 1890 1891 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 1892 * combinations of format, internalFormat, and type that can be used. 1893 * Formats and types that require additional extensions (e.g., GL_FLOAT 1894 * requires GL_OES_texture_float) are filtered elsewhere. 1895 */ 1896 char bufCallerName[20]; 1897 snprintf(bufCallerName, 20, "glTexImage%dD", dimensions); 1898 if (_mesa_is_gles(ctx) && 1899 texture_format_error_check_gles(ctx, format, type, 1900 internalFormat, bufCallerName)) { 1901 return GL_TRUE; 1902 } 1903 1904 /* validate the bound PBO, if any */ 1905 if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack, 1906 width, height, depth, format, type, 1907 INT_MAX, pixels, "glTexImage")) { 1908 return GL_TRUE; 1909 } 1910 1911 /* make sure internal format and format basically agree */ 1912 if (!texture_formats_agree(internalFormat, format)) { 1913 _mesa_error(ctx, GL_INVALID_OPERATION, 1914 "glTexImage%dD(incompatible internalFormat = %s, format = %s)", 1915 dimensions, _mesa_enum_to_string(internalFormat), 1916 _mesa_enum_to_string(format)); 1917 return GL_TRUE; 1918 } 1919 1920 /* additional checks for ycbcr textures */ 1921 if (internalFormat == GL_YCBCR_MESA) { 1922 assert(ctx->Extensions.MESA_ycbcr_texture); 1923 if (type != GL_UNSIGNED_SHORT_8_8_MESA && 1924 type != GL_UNSIGNED_SHORT_8_8_REV_MESA) { 1925 char message[100]; 1926 snprintf(message, sizeof(message), 1927 "glTexImage%dD(format/type YCBCR mismatch)", 1928 dimensions); 1929 _mesa_error(ctx, GL_INVALID_ENUM, "%s", message); 1930 return GL_TRUE; /* error */ 1931 } 1932 if (target != GL_TEXTURE_2D && 1933 target != GL_PROXY_TEXTURE_2D && 1934 target != GL_TEXTURE_RECTANGLE_NV && 1935 target != GL_PROXY_TEXTURE_RECTANGLE_NV) { 1936 _mesa_error(ctx, GL_INVALID_ENUM, 1937 "glTexImage%dD(bad target for YCbCr texture)", 1938 dimensions); 1939 return GL_TRUE; 1940 } 1941 if (border != 0) { 1942 char message[100]; 1943 snprintf(message, sizeof(message), 1944 "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)", 1945 dimensions, border); 1946 _mesa_error(ctx, GL_INVALID_VALUE, "%s", message); 1947 return GL_TRUE; 1948 } 1949 } 1950 1951 /* additional checks for depth textures */ 1952 if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalFormat)) { 1953 _mesa_error(ctx, GL_INVALID_OPERATION, 1954 "glTexImage%dD(bad target for texture)", dimensions); 1955 return GL_TRUE; 1956 } 1957 1958 /* additional checks for compressed textures */ 1959 if (_mesa_is_compressed_format(ctx, internalFormat)) { 1960 GLenum err; 1961 if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) { 1962 _mesa_error(ctx, err, 1963 "glTexImage%dD(target can't be compressed)", dimensions); 1964 return GL_TRUE; 1965 } 1966 if (_mesa_format_no_online_compression(internalFormat)) { 1967 _mesa_error(ctx, GL_INVALID_OPERATION, 1968 "glTexImage%dD(no compression for format)", dimensions); 1969 return GL_TRUE; 1970 } 1971 if (border != 0) { 1972 _mesa_error(ctx, GL_INVALID_OPERATION, 1973 "glTexImage%dD(border!=0)", dimensions); 1974 return GL_TRUE; 1975 } 1976 } 1977 1978 /* additional checks for integer textures */ 1979 if ((ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) && 1980 (_mesa_is_enum_format_integer(format) != 1981 _mesa_is_enum_format_integer(internalFormat))) { 1982 _mesa_error(ctx, GL_INVALID_OPERATION, 1983 "glTexImage%dD(integer/non-integer format mismatch)", 1984 dimensions); 1985 return GL_TRUE; 1986 } 1987 1988 if (!mutable_tex_object(texObj)) { 1989 _mesa_error(ctx, GL_INVALID_OPERATION, 1990 "glTexImage%dD(immutable texture)", dimensions); 1991 return GL_TRUE; 1992 } 1993 1994 /* if we get here, the parameters are OK */ 1995 return GL_FALSE; 1996} 1997 1998 1999/** 2000 * Error checking for glCompressedTexImage[123]D(). 2001 * Note that the width, height and depth values are not fully error checked 2002 * here. 2003 * \return GL_TRUE if a error is found, GL_FALSE otherwise 2004 */ 2005static GLenum 2006compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, 2007 GLenum target, struct gl_texture_object* texObj, 2008 GLint level, GLenum internalFormat, GLsizei width, 2009 GLsizei height, GLsizei depth, GLint border, 2010 GLsizei imageSize, const GLvoid *data) 2011{ 2012 const GLint maxLevels = _mesa_max_texture_levels(ctx, target); 2013 GLint expectedSize; 2014 GLenum error = GL_NO_ERROR; 2015 char *reason = ""; /* no error */ 2016 2017 if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &error)) { 2018 reason = "target"; 2019 goto error; 2020 } 2021 2022 /* This will detect any invalid internalFormat value */ 2023 if (!_mesa_is_compressed_format(ctx, internalFormat)) { 2024 _mesa_error(ctx, GL_INVALID_ENUM, 2025 "glCompressedTexImage%dD(internalFormat=%s)", 2026 dimensions, _mesa_enum_to_string(internalFormat)); 2027 return GL_TRUE; 2028 } 2029 2030 /* validate the bound PBO, if any */ 2031 if (!_mesa_validate_pbo_source_compressed(ctx, dimensions, &ctx->Unpack, 2032 imageSize, data, 2033 "glCompressedTexImage")) { 2034 return GL_TRUE; 2035 } 2036 2037 switch (internalFormat) { 2038 case GL_PALETTE4_RGB8_OES: 2039 case GL_PALETTE4_RGBA8_OES: 2040 case GL_PALETTE4_R5_G6_B5_OES: 2041 case GL_PALETTE4_RGBA4_OES: 2042 case GL_PALETTE4_RGB5_A1_OES: 2043 case GL_PALETTE8_RGB8_OES: 2044 case GL_PALETTE8_RGBA8_OES: 2045 case GL_PALETTE8_R5_G6_B5_OES: 2046 case GL_PALETTE8_RGBA4_OES: 2047 case GL_PALETTE8_RGB5_A1_OES: 2048 /* check level (note that level should be zero or less!) */ 2049 if (level > 0 || level < -maxLevels) { 2050 reason = "level"; 2051 error = GL_INVALID_VALUE; 2052 goto error; 2053 } 2054 2055 if (dimensions != 2) { 2056 reason = "compressed paletted textures must be 2D"; 2057 error = GL_INVALID_OPERATION; 2058 goto error; 2059 } 2060 2061 /* Figure out the expected texture size (in bytes). This will be 2062 * checked against the actual size later. 2063 */ 2064 expectedSize = _mesa_cpal_compressed_size(level, internalFormat, 2065 width, height); 2066 2067 /* This is for the benefit of the TestProxyTexImage below. It expects 2068 * level to be non-negative. OES_compressed_paletted_texture uses a 2069 * weird mechanism where the level specified to glCompressedTexImage2D 2070 * is -(n-1) number of levels in the texture, and the data specifies the 2071 * complete mipmap stack. This is done to ensure the palette is the 2072 * same for all levels. 2073 */ 2074 level = -level; 2075 break; 2076 2077 default: 2078 /* check level */ 2079 if (level < 0 || level >= maxLevels) { 2080 reason = "level"; 2081 error = GL_INVALID_VALUE; 2082 goto error; 2083 } 2084 2085 /* Figure out the expected texture size (in bytes). This will be 2086 * checked against the actual size later. 2087 */ 2088 expectedSize = compressed_tex_size(width, height, depth, internalFormat); 2089 break; 2090 } 2091 2092 /* This should really never fail */ 2093 if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 2094 reason = "internalFormat"; 2095 error = GL_INVALID_ENUM; 2096 goto error; 2097 } 2098 2099 /* No compressed formats support borders at this time */ 2100 if (border != 0) { 2101 reason = "border != 0"; 2102 error = _mesa_is_desktop_gl(ctx) ? GL_INVALID_OPERATION : GL_INVALID_VALUE; 2103 goto error; 2104 } 2105 2106 /* Check for invalid pixel storage modes */ 2107 if (!_mesa_compressed_pixel_storage_error_check(ctx, dimensions, 2108 &ctx->Unpack, 2109 "glCompressedTexImage")) { 2110 return GL_FALSE; 2111 } 2112 2113 /* check image size in bytes */ 2114 if (expectedSize != imageSize) { 2115 /* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...] 2116 * if <imageSize> is not consistent with the format, dimensions, and 2117 * contents of the specified image. 2118 */ 2119 reason = "imageSize inconsistent with width/height/format"; 2120 error = GL_INVALID_VALUE; 2121 goto error; 2122 } 2123 2124 if (!mutable_tex_object(texObj)) { 2125 reason = "immutable texture"; 2126 error = GL_INVALID_OPERATION; 2127 goto error; 2128 } 2129 2130 return GL_FALSE; 2131 2132error: 2133 /* Note: not all error paths exit through here. */ 2134 _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", 2135 dimensions, reason); 2136 return GL_TRUE; 2137} 2138 2139 2140 2141/** 2142 * Test glTexSubImage[123]D() parameters for errors. 2143 * 2144 * \param ctx GL context. 2145 * \param dimensions texture image dimensions (must be 1, 2 or 3). 2146 * \param target texture target given by the user (already validated) 2147 * \param level image level given by the user. 2148 * \param xoffset sub-image x offset given by the user. 2149 * \param yoffset sub-image y offset given by the user. 2150 * \param zoffset sub-image z offset given by the user. 2151 * \param format pixel data format given by the user. 2152 * \param type pixel data type given by the user. 2153 * \param width image width given by the user. 2154 * \param height image height given by the user. 2155 * \param depth image depth given by the user. 2156 * 2157 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2158 * 2159 * Verifies each of the parameters against the constants specified in 2160 * __struct gl_contextRec::Const and the supported extensions, and according 2161 * to the OpenGL specification. 2162 */ 2163static GLboolean 2164texsubimage_error_check(struct gl_context *ctx, GLuint dimensions, 2165 struct gl_texture_object *texObj, 2166 GLenum target, GLint level, 2167 GLint xoffset, GLint yoffset, GLint zoffset, 2168 GLint width, GLint height, GLint depth, 2169 GLenum format, GLenum type, const GLvoid *pixels, 2170 const char *callerName) 2171{ 2172 struct gl_texture_image *texImage; 2173 GLenum err; 2174 2175 if (!texObj) { 2176 /* must be out of memory */ 2177 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", callerName); 2178 return GL_TRUE; 2179 } 2180 2181 /* level check */ 2182 if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 2183 _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", callerName, level); 2184 return GL_TRUE; 2185 } 2186 2187 if (error_check_subtexture_negative_dimensions(ctx, dimensions, 2188 width, height, depth, 2189 callerName)) { 2190 return GL_TRUE; 2191 } 2192 2193 texImage = _mesa_select_tex_image(texObj, target, level); 2194 if (!texImage) { 2195 /* non-existant texture level */ 2196 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture level %d)", 2197 callerName, level); 2198 return GL_TRUE; 2199 } 2200 2201 err = _mesa_error_check_format_and_type(ctx, format, type); 2202 if (err != GL_NO_ERROR) { 2203 _mesa_error(ctx, err, 2204 "%s(incompatible format = %s, type = %s)", 2205 callerName, _mesa_enum_to_string(format), 2206 _mesa_enum_to_string(type)); 2207 return GL_TRUE; 2208 } 2209 2210 if (!texture_formats_agree(texImage->InternalFormat, format)) { 2211 _mesa_error(ctx, GL_INVALID_OPERATION, 2212 "%s(incompatible internalFormat = %s, format = %s)", 2213 callerName, 2214 _mesa_enum_to_string(texImage->InternalFormat), 2215 _mesa_enum_to_string(format)); 2216 return GL_TRUE; 2217 } 2218 2219 GLenum internalFormat = _mesa_is_gles(ctx) ? 2220 oes_float_internal_format(ctx, texImage->InternalFormat, type) : 2221 texImage->InternalFormat; 2222 2223 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 2224 * combinations of format, internalFormat, and type that can be used. 2225 * Formats and types that require additional extensions (e.g., GL_FLOAT 2226 * requires GL_OES_texture_float) are filtered elsewhere. 2227 */ 2228 if (_mesa_is_gles(ctx) && 2229 texture_format_error_check_gles(ctx, format, type, 2230 internalFormat, callerName)) { 2231 return GL_TRUE; 2232 } 2233 2234 /* validate the bound PBO, if any */ 2235 if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack, 2236 width, height, depth, format, type, 2237 INT_MAX, pixels, callerName)) { 2238 return GL_TRUE; 2239 } 2240 2241 if (error_check_subtexture_dimensions(ctx, dimensions, 2242 texImage, xoffset, yoffset, zoffset, 2243 width, height, depth, callerName)) { 2244 return GL_TRUE; 2245 } 2246 2247 if (_mesa_is_format_compressed(texImage->TexFormat)) { 2248 if (_mesa_format_no_online_compression(texImage->InternalFormat)) { 2249 _mesa_error(ctx, GL_INVALID_OPERATION, 2250 "%s(no compression for format)", callerName); 2251 return GL_TRUE; 2252 } 2253 } 2254 2255 if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) { 2256 /* both source and dest must be integer-valued, or neither */ 2257 if (_mesa_is_format_integer_color(texImage->TexFormat) != 2258 _mesa_is_enum_format_integer(format)) { 2259 _mesa_error(ctx, GL_INVALID_OPERATION, 2260 "%s(integer/non-integer format mismatch)", callerName); 2261 return GL_TRUE; 2262 } 2263 } 2264 2265 return GL_FALSE; 2266} 2267 2268 2269/** 2270 * Test glCopyTexImage[12]D() parameters for errors. 2271 * 2272 * \param ctx GL context. 2273 * \param dimensions texture image dimensions (must be 1, 2 or 3). 2274 * \param target texture target given by the user. 2275 * \param level image level given by the user. 2276 * \param internalFormat internal format given by the user. 2277 * \param width image width given by the user. 2278 * \param height image height given by the user. 2279 * \param border texture border. 2280 * 2281 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2282 * 2283 * Verifies each of the parameters against the constants specified in 2284 * __struct gl_contextRec::Const and the supported extensions, and according 2285 * to the OpenGL specification. 2286 */ 2287static GLboolean 2288copytexture_error_check( struct gl_context *ctx, GLuint dimensions, 2289 GLenum target, struct gl_texture_object* texObj, 2290 GLint level, GLint internalFormat, GLint border ) 2291{ 2292 GLint baseFormat; 2293 GLint rb_base_format; 2294 struct gl_renderbuffer *rb; 2295 GLenum rb_internal_format; 2296 2297 /* level check */ 2298 if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 2299 _mesa_error(ctx, GL_INVALID_VALUE, 2300 "glCopyTexImage%dD(level=%d)", dimensions, level); 2301 return GL_TRUE; 2302 } 2303 2304 /* Check that the source buffer is complete */ 2305 if (_mesa_is_user_fbo(ctx->ReadBuffer)) { 2306 if (ctx->ReadBuffer->_Status == 0) { 2307 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 2308 } 2309 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2310 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 2311 "glCopyTexImage%dD(invalid readbuffer)", dimensions); 2312 return GL_TRUE; 2313 } 2314 2315 if (ctx->ReadBuffer->Visual.samples > 0) { 2316 _mesa_error(ctx, GL_INVALID_OPERATION, 2317 "glCopyTexImage%dD(multisample FBO)", dimensions); 2318 return GL_TRUE; 2319 } 2320 } 2321 2322 /* Check border */ 2323 if (border < 0 || border > 1 || 2324 ((ctx->API != API_OPENGL_COMPAT || 2325 target == GL_TEXTURE_RECTANGLE_NV || 2326 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 2327 _mesa_error(ctx, GL_INVALID_VALUE, 2328 "glCopyTexImage%dD(border=%d)", dimensions, border); 2329 return GL_TRUE; 2330 } 2331 2332 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 2333 * internalFormat. 2334 */ 2335 if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) { 2336 switch (internalFormat) { 2337 case GL_ALPHA: 2338 case GL_RGB: 2339 case GL_RGBA: 2340 case GL_LUMINANCE: 2341 case GL_LUMINANCE_ALPHA: 2342 2343 /* Added by GL_OES_required_internalformat (always enabled) in table 3.4.y.*/ 2344 case GL_ALPHA8: 2345 case GL_LUMINANCE8: 2346 case GL_LUMINANCE8_ALPHA8: 2347 case GL_LUMINANCE4_ALPHA4: 2348 case GL_RGB565: 2349 case GL_RGB8: 2350 case GL_RGBA4: 2351 case GL_RGB5_A1: 2352 case GL_RGBA8: 2353 case GL_DEPTH_COMPONENT16: 2354 case GL_DEPTH_COMPONENT24: 2355 case GL_DEPTH_COMPONENT32: 2356 case GL_DEPTH24_STENCIL8: 2357 case GL_RGB10: 2358 case GL_RGB10_A2: 2359 break; 2360 2361 default: 2362 _mesa_error(ctx, GL_INVALID_ENUM, 2363 "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2364 _mesa_enum_to_string(internalFormat)); 2365 return GL_TRUE; 2366 } 2367 } else { 2368 /* 2369 * Section 8.6 (Alternate Texture Image Specification Commands) of the 2370 * OpenGL 4.5 (Compatibility Profile) spec says: 2371 * 2372 * "Parameters level, internalformat, and border are specified using 2373 * the same values, with the same meanings, as the corresponding 2374 * arguments of TexImage2D, except that internalformat may not be 2375 * specified as 1, 2, 3, or 4." 2376 */ 2377 if (internalFormat >= 1 && internalFormat <= 4) { 2378 _mesa_error(ctx, GL_INVALID_ENUM, 2379 "glCopyTexImage%dD(internalFormat=%d)", dimensions, 2380 internalFormat); 2381 return GL_TRUE; 2382 } 2383 } 2384 2385 baseFormat = _mesa_base_tex_format(ctx, internalFormat); 2386 if (baseFormat < 0) { 2387 _mesa_error(ctx, GL_INVALID_ENUM, 2388 "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2389 _mesa_enum_to_string(internalFormat)); 2390 return GL_TRUE; 2391 } 2392 2393 rb = _mesa_get_read_renderbuffer_for_format(ctx, internalFormat); 2394 if (rb == NULL) { 2395 _mesa_error(ctx, GL_INVALID_OPERATION, 2396 "glCopyTexImage%dD(read buffer)", dimensions); 2397 return GL_TRUE; 2398 } 2399 2400 rb_internal_format = rb->InternalFormat; 2401 rb_base_format = _mesa_base_tex_format(ctx, rb->InternalFormat); 2402 if (_mesa_is_color_format(internalFormat)) { 2403 if (rb_base_format < 0) { 2404 _mesa_error(ctx, GL_INVALID_VALUE, 2405 "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2406 _mesa_enum_to_string(internalFormat)); 2407 return GL_TRUE; 2408 } 2409 } 2410 2411 if (_mesa_is_gles(ctx)) { 2412 bool valid = true; 2413 if (_mesa_components_in_format(baseFormat) > 2414 _mesa_components_in_format(rb_base_format)) { 2415 valid = false; 2416 } 2417 if (baseFormat == GL_DEPTH_COMPONENT || 2418 baseFormat == GL_DEPTH_STENCIL || 2419 baseFormat == GL_STENCIL_INDEX || 2420 rb_base_format == GL_DEPTH_COMPONENT || 2421 rb_base_format == GL_DEPTH_STENCIL || 2422 rb_base_format == GL_STENCIL_INDEX || 2423 ((baseFormat == GL_LUMINANCE_ALPHA || 2424 baseFormat == GL_ALPHA) && 2425 rb_base_format != GL_RGBA) || 2426 internalFormat == GL_RGB9_E5) { 2427 valid = false; 2428 } 2429 if (internalFormat == GL_RGB9_E5) { 2430 valid = false; 2431 } 2432 if (!valid) { 2433 _mesa_error(ctx, GL_INVALID_OPERATION, 2434 "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2435 _mesa_enum_to_string(internalFormat)); 2436 return GL_TRUE; 2437 } 2438 } 2439 2440 if (_mesa_is_gles3(ctx)) { 2441 bool rb_is_srgb = (ctx->Extensions.EXT_sRGB && 2442 _mesa_is_format_srgb(rb->Format)); 2443 bool dst_is_srgb = false; 2444 2445 if (_mesa_get_linear_internalformat(internalFormat) != internalFormat) { 2446 dst_is_srgb = true; 2447 } 2448 2449 if (rb_is_srgb != dst_is_srgb) { 2450 /* Page 137 (page 149 of the PDF) in section 3.8.5 of the 2451 * OpenGLES 3.0.0 spec says: 2452 * 2453 * "The error INVALID_OPERATION is also generated if the 2454 * value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the 2455 * framebuffer attachment corresponding to the read buffer 2456 * is LINEAR (see section 6.1.13) and internalformat is 2457 * one of the sRGB formats described in section 3.8.16, or 2458 * if the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is 2459 * SRGB and internalformat is not one of the sRGB formats." 2460 */ 2461 _mesa_error(ctx, GL_INVALID_OPERATION, 2462 "glCopyTexImage%dD(srgb usage mismatch)", dimensions); 2463 return GL_TRUE; 2464 } 2465 2466 /* Page 139, Table 3.15 of OpenGL ES 3.0 spec does not define ReadPixels 2467 * types for SNORM formats. Also, conversion to SNORM formats is not 2468 * allowed by Table 3.2 on Page 110. 2469 */ 2470 if (!_mesa_has_EXT_render_snorm(ctx) && 2471 _mesa_is_enum_format_snorm(internalFormat)) { 2472 _mesa_error(ctx, GL_INVALID_OPERATION, 2473 "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2474 _mesa_enum_to_string(internalFormat)); 2475 return GL_TRUE; 2476 } 2477 } 2478 2479 if (!_mesa_source_buffer_exists(ctx, baseFormat)) { 2480 _mesa_error(ctx, GL_INVALID_OPERATION, 2481 "glCopyTexImage%dD(missing readbuffer)", dimensions); 2482 return GL_TRUE; 2483 } 2484 2485 /* From the EXT_texture_integer spec: 2486 * 2487 * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage* 2488 * if the texture internalformat is an integer format and the read color 2489 * buffer is not an integer format, or if the internalformat is not an 2490 * integer format and the read color buffer is an integer format." 2491 */ 2492 if (_mesa_is_color_format(internalFormat)) { 2493 bool is_int = _mesa_is_enum_format_integer(internalFormat); 2494 bool is_rbint = _mesa_is_enum_format_integer(rb_internal_format); 2495 bool is_unorm = _mesa_is_enum_format_unorm(internalFormat); 2496 bool is_rbunorm = _mesa_is_enum_format_unorm(rb_internal_format); 2497 if (is_int || is_rbint) { 2498 if (is_int != is_rbint) { 2499 _mesa_error(ctx, GL_INVALID_OPERATION, 2500 "glCopyTexImage%dD(integer vs non-integer)", dimensions); 2501 return GL_TRUE; 2502 } else if (_mesa_is_gles(ctx) && 2503 _mesa_is_enum_format_unsigned_int(internalFormat) != 2504 _mesa_is_enum_format_unsigned_int(rb_internal_format)) { 2505 _mesa_error(ctx, GL_INVALID_OPERATION, 2506 "glCopyTexImage%dD(signed vs unsigned integer)", 2507 dimensions); 2508 return GL_TRUE; 2509 } 2510 } 2511 2512 /* From page 138 of OpenGL ES 3.0 spec: 2513 * "The error INVALID_OPERATION is generated if floating-point RGBA 2514 * data is required; if signed integer RGBA data is required and the 2515 * format of the current color buffer is not signed integer; if 2516 * unsigned integer RGBA data is required and the format of the 2517 * current color buffer is not unsigned integer; or if fixed-point 2518 * RGBA data is required and the format of the current color buffer 2519 * is not fixed-point. 2520 */ 2521 if (_mesa_is_gles(ctx) && is_unorm != is_rbunorm) 2522 _mesa_error(ctx, GL_INVALID_OPERATION, 2523 "glCopyTexImage%dD(unorm vs non-unorm)", dimensions); 2524 } 2525 2526 if (_mesa_is_compressed_format(ctx, internalFormat)) { 2527 GLenum err; 2528 if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) { 2529 _mesa_error(ctx, err, 2530 "glCopyTexImage%dD(target can't be compressed)", dimensions); 2531 return GL_TRUE; 2532 } 2533 if (_mesa_format_no_online_compression(internalFormat)) { 2534 _mesa_error(ctx, GL_INVALID_OPERATION, 2535 "glCopyTexImage%dD(no compression for format)", dimensions); 2536 return GL_TRUE; 2537 } 2538 if (border != 0) { 2539 _mesa_error(ctx, GL_INVALID_OPERATION, 2540 "glCopyTexImage%dD(border!=0)", dimensions); 2541 return GL_TRUE; 2542 } 2543 } 2544 2545 if (!mutable_tex_object(texObj)) { 2546 _mesa_error(ctx, GL_INVALID_OPERATION, 2547 "glCopyTexImage%dD(immutable texture)", dimensions); 2548 return GL_TRUE; 2549 } 2550 2551 /* if we get here, the parameters are OK */ 2552 return GL_FALSE; 2553} 2554 2555 2556/** 2557 * Test glCopyTexSubImage[12]D() parameters for errors. 2558 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2559 */ 2560static GLboolean 2561copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions, 2562 const struct gl_texture_object *texObj, 2563 GLenum target, GLint level, 2564 GLint xoffset, GLint yoffset, GLint zoffset, 2565 GLint width, GLint height, const char *caller) 2566{ 2567 assert(texObj); 2568 2569 struct gl_texture_image *texImage; 2570 2571 /* Check that the source buffer is complete */ 2572 if (_mesa_is_user_fbo(ctx->ReadBuffer)) { 2573 if (ctx->ReadBuffer->_Status == 0) { 2574 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 2575 } 2576 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2577 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 2578 "%s(invalid readbuffer)", caller); 2579 return GL_TRUE; 2580 } 2581 2582 if (ctx->ReadBuffer->Visual.samples > 0) { 2583 _mesa_error(ctx, GL_INVALID_OPERATION, 2584 "%s(multisample FBO)", caller); 2585 return GL_TRUE; 2586 } 2587 } 2588 2589 /* Check level */ 2590 if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 2591 _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", caller, level); 2592 return GL_TRUE; 2593 } 2594 2595 texImage = _mesa_select_tex_image(texObj, target, level); 2596 if (!texImage) { 2597 /* destination image does not exist */ 2598 _mesa_error(ctx, GL_INVALID_OPERATION, 2599 "%s(invalid texture level %d)", caller, level); 2600 return GL_TRUE; 2601 } 2602 2603 if (error_check_subtexture_negative_dimensions(ctx, dimensions, 2604 width, height, 1, caller)) { 2605 return GL_TRUE; 2606 } 2607 2608 if (error_check_subtexture_dimensions(ctx, dimensions, texImage, 2609 xoffset, yoffset, zoffset, 2610 width, height, 1, caller)) { 2611 return GL_TRUE; 2612 } 2613 2614 if (_mesa_is_format_compressed(texImage->TexFormat)) { 2615 if (_mesa_format_no_online_compression(texImage->InternalFormat)) { 2616 _mesa_error(ctx, GL_INVALID_OPERATION, 2617 "%s(no compression for format)", caller); 2618 return GL_TRUE; 2619 } 2620 } 2621 2622 if (texImage->InternalFormat == GL_YCBCR_MESA) { 2623 _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", caller); 2624 return GL_TRUE; 2625 } 2626 2627 /* From OpenGL ES 3.2 spec, section 8.6: 2628 * 2629 * "An INVALID_OPERATION error is generated by CopyTexSubImage3D, 2630 * CopyTexImage2D, or CopyTexSubImage2D if the internalformat of the 2631 * texture image being (re)specified is RGB9_E5" 2632 */ 2633 if (texImage->InternalFormat == GL_RGB9_E5 && 2634 !_mesa_is_desktop_gl(ctx)) { 2635 _mesa_error(ctx, GL_INVALID_OPERATION, 2636 "%s(invalid internal format %s)", caller, 2637 _mesa_enum_to_string(texImage->InternalFormat)); 2638 return GL_TRUE; 2639 } 2640 2641 if (!_mesa_source_buffer_exists(ctx, texImage->_BaseFormat)) { 2642 _mesa_error(ctx, GL_INVALID_OPERATION, 2643 "%s(missing readbuffer, format=%s)", caller, 2644 _mesa_enum_to_string(texImage->_BaseFormat)); 2645 return GL_TRUE; 2646 } 2647 2648 /* From the EXT_texture_integer spec: 2649 * 2650 * "INVALID_OPERATION is generated by CopyTexImage* and 2651 * CopyTexSubImage* if the texture internalformat is an integer format 2652 * and the read color buffer is not an integer format, or if the 2653 * internalformat is not an integer format and the read color buffer 2654 * is an integer format." 2655 */ 2656 if (_mesa_is_color_format(texImage->InternalFormat)) { 2657 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 2658 2659 if (_mesa_is_format_integer_color(rb->Format) != 2660 _mesa_is_format_integer_color(texImage->TexFormat)) { 2661 _mesa_error(ctx, GL_INVALID_OPERATION, 2662 "%s(integer vs non-integer)", caller); 2663 return GL_TRUE; 2664 } 2665 } 2666 2667 /* In the ES 3.2 specification's Table 8.13 (Valid CopyTexImage source 2668 * framebuffer/destination texture base internal format combinations), 2669 * all the entries for stencil are left blank (unsupported). 2670 */ 2671 if (_mesa_is_gles(ctx) && _mesa_is_stencil_format(texImage->_BaseFormat)) { 2672 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(stencil disallowed)", caller); 2673 return GL_TRUE; 2674 } 2675 2676 /* if we get here, the parameters are OK */ 2677 return GL_FALSE; 2678} 2679 2680 2681/** Callback info for walking over FBO hash table */ 2682struct cb_info 2683{ 2684 struct gl_context *ctx; 2685 struct gl_texture_object *texObj; 2686 GLuint level, face; 2687}; 2688 2689 2690/** 2691 * Check render to texture callback. Called from _mesa_HashWalk(). 2692 */ 2693static void 2694check_rtt_cb(void *data, void *userData) 2695{ 2696 struct gl_framebuffer *fb = (struct gl_framebuffer *) data; 2697 const struct cb_info *info = (struct cb_info *) userData; 2698 struct gl_context *ctx = info->ctx; 2699 const struct gl_texture_object *texObj = info->texObj; 2700 const GLuint level = info->level, face = info->face; 2701 2702 /* If this is a user-created FBO */ 2703 if (_mesa_is_user_fbo(fb)) { 2704 GLuint i; 2705 /* check if any of the FBO's attachments point to 'texObj' */ 2706 for (i = 0; i < BUFFER_COUNT; i++) { 2707 struct gl_renderbuffer_attachment *att = fb->Attachment + i; 2708 if (att->Type == GL_TEXTURE && 2709 att->Texture == texObj && 2710 att->TextureLevel == level && 2711 att->CubeMapFace == face) { 2712 _mesa_update_texture_renderbuffer(ctx, fb, att); 2713 assert(att->Renderbuffer->TexImage); 2714 /* Mark fb status as indeterminate to force re-validation */ 2715 fb->_Status = 0; 2716 2717 /* Make sure that the revalidation actually happens if this is 2718 * being done to currently-bound buffers. 2719 */ 2720 if (fb == ctx->DrawBuffer || fb == ctx->ReadBuffer) 2721 ctx->NewState |= _NEW_BUFFERS; 2722 } 2723 } 2724 } 2725} 2726 2727 2728/** 2729 * When a texture image is specified we have to check if it's bound to 2730 * any framebuffer objects (render to texture) in order to detect changes 2731 * in size or format since that effects FBO completeness. 2732 * Any FBOs rendering into the texture must be re-validated. 2733 */ 2734void 2735_mesa_update_fbo_texture(struct gl_context *ctx, 2736 struct gl_texture_object *texObj, 2737 GLuint face, GLuint level) 2738{ 2739 /* Only check this texture if it's been marked as RenderToTexture */ 2740 if (texObj->_RenderToTexture) { 2741 struct cb_info info; 2742 info.ctx = ctx; 2743 info.texObj = texObj; 2744 info.level = level; 2745 info.face = face; 2746 _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info); 2747 } 2748} 2749 2750 2751/** 2752 * If the texture object's GenerateMipmap flag is set and we've 2753 * changed the texture base level image, regenerate the rest of the 2754 * mipmap levels now. 2755 */ 2756static inline void 2757check_gen_mipmap(struct gl_context *ctx, GLenum target, 2758 struct gl_texture_object *texObj, GLint level) 2759{ 2760 if (texObj->Attrib.GenerateMipmap && 2761 level == texObj->Attrib.BaseLevel && 2762 level < texObj->Attrib.MaxLevel) { 2763 st_generate_mipmap(ctx, target, texObj); 2764 } 2765} 2766 2767 2768/** Debug helper: override the user-requested internal format */ 2769static GLenum 2770override_internal_format(GLenum internalFormat, UNUSED GLint width, 2771 UNUSED GLint height) 2772{ 2773#if 0 2774 if (internalFormat == GL_RGBA16F_ARB || 2775 internalFormat == GL_RGBA32F_ARB) { 2776 printf("Convert rgba float tex to int %d x %d\n", width, height); 2777 return GL_RGBA; 2778 } 2779 else if (internalFormat == GL_RGB16F_ARB || 2780 internalFormat == GL_RGB32F_ARB) { 2781 printf("Convert rgb float tex to int %d x %d\n", width, height); 2782 return GL_RGB; 2783 } 2784 else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB || 2785 internalFormat == GL_LUMINANCE_ALPHA32F_ARB) { 2786 printf("Convert luminance float tex to int %d x %d\n", width, height); 2787 return GL_LUMINANCE_ALPHA; 2788 } 2789 else if (internalFormat == GL_LUMINANCE16F_ARB || 2790 internalFormat == GL_LUMINANCE32F_ARB) { 2791 printf("Convert luminance float tex to int %d x %d\n", width, height); 2792 return GL_LUMINANCE; 2793 } 2794 else if (internalFormat == GL_ALPHA16F_ARB || 2795 internalFormat == GL_ALPHA32F_ARB) { 2796 printf("Convert luminance float tex to int %d x %d\n", width, height); 2797 return GL_ALPHA; 2798 } 2799 /* 2800 else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) { 2801 internalFormat = GL_RGBA; 2802 } 2803 */ 2804 else { 2805 return internalFormat; 2806 } 2807#else 2808 return internalFormat; 2809#endif 2810} 2811 2812 2813/** 2814 * Choose the actual hardware format for a texture image. 2815 * Try to use the same format as the previous image level when possible. 2816 * Otherwise, ask the driver for the best format. 2817 * It's important to try to choose a consistant format for all levels 2818 * for efficient texture memory layout/allocation. In particular, this 2819 * comes up during automatic mipmap generation. 2820 */ 2821mesa_format 2822_mesa_choose_texture_format(struct gl_context *ctx, 2823 struct gl_texture_object *texObj, 2824 GLenum target, GLint level, 2825 GLenum internalFormat, GLenum format, GLenum type) 2826{ 2827 mesa_format f = MESA_FORMAT_NONE; 2828 2829 /* see if we've already chosen a format for the previous level */ 2830 if (level > 0) { 2831 struct gl_texture_image *prevImage = 2832 _mesa_select_tex_image(texObj, target, level - 1); 2833 /* See if the prev level is defined and has an internal format which 2834 * matches the new internal format. 2835 */ 2836 if (prevImage && 2837 prevImage->Width > 0 && 2838 prevImage->InternalFormat == internalFormat) { 2839 /* use the same format */ 2840 assert(prevImage->TexFormat != MESA_FORMAT_NONE); 2841 return prevImage->TexFormat; 2842 } 2843 } 2844 2845 f = st_ChooseTextureFormat(ctx, target, internalFormat, 2846 format, type); 2847 assert(f != MESA_FORMAT_NONE); 2848 return f; 2849} 2850 2851 2852/** 2853 * Adjust pixel unpack params and image dimensions to strip off the 2854 * one-pixel texture border. 2855 * 2856 * Gallium and intel don't support texture borders. They've seldem been used 2857 * and seldom been implemented correctly anyway. 2858 * 2859 * \param unpackNew returns the new pixel unpack parameters 2860 */ 2861static void 2862strip_texture_border(GLenum target, 2863 GLint *width, GLint *height, GLint *depth, 2864 const struct gl_pixelstore_attrib *unpack, 2865 struct gl_pixelstore_attrib *unpackNew) 2866{ 2867 assert(width); 2868 assert(height); 2869 assert(depth); 2870 2871 *unpackNew = *unpack; 2872 2873 if (unpackNew->RowLength == 0) 2874 unpackNew->RowLength = *width; 2875 2876 if (unpackNew->ImageHeight == 0) 2877 unpackNew->ImageHeight = *height; 2878 2879 assert(*width >= 3); 2880 unpackNew->SkipPixels++; /* skip the border */ 2881 *width = *width - 2; /* reduce the width by two border pixels */ 2882 2883 /* The min height of a texture with a border is 3 */ 2884 if (*height >= 3 && target != GL_TEXTURE_1D_ARRAY) { 2885 unpackNew->SkipRows++; /* skip the border */ 2886 *height = *height - 2; /* reduce the height by two border pixels */ 2887 } 2888 2889 if (*depth >= 3 && 2890 target != GL_TEXTURE_2D_ARRAY && 2891 target != GL_TEXTURE_CUBE_MAP_ARRAY) { 2892 unpackNew->SkipImages++; /* skip the border */ 2893 *depth = *depth - 2; /* reduce the depth by two border pixels */ 2894 } 2895} 2896 2897static struct gl_texture_object * 2898lookup_texture_ext_dsa(struct gl_context *ctx, GLenum target, GLuint texture, 2899 const char *caller) 2900{ 2901 GLenum boundTarget; 2902 switch (target) { 2903 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 2904 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 2905 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 2906 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 2907 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 2908 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 2909 boundTarget = GL_TEXTURE_CUBE_MAP; 2910 break; 2911 default: 2912 boundTarget = target; 2913 break; 2914 } 2915 2916 int targetIndex = _mesa_tex_target_to_index(ctx, boundTarget); 2917 if (targetIndex < 0) { 2918 _mesa_error(ctx, GL_INVALID_ENUM, "%s(target = %s)", caller, 2919 _mesa_enum_to_string(target)); 2920 return NULL; 2921 } 2922 assert(targetIndex < NUM_TEXTURE_TARGETS); 2923 2924 struct gl_texture_object *texObj; 2925 if (texture == 0) { 2926 /* Use a default texture object */ 2927 texObj = ctx->Shared->DefaultTex[targetIndex]; 2928 assert(texObj); 2929 } else { 2930 bool isGenName; 2931 texObj = _mesa_lookup_texture(ctx, texture); 2932 isGenName = texObj != NULL; 2933 if (!texObj && ctx->API == API_OPENGL_CORE) { 2934 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", caller); 2935 return NULL; 2936 } 2937 2938 if (!texObj) { 2939 texObj = _mesa_new_texture_object(ctx, texture, boundTarget); 2940 if (!texObj) { 2941 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); 2942 return NULL; 2943 } 2944 2945 /* insert into hash table */ 2946 _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj, isGenName); 2947 } 2948 2949 if (texObj->Target != boundTarget) { 2950 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s != %s)", 2951 caller, _mesa_enum_to_string(texObj->Target), 2952 _mesa_enum_to_string(target)); 2953 return NULL; 2954 } 2955 } 2956 2957 return texObj; 2958} 2959 2960/** 2961 * Common code to implement all the glTexImage1D/2D/3D functions, 2962 * glCompressedTexImage1D/2D/3D and glTextureImage1D/2D/3DEXT 2963 * \param compressed only GL_TRUE for glCompressedTexImage1D/2D/3D calls. 2964 * \param format the user's image format (only used if !compressed) 2965 * \param type the user's image type (only used if !compressed) 2966 * \param imageSize only used for glCompressedTexImage1D/2D/3D calls. 2967 */ 2968static ALWAYS_INLINE void 2969teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, 2970 struct gl_texture_object *texObj, 2971 GLenum target, GLint level, GLint internalFormat, 2972 GLsizei width, GLsizei height, GLsizei depth, 2973 GLint border, GLenum format, GLenum type, 2974 GLsizei imageSize, const GLvoid *pixels, bool no_error) 2975{ 2976 const char *func = compressed ? "glCompressedTexImage" : "glTexImage"; 2977 struct gl_pixelstore_attrib unpack_no_border; 2978 const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; 2979 mesa_format texFormat; 2980 bool dimensionsOK = true, sizeOK = true; 2981 2982 FLUSH_VERTICES(ctx, 0, 0); 2983 2984 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) { 2985 if (compressed) 2986 _mesa_debug(ctx, 2987 "glCompressedTexImage%uD %s %d %s %d %d %d %d %p\n", 2988 dims, 2989 _mesa_enum_to_string(target), level, 2990 _mesa_enum_to_string(internalFormat), 2991 width, height, depth, border, pixels); 2992 else 2993 _mesa_debug(ctx, 2994 "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n", 2995 dims, 2996 _mesa_enum_to_string(target), level, 2997 _mesa_enum_to_string(internalFormat), 2998 width, height, depth, border, 2999 _mesa_enum_to_string(format), 3000 _mesa_enum_to_string(type), pixels); 3001 } 3002 3003 internalFormat = override_internal_format(internalFormat, width, height); 3004 3005 if (!no_error && 3006 /* target error checking */ 3007 !legal_teximage_target(ctx, dims, target)) { 3008 _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)", 3009 func, dims, _mesa_enum_to_string(target)); 3010 return; 3011 } 3012 3013 if (!texObj) 3014 texObj = _mesa_get_current_tex_object(ctx, target); 3015 3016 if (!no_error) { 3017 /* general error checking */ 3018 if (compressed) { 3019 if (compressed_texture_error_check(ctx, dims, target, texObj, 3020 level, internalFormat, 3021 width, height, depth, 3022 border, imageSize, pixels)) 3023 return; 3024 } else { 3025 if (texture_error_check(ctx, dims, target, texObj, level, internalFormat, 3026 format, type, width, height, depth, border, 3027 pixels)) 3028 return; 3029 } 3030 } 3031 assert(texObj); 3032 3033 /* Here we convert a cpal compressed image into a regular glTexImage2D 3034 * call by decompressing the texture. If we really want to support cpal 3035 * textures in any driver this would have to be changed. 3036 */ 3037 if (ctx->API == API_OPENGLES && compressed && dims == 2) { 3038 switch (internalFormat) { 3039 case GL_PALETTE4_RGB8_OES: 3040 case GL_PALETTE4_RGBA8_OES: 3041 case GL_PALETTE4_R5_G6_B5_OES: 3042 case GL_PALETTE4_RGBA4_OES: 3043 case GL_PALETTE4_RGB5_A1_OES: 3044 case GL_PALETTE8_RGB8_OES: 3045 case GL_PALETTE8_RGBA8_OES: 3046 case GL_PALETTE8_R5_G6_B5_OES: 3047 case GL_PALETTE8_RGBA4_OES: 3048 case GL_PALETTE8_RGB5_A1_OES: 3049 _mesa_cpal_compressed_teximage2d(target, level, internalFormat, 3050 width, height, imageSize, pixels); 3051 return; 3052 } 3053 } 3054 3055 if (compressed) { 3056 /* For glCompressedTexImage() the driver has no choice about the 3057 * texture format since we'll never transcode the user's compressed 3058 * image data. The internalFormat was error checked earlier. 3059 */ 3060 texFormat = _mesa_glenum_to_compressed_format(internalFormat); 3061 } 3062 else { 3063 /* In case of HALF_FLOAT_OES or FLOAT_OES, find corresponding sized 3064 * internal floating point format for the given base format. 3065 */ 3066 if (_mesa_is_gles(ctx) && format == internalFormat) { 3067 if (type == GL_FLOAT) { 3068 texObj->_IsFloat = GL_TRUE; 3069 } else if (type == GL_HALF_FLOAT_OES || type == GL_HALF_FLOAT) { 3070 texObj->_IsHalfFloat = GL_TRUE; 3071 } 3072 3073 internalFormat = adjust_for_oes_float_texture(ctx, format, type); 3074 } 3075 3076 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 3077 internalFormat, format, type); 3078 } 3079 3080 assert(texFormat != MESA_FORMAT_NONE); 3081 3082 if (!no_error) { 3083 /* check that width, height, depth are legal for the mipmap level */ 3084 dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, level, width, 3085 height, depth, border); 3086 3087 /* check that the texture won't take too much memory, etc */ 3088 sizeOK = st_TestProxyTexImage(ctx, proxy_target(target), 3089 0, level, texFormat, 1, 3090 width, height, depth); 3091 } 3092 3093 if (_mesa_is_proxy_texture(target)) { 3094 /* Proxy texture: just clear or set state depending on error checking */ 3095 struct gl_texture_image *texImage = 3096 get_proxy_tex_image(ctx, target, level); 3097 3098 if (!texImage) 3099 return; /* GL_OUT_OF_MEMORY already recorded */ 3100 3101 if (dimensionsOK && sizeOK) { 3102 _mesa_init_teximage_fields(ctx, texImage, width, height, depth, 3103 border, internalFormat, texFormat); 3104 } 3105 else { 3106 clear_teximage_fields(texImage); 3107 } 3108 } 3109 else { 3110 /* non-proxy target */ 3111 const GLuint face = _mesa_tex_target_to_face(target); 3112 struct gl_texture_image *texImage; 3113 3114 if (!dimensionsOK) { 3115 _mesa_error(ctx, GL_INVALID_VALUE, 3116 "%s%uD(invalid width=%d or height=%d or depth=%d)", 3117 func, dims, width, height, depth); 3118 return; 3119 } 3120 3121 if (!sizeOK) { 3122 _mesa_error(ctx, GL_OUT_OF_MEMORY, 3123 "%s%uD(image too large: %d x %d x %d, %s format)", 3124 func, dims, width, height, depth, 3125 _mesa_enum_to_string(internalFormat)); 3126 return; 3127 } 3128 3129 /* Allow a hardware driver to just strip out the border, to provide 3130 * reliable but slightly incorrect hardware rendering instead of 3131 * rarely-tested software fallback rendering. 3132 */ 3133 if (border) { 3134 strip_texture_border(target, &width, &height, &depth, unpack, 3135 &unpack_no_border); 3136 border = 0; 3137 unpack = &unpack_no_border; 3138 } 3139 3140 _mesa_update_pixel(ctx); 3141 3142 _mesa_lock_texture(ctx, texObj); 3143 { 3144 texObj->External = GL_FALSE; 3145 3146 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3147 3148 if (!texImage) { 3149 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims); 3150 } 3151 else { 3152 st_FreeTextureImageBuffer(ctx, texImage); 3153 3154 _mesa_init_teximage_fields(ctx, texImage, 3155 width, height, depth, 3156 border, internalFormat, texFormat); 3157 3158 /* Give the texture to the driver. <pixels> may be null. */ 3159 if (width > 0 && height > 0 && depth > 0) { 3160 if (compressed) { 3161 st_CompressedTexImage(ctx, dims, texImage, 3162 imageSize, pixels); 3163 } 3164 else { 3165 st_TexImage(ctx, dims, texImage, format, 3166 type, pixels, unpack); 3167 } 3168 } 3169 3170 check_gen_mipmap(ctx, target, texObj, level); 3171 3172 _mesa_update_fbo_texture(ctx, texObj, face, level); 3173 3174 _mesa_dirty_texobj(ctx, texObj); 3175 } 3176 } 3177 _mesa_unlock_texture(ctx, texObj); 3178 } 3179} 3180 3181 3182/* This is a wrapper around teximage() so that we can force the KHR_no_error 3183 * logic to be inlined without inlining the function into all the callers. 3184 */ 3185static void 3186teximage_err(struct gl_context *ctx, GLboolean compressed, GLuint dims, 3187 GLenum target, GLint level, GLint internalFormat, 3188 GLsizei width, GLsizei height, GLsizei depth, 3189 GLint border, GLenum format, GLenum type, 3190 GLsizei imageSize, const GLvoid *pixels) 3191{ 3192 teximage(ctx, compressed, dims, NULL, target, level, internalFormat, width, height, 3193 depth, border, format, type, imageSize, pixels, false); 3194} 3195 3196 3197static void 3198teximage_no_error(struct gl_context *ctx, GLboolean compressed, GLuint dims, 3199 GLenum target, GLint level, GLint internalFormat, 3200 GLsizei width, GLsizei height, GLsizei depth, 3201 GLint border, GLenum format, GLenum type, 3202 GLsizei imageSize, const GLvoid *pixels) 3203{ 3204 teximage(ctx, compressed, dims, NULL, target, level, internalFormat, width, height, 3205 depth, border, format, type, imageSize, pixels, true); 3206} 3207 3208 3209/* 3210 * Called from the API. Note that width includes the border. 3211 */ 3212void GLAPIENTRY 3213_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, 3214 GLsizei width, GLint border, GLenum format, 3215 GLenum type, const GLvoid *pixels ) 3216{ 3217 GET_CURRENT_CONTEXT(ctx); 3218 teximage_err(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 1, 3219 border, format, type, 0, pixels); 3220} 3221 3222void GLAPIENTRY 3223_mesa_TextureImage1DEXT(GLuint texture, GLenum target, GLint level, 3224 GLint internalFormat, GLsizei width, GLint border, 3225 GLenum format, GLenum type, const GLvoid *pixels ) 3226{ 3227 struct gl_texture_object* texObj; 3228 GET_CURRENT_CONTEXT(ctx); 3229 3230 texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 3231 "glTextureImage1DEXT"); 3232 if (!texObj) 3233 return; 3234 teximage(ctx, GL_FALSE, 1, texObj, target, level, internalFormat, 3235 width, 1, 1, border, format, type, 0, pixels, false); 3236} 3237 3238void GLAPIENTRY 3239_mesa_MultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, 3240 GLint internalFormat, GLsizei width, GLint border, 3241 GLenum format, GLenum type, const GLvoid *pixels ) 3242{ 3243 struct gl_texture_object* texObj; 3244 GET_CURRENT_CONTEXT(ctx); 3245 3246 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 3247 texunit - GL_TEXTURE0, 3248 true, 3249 "glMultiTexImage1DEXT"); 3250 if (!texObj) 3251 return; 3252 teximage(ctx, GL_FALSE, 1, texObj, target, level, internalFormat, width, 1, 1, 3253 border, format, type, 0, pixels, false); 3254} 3255 3256void GLAPIENTRY 3257_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 3258 GLsizei width, GLsizei height, GLint border, 3259 GLenum format, GLenum type, 3260 const GLvoid *pixels ) 3261{ 3262 GET_CURRENT_CONTEXT(ctx); 3263 teximage_err(ctx, GL_FALSE, 2, target, level, internalFormat, width, height, 1, 3264 border, format, type, 0, pixels); 3265} 3266 3267void GLAPIENTRY 3268_mesa_TextureImage2DEXT(GLuint texture, GLenum target, GLint level, 3269 GLint internalFormat, GLsizei width, GLsizei height, 3270 GLint border, 3271 GLenum format, GLenum type, const GLvoid *pixels ) 3272{ 3273 struct gl_texture_object* texObj; 3274 GET_CURRENT_CONTEXT(ctx); 3275 3276 texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 3277 "glTextureImage2DEXT"); 3278 if (!texObj) 3279 return; 3280 teximage(ctx, GL_FALSE, 2, texObj, target, level, internalFormat, 3281 width, height, 1, border, format, type, 0, pixels, false); 3282} 3283 3284void GLAPIENTRY 3285_mesa_MultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, 3286 GLint internalFormat, GLsizei width, GLsizei height, 3287 GLint border, 3288 GLenum format, GLenum type, const GLvoid *pixels ) 3289{ 3290 struct gl_texture_object* texObj; 3291 GET_CURRENT_CONTEXT(ctx); 3292 3293 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 3294 texunit - GL_TEXTURE0, 3295 true, 3296 "glMultiTexImage2DEXT"); 3297 if (!texObj) 3298 return; 3299 teximage(ctx, GL_FALSE, 2, texObj, target, level, internalFormat, width, height, 1, 3300 border, format, type, 0, pixels, false); 3301} 3302 3303/* 3304 * Called by the API or display list executor. 3305 * Note that width and height include the border. 3306 */ 3307void GLAPIENTRY 3308_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, 3309 GLsizei width, GLsizei height, GLsizei depth, 3310 GLint border, GLenum format, GLenum type, 3311 const GLvoid *pixels ) 3312{ 3313 GET_CURRENT_CONTEXT(ctx); 3314 teximage_err(ctx, GL_FALSE, 3, target, level, internalFormat, 3315 width, height, depth, border, format, type, 0, pixels); 3316} 3317 3318void GLAPIENTRY 3319_mesa_TextureImage3DEXT(GLuint texture, GLenum target, GLint level, 3320 GLint internalFormat, GLsizei width, GLsizei height, 3321 GLsizei depth, GLint border, 3322 GLenum format, GLenum type, const GLvoid *pixels ) 3323{ 3324 struct gl_texture_object* texObj; 3325 GET_CURRENT_CONTEXT(ctx); 3326 3327 texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 3328 "glTextureImage3DEXT"); 3329 if (!texObj) 3330 return; 3331 teximage(ctx, GL_FALSE, 3, texObj, target, level, internalFormat, 3332 width, height, depth, border, format, type, 0, pixels, false); 3333} 3334 3335 3336void GLAPIENTRY 3337_mesa_MultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, 3338 GLint internalFormat, GLsizei width, GLsizei height, 3339 GLsizei depth, GLint border, GLenum format, GLenum type, 3340 const GLvoid *pixels ) 3341{ 3342 struct gl_texture_object* texObj; 3343 GET_CURRENT_CONTEXT(ctx); 3344 3345 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 3346 texunit - GL_TEXTURE0, 3347 true, 3348 "glMultiTexImage3DEXT"); 3349 if (!texObj) 3350 return; 3351 teximage(ctx, GL_FALSE, 3, texObj, target, level, internalFormat, 3352 width, height, depth, border, format, type, 0, pixels, false); 3353} 3354 3355 3356void GLAPIENTRY 3357_mesa_TexImage1D_no_error(GLenum target, GLint level, GLint internalFormat, 3358 GLsizei width, GLint border, GLenum format, 3359 GLenum type, const GLvoid *pixels) 3360{ 3361 GET_CURRENT_CONTEXT(ctx); 3362 teximage_no_error(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 3363 1, border, format, type, 0, pixels); 3364} 3365 3366 3367void GLAPIENTRY 3368_mesa_TexImage2D_no_error(GLenum target, GLint level, GLint internalFormat, 3369 GLsizei width, GLsizei height, GLint border, 3370 GLenum format, GLenum type, const GLvoid *pixels) 3371{ 3372 GET_CURRENT_CONTEXT(ctx); 3373 teximage_no_error(ctx, GL_FALSE, 2, target, level, internalFormat, width, 3374 height, 1, border, format, type, 0, pixels); 3375} 3376 3377 3378void GLAPIENTRY 3379_mesa_TexImage3D_no_error(GLenum target, GLint level, GLint internalFormat, 3380 GLsizei width, GLsizei height, GLsizei depth, 3381 GLint border, GLenum format, GLenum type, 3382 const GLvoid *pixels ) 3383{ 3384 GET_CURRENT_CONTEXT(ctx); 3385 teximage_no_error(ctx, GL_FALSE, 3, target, level, internalFormat, 3386 width, height, depth, border, format, type, 0, pixels); 3387} 3388 3389/* 3390 * Helper used by __mesa_EGLImageTargetTexture2DOES and 3391 * _mesa_EGLImageTargetTexStorageEXT. 3392 */ 3393static void 3394egl_image_target_texture(struct gl_context *ctx, 3395 struct gl_texture_object *texObj, GLenum target, 3396 GLeglImageOES image, bool tex_storage, 3397 const char *caller) 3398{ 3399 struct gl_texture_image *texImage; 3400 bool valid_target; 3401 FLUSH_VERTICES(ctx, 0, 0); 3402 3403 switch (target) { 3404 case GL_TEXTURE_2D: 3405 valid_target = _mesa_has_OES_EGL_image(ctx) || 3406 (tex_storage && _mesa_has_EXT_EGL_image_storage(ctx)); 3407 break; 3408 case GL_TEXTURE_EXTERNAL_OES: 3409 valid_target = _mesa_has_OES_EGL_image_external(ctx); 3410 break; 3411 default: 3412 valid_target = false; 3413 break; 3414 } 3415 3416 if (!valid_target) { 3417 _mesa_error(ctx, tex_storage ? GL_INVALID_OPERATION : GL_INVALID_ENUM, "%s(target=%d)", caller, target); 3418 return; 3419 } 3420 3421 if (!texObj) 3422 texObj = _mesa_get_current_tex_object(ctx, target); 3423 if (!texObj) 3424 return; 3425 3426 if (!image || (ctx->Driver.ValidateEGLImage && 3427 !ctx->Driver.ValidateEGLImage(ctx, image))) { 3428 _mesa_error(ctx, GL_INVALID_VALUE, "%s(image=%p)", caller, image); 3429 return; 3430 } 3431 3432 _mesa_lock_texture(ctx, texObj); 3433 3434 if (texObj->Immutable) { 3435 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture is immutable)", caller); 3436 _mesa_unlock_texture(ctx, texObj); 3437 return; 3438 } 3439 3440 texImage = _mesa_get_tex_image(ctx, texObj, target, 0); 3441 if (!texImage) { 3442 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); 3443 } else { 3444 st_FreeTextureImageBuffer(ctx, texImage); 3445 3446 texObj->External = GL_TRUE; 3447 3448 if (tex_storage) { 3449 st_egl_image_target_tex_storage(ctx, target, texObj, texImage, 3450 image); 3451 } else { 3452 st_egl_image_target_texture_2d(ctx, target, texObj, texImage, 3453 image); 3454 } 3455 3456 _mesa_dirty_texobj(ctx, texObj); 3457 } 3458 3459 if (tex_storage) 3460 _mesa_set_texture_view_state(ctx, texObj, target, 1); 3461 3462 _mesa_update_fbo_texture(ctx, texObj, 0, 0); 3463 3464 _mesa_unlock_texture(ctx, texObj); 3465} 3466 3467void GLAPIENTRY 3468_mesa_EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) 3469{ 3470 const char *func = "glEGLImageTargetTexture2D"; 3471 GET_CURRENT_CONTEXT(ctx); 3472 3473 egl_image_target_texture(ctx, NULL, target, image, false, func); 3474} 3475 3476static void 3477egl_image_target_texture_storage(struct gl_context *ctx, 3478 struct gl_texture_object *texObj, GLenum target, 3479 GLeglImageOES image, const GLint *attrib_list, 3480 const char *caller) 3481{ 3482 /* 3483 * EXT_EGL_image_storage: 3484 * 3485 * "<attrib_list> must be NULL or a pointer to the value GL_NONE." 3486 */ 3487 if (attrib_list && attrib_list[0] != GL_NONE) { 3488 _mesa_error(ctx, GL_INVALID_VALUE, "%s(image=%p)", caller, image); 3489 return; 3490 } 3491 3492 egl_image_target_texture(ctx, texObj, target, image, true, caller); 3493} 3494 3495 3496void GLAPIENTRY 3497_mesa_EGLImageTargetTexStorageEXT(GLenum target, GLeglImageOES image, 3498 const GLint *attrib_list) 3499{ 3500 const char *func = "glEGLImageTargetTexStorageEXT"; 3501 GET_CURRENT_CONTEXT(ctx); 3502 3503 egl_image_target_texture_storage(ctx, NULL, target, image, attrib_list, 3504 func); 3505} 3506 3507void GLAPIENTRY 3508_mesa_EGLImageTargetTextureStorageEXT(GLuint texture, GLeglImageOES image, 3509 const GLint *attrib_list) 3510{ 3511 struct gl_texture_object *texObj; 3512 const char *func = "glEGLImageTargetTextureStorageEXT"; 3513 GET_CURRENT_CONTEXT(ctx); 3514 3515 if (!(_mesa_is_desktop_gl(ctx) && ctx->Version >= 45) && 3516 !_mesa_has_ARB_direct_state_access(ctx) && 3517 !_mesa_has_EXT_direct_state_access(ctx)) { 3518 _mesa_error(ctx, GL_INVALID_OPERATION, "direct access not supported"); 3519 return; 3520 } 3521 3522 texObj = _mesa_lookup_texture_err(ctx, texture, func); 3523 if (!texObj) 3524 return; 3525 3526 egl_image_target_texture_storage(ctx, texObj, texObj->Target, image, 3527 attrib_list, func); 3528} 3529 3530/** 3531 * Helper that implements the glTexSubImage1/2/3D() 3532 * and glTextureSubImage1/2/3D() functions. 3533 */ 3534static void 3535texture_sub_image(struct gl_context *ctx, GLuint dims, 3536 struct gl_texture_object *texObj, 3537 struct gl_texture_image *texImage, 3538 GLenum target, GLint level, 3539 GLint xoffset, GLint yoffset, GLint zoffset, 3540 GLsizei width, GLsizei height, GLsizei depth, 3541 GLenum format, GLenum type, const GLvoid *pixels) 3542{ 3543 FLUSH_VERTICES(ctx, 0, 0); 3544 3545 _mesa_update_pixel(ctx); 3546 3547 _mesa_lock_texture(ctx, texObj); 3548 { 3549 if (width > 0 && height > 0 && depth > 0) { 3550 /* If we have a border, offset=-1 is legal. Bias by border width. */ 3551 switch (dims) { 3552 case 3: 3553 if (target != GL_TEXTURE_2D_ARRAY) 3554 zoffset += texImage->Border; 3555 FALLTHROUGH; 3556 case 2: 3557 if (target != GL_TEXTURE_1D_ARRAY) 3558 yoffset += texImage->Border; 3559 FALLTHROUGH; 3560 case 1: 3561 xoffset += texImage->Border; 3562 } 3563 3564 st_TexSubImage(ctx, dims, texImage, 3565 xoffset, yoffset, zoffset, 3566 width, height, depth, 3567 format, type, pixels, &ctx->Unpack); 3568 3569 check_gen_mipmap(ctx, target, texObj, level); 3570 3571 /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed 3572 * the texel data, not the texture format, size, etc. 3573 */ 3574 } 3575 } 3576 _mesa_unlock_texture(ctx, texObj); 3577} 3578 3579/** 3580 * Implement all the glTexSubImage1/2/3D() functions. 3581 * Must split this out this way because of GL_TEXTURE_CUBE_MAP. 3582 */ 3583static void 3584texsubimage_err(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, 3585 GLint xoffset, GLint yoffset, GLint zoffset, 3586 GLsizei width, GLsizei height, GLsizei depth, 3587 GLenum format, GLenum type, const GLvoid *pixels, 3588 const char *callerName) 3589{ 3590 struct gl_texture_object *texObj; 3591 struct gl_texture_image *texImage; 3592 3593 /* check target (proxies not allowed) */ 3594 if (!legal_texsubimage_target(ctx, dims, target, false)) { 3595 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)", 3596 dims, _mesa_enum_to_string(target)); 3597 return; 3598 } 3599 3600 texObj = _mesa_get_current_tex_object(ctx, target); 3601 if (!texObj) 3602 return; 3603 3604 if (texsubimage_error_check(ctx, dims, texObj, target, level, 3605 xoffset, yoffset, zoffset, 3606 width, height, depth, format, type, 3607 pixels, callerName)) { 3608 return; /* error was detected */ 3609 } 3610 3611 texImage = _mesa_select_tex_image(texObj, target, level); 3612 /* texsubimage_error_check ensures that texImage is not NULL */ 3613 3614 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3615 _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n", 3616 dims, 3617 _mesa_enum_to_string(target), level, 3618 xoffset, yoffset, zoffset, width, height, depth, 3619 _mesa_enum_to_string(format), 3620 _mesa_enum_to_string(type), pixels); 3621 3622 texture_sub_image(ctx, dims, texObj, texImage, target, level, 3623 xoffset, yoffset, zoffset, width, height, depth, 3624 format, type, pixels); 3625} 3626 3627 3628static void 3629texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, 3630 GLint xoffset, GLint yoffset, GLint zoffset, 3631 GLsizei width, GLsizei height, GLsizei depth, 3632 GLenum format, GLenum type, const GLvoid *pixels) 3633{ 3634 struct gl_texture_object *texObj; 3635 struct gl_texture_image *texImage; 3636 3637 texObj = _mesa_get_current_tex_object(ctx, target); 3638 texImage = _mesa_select_tex_image(texObj, target, level); 3639 3640 texture_sub_image(ctx, dims, texObj, texImage, target, level, 3641 xoffset, yoffset, zoffset, width, height, depth, 3642 format, type, pixels); 3643} 3644 3645 3646/** 3647 * Implement all the glTextureSubImage1/2/3D() functions. 3648 * Must split this out this way because of GL_TEXTURE_CUBE_MAP. 3649 */ 3650static ALWAYS_INLINE void 3651texturesubimage(struct gl_context *ctx, GLuint dims, 3652 GLuint texture, GLenum target, GLint level, 3653 GLint xoffset, GLint yoffset, GLint zoffset, 3654 GLsizei width, GLsizei height, GLsizei depth, 3655 GLenum format, GLenum type, const GLvoid *pixels, 3656 const char *callerName, bool no_error, bool ext_dsa) 3657{ 3658 struct gl_texture_object *texObj; 3659 struct gl_texture_image *texImage; 3660 int i; 3661 3662 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3663 _mesa_debug(ctx, 3664 "glTextureSubImage%uD %d %d %d %d %d %d %d %d %s %s %p\n", 3665 dims, texture, level, 3666 xoffset, yoffset, zoffset, width, height, depth, 3667 _mesa_enum_to_string(format), 3668 _mesa_enum_to_string(type), pixels); 3669 3670 /* Get the texture object by Name. */ 3671 if (!no_error) { 3672 if (!ext_dsa) { 3673 texObj = _mesa_lookup_texture_err(ctx, texture, callerName); 3674 } else { 3675 texObj = lookup_texture_ext_dsa(ctx, target, texture, callerName); 3676 } 3677 if (!texObj) 3678 return; 3679 } else { 3680 texObj = _mesa_lookup_texture(ctx, texture); 3681 } 3682 3683 if (!no_error) { 3684 /* check target (proxies not allowed) */ 3685 if (!legal_texsubimage_target(ctx, dims, texObj->Target, true)) { 3686 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target=%s)", 3687 callerName, _mesa_enum_to_string(texObj->Target)); 3688 return; 3689 } 3690 3691 if (texsubimage_error_check(ctx, dims, texObj, texObj->Target, level, 3692 xoffset, yoffset, zoffset, 3693 width, height, depth, format, type, 3694 pixels, callerName)) { 3695 return; /* error was detected */ 3696 } 3697 } 3698 3699 /* Must handle special case GL_TEXTURE_CUBE_MAP. */ 3700 if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 3701 GLint imageStride; 3702 3703 /* 3704 * What do we do if the user created a texture with the following code 3705 * and then called this function with its handle? 3706 * 3707 * GLuint tex; 3708 * glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &tex); 3709 * glBindTexture(GL_TEXTURE_CUBE_MAP, tex); 3710 * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ...); 3711 * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ...); 3712 * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ...); 3713 * // Note: GL_TEXTURE_CUBE_MAP_NEGATIVE_Y not set, or given the 3714 * // wrong format, or given the wrong size, etc. 3715 * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ...); 3716 * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ...); 3717 * 3718 * A bug has been filed against the spec for this case. In the 3719 * meantime, we will check for cube completeness. 3720 * 3721 * According to Section 8.17 Texture Completeness in the OpenGL 4.5 3722 * Core Profile spec (30.10.2014): 3723 * "[A] cube map texture is cube complete if the 3724 * following conditions all hold true: The [base level] texture 3725 * images of each of the six cube map faces have identical, positive, 3726 * and square dimensions. The [base level] images were each specified 3727 * with the same internal format." 3728 * 3729 * It seems reasonable to check for cube completeness of an arbitrary 3730 * level here so that the image data has a consistent format and size. 3731 */ 3732 if (!no_error && !_mesa_cube_level_complete(texObj, level)) { 3733 _mesa_error(ctx, GL_INVALID_OPERATION, 3734 "glTextureSubImage%uD(cube map incomplete)", 3735 dims); 3736 return; 3737 } 3738 3739 imageStride = _mesa_image_image_stride(&ctx->Unpack, width, height, 3740 format, type); 3741 /* Copy in each face. */ 3742 for (i = zoffset; i < zoffset + depth; ++i) { 3743 texImage = texObj->Image[i][level]; 3744 assert(texImage); 3745 3746 texture_sub_image(ctx, 3, texObj, texImage, texObj->Target, 3747 level, xoffset, yoffset, 0, 3748 width, height, 1, format, 3749 type, pixels); 3750 pixels = (GLubyte *) pixels + imageStride; 3751 } 3752 } 3753 else { 3754 texImage = _mesa_select_tex_image(texObj, texObj->Target, level); 3755 assert(texImage); 3756 3757 texture_sub_image(ctx, dims, texObj, texImage, texObj->Target, 3758 level, xoffset, yoffset, zoffset, 3759 width, height, depth, format, 3760 type, pixels); 3761 } 3762} 3763 3764 3765static void 3766texturesubimage_error(struct gl_context *ctx, GLuint dims, 3767 GLuint texture, GLenum target, GLint level, 3768 GLint xoffset, GLint yoffset, GLint zoffset, 3769 GLsizei width, GLsizei height, GLsizei depth, 3770 GLenum format, GLenum type, const GLvoid *pixels, 3771 const char *callerName, bool ext_dsa) 3772{ 3773 texturesubimage(ctx, dims, texture, target, level, xoffset, yoffset, 3774 zoffset, width, height, depth, format, type, pixels, 3775 callerName, false, ext_dsa); 3776} 3777 3778 3779static void 3780texturesubimage_no_error(struct gl_context *ctx, GLuint dims, 3781 GLuint texture, GLenum target, GLint level, 3782 GLint xoffset, GLint yoffset, GLint zoffset, 3783 GLsizei width, GLsizei height, GLsizei depth, 3784 GLenum format, GLenum type, const GLvoid *pixels, 3785 const char *callerName, bool ext_dsa) 3786{ 3787 texturesubimage(ctx, dims, texture, target, level, xoffset, yoffset, 3788 zoffset, width, height, depth, format, type, pixels, 3789 callerName, true, ext_dsa); 3790} 3791 3792 3793void GLAPIENTRY 3794_mesa_TexSubImage1D_no_error(GLenum target, GLint level, 3795 GLint xoffset, GLsizei width, 3796 GLenum format, GLenum type, 3797 const GLvoid *pixels) 3798{ 3799 GET_CURRENT_CONTEXT(ctx); 3800 texsubimage(ctx, 1, target, level, 3801 xoffset, 0, 0, 3802 width, 1, 1, 3803 format, type, pixels); 3804} 3805 3806 3807void GLAPIENTRY 3808_mesa_TexSubImage1D( GLenum target, GLint level, 3809 GLint xoffset, GLsizei width, 3810 GLenum format, GLenum type, 3811 const GLvoid *pixels ) 3812{ 3813 GET_CURRENT_CONTEXT(ctx); 3814 texsubimage_err(ctx, 1, target, level, 3815 xoffset, 0, 0, 3816 width, 1, 1, 3817 format, type, pixels, "glTexSubImage1D"); 3818} 3819 3820 3821void GLAPIENTRY 3822_mesa_TexSubImage2D_no_error(GLenum target, GLint level, 3823 GLint xoffset, GLint yoffset, 3824 GLsizei width, GLsizei height, 3825 GLenum format, GLenum type, 3826 const GLvoid *pixels) 3827{ 3828 GET_CURRENT_CONTEXT(ctx); 3829 texsubimage(ctx, 2, target, level, 3830 xoffset, yoffset, 0, 3831 width, height, 1, 3832 format, type, pixels); 3833} 3834 3835 3836void GLAPIENTRY 3837_mesa_TexSubImage2D( GLenum target, GLint level, 3838 GLint xoffset, GLint yoffset, 3839 GLsizei width, GLsizei height, 3840 GLenum format, GLenum type, 3841 const GLvoid *pixels ) 3842{ 3843 GET_CURRENT_CONTEXT(ctx); 3844 texsubimage_err(ctx, 2, target, level, 3845 xoffset, yoffset, 0, 3846 width, height, 1, 3847 format, type, pixels, "glTexSubImage2D"); 3848} 3849 3850 3851void GLAPIENTRY 3852_mesa_TexSubImage3D_no_error(GLenum target, GLint level, 3853 GLint xoffset, GLint yoffset, GLint zoffset, 3854 GLsizei width, GLsizei height, GLsizei depth, 3855 GLenum format, GLenum type, 3856 const GLvoid *pixels) 3857{ 3858 GET_CURRENT_CONTEXT(ctx); 3859 texsubimage(ctx, 3, target, level, 3860 xoffset, yoffset, zoffset, 3861 width, height, depth, 3862 format, type, pixels); 3863} 3864 3865 3866void GLAPIENTRY 3867_mesa_TexSubImage3D( GLenum target, GLint level, 3868 GLint xoffset, GLint yoffset, GLint zoffset, 3869 GLsizei width, GLsizei height, GLsizei depth, 3870 GLenum format, GLenum type, 3871 const GLvoid *pixels ) 3872{ 3873 GET_CURRENT_CONTEXT(ctx); 3874 texsubimage_err(ctx, 3, target, level, 3875 xoffset, yoffset, zoffset, 3876 width, height, depth, 3877 format, type, pixels, "glTexSubImage3D"); 3878} 3879 3880 3881void GLAPIENTRY 3882_mesa_TextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset, 3883 GLsizei width, GLenum format, GLenum type, 3884 const GLvoid *pixels) 3885{ 3886 GET_CURRENT_CONTEXT(ctx); 3887 texturesubimage_no_error(ctx, 1, texture, 0, level, xoffset, 0, 0, width, 3888 1, 1, format, type, pixels, "glTextureSubImage1D", 3889 false); 3890} 3891 3892 3893void GLAPIENTRY 3894_mesa_TextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, 3895 GLint xoffset, GLsizei width, 3896 GLenum format, GLenum type, 3897 const GLvoid *pixels) 3898{ 3899 GET_CURRENT_CONTEXT(ctx); 3900 texturesubimage_error(ctx, 1, texture, target, level, xoffset, 0, 0, width, 1, 3901 1, format, type, pixels, "glTextureSubImage1DEXT", 3902 false); 3903} 3904 3905 3906void GLAPIENTRY 3907_mesa_MultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, 3908 GLint xoffset, GLsizei width, 3909 GLenum format, GLenum type, 3910 const GLvoid *pixels) 3911{ 3912 GET_CURRENT_CONTEXT(ctx); 3913 struct gl_texture_object *texObj; 3914 struct gl_texture_image *texImage; 3915 3916 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 3917 texunit - GL_TEXTURE0, 3918 false, 3919 "glMultiTexImage1DEXT"); 3920 texImage = _mesa_select_tex_image(texObj, target, level); 3921 3922 texture_sub_image(ctx, 1, texObj, texImage, target, level, 3923 xoffset, 0, 0, width, 1, 1, 3924 format, type, pixels); 3925} 3926 3927 3928void GLAPIENTRY 3929_mesa_TextureSubImage1D(GLuint texture, GLint level, 3930 GLint xoffset, GLsizei width, 3931 GLenum format, GLenum type, 3932 const GLvoid *pixels) 3933{ 3934 GET_CURRENT_CONTEXT(ctx); 3935 texturesubimage_error(ctx, 1, texture, 0, level, xoffset, 0, 0, width, 1, 3936 1, format, type, pixels, "glTextureSubImage1D", 3937 false); 3938} 3939 3940 3941void GLAPIENTRY 3942_mesa_TextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset, 3943 GLint yoffset, GLsizei width, GLsizei height, 3944 GLenum format, GLenum type, 3945 const GLvoid *pixels) 3946{ 3947 GET_CURRENT_CONTEXT(ctx); 3948 texturesubimage_no_error(ctx, 2, texture, 0, level, xoffset, yoffset, 0, 3949 width, height, 1, format, type, pixels, 3950 "glTextureSubImage2D", false); 3951} 3952 3953 3954void GLAPIENTRY 3955_mesa_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, 3956 GLint xoffset, GLint yoffset, GLsizei width, 3957 GLsizei height, GLenum format, GLenum type, 3958 const GLvoid *pixels) 3959{ 3960 GET_CURRENT_CONTEXT(ctx); 3961 texturesubimage_error(ctx, 2, texture, target, level, xoffset, yoffset, 0, 3962 width, height, 1, format, type, pixels, 3963 "glTextureSubImage2DEXT", true); 3964} 3965 3966 3967void GLAPIENTRY 3968_mesa_MultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, 3969 GLint xoffset, GLint yoffset, GLsizei width, 3970 GLsizei height, GLenum format, GLenum type, 3971 const GLvoid *pixels) 3972{ 3973 GET_CURRENT_CONTEXT(ctx); 3974 struct gl_texture_object *texObj; 3975 struct gl_texture_image *texImage; 3976 3977 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 3978 texunit - GL_TEXTURE0, 3979 false, 3980 "glMultiTexImage2DEXT"); 3981 texImage = _mesa_select_tex_image(texObj, target, level); 3982 3983 texture_sub_image(ctx, 2, texObj, texImage, target, level, 3984 xoffset, yoffset, 0, width, height, 1, 3985 format, type, pixels); 3986} 3987 3988 3989void GLAPIENTRY 3990_mesa_TextureSubImage2D(GLuint texture, GLint level, 3991 GLint xoffset, GLint yoffset, 3992 GLsizei width, GLsizei height, 3993 GLenum format, GLenum type, 3994 const GLvoid *pixels) 3995{ 3996 GET_CURRENT_CONTEXT(ctx); 3997 texturesubimage_error(ctx, 2, texture, 0, level, xoffset, yoffset, 0, 3998 width, height, 1, format, type, pixels, 3999 "glTextureSubImage2D", false); 4000} 4001 4002 4003void GLAPIENTRY 4004_mesa_TextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset, 4005 GLint yoffset, GLint zoffset, GLsizei width, 4006 GLsizei height, GLsizei depth, GLenum format, 4007 GLenum type, const GLvoid *pixels) 4008{ 4009 GET_CURRENT_CONTEXT(ctx); 4010 texturesubimage_no_error(ctx, 3, texture, 0, level, xoffset, yoffset, 4011 zoffset, width, height, depth, format, type, 4012 pixels, "glTextureSubImage3D", false); 4013} 4014 4015 4016void GLAPIENTRY 4017_mesa_TextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, 4018 GLint xoffset, GLint yoffset, GLint zoffset, 4019 GLsizei width, GLsizei height, GLsizei depth, 4020 GLenum format, GLenum type, const GLvoid *pixels) 4021{ 4022 GET_CURRENT_CONTEXT(ctx); 4023 texturesubimage_error(ctx, 3, texture, target, level, xoffset, yoffset, 4024 zoffset, width, height, depth, format, type, 4025 pixels, "glTextureSubImage3DEXT", true); 4026} 4027 4028 4029void GLAPIENTRY 4030_mesa_MultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, 4031 GLint xoffset, GLint yoffset, GLint zoffset, 4032 GLsizei width, GLsizei height, GLsizei depth, 4033 GLenum format, GLenum type, const GLvoid *pixels) 4034{ 4035 GET_CURRENT_CONTEXT(ctx); 4036 struct gl_texture_object *texObj; 4037 struct gl_texture_image *texImage; 4038 4039 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 4040 texunit - GL_TEXTURE0, 4041 false, 4042 "glMultiTexImage3DEXT"); 4043 texImage = _mesa_select_tex_image(texObj, target, level); 4044 4045 texture_sub_image(ctx, 3, texObj, texImage, target, level, 4046 xoffset, yoffset, zoffset, width, height, depth, 4047 format, type, pixels); 4048} 4049 4050 4051void GLAPIENTRY 4052_mesa_TextureSubImage3D(GLuint texture, GLint level, 4053 GLint xoffset, GLint yoffset, GLint zoffset, 4054 GLsizei width, GLsizei height, GLsizei depth, 4055 GLenum format, GLenum type, 4056 const GLvoid *pixels) 4057{ 4058 GET_CURRENT_CONTEXT(ctx); 4059 texturesubimage_error(ctx, 3, texture, 0, level, xoffset, yoffset, zoffset, 4060 width, height, depth, format, type, pixels, 4061 "glTextureSubImage3D", false); 4062} 4063 4064 4065/** 4066 * For glCopyTexSubImage, return the source renderbuffer to copy texel data 4067 * from. This depends on whether the texture contains color or depth values. 4068 */ 4069static struct gl_renderbuffer * 4070get_copy_tex_image_source(struct gl_context *ctx, mesa_format texFormat) 4071{ 4072 if (_mesa_get_format_bits(texFormat, GL_DEPTH_BITS) > 0) { 4073 /* reading from depth/stencil buffer */ 4074 return ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 4075 } else if (_mesa_get_format_bits(texFormat, GL_STENCIL_BITS) > 0) { 4076 return ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; 4077 } else { 4078 /* copying from color buffer */ 4079 return ctx->ReadBuffer->_ColorReadBuffer; 4080 } 4081} 4082 4083 4084static void 4085copytexsubimage_by_slice(struct gl_context *ctx, 4086 struct gl_texture_image *texImage, 4087 GLuint dims, 4088 GLint xoffset, GLint yoffset, GLint zoffset, 4089 struct gl_renderbuffer *rb, 4090 GLint x, GLint y, 4091 GLsizei width, GLsizei height) 4092{ 4093 if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { 4094 int slice; 4095 4096 /* For 1D arrays, we copy each scanline of the source rectangle into the 4097 * next array slice. 4098 */ 4099 assert(zoffset == 0); 4100 4101 for (slice = 0; slice < height; slice++) { 4102 assert(yoffset + slice < texImage->Height); 4103 st_CopyTexSubImage(ctx, 2, texImage, 4104 xoffset, 0, yoffset + slice, 4105 rb, x, y + slice, width, 1); 4106 } 4107 } else { 4108 st_CopyTexSubImage(ctx, dims, texImage, 4109 xoffset, yoffset, zoffset, 4110 rb, x, y, width, height); 4111 } 4112} 4113 4114 4115static GLboolean 4116formats_differ_in_component_sizes(mesa_format f1, mesa_format f2) 4117{ 4118 GLint f1_r_bits = _mesa_get_format_bits(f1, GL_RED_BITS); 4119 GLint f1_g_bits = _mesa_get_format_bits(f1, GL_GREEN_BITS); 4120 GLint f1_b_bits = _mesa_get_format_bits(f1, GL_BLUE_BITS); 4121 GLint f1_a_bits = _mesa_get_format_bits(f1, GL_ALPHA_BITS); 4122 4123 GLint f2_r_bits = _mesa_get_format_bits(f2, GL_RED_BITS); 4124 GLint f2_g_bits = _mesa_get_format_bits(f2, GL_GREEN_BITS); 4125 GLint f2_b_bits = _mesa_get_format_bits(f2, GL_BLUE_BITS); 4126 GLint f2_a_bits = _mesa_get_format_bits(f2, GL_ALPHA_BITS); 4127 4128 if ((f1_r_bits && f2_r_bits && f1_r_bits != f2_r_bits) 4129 || (f1_g_bits && f2_g_bits && f1_g_bits != f2_g_bits) 4130 || (f1_b_bits && f2_b_bits && f1_b_bits != f2_b_bits) 4131 || (f1_a_bits && f2_a_bits && f1_a_bits != f2_a_bits)) 4132 return GL_TRUE; 4133 4134 return GL_FALSE; 4135} 4136 4137 4138/** 4139 * Check if the given texture format and size arguments match those 4140 * of the texture image. 4141 * \param return true if arguments match, false otherwise. 4142 */ 4143static bool 4144can_avoid_reallocation(const struct gl_texture_image *texImage, 4145 GLenum internalFormat, 4146 mesa_format texFormat, GLsizei width, 4147 GLsizei height, GLint border) 4148{ 4149 if (texImage->InternalFormat != internalFormat) 4150 return false; 4151 if (texImage->TexFormat != texFormat) 4152 return false; 4153 if (texImage->Border != border) 4154 return false; 4155 if (texImage->Width2 != width) 4156 return false; 4157 if (texImage->Height2 != height) 4158 return false; 4159 return true; 4160} 4161 4162 4163/** 4164 * Implementation for glCopyTex(ture)SubImage1/2/3D() functions. 4165 */ 4166static void 4167copy_texture_sub_image(struct gl_context *ctx, GLuint dims, 4168 struct gl_texture_object *texObj, 4169 GLenum target, GLint level, 4170 GLint xoffset, GLint yoffset, GLint zoffset, 4171 GLint x, GLint y, GLsizei width, GLsizei height) 4172{ 4173 struct gl_texture_image *texImage; 4174 4175 _mesa_lock_texture(ctx, texObj); 4176 4177 texImage = _mesa_select_tex_image(texObj, target, level); 4178 4179 /* If we have a border, offset=-1 is legal. Bias by border width. */ 4180 switch (dims) { 4181 case 3: 4182 if (target != GL_TEXTURE_2D_ARRAY) 4183 zoffset += texImage->Border; 4184 FALLTHROUGH; 4185 case 2: 4186 if (target != GL_TEXTURE_1D_ARRAY) 4187 yoffset += texImage->Border; 4188 FALLTHROUGH; 4189 case 1: 4190 xoffset += texImage->Border; 4191 } 4192 4193 if (ctx->Const.NoClippingOnCopyTex || 4194 _mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, 4195 &width, &height)) { 4196 struct gl_renderbuffer *srcRb = 4197 get_copy_tex_image_source(ctx, texImage->TexFormat); 4198 4199 copytexsubimage_by_slice(ctx, texImage, dims, xoffset, yoffset, zoffset, 4200 srcRb, x, y, width, height); 4201 4202 check_gen_mipmap(ctx, target, texObj, level); 4203 4204 /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed 4205 * the texel data, not the texture format, size, etc. 4206 */ 4207 } 4208 4209 _mesa_unlock_texture(ctx, texObj); 4210} 4211 4212 4213static void 4214copy_texture_sub_image_err(struct gl_context *ctx, GLuint dims, 4215 struct gl_texture_object *texObj, 4216 GLenum target, GLint level, 4217 GLint xoffset, GLint yoffset, GLint zoffset, 4218 GLint x, GLint y, GLsizei width, GLsizei height, 4219 const char *caller) 4220{ 4221 FLUSH_VERTICES(ctx, 0, 0); 4222 4223 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 4224 _mesa_debug(ctx, "%s %s %d %d %d %d %d %d %d %d\n", caller, 4225 _mesa_enum_to_string(target), 4226 level, xoffset, yoffset, zoffset, x, y, width, height); 4227 4228 _mesa_update_pixel(ctx); 4229 4230 if (ctx->NewState & _NEW_BUFFERS) 4231 _mesa_update_state(ctx); 4232 4233 if (copytexsubimage_error_check(ctx, dims, texObj, target, level, 4234 xoffset, yoffset, zoffset, 4235 width, height, caller)) { 4236 return; 4237 } 4238 4239 copy_texture_sub_image(ctx, dims, texObj, target, level, xoffset, yoffset, 4240 zoffset, x, y, width, height); 4241} 4242 4243 4244static void 4245copy_texture_sub_image_no_error(struct gl_context *ctx, GLuint dims, 4246 struct gl_texture_object *texObj, 4247 GLenum target, GLint level, 4248 GLint xoffset, GLint yoffset, GLint zoffset, 4249 GLint x, GLint y, GLsizei width, GLsizei height) 4250{ 4251 FLUSH_VERTICES(ctx, 0, 0); 4252 4253 _mesa_update_pixel(ctx); 4254 4255 if (ctx->NewState & _NEW_BUFFERS) 4256 _mesa_update_state(ctx); 4257 4258 copy_texture_sub_image(ctx, dims, texObj, target, level, xoffset, yoffset, 4259 zoffset, x, y, width, height); 4260} 4261 4262 4263/** 4264 * Implement the glCopyTexImage1/2D() functions. 4265 */ 4266static ALWAYS_INLINE void 4267copyteximage(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texObj, 4268 GLenum target, GLint level, GLenum internalFormat, 4269 GLint x, GLint y, GLsizei width, GLsizei height, GLint border, 4270 bool no_error) 4271{ 4272 struct gl_texture_image *texImage; 4273 mesa_format texFormat; 4274 4275 FLUSH_VERTICES(ctx, 0, 0); 4276 4277 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 4278 _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n", 4279 dims, 4280 _mesa_enum_to_string(target), level, 4281 _mesa_enum_to_string(internalFormat), 4282 x, y, width, height, border); 4283 4284 _mesa_update_pixel(ctx); 4285 4286 if (ctx->NewState & _NEW_BUFFERS) 4287 _mesa_update_state(ctx); 4288 4289 /* check target */ 4290 if (!no_error && !legal_texsubimage_target(ctx, dims, target, false)) { 4291 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)", 4292 dims, _mesa_enum_to_string(target)); 4293 return; 4294 } 4295 4296 if (!texObj) 4297 texObj = _mesa_get_current_tex_object(ctx, target); 4298 4299 if (!no_error) { 4300 if (copytexture_error_check(ctx, dims, target, texObj, level, 4301 internalFormat, border)) 4302 return; 4303 4304 if (!_mesa_legal_texture_dimensions(ctx, target, level, width, height, 4305 1, border)) { 4306 _mesa_error(ctx, GL_INVALID_VALUE, 4307 "glCopyTexImage%uD(invalid width=%d or height=%d)", 4308 dims, width, height); 4309 return; 4310 } 4311 } 4312 4313 assert(texObj); 4314 4315 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 4316 internalFormat, GL_NONE, GL_NONE); 4317 4318 /* First check if reallocating the texture buffer can be avoided. 4319 * Without the realloc the copy can be 20x faster. 4320 */ 4321 _mesa_lock_texture(ctx, texObj); 4322 { 4323 texImage = _mesa_select_tex_image(texObj, target, level); 4324 if (texImage && can_avoid_reallocation(texImage, internalFormat, texFormat, 4325 width, height, border)) { 4326 _mesa_unlock_texture(ctx, texObj); 4327 if (no_error) { 4328 copy_texture_sub_image_no_error(ctx, dims, texObj, target, level, 0, 4329 0, 0, x, y, width, height); 4330 } else { 4331 copy_texture_sub_image_err(ctx, dims, texObj, target, level, 0, 0, 4332 0, x, y, width, height,"CopyTexImage"); 4333 } 4334 return; 4335 } 4336 } 4337 _mesa_unlock_texture(ctx, texObj); 4338 _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_LOW, "glCopyTexImage " 4339 "can't avoid reallocating texture storage\n"); 4340 4341 if (!no_error && _mesa_is_gles3(ctx)) { 4342 struct gl_renderbuffer *rb = 4343 _mesa_get_read_renderbuffer_for_format(ctx, internalFormat); 4344 4345 if (_mesa_is_enum_format_unsized(internalFormat)) { 4346 /* Conversion from GL_RGB10_A2 source buffer format is not allowed in 4347 * OpenGL ES 3.0. Khronos bug# 9807. 4348 */ 4349 if (rb->InternalFormat == GL_RGB10_A2) { 4350 _mesa_error(ctx, GL_INVALID_OPERATION, 4351 "glCopyTexImage%uD(Reading from GL_RGB10_A2 buffer" 4352 " and writing to unsized internal format)", dims); 4353 return; 4354 } 4355 } 4356 /* From Page 139 of OpenGL ES 3.0 spec: 4357 * "If internalformat is sized, the internal format of the new texel 4358 * array is internalformat, and this is also the new texel array’s 4359 * effective internal format. If the component sizes of internalformat 4360 * do not exactly match the corresponding component sizes of the source 4361 * buffer’s effective internal format, described below, an 4362 * INVALID_OPERATION error is generated. If internalformat is unsized, 4363 * the internal format of the new texel array is the effective internal 4364 * format of the source buffer, and this is also the new texel array’s 4365 * effective internal format. 4366 */ 4367 else if (formats_differ_in_component_sizes (texFormat, rb->Format)) { 4368 _mesa_error(ctx, GL_INVALID_OPERATION, 4369 "glCopyTexImage%uD(component size changed in" 4370 " internal format)", dims); 4371 return; 4372 } 4373 } 4374 4375 assert(texFormat != MESA_FORMAT_NONE); 4376 4377 if (!st_TestProxyTexImage(ctx, proxy_target(target), 4378 0, level, texFormat, 1, 4379 width, height, 1)) { 4380 _mesa_error(ctx, GL_OUT_OF_MEMORY, 4381 "glCopyTexImage%uD(image too large)", dims); 4382 return; 4383 } 4384 4385 if (border) { 4386 x += border; 4387 width -= border * 2; 4388 if (dims == 2) { 4389 y += border; 4390 height -= border * 2; 4391 } 4392 border = 0; 4393 } 4394 4395 _mesa_lock_texture(ctx, texObj); 4396 { 4397 texObj->External = GL_FALSE; 4398 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 4399 4400 if (!texImage) { 4401 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); 4402 } 4403 else { 4404 GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0; 4405 const GLuint face = _mesa_tex_target_to_face(target); 4406 4407 /* Free old texture image */ 4408 st_FreeTextureImageBuffer(ctx, texImage); 4409 4410 _mesa_init_teximage_fields(ctx, texImage, width, height, 1, 4411 border, internalFormat, texFormat); 4412 4413 if (width && height) { 4414 /* Allocate texture memory (no pixel data yet) */ 4415 st_AllocTextureImageBuffer(ctx, texImage); 4416 4417 if (ctx->Const.NoClippingOnCopyTex || 4418 _mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY, 4419 &width, &height)) { 4420 struct gl_renderbuffer *srcRb = 4421 get_copy_tex_image_source(ctx, texImage->TexFormat); 4422 4423 copytexsubimage_by_slice(ctx, texImage, dims, 4424 dstX, dstY, dstZ, 4425 srcRb, srcX, srcY, width, height); 4426 } 4427 4428 check_gen_mipmap(ctx, target, texObj, level); 4429 } 4430 4431 _mesa_update_fbo_texture(ctx, texObj, face, level); 4432 4433 _mesa_dirty_texobj(ctx, texObj); 4434 } 4435 } 4436 _mesa_unlock_texture(ctx, texObj); 4437} 4438 4439 4440static void 4441copyteximage_err(struct gl_context *ctx, GLuint dims, 4442 GLenum target, 4443 GLint level, GLenum internalFormat, GLint x, GLint y, 4444 GLsizei width, GLsizei height, GLint border) 4445{ 4446 copyteximage(ctx, dims, NULL, target, level, internalFormat, x, y, width, height, 4447 border, false); 4448} 4449 4450 4451static void 4452copyteximage_no_error(struct gl_context *ctx, GLuint dims, GLenum target, 4453 GLint level, GLenum internalFormat, GLint x, GLint y, 4454 GLsizei width, GLsizei height, GLint border) 4455{ 4456 copyteximage(ctx, dims, NULL, target, level, internalFormat, x, y, width, height, 4457 border, true); 4458} 4459 4460 4461void GLAPIENTRY 4462_mesa_CopyTexImage1D( GLenum target, GLint level, 4463 GLenum internalFormat, 4464 GLint x, GLint y, 4465 GLsizei width, GLint border ) 4466{ 4467 GET_CURRENT_CONTEXT(ctx); 4468 copyteximage_err(ctx, 1, target, level, internalFormat, x, y, width, 1, 4469 border); 4470} 4471 4472 4473void GLAPIENTRY 4474_mesa_CopyTextureImage1DEXT( GLuint texture, GLenum target, GLint level, 4475 GLenum internalFormat, 4476 GLint x, GLint y, 4477 GLsizei width, GLint border ) 4478{ 4479 GET_CURRENT_CONTEXT(ctx); 4480 struct gl_texture_object* texObj = 4481 _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 4482 "glCopyTextureImage1DEXT"); 4483 if (!texObj) 4484 return; 4485 copyteximage(ctx, 1, texObj, target, level, internalFormat, x, y, width, 1, 4486 border, false); 4487} 4488 4489 4490void GLAPIENTRY 4491_mesa_CopyMultiTexImage1DEXT( GLenum texunit, GLenum target, GLint level, 4492 GLenum internalFormat, 4493 GLint x, GLint y, 4494 GLsizei width, GLint border ) 4495{ 4496 GET_CURRENT_CONTEXT(ctx); 4497 struct gl_texture_object* texObj = 4498 _mesa_get_texobj_by_target_and_texunit(ctx, target, 4499 texunit - GL_TEXTURE0, 4500 false, 4501 "glCopyMultiTexImage1DEXT"); 4502 if (!texObj) 4503 return; 4504 copyteximage(ctx, 1, texObj, target, level, internalFormat, x, y, width, 1, 4505 border, false); 4506} 4507 4508 4509void GLAPIENTRY 4510_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, 4511 GLint x, GLint y, GLsizei width, GLsizei height, 4512 GLint border ) 4513{ 4514 GET_CURRENT_CONTEXT(ctx); 4515 copyteximage_err(ctx, 2, target, level, internalFormat, 4516 x, y, width, height, border); 4517} 4518 4519 4520void GLAPIENTRY 4521_mesa_CopyTextureImage2DEXT( GLuint texture, GLenum target, GLint level, 4522 GLenum internalFormat, 4523 GLint x, GLint y, 4524 GLsizei width, GLsizei height, 4525 GLint border ) 4526{ 4527 GET_CURRENT_CONTEXT(ctx); 4528 struct gl_texture_object* texObj = 4529 _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 4530 "glCopyTextureImage2DEXT"); 4531 if (!texObj) 4532 return; 4533 copyteximage(ctx, 2, texObj, target, level, internalFormat, x, y, width, height, 4534 border, false); 4535} 4536 4537 4538void GLAPIENTRY 4539_mesa_CopyMultiTexImage2DEXT( GLenum texunit, GLenum target, GLint level, 4540 GLenum internalFormat, 4541 GLint x, GLint y, 4542 GLsizei width, GLsizei height, GLint border ) 4543{ 4544 GET_CURRENT_CONTEXT(ctx); 4545 struct gl_texture_object* texObj = 4546 _mesa_get_texobj_by_target_and_texunit(ctx, target, 4547 texunit - GL_TEXTURE0, 4548 false, 4549 "glCopyMultiTexImage2DEXT"); 4550 if (!texObj) 4551 return; 4552 copyteximage(ctx, 2, texObj, target, level, internalFormat, x, y, width, height, 4553 border, false); 4554} 4555 4556 4557void GLAPIENTRY 4558_mesa_CopyTexImage1D_no_error(GLenum target, GLint level, GLenum internalFormat, 4559 GLint x, GLint y, GLsizei width, GLint border) 4560{ 4561 GET_CURRENT_CONTEXT(ctx); 4562 copyteximage_no_error(ctx, 1, target, level, internalFormat, x, y, width, 1, 4563 border); 4564} 4565 4566 4567void GLAPIENTRY 4568_mesa_CopyTexImage2D_no_error(GLenum target, GLint level, GLenum internalFormat, 4569 GLint x, GLint y, GLsizei width, GLsizei height, 4570 GLint border) 4571{ 4572 GET_CURRENT_CONTEXT(ctx); 4573 copyteximage_no_error(ctx, 2, target, level, internalFormat, 4574 x, y, width, height, border); 4575} 4576 4577 4578void GLAPIENTRY 4579_mesa_CopyTexSubImage1D(GLenum target, GLint level, 4580 GLint xoffset, GLint x, GLint y, GLsizei width) 4581{ 4582 struct gl_texture_object* texObj; 4583 const char *self = "glCopyTexSubImage1D"; 4584 GET_CURRENT_CONTEXT(ctx); 4585 4586 /* Check target (proxies not allowed). Target must be checked prior to 4587 * calling _mesa_get_current_tex_object. 4588 */ 4589 if (!legal_texsubimage_target(ctx, 1, target, false)) { 4590 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self, 4591 _mesa_enum_to_string(target)); 4592 return; 4593 } 4594 4595 texObj = _mesa_get_current_tex_object(ctx, target); 4596 if (!texObj) 4597 return; 4598 4599 copy_texture_sub_image_err(ctx, 1, texObj, target, level, xoffset, 0, 0, 4600 x, y, width, 1, self); 4601} 4602 4603 4604void GLAPIENTRY 4605_mesa_CopyTexSubImage2D(GLenum target, GLint level, 4606 GLint xoffset, GLint yoffset, 4607 GLint x, GLint y, GLsizei width, GLsizei height) 4608{ 4609 struct gl_texture_object* texObj; 4610 const char *self = "glCopyTexSubImage2D"; 4611 GET_CURRENT_CONTEXT(ctx); 4612 4613 /* Check target (proxies not allowed). Target must be checked prior to 4614 * calling _mesa_get_current_tex_object. 4615 */ 4616 if (!legal_texsubimage_target(ctx, 2, target, false)) { 4617 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self, 4618 _mesa_enum_to_string(target)); 4619 return; 4620 } 4621 4622 texObj = _mesa_get_current_tex_object(ctx, target); 4623 if (!texObj) 4624 return; 4625 4626 copy_texture_sub_image_err(ctx, 2, texObj, target, level, xoffset, yoffset, 4627 0, x, y, width, height, self); 4628} 4629 4630 4631void GLAPIENTRY 4632_mesa_CopyTexSubImage3D(GLenum target, GLint level, 4633 GLint xoffset, GLint yoffset, GLint zoffset, 4634 GLint x, GLint y, GLsizei width, GLsizei height) 4635{ 4636 struct gl_texture_object* texObj; 4637 const char *self = "glCopyTexSubImage3D"; 4638 GET_CURRENT_CONTEXT(ctx); 4639 4640 /* Check target (proxies not allowed). Target must be checked prior to 4641 * calling _mesa_get_current_tex_object. 4642 */ 4643 if (!legal_texsubimage_target(ctx, 3, target, false)) { 4644 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self, 4645 _mesa_enum_to_string(target)); 4646 return; 4647 } 4648 4649 texObj = _mesa_get_current_tex_object(ctx, target); 4650 if (!texObj) 4651 return; 4652 4653 copy_texture_sub_image_err(ctx, 3, texObj, target, level, xoffset, yoffset, 4654 zoffset, x, y, width, height, self); 4655} 4656 4657 4658void GLAPIENTRY 4659_mesa_CopyTextureSubImage1D(GLuint texture, GLint level, 4660 GLint xoffset, GLint x, GLint y, GLsizei width) 4661{ 4662 struct gl_texture_object* texObj; 4663 const char *self = "glCopyTextureSubImage1D"; 4664 GET_CURRENT_CONTEXT(ctx); 4665 4666 texObj = _mesa_lookup_texture_err(ctx, texture, self); 4667 if (!texObj) 4668 return; 4669 4670 /* Check target (proxies not allowed). */ 4671 if (!legal_texsubimage_target(ctx, 1, texObj->Target, true)) { 4672 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, 4673 _mesa_enum_to_string(texObj->Target)); 4674 return; 4675 } 4676 4677 copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0, 4678 0, x, y, width, 1, self); 4679} 4680 4681 4682void GLAPIENTRY 4683_mesa_CopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, 4684 GLint xoffset, GLint x, GLint y, GLsizei width) 4685{ 4686 struct gl_texture_object* texObj; 4687 const char *self = "glCopyTextureSubImage1DEXT"; 4688 GET_CURRENT_CONTEXT(ctx); 4689 4690 texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 4691 self); 4692 if (!texObj) 4693 return; 4694 4695 /* Check target (proxies not allowed). */ 4696 if (!legal_texsubimage_target(ctx, 1, texObj->Target, true)) { 4697 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, 4698 _mesa_enum_to_string(texObj->Target)); 4699 return; 4700 } 4701 4702 copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0, 4703 0, x, y, width, 1, self); 4704} 4705 4706 4707void GLAPIENTRY 4708_mesa_CopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, 4709 GLint xoffset, GLint x, GLint y, GLsizei width) 4710{ 4711 struct gl_texture_object* texObj; 4712 const char *self = "glCopyMultiTexSubImage1DEXT"; 4713 GET_CURRENT_CONTEXT(ctx); 4714 4715 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 4716 texunit - GL_TEXTURE0, 4717 false, self); 4718 if (!texObj) 4719 return; 4720 4721 copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0, 4722 0, x, y, width, 1, self); 4723} 4724 4725 4726void GLAPIENTRY 4727_mesa_CopyTextureSubImage2D(GLuint texture, GLint level, 4728 GLint xoffset, GLint yoffset, 4729 GLint x, GLint y, GLsizei width, GLsizei height) 4730{ 4731 struct gl_texture_object* texObj; 4732 const char *self = "glCopyTextureSubImage2D"; 4733 GET_CURRENT_CONTEXT(ctx); 4734 4735 texObj = _mesa_lookup_texture_err(ctx, texture, self); 4736 if (!texObj) 4737 return; 4738 4739 /* Check target (proxies not allowed). */ 4740 if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) { 4741 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, 4742 _mesa_enum_to_string(texObj->Target)); 4743 return; 4744 } 4745 4746 copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset, 4747 yoffset, 0, x, y, width, height, self); 4748} 4749 4750 4751void GLAPIENTRY 4752_mesa_CopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, 4753 GLint xoffset, GLint yoffset, 4754 GLint x, GLint y, GLsizei width, GLsizei height) 4755{ 4756 struct gl_texture_object* texObj; 4757 const char *self = "glCopyTextureSubImage2DEXT"; 4758 GET_CURRENT_CONTEXT(ctx); 4759 4760 texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, self); 4761 if (!texObj) 4762 return; 4763 4764 /* Check target (proxies not allowed). */ 4765 if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) { 4766 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, 4767 _mesa_enum_to_string(texObj->Target)); 4768 return; 4769 } 4770 4771 copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset, 4772 yoffset, 0, x, y, width, height, self); 4773} 4774 4775 4776void GLAPIENTRY 4777_mesa_CopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, 4778 GLint xoffset, GLint yoffset, 4779 GLint x, GLint y, GLsizei width, GLsizei height) 4780{ 4781 struct gl_texture_object* texObj; 4782 const char *self = "glCopyMultiTexSubImage2DEXT"; 4783 GET_CURRENT_CONTEXT(ctx); 4784 4785 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 4786 texunit - GL_TEXTURE0, 4787 false, self); 4788 if (!texObj) 4789 return; 4790 4791 copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset, 4792 yoffset, 0, x, y, width, height, self); 4793} 4794 4795void GLAPIENTRY 4796_mesa_CopyTextureSubImage3D(GLuint texture, GLint level, 4797 GLint xoffset, GLint yoffset, GLint zoffset, 4798 GLint x, GLint y, GLsizei width, GLsizei height) 4799{ 4800 struct gl_texture_object* texObj; 4801 const char *self = "glCopyTextureSubImage3D"; 4802 GET_CURRENT_CONTEXT(ctx); 4803 4804 texObj = _mesa_lookup_texture_err(ctx, texture, self); 4805 if (!texObj) 4806 return; 4807 4808 /* Check target (proxies not allowed). */ 4809 if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) { 4810 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, 4811 _mesa_enum_to_string(texObj->Target)); 4812 return; 4813 } 4814 4815 if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 4816 /* Act like CopyTexSubImage2D */ 4817 copy_texture_sub_image_err(ctx, 2, texObj, 4818 GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, 4819 level, xoffset, yoffset, 0, x, y, width, height, 4820 self); 4821 } 4822 else 4823 copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset, 4824 yoffset, zoffset, x, y, width, height, self); 4825} 4826 4827 4828void GLAPIENTRY 4829_mesa_CopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, 4830 GLint xoffset, GLint yoffset, GLint zoffset, 4831 GLint x, GLint y, GLsizei width, GLsizei height) 4832{ 4833 struct gl_texture_object* texObj; 4834 const char *self = "glCopyTextureSubImage3D"; 4835 GET_CURRENT_CONTEXT(ctx); 4836 4837 texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, self); 4838 if (!texObj) 4839 return; 4840 4841 /* Check target (proxies not allowed). */ 4842 if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) { 4843 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self, 4844 _mesa_enum_to_string(texObj->Target)); 4845 return; 4846 } 4847 4848 if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 4849 /* Act like CopyTexSubImage2D */ 4850 copy_texture_sub_image_err(ctx, 2, texObj, 4851 GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, 4852 level, xoffset, yoffset, 0, x, y, width, height, 4853 self); 4854 } 4855 else 4856 copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset, 4857 yoffset, zoffset, x, y, width, height, self); 4858} 4859 4860 4861void GLAPIENTRY 4862_mesa_CopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, 4863 GLint xoffset, GLint yoffset, GLint zoffset, 4864 GLint x, GLint y, GLsizei width, GLsizei height) 4865{ 4866 struct gl_texture_object* texObj; 4867 const char *self = "glCopyMultiTexSubImage3D"; 4868 GET_CURRENT_CONTEXT(ctx); 4869 4870 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 4871 texunit - GL_TEXTURE0, 4872 false, self); 4873 if (!texObj) 4874 return; 4875 4876 if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 4877 /* Act like CopyTexSubImage2D */ 4878 copy_texture_sub_image_err(ctx, 2, texObj, 4879 GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, 4880 level, xoffset, yoffset, 0, x, y, width, height, 4881 self); 4882 } 4883 else 4884 copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset, 4885 yoffset, zoffset, x, y, width, height, self); 4886} 4887 4888 4889void GLAPIENTRY 4890_mesa_CopyTexSubImage1D_no_error(GLenum target, GLint level, GLint xoffset, 4891 GLint x, GLint y, GLsizei width) 4892{ 4893 GET_CURRENT_CONTEXT(ctx); 4894 4895 struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target); 4896 copy_texture_sub_image_no_error(ctx, 1, texObj, target, level, xoffset, 0, 0, 4897 x, y, width, 1); 4898} 4899 4900 4901void GLAPIENTRY 4902_mesa_CopyTexSubImage2D_no_error(GLenum target, GLint level, GLint xoffset, 4903 GLint yoffset, GLint x, GLint y, GLsizei width, 4904 GLsizei height) 4905{ 4906 GET_CURRENT_CONTEXT(ctx); 4907 4908 struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target); 4909 copy_texture_sub_image_no_error(ctx, 2, texObj, target, level, xoffset, 4910 yoffset, 0, x, y, width, height); 4911} 4912 4913 4914void GLAPIENTRY 4915_mesa_CopyTexSubImage3D_no_error(GLenum target, GLint level, GLint xoffset, 4916 GLint yoffset, GLint zoffset, GLint x, GLint y, 4917 GLsizei width, GLsizei height) 4918{ 4919 GET_CURRENT_CONTEXT(ctx); 4920 4921 struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target); 4922 copy_texture_sub_image_no_error(ctx, 3, texObj, target, level, xoffset, 4923 yoffset, zoffset, x, y, width, height); 4924} 4925 4926 4927void GLAPIENTRY 4928_mesa_CopyTextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset, 4929 GLint x, GLint y, GLsizei width) 4930{ 4931 GET_CURRENT_CONTEXT(ctx); 4932 4933 struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture); 4934 copy_texture_sub_image_no_error(ctx, 1, texObj, texObj->Target, level, 4935 xoffset, 0, 0, x, y, width, 1); 4936} 4937 4938 4939void GLAPIENTRY 4940_mesa_CopyTextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset, 4941 GLint yoffset, GLint x, GLint y, 4942 GLsizei width, GLsizei height) 4943{ 4944 GET_CURRENT_CONTEXT(ctx); 4945 4946 struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture); 4947 copy_texture_sub_image_no_error(ctx, 2, texObj, texObj->Target, level, 4948 xoffset, yoffset, 0, x, y, width, height); 4949} 4950 4951 4952void GLAPIENTRY 4953_mesa_CopyTextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset, 4954 GLint yoffset, GLint zoffset, GLint x, 4955 GLint y, GLsizei width, GLsizei height) 4956{ 4957 GET_CURRENT_CONTEXT(ctx); 4958 4959 struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture); 4960 if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 4961 /* Act like CopyTexSubImage2D */ 4962 copy_texture_sub_image_no_error(ctx, 2, texObj, 4963 GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, 4964 level, xoffset, yoffset, 0, x, y, width, 4965 height); 4966 } 4967 else 4968 copy_texture_sub_image_no_error(ctx, 3, texObj, texObj->Target, level, 4969 xoffset, yoffset, zoffset, x, y, width, 4970 height); 4971} 4972 4973 4974static bool 4975check_clear_tex_image(struct gl_context *ctx, 4976 const char *function, 4977 struct gl_texture_image *texImage, 4978 GLenum format, GLenum type, 4979 const void *data, 4980 GLubyte *clearValue) 4981{ 4982 struct gl_texture_object *texObj = texImage->TexObject; 4983 static const GLubyte zeroData[MAX_PIXEL_BYTES]; 4984 GLenum internalFormat = texImage->InternalFormat; 4985 GLenum err; 4986 4987 if (texObj->Target == GL_TEXTURE_BUFFER) { 4988 _mesa_error(ctx, GL_INVALID_OPERATION, 4989 "%s(buffer texture)", function); 4990 return false; 4991 } 4992 4993 if (_mesa_is_compressed_format(ctx, internalFormat)) { 4994 _mesa_error(ctx, GL_INVALID_OPERATION, 4995 "%s(compressed texture)", function); 4996 return false; 4997 } 4998 4999 err = _mesa_error_check_format_and_type(ctx, format, type); 5000 if (err != GL_NO_ERROR) { 5001 _mesa_error(ctx, err, 5002 "%s(incompatible format = %s, type = %s)", 5003 function, 5004 _mesa_enum_to_string(format), 5005 _mesa_enum_to_string(type)); 5006 return false; 5007 } 5008 5009 /* make sure internal format and format basically agree */ 5010 if (!texture_formats_agree(internalFormat, format)) { 5011 _mesa_error(ctx, GL_INVALID_OPERATION, 5012 "%s(incompatible internalFormat = %s, format = %s)", 5013 function, 5014 _mesa_enum_to_string(internalFormat), 5015 _mesa_enum_to_string(format)); 5016 return false; 5017 } 5018 5019 if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) { 5020 /* both source and dest must be integer-valued, or neither */ 5021 if (_mesa_is_format_integer_color(texImage->TexFormat) != 5022 _mesa_is_enum_format_integer(format)) { 5023 _mesa_error(ctx, GL_INVALID_OPERATION, 5024 "%s(integer/non-integer format mismatch)", 5025 function); 5026 return false; 5027 } 5028 } 5029 5030 if (!_mesa_texstore(ctx, 5031 1, /* dims */ 5032 texImage->_BaseFormat, 5033 texImage->TexFormat, 5034 0, /* dstRowStride */ 5035 &clearValue, 5036 1, 1, 1, /* srcWidth/Height/Depth */ 5037 format, type, 5038 data ? data : zeroData, 5039 &ctx->DefaultPacking)) { 5040 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid format)", function); 5041 return false; 5042 } 5043 5044 return true; 5045} 5046 5047 5048static struct gl_texture_object * 5049get_tex_obj_for_clear(struct gl_context *ctx, 5050 const char *function, 5051 GLuint texture) 5052{ 5053 struct gl_texture_object *texObj; 5054 5055 texObj = _mesa_lookup_texture_err(ctx, texture, function); 5056 if (!texObj) 5057 return NULL; 5058 5059 if (texObj->Target == 0) { 5060 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unbound tex)", function); 5061 return NULL; 5062 } 5063 5064 return texObj; 5065} 5066 5067 5068/** 5069 * For clearing cube textures, the zoffset and depth parameters indicate 5070 * which cube map faces are to be cleared. This is the one case where we 5071 * need to be concerned with multiple gl_texture_images. This function 5072 * returns the array of texture images to clear for cube maps, or one 5073 * texture image otherwise. 5074 * \return number of texture images, 0 for error, 6 for cube, 1 otherwise. 5075 */ 5076static int 5077get_tex_images_for_clear(struct gl_context *ctx, 5078 const char *function, 5079 struct gl_texture_object *texObj, 5080 GLint level, 5081 struct gl_texture_image **texImages) 5082{ 5083 GLenum target; 5084 int numFaces, i; 5085 5086 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 5087 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function); 5088 return 0; 5089 } 5090 5091 if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 5092 target = GL_TEXTURE_CUBE_MAP_POSITIVE_X; 5093 numFaces = MAX_FACES; 5094 } 5095 else { 5096 target = texObj->Target; 5097 numFaces = 1; 5098 } 5099 5100 for (i = 0; i < numFaces; i++) { 5101 texImages[i] = _mesa_select_tex_image(texObj, target + i, level); 5102 if (texImages[i] == NULL) { 5103 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function); 5104 return 0; 5105 } 5106 } 5107 5108 return numFaces; 5109} 5110 5111 5112void GLAPIENTRY 5113_mesa_ClearTexSubImage(GLuint texture, GLint level, 5114 GLint xoffset, GLint yoffset, GLint zoffset, 5115 GLsizei width, GLsizei height, GLsizei depth, 5116 GLenum format, GLenum type, const void *data) 5117{ 5118 GET_CURRENT_CONTEXT(ctx); 5119 struct gl_texture_object *texObj; 5120 struct gl_texture_image *texImages[MAX_FACES]; 5121 GLubyte clearValue[MAX_FACES][MAX_PIXEL_BYTES]; 5122 int i, numImages; 5123 int minDepth, maxDepth; 5124 5125 texObj = get_tex_obj_for_clear(ctx, "glClearTexSubImage", texture); 5126 5127 if (texObj == NULL) 5128 return; 5129 5130 _mesa_lock_texture(ctx, texObj); 5131 5132 numImages = get_tex_images_for_clear(ctx, "glClearTexSubImage", 5133 texObj, level, texImages); 5134 if (numImages == 0) 5135 goto out; 5136 5137 if (numImages == 1) { 5138 minDepth = -(int) texImages[0]->Border; 5139 maxDepth = texImages[0]->Depth; 5140 } else { 5141 assert(numImages == MAX_FACES); 5142 minDepth = 0; 5143 maxDepth = numImages; 5144 } 5145 5146 if (xoffset < -(GLint) texImages[0]->Border || 5147 yoffset < -(GLint) texImages[0]->Border || 5148 zoffset < minDepth || 5149 width < 0 || 5150 height < 0 || 5151 depth < 0 || 5152 xoffset + width > texImages[0]->Width || 5153 yoffset + height > texImages[0]->Height || 5154 zoffset + depth > maxDepth) { 5155 _mesa_error(ctx, GL_INVALID_OPERATION, 5156 "glClearSubTexImage(invalid dimensions)"); 5157 goto out; 5158 } 5159 5160 if (numImages == 1) { 5161 if (check_clear_tex_image(ctx, "glClearTexSubImage", texImages[0], 5162 format, type, data, clearValue[0])) { 5163 st_ClearTexSubImage(ctx, 5164 texImages[0], 5165 xoffset, yoffset, zoffset, 5166 width, height, depth, 5167 data ? clearValue[0] : NULL); 5168 } 5169 } else { 5170 /* loop over cube face images */ 5171 for (i = zoffset; i < zoffset + depth; i++) { 5172 assert(i < MAX_FACES); 5173 if (!check_clear_tex_image(ctx, "glClearTexSubImage", texImages[i], 5174 format, type, data, clearValue[i])) 5175 goto out; 5176 } 5177 for (i = zoffset; i < zoffset + depth; i++) { 5178 st_ClearTexSubImage(ctx, 5179 texImages[i], 5180 xoffset, yoffset, 0, 5181 width, height, 1, 5182 data ? clearValue[i] : NULL); 5183 } 5184 } 5185 5186 out: 5187 _mesa_unlock_texture(ctx, texObj); 5188} 5189 5190 5191void GLAPIENTRY 5192_mesa_ClearTexImage( GLuint texture, GLint level, 5193 GLenum format, GLenum type, const void *data ) 5194{ 5195 GET_CURRENT_CONTEXT(ctx); 5196 struct gl_texture_object *texObj; 5197 struct gl_texture_image *texImages[MAX_FACES]; 5198 GLubyte clearValue[MAX_FACES][MAX_PIXEL_BYTES]; 5199 int i, numImages; 5200 5201 texObj = get_tex_obj_for_clear(ctx, "glClearTexImage", texture); 5202 5203 if (texObj == NULL) 5204 return; 5205 5206 _mesa_lock_texture(ctx, texObj); 5207 5208 numImages = get_tex_images_for_clear(ctx, "glClearTexImage", 5209 texObj, level, texImages); 5210 5211 for (i = 0; i < numImages; i++) { 5212 if (!check_clear_tex_image(ctx, "glClearTexImage", texImages[i], format, 5213 type, data, clearValue[i])) 5214 goto out; 5215 } 5216 5217 for (i = 0; i < numImages; i++) { 5218 st_ClearTexSubImage(ctx, texImages[i], 5219 -(GLint) texImages[i]->Border, /* xoffset */ 5220 -(GLint) texImages[i]->Border, /* yoffset */ 5221 -(GLint) texImages[i]->Border, /* zoffset */ 5222 texImages[i]->Width, 5223 texImages[i]->Height, 5224 texImages[i]->Depth, 5225 data ? clearValue[i] : NULL); 5226 } 5227 5228out: 5229 _mesa_unlock_texture(ctx, texObj); 5230} 5231 5232 5233 5234 5235/**********************************************************************/ 5236/****** Compressed Textures ******/ 5237/**********************************************************************/ 5238 5239 5240/** 5241 * Target checking for glCompressedTexSubImage[123]D(). 5242 * \return GL_TRUE if error, GL_FALSE if no error 5243 * Must come before other error checking so that the texture object can 5244 * be correctly retrieved using _mesa_get_current_tex_object. 5245 */ 5246static GLboolean 5247compressed_subtexture_target_check(struct gl_context *ctx, GLenum target, 5248 GLint dims, GLenum intFormat, bool dsa, 5249 const char *caller) 5250{ 5251 GLboolean targetOK; 5252 mesa_format format; 5253 enum mesa_format_layout layout; 5254 5255 if (dsa && target == GL_TEXTURE_RECTANGLE) { 5256 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", caller, 5257 _mesa_enum_to_string(target)); 5258 return GL_TRUE; 5259 } 5260 5261 switch (dims) { 5262 case 2: 5263 switch (target) { 5264 case GL_TEXTURE_2D: 5265 targetOK = GL_TRUE; 5266 break; 5267 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 5268 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 5269 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 5270 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 5271 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 5272 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 5273 targetOK = GL_TRUE; 5274 break; 5275 default: 5276 targetOK = GL_FALSE; 5277 break; 5278 } 5279 break; 5280 case 3: 5281 switch (target) { 5282 case GL_TEXTURE_CUBE_MAP: 5283 targetOK = dsa; 5284 break; 5285 case GL_TEXTURE_2D_ARRAY: 5286 targetOK = _mesa_is_gles3(ctx) || 5287 (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array); 5288 break; 5289 case GL_TEXTURE_CUBE_MAP_ARRAY: 5290 targetOK = _mesa_has_texture_cube_map_array(ctx); 5291 break; 5292 case GL_TEXTURE_3D: 5293 targetOK = GL_TRUE; 5294 /* 5295 * OpenGL 4.5 spec (30.10.2014) says in Section 8.7 Compressed Texture 5296 * Images: 5297 * "An INVALID_OPERATION error is generated by 5298 * CompressedTex*SubImage3D if the internal format of the texture 5299 * is one of the EAC, ETC2, or RGTC formats and either border is 5300 * non-zero, or the effective target for the texture is not 5301 * TEXTURE_2D_ARRAY." 5302 * 5303 * NOTE: that's probably a spec error. It should probably say 5304 * "... or the effective target for the texture is not 5305 * TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP, nor 5306 * GL_TEXTURE_CUBE_MAP_ARRAY." 5307 * since those targets are 2D images and they support all compression 5308 * formats. 5309 * 5310 * Instead of listing all these, just list those which are allowed, 5311 * which is (at this time) only bptc. Otherwise we'd say s3tc (and 5312 * more) are valid here, which they are not, but of course not 5313 * mentioned by core spec. 5314 * 5315 * Also, from GL_KHR_texture_compression_astc_{hdr,ldr}: 5316 * 5317 * "Add a second new column "3D Tex." which is empty for all non-ASTC 5318 * formats. If only the LDR profile is supported by the implementation, 5319 * this column is also empty for all ASTC formats. If both the LDR and HDR 5320 * profiles are supported, this column is checked for all ASTC formats." 5321 * 5322 * "An INVALID_OPERATION error is generated by CompressedTexSubImage3D if 5323 * <format> is one of the formats in table 8.19 and <target> is not 5324 * TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, or TEXTURE_3D. 5325 * 5326 * An INVALID_OPERATION error is generated by CompressedTexSubImage3D if 5327 * <format> is TEXTURE_CUBE_MAP_ARRAY and the "Cube Map Array" column of 5328 * table 8.19 is *not* checked, or if <format> is TEXTURE_3D and the "3D 5329 * Tex." column of table 8.19 is *not* checked" 5330 * 5331 * And from GL_KHR_texture_compression_astc_sliced_3d: 5332 * 5333 * "Modify the "3D Tex." column to be checked for all ASTC formats." 5334 */ 5335 format = _mesa_glenum_to_compressed_format(intFormat); 5336 layout = _mesa_get_format_layout(format); 5337 switch (layout) { 5338 case MESA_FORMAT_LAYOUT_BPTC: 5339 /* valid format */ 5340 break; 5341 case MESA_FORMAT_LAYOUT_ASTC: 5342 targetOK = 5343 ctx->Extensions.KHR_texture_compression_astc_hdr || 5344 ctx->Extensions.KHR_texture_compression_astc_sliced_3d; 5345 break; 5346 default: 5347 /* invalid format */ 5348 _mesa_error(ctx, GL_INVALID_OPERATION, 5349 "%s(invalid target %s for format %s)", caller, 5350 _mesa_enum_to_string(target), 5351 _mesa_enum_to_string(intFormat)); 5352 return GL_TRUE; 5353 } 5354 break; 5355 default: 5356 targetOK = GL_FALSE; 5357 } 5358 5359 break; 5360 default: 5361 assert(dims == 1); 5362 /* no 1D compressed textures at this time */ 5363 targetOK = GL_FALSE; 5364 break; 5365 } 5366 5367 if (!targetOK) { 5368 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", caller, 5369 _mesa_enum_to_string(target)); 5370 return GL_TRUE; 5371 } 5372 5373 return GL_FALSE; 5374} 5375 5376/** 5377 * Error checking for glCompressedTexSubImage[123]D(). 5378 * \return GL_TRUE if error, GL_FALSE if no error 5379 */ 5380static GLboolean 5381compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, 5382 const struct gl_texture_object *texObj, 5383 GLenum target, GLint level, 5384 GLint xoffset, GLint yoffset, GLint zoffset, 5385 GLsizei width, GLsizei height, GLsizei depth, 5386 GLenum format, GLsizei imageSize, 5387 const GLvoid *data, const char *callerName) 5388{ 5389 struct gl_texture_image *texImage; 5390 GLint expectedSize; 5391 5392 GLenum is_generic_compressed_token = 5393 _mesa_generic_compressed_format_to_uncompressed_format(format) != 5394 format; 5395 5396 /* OpenGL 4.6 and OpenGL ES 3.2 spec: 5397 * 5398 * "An INVALID_OPERATION error is generated if format does not match the 5399 * internal format of the texture image being modified, since these commands do 5400 * not provide for image format conversion." 5401 * 5402 * Desktop spec has an additional rule for GL_INVALID_ENUM: 5403 * 5404 * "An INVALID_ENUM error is generated if format is one of the generic 5405 * compressed internal formats." 5406 */ 5407 /* this will catch any invalid compressed format token */ 5408 if (!_mesa_is_compressed_format(ctx, format)) { 5409 GLenum error = _mesa_is_desktop_gl(ctx) && is_generic_compressed_token ? 5410 GL_INVALID_ENUM : GL_INVALID_OPERATION; 5411 _mesa_error(ctx, error, "%s(format)", callerName); 5412 return GL_TRUE; 5413 } 5414 5415 if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 5416 _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", callerName, level); 5417 return GL_TRUE; 5418 } 5419 5420 /* validate the bound PBO, if any */ 5421 if (!_mesa_validate_pbo_source_compressed(ctx, dims, &ctx->Unpack, 5422 imageSize, data, callerName)) { 5423 return GL_TRUE; 5424 } 5425 5426 /* Check for invalid pixel storage modes */ 5427 if (!_mesa_compressed_pixel_storage_error_check(ctx, dims, 5428 &ctx->Unpack, callerName)) { 5429 return GL_TRUE; 5430 } 5431 5432 expectedSize = compressed_tex_size(width, height, depth, format); 5433 if (expectedSize != imageSize) { 5434 _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", callerName, imageSize); 5435 return GL_TRUE; 5436 } 5437 5438 texImage = _mesa_select_tex_image(texObj, target, level); 5439 if (!texImage) { 5440 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture level %d)", 5441 callerName, level); 5442 return GL_TRUE; 5443 } 5444 5445 if ((GLint) format != texImage->InternalFormat) { 5446 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(format=%s)", 5447 callerName, _mesa_enum_to_string(format)); 5448 return GL_TRUE; 5449 } 5450 5451 if (compressedteximage_only_format(format)) { 5452 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(format=%s cannot be updated)", 5453 callerName, _mesa_enum_to_string(format)); 5454 return GL_TRUE; 5455 } 5456 5457 if (error_check_subtexture_negative_dimensions(ctx, dims, width, height, 5458 depth, callerName)) { 5459 return GL_TRUE; 5460 } 5461 5462 if (error_check_subtexture_dimensions(ctx, dims, texImage, xoffset, yoffset, 5463 zoffset, width, height, depth, 5464 callerName)) { 5465 return GL_TRUE; 5466 } 5467 5468 return GL_FALSE; 5469} 5470 5471 5472void GLAPIENTRY 5473_mesa_CompressedTexImage1D(GLenum target, GLint level, 5474 GLenum internalFormat, GLsizei width, 5475 GLint border, GLsizei imageSize, 5476 const GLvoid *data) 5477{ 5478 GET_CURRENT_CONTEXT(ctx); 5479 teximage_err(ctx, GL_TRUE, 1, target, level, internalFormat, 5480 width, 1, 1, border, GL_NONE, GL_NONE, imageSize, data); 5481} 5482 5483 5484void GLAPIENTRY 5485_mesa_CompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, 5486 GLenum internalFormat, GLsizei width, 5487 GLint border, GLsizei imageSize, 5488 const GLvoid *pixels) 5489{ 5490 struct gl_texture_object* texObj; 5491 GET_CURRENT_CONTEXT(ctx); 5492 5493 texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 5494 "glCompressedTextureImage1DEXT"); 5495 if (!texObj) 5496 return; 5497 teximage(ctx, GL_TRUE, 1, texObj, target, level, internalFormat, 5498 width, 1, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false); 5499} 5500 5501 5502void GLAPIENTRY 5503_mesa_CompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, 5504 GLenum internalFormat, GLsizei width, 5505 GLint border, GLsizei imageSize, 5506 const GLvoid *pixels) 5507{ 5508 struct gl_texture_object* texObj; 5509 GET_CURRENT_CONTEXT(ctx); 5510 5511 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 5512 texunit - GL_TEXTURE0, 5513 true, 5514 "glCompressedMultiTexImage1DEXT"); 5515 if (!texObj) 5516 return; 5517 teximage(ctx, GL_TRUE, 1, texObj, target, level, internalFormat, 5518 width, 1, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false); 5519} 5520 5521 5522void GLAPIENTRY 5523_mesa_CompressedTexImage2D(GLenum target, GLint level, 5524 GLenum internalFormat, GLsizei width, 5525 GLsizei height, GLint border, GLsizei imageSize, 5526 const GLvoid *data) 5527{ 5528 GET_CURRENT_CONTEXT(ctx); 5529 teximage_err(ctx, GL_TRUE, 2, target, level, internalFormat, 5530 width, height, 1, border, GL_NONE, GL_NONE, imageSize, data); 5531} 5532 5533 5534void GLAPIENTRY 5535_mesa_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, 5536 GLenum internalFormat, GLsizei width, 5537 GLsizei height, GLint border, GLsizei imageSize, 5538 const GLvoid *pixels) 5539{ 5540 struct gl_texture_object* texObj; 5541 GET_CURRENT_CONTEXT(ctx); 5542 5543 texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 5544 "glCompressedTextureImage2DEXT"); 5545 if (!texObj) 5546 return; 5547 teximage(ctx, GL_TRUE, 2, texObj, target, level, internalFormat, 5548 width, height, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false); 5549} 5550 5551 5552void GLAPIENTRY 5553_mesa_CompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, 5554 GLenum internalFormat, GLsizei width, 5555 GLsizei height, GLint border, GLsizei imageSize, 5556 const GLvoid *pixels) 5557{ 5558 struct gl_texture_object* texObj; 5559 GET_CURRENT_CONTEXT(ctx); 5560 5561 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 5562 texunit - GL_TEXTURE0, 5563 true, 5564 "glCompressedMultiTexImage2DEXT"); 5565 if (!texObj) 5566 return; 5567 teximage(ctx, GL_TRUE, 2, texObj, target, level, internalFormat, 5568 width, height, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false); 5569} 5570 5571 5572void GLAPIENTRY 5573_mesa_CompressedTexImage3D(GLenum target, GLint level, 5574 GLenum internalFormat, GLsizei width, 5575 GLsizei height, GLsizei depth, GLint border, 5576 GLsizei imageSize, const GLvoid *data) 5577{ 5578 GET_CURRENT_CONTEXT(ctx); 5579 teximage_err(ctx, GL_TRUE, 3, target, level, internalFormat, width, height, 5580 depth, border, GL_NONE, GL_NONE, imageSize, data); 5581} 5582 5583 5584void GLAPIENTRY 5585_mesa_CompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, 5586 GLenum internalFormat, GLsizei width, 5587 GLsizei height, GLsizei depth, GLint border, 5588 GLsizei imageSize, const GLvoid *pixels) 5589{ 5590 struct gl_texture_object* texObj; 5591 GET_CURRENT_CONTEXT(ctx); 5592 5593 texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 5594 "glCompressedTextureImage3DEXT"); 5595 if (!texObj) 5596 return; 5597 teximage(ctx, GL_TRUE, 3, texObj, target, level, internalFormat, 5598 width, height, depth, border, GL_NONE, GL_NONE, imageSize, pixels, false); 5599} 5600 5601 5602void GLAPIENTRY 5603_mesa_CompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, 5604 GLenum internalFormat, GLsizei width, 5605 GLsizei height, GLsizei depth, GLint border, 5606 GLsizei imageSize, const GLvoid *pixels) 5607{ 5608 struct gl_texture_object* texObj; 5609 GET_CURRENT_CONTEXT(ctx); 5610 5611 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 5612 texunit - GL_TEXTURE0, 5613 true, 5614 "glCompressedMultiTexImage3DEXT"); 5615 if (!texObj) 5616 return; 5617 teximage(ctx, GL_TRUE, 3, texObj, target, level, internalFormat, 5618 width, height, depth, border, GL_NONE, GL_NONE, imageSize, pixels, false); 5619} 5620 5621 5622void GLAPIENTRY 5623_mesa_CompressedTexImage1D_no_error(GLenum target, GLint level, 5624 GLenum internalFormat, GLsizei width, 5625 GLint border, GLsizei imageSize, 5626 const GLvoid *data) 5627{ 5628 GET_CURRENT_CONTEXT(ctx); 5629 teximage_no_error(ctx, GL_TRUE, 1, target, level, internalFormat, width, 1, 5630 1, border, GL_NONE, GL_NONE, imageSize, data); 5631} 5632 5633 5634void GLAPIENTRY 5635_mesa_CompressedTexImage2D_no_error(GLenum target, GLint level, 5636 GLenum internalFormat, GLsizei width, 5637 GLsizei height, GLint border, 5638 GLsizei imageSize, const GLvoid *data) 5639{ 5640 GET_CURRENT_CONTEXT(ctx); 5641 teximage_no_error(ctx, GL_TRUE, 2, target, level, internalFormat, width, 5642 height, 1, border, GL_NONE, GL_NONE, imageSize, data); 5643} 5644 5645 5646void GLAPIENTRY 5647_mesa_CompressedTexImage3D_no_error(GLenum target, GLint level, 5648 GLenum internalFormat, GLsizei width, 5649 GLsizei height, GLsizei depth, GLint border, 5650 GLsizei imageSize, const GLvoid *data) 5651{ 5652 GET_CURRENT_CONTEXT(ctx); 5653 teximage_no_error(ctx, GL_TRUE, 3, target, level, internalFormat, width, 5654 height, depth, border, GL_NONE, GL_NONE, imageSize, data); 5655} 5656 5657 5658/** 5659 * Common helper for glCompressedTexSubImage1/2/3D() and 5660 * glCompressedTextureSubImage1/2/3D(). 5661 */ 5662static void 5663compressed_texture_sub_image(struct gl_context *ctx, GLuint dims, 5664 struct gl_texture_object *texObj, 5665 struct gl_texture_image *texImage, 5666 GLenum target, GLint level, GLint xoffset, 5667 GLint yoffset, GLint zoffset, GLsizei width, 5668 GLsizei height, GLsizei depth, GLenum format, 5669 GLsizei imageSize, const GLvoid *data) 5670{ 5671 FLUSH_VERTICES(ctx, 0, 0); 5672 5673 _mesa_lock_texture(ctx, texObj); 5674 { 5675 if (width > 0 && height > 0 && depth > 0) { 5676 st_CompressedTexSubImage(ctx, dims, texImage, 5677 xoffset, yoffset, zoffset, 5678 width, height, depth, 5679 format, imageSize, data); 5680 5681 check_gen_mipmap(ctx, target, texObj, level); 5682 5683 /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed 5684 * the texel data, not the texture format, size, etc. 5685 */ 5686 } 5687 } 5688 _mesa_unlock_texture(ctx, texObj); 5689} 5690 5691 5692enum tex_mode { 5693 /* Use bound texture to current unit */ 5694 TEX_MODE_CURRENT_NO_ERROR = 0, 5695 TEX_MODE_CURRENT_ERROR, 5696 /* Use the specified texture name */ 5697 TEX_MODE_DSA_NO_ERROR, 5698 TEX_MODE_DSA_ERROR, 5699 /* Use the specified texture name + target */ 5700 TEX_MODE_EXT_DSA_TEXTURE, 5701 /* Use the specified texture unit + target */ 5702 TEX_MODE_EXT_DSA_TEXUNIT, 5703}; 5704 5705 5706static void 5707compressed_tex_sub_image(unsigned dim, GLenum target, GLuint textureOrIndex, 5708 GLint level, GLint xoffset, GLint yoffset, 5709 GLint zoffset, GLsizei width, GLsizei height, 5710 GLsizei depth, GLenum format, GLsizei imageSize, 5711 const GLvoid *data, enum tex_mode mode, 5712 const char *caller) 5713{ 5714 struct gl_texture_object *texObj = NULL; 5715 struct gl_texture_image *texImage; 5716 bool no_error = false; 5717 GET_CURRENT_CONTEXT(ctx); 5718 5719 switch (mode) { 5720 case TEX_MODE_DSA_ERROR: 5721 assert(target == 0); 5722 texObj = _mesa_lookup_texture_err(ctx, textureOrIndex, caller); 5723 if (texObj) 5724 target = texObj->Target; 5725 break; 5726 case TEX_MODE_DSA_NO_ERROR: 5727 assert(target == 0); 5728 texObj = _mesa_lookup_texture(ctx, textureOrIndex); 5729 if (texObj) 5730 target = texObj->Target; 5731 no_error = true; 5732 break; 5733 case TEX_MODE_EXT_DSA_TEXTURE: 5734 texObj = _mesa_lookup_or_create_texture(ctx, target, textureOrIndex, 5735 false, true, caller); 5736 break; 5737 case TEX_MODE_EXT_DSA_TEXUNIT: 5738 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 5739 textureOrIndex, 5740 false, 5741 caller); 5742 break; 5743 case TEX_MODE_CURRENT_NO_ERROR: 5744 no_error = true; 5745 FALLTHROUGH; 5746 case TEX_MODE_CURRENT_ERROR: 5747 default: 5748 assert(textureOrIndex == 0); 5749 break; 5750 } 5751 5752 if (!no_error && 5753 compressed_subtexture_target_check(ctx, target, dim, format, 5754 mode == TEX_MODE_DSA_ERROR, 5755 caller)) { 5756 return; 5757 } 5758 5759 if (mode == TEX_MODE_CURRENT_NO_ERROR || 5760 mode == TEX_MODE_CURRENT_ERROR) { 5761 texObj = _mesa_get_current_tex_object(ctx, target); 5762 } 5763 5764 if (!texObj) 5765 return; 5766 5767 if (!no_error && 5768 compressed_subtexture_error_check(ctx, dim, texObj, target, level, 5769 xoffset, yoffset, zoffset, width, 5770 height, depth, format, 5771 imageSize, data, caller)) { 5772 return; 5773 } 5774 5775 /* Must handle special case GL_TEXTURE_CUBE_MAP. */ 5776 if (dim == 3 && 5777 (mode == TEX_MODE_DSA_ERROR || mode == TEX_MODE_DSA_NO_ERROR) && 5778 texObj->Target == GL_TEXTURE_CUBE_MAP) { 5779 const char *pixels = data; 5780 GLint image_stride; 5781 5782 /* Make sure the texture object is a proper cube. 5783 * (See texturesubimage in teximage.c for details on why this check is 5784 * performed.) 5785 */ 5786 if (!no_error && !_mesa_cube_level_complete(texObj, level)) { 5787 _mesa_error(ctx, GL_INVALID_OPERATION, 5788 "glCompressedTextureSubImage3D(cube map incomplete)"); 5789 return; 5790 } 5791 5792 /* Copy in each face. */ 5793 for (int i = zoffset; i < zoffset + depth; ++i) { 5794 texImage = texObj->Image[i][level]; 5795 assert(texImage); 5796 5797 compressed_texture_sub_image(ctx, 3, texObj, texImage, 5798 texObj->Target, level, xoffset, yoffset, 5799 0, width, height, 1, format, 5800 imageSize, pixels); 5801 5802 /* Compressed images don't have a client format */ 5803 image_stride = _mesa_format_image_size(texImage->TexFormat, 5804 texImage->Width, 5805 texImage->Height, 1); 5806 5807 pixels += image_stride; 5808 imageSize -= image_stride; 5809 } 5810 } else { 5811 texImage = _mesa_select_tex_image(texObj, target, level); 5812 assert(texImage); 5813 5814 compressed_texture_sub_image(ctx, dim, texObj, texImage, target, level, 5815 xoffset, yoffset, zoffset, width, height, 5816 depth, format, imageSize, data); 5817 } 5818} 5819 5820 5821void GLAPIENTRY 5822_mesa_CompressedTexSubImage1D_no_error(GLenum target, GLint level, 5823 GLint xoffset, GLsizei width, 5824 GLenum format, GLsizei imageSize, 5825 const GLvoid *data) 5826{ 5827 compressed_tex_sub_image(1, target, 0, 5828 level, xoffset, 0, 0, width, 5829 1, 1, format, imageSize, data, 5830 TEX_MODE_CURRENT_NO_ERROR, 5831 "glCompressedTexSubImage1D"); 5832} 5833 5834 5835void GLAPIENTRY 5836_mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, 5837 GLsizei width, GLenum format, 5838 GLsizei imageSize, const GLvoid *data) 5839{ 5840 compressed_tex_sub_image(1, target, 0, 5841 level, xoffset, 0, 0, width, 5842 1, 1, format, imageSize, data, 5843 TEX_MODE_CURRENT_ERROR, 5844 "glCompressedTexSubImage1D"); 5845} 5846 5847 5848void GLAPIENTRY 5849_mesa_CompressedTextureSubImage1D_no_error(GLuint texture, GLint level, 5850 GLint xoffset, GLsizei width, 5851 GLenum format, GLsizei imageSize, 5852 const GLvoid *data) 5853{ 5854 compressed_tex_sub_image(1, 0, texture, 5855 level, xoffset, 0, 0, 5856 width, 1, 1, format, imageSize, data, 5857 TEX_MODE_DSA_NO_ERROR, 5858 "glCompressedTextureSubImage1D"); 5859} 5860 5861 5862void GLAPIENTRY 5863_mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, 5864 GLsizei width, GLenum format, 5865 GLsizei imageSize, const GLvoid *data) 5866{ 5867 compressed_tex_sub_image(1, 0, texture, 5868 level, xoffset, 0, 0, 5869 width, 1, 1, format, imageSize, data, 5870 TEX_MODE_DSA_ERROR, 5871 "glCompressedTextureSubImage1D"); 5872} 5873 5874 5875void GLAPIENTRY 5876_mesa_CompressedTextureSubImage1DEXT(GLuint texture, GLenum target, 5877 GLint level, GLint xoffset, 5878 GLsizei width, GLenum format, 5879 GLsizei imageSize, const GLvoid *data) 5880{ 5881 compressed_tex_sub_image(1, target, texture, level, xoffset, 0, 5882 0, width, 1, 1, format, imageSize, 5883 data, 5884 TEX_MODE_EXT_DSA_TEXTURE, 5885 "glCompressedTextureSubImage1DEXT"); 5886} 5887 5888 5889void GLAPIENTRY 5890_mesa_CompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, 5891 GLint level, GLint xoffset, 5892 GLsizei width, GLenum format, 5893 GLsizei imageSize, const GLvoid *data) 5894{ 5895 compressed_tex_sub_image(1, target, texunit - GL_TEXTURE0, level, 5896 xoffset, 0, 0, width, 1, 1, format, imageSize, 5897 data, 5898 TEX_MODE_EXT_DSA_TEXUNIT, 5899 "glCompressedMultiTexSubImage1DEXT"); 5900} 5901 5902 5903void GLAPIENTRY 5904_mesa_CompressedTexSubImage2D_no_error(GLenum target, GLint level, 5905 GLint xoffset, GLint yoffset, 5906 GLsizei width, GLsizei height, 5907 GLenum format, GLsizei imageSize, 5908 const GLvoid *data) 5909{ 5910 compressed_tex_sub_image(2, target, 0, level, 5911 xoffset, yoffset, 0, 5912 width, height, 1, format, imageSize, data, 5913 TEX_MODE_CURRENT_NO_ERROR, 5914 "glCompressedTexSubImage2D"); 5915} 5916 5917 5918void GLAPIENTRY 5919_mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, 5920 GLint yoffset, GLsizei width, GLsizei height, 5921 GLenum format, GLsizei imageSize, 5922 const GLvoid *data) 5923{ 5924 compressed_tex_sub_image(2, target, 0, level, 5925 xoffset, yoffset, 0, 5926 width, height, 1, format, imageSize, data, 5927 TEX_MODE_CURRENT_ERROR, 5928 "glCompressedTexSubImage2D"); 5929} 5930 5931 5932void GLAPIENTRY 5933_mesa_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target, 5934 GLint level, GLint xoffset, 5935 GLint yoffset, GLsizei width, 5936 GLsizei height, GLenum format, 5937 GLsizei imageSize, const GLvoid *data) 5938{ 5939 compressed_tex_sub_image(2, target, texture, level, xoffset, 5940 yoffset, 0, width, height, 1, format, 5941 imageSize, data, 5942 TEX_MODE_EXT_DSA_TEXTURE, 5943 "glCompressedTextureSubImage2DEXT"); 5944} 5945 5946 5947void GLAPIENTRY 5948_mesa_CompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target, 5949 GLint level, GLint xoffset, GLint yoffset, 5950 GLsizei width, GLsizei height, GLenum format, 5951 GLsizei imageSize, const GLvoid *data) 5952{ 5953 compressed_tex_sub_image(2, target, texunit - GL_TEXTURE0, level, 5954 xoffset, yoffset, 0, width, height, 1, format, 5955 imageSize, data, 5956 TEX_MODE_EXT_DSA_TEXUNIT, 5957 "glCompressedMultiTexSubImage2DEXT"); 5958} 5959 5960 5961void GLAPIENTRY 5962_mesa_CompressedTextureSubImage2D_no_error(GLuint texture, GLint level, 5963 GLint xoffset, GLint yoffset, 5964 GLsizei width, GLsizei height, 5965 GLenum format, GLsizei imageSize, 5966 const GLvoid *data) 5967{ 5968 compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0, 5969 width, height, 1, format, imageSize, data, 5970 TEX_MODE_DSA_NO_ERROR, 5971 "glCompressedTextureSubImage2D"); 5972} 5973 5974 5975void GLAPIENTRY 5976_mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, 5977 GLint yoffset, 5978 GLsizei width, GLsizei height, 5979 GLenum format, GLsizei imageSize, 5980 const GLvoid *data) 5981{ 5982 compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0, 5983 width, height, 1, format, imageSize, data, 5984 TEX_MODE_DSA_ERROR, 5985 "glCompressedTextureSubImage2D"); 5986} 5987 5988void GLAPIENTRY 5989_mesa_CompressedTexSubImage3D_no_error(GLenum target, GLint level, 5990 GLint xoffset, GLint yoffset, 5991 GLint zoffset, GLsizei width, 5992 GLsizei height, GLsizei depth, 5993 GLenum format, GLsizei imageSize, 5994 const GLvoid *data) 5995{ 5996 compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset, 5997 zoffset, width, height, depth, format, 5998 imageSize, data, 5999 TEX_MODE_CURRENT_NO_ERROR, 6000 "glCompressedTexSubImage3D"); 6001} 6002 6003void GLAPIENTRY 6004_mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, 6005 GLint yoffset, GLint zoffset, GLsizei width, 6006 GLsizei height, GLsizei depth, GLenum format, 6007 GLsizei imageSize, const GLvoid *data) 6008{ 6009 compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset, 6010 zoffset, width, height, depth, format, 6011 imageSize, data, 6012 TEX_MODE_CURRENT_ERROR, 6013 "glCompressedTexSubImage3D"); 6014} 6015 6016void GLAPIENTRY 6017_mesa_CompressedTextureSubImage3D_no_error(GLuint texture, GLint level, 6018 GLint xoffset, GLint yoffset, 6019 GLint zoffset, GLsizei width, 6020 GLsizei height, GLsizei depth, 6021 GLenum format, GLsizei imageSize, 6022 const GLvoid *data) 6023{ 6024 compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset, 6025 zoffset, width, height, depth, format, 6026 imageSize, data, 6027 TEX_MODE_DSA_NO_ERROR, 6028 "glCompressedTextureSubImage3D"); 6029} 6030 6031void GLAPIENTRY 6032_mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, 6033 GLint yoffset, GLint zoffset, GLsizei width, 6034 GLsizei height, GLsizei depth, 6035 GLenum format, GLsizei imageSize, 6036 const GLvoid *data) 6037{ 6038 compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset, 6039 zoffset, width, height, depth, format, 6040 imageSize, data, 6041 TEX_MODE_DSA_ERROR, 6042 "glCompressedTextureSubImage3D"); 6043} 6044 6045 6046void GLAPIENTRY 6047_mesa_CompressedTextureSubImage3DEXT(GLuint texture, GLenum target, 6048 GLint level, GLint xoffset, 6049 GLint yoffset, GLint zoffset, 6050 GLsizei width, GLsizei height, 6051 GLsizei depth, GLenum format, 6052 GLsizei imageSize, const GLvoid *data) 6053{ 6054 compressed_tex_sub_image(3, target, texture, level, xoffset, yoffset, 6055 zoffset, width, height, depth, format, 6056 imageSize, data, 6057 TEX_MODE_EXT_DSA_TEXTURE, 6058 "glCompressedTextureSubImage3DEXT"); 6059} 6060 6061 6062void GLAPIENTRY 6063_mesa_CompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, 6064 GLint level, GLint xoffset, GLint yoffset, 6065 GLint zoffset, GLsizei width, GLsizei height, 6066 GLsizei depth, GLenum format, 6067 GLsizei imageSize, const GLvoid *data) 6068{ 6069 compressed_tex_sub_image(3, target, texunit - GL_TEXTURE0, level, 6070 xoffset, yoffset, zoffset, width, height, depth, 6071 format, imageSize, data, 6072 TEX_MODE_EXT_DSA_TEXUNIT, 6073 "glCompressedMultiTexSubImage3DEXT"); 6074} 6075 6076 6077mesa_format 6078_mesa_get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) 6079{ 6080 if (ctx->API == API_OPENGL_COMPAT) { 6081 switch (internalFormat) { 6082 case GL_ALPHA8: 6083 return MESA_FORMAT_A_UNORM8; 6084 case GL_ALPHA16: 6085 return MESA_FORMAT_A_UNORM16; 6086 case GL_ALPHA16F_ARB: 6087 return MESA_FORMAT_A_FLOAT16; 6088 case GL_ALPHA32F_ARB: 6089 return MESA_FORMAT_A_FLOAT32; 6090 case GL_ALPHA8I_EXT: 6091 return MESA_FORMAT_A_SINT8; 6092 case GL_ALPHA16I_EXT: 6093 return MESA_FORMAT_A_SINT16; 6094 case GL_ALPHA32I_EXT: 6095 return MESA_FORMAT_A_SINT32; 6096 case GL_ALPHA8UI_EXT: 6097 return MESA_FORMAT_A_UINT8; 6098 case GL_ALPHA16UI_EXT: 6099 return MESA_FORMAT_A_UINT16; 6100 case GL_ALPHA32UI_EXT: 6101 return MESA_FORMAT_A_UINT32; 6102 case GL_LUMINANCE8: 6103 return MESA_FORMAT_L_UNORM8; 6104 case GL_LUMINANCE16: 6105 return MESA_FORMAT_L_UNORM16; 6106 case GL_LUMINANCE16F_ARB: 6107 return MESA_FORMAT_L_FLOAT16; 6108 case GL_LUMINANCE32F_ARB: 6109 return MESA_FORMAT_L_FLOAT32; 6110 case GL_LUMINANCE8I_EXT: 6111 return MESA_FORMAT_L_SINT8; 6112 case GL_LUMINANCE16I_EXT: 6113 return MESA_FORMAT_L_SINT16; 6114 case GL_LUMINANCE32I_EXT: 6115 return MESA_FORMAT_L_SINT32; 6116 case GL_LUMINANCE8UI_EXT: 6117 return MESA_FORMAT_L_UINT8; 6118 case GL_LUMINANCE16UI_EXT: 6119 return MESA_FORMAT_L_UINT16; 6120 case GL_LUMINANCE32UI_EXT: 6121 return MESA_FORMAT_L_UINT32; 6122 case GL_LUMINANCE8_ALPHA8: 6123 return MESA_FORMAT_LA_UNORM8; 6124 case GL_LUMINANCE16_ALPHA16: 6125 return MESA_FORMAT_LA_UNORM16; 6126 case GL_LUMINANCE_ALPHA16F_ARB: 6127 return MESA_FORMAT_LA_FLOAT16; 6128 case GL_LUMINANCE_ALPHA32F_ARB: 6129 return MESA_FORMAT_LA_FLOAT32; 6130 case GL_LUMINANCE_ALPHA8I_EXT: 6131 return MESA_FORMAT_LA_SINT8; 6132 case GL_LUMINANCE_ALPHA16I_EXT: 6133 return MESA_FORMAT_LA_SINT16; 6134 case GL_LUMINANCE_ALPHA32I_EXT: 6135 return MESA_FORMAT_LA_SINT32; 6136 case GL_LUMINANCE_ALPHA8UI_EXT: 6137 return MESA_FORMAT_LA_UINT8; 6138 case GL_LUMINANCE_ALPHA16UI_EXT: 6139 return MESA_FORMAT_LA_UINT16; 6140 case GL_LUMINANCE_ALPHA32UI_EXT: 6141 return MESA_FORMAT_LA_UINT32; 6142 case GL_INTENSITY8: 6143 return MESA_FORMAT_I_UNORM8; 6144 case GL_INTENSITY16: 6145 return MESA_FORMAT_I_UNORM16; 6146 case GL_INTENSITY16F_ARB: 6147 return MESA_FORMAT_I_FLOAT16; 6148 case GL_INTENSITY32F_ARB: 6149 return MESA_FORMAT_I_FLOAT32; 6150 case GL_INTENSITY8I_EXT: 6151 return MESA_FORMAT_I_SINT8; 6152 case GL_INTENSITY16I_EXT: 6153 return MESA_FORMAT_I_SINT16; 6154 case GL_INTENSITY32I_EXT: 6155 return MESA_FORMAT_I_SINT32; 6156 case GL_INTENSITY8UI_EXT: 6157 return MESA_FORMAT_I_UINT8; 6158 case GL_INTENSITY16UI_EXT: 6159 return MESA_FORMAT_I_UINT16; 6160 case GL_INTENSITY32UI_EXT: 6161 return MESA_FORMAT_I_UINT32; 6162 default: 6163 break; 6164 } 6165 } 6166 6167 if (_mesa_has_ARB_texture_buffer_object_rgb32(ctx) || 6168 _mesa_has_OES_texture_buffer(ctx)) { 6169 switch (internalFormat) { 6170 case GL_RGB32F: 6171 return MESA_FORMAT_RGB_FLOAT32; 6172 case GL_RGB32UI: 6173 return MESA_FORMAT_RGB_UINT32; 6174 case GL_RGB32I: 6175 return MESA_FORMAT_RGB_SINT32; 6176 default: 6177 break; 6178 } 6179 } 6180 6181 switch (internalFormat) { 6182 case GL_RGBA8: 6183 return MESA_FORMAT_R8G8B8A8_UNORM; 6184 case GL_RGBA16: 6185 if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx)) 6186 return MESA_FORMAT_NONE; 6187 return MESA_FORMAT_RGBA_UNORM16; 6188 case GL_RGBA16F_ARB: 6189 return MESA_FORMAT_RGBA_FLOAT16; 6190 case GL_RGBA32F_ARB: 6191 return MESA_FORMAT_RGBA_FLOAT32; 6192 case GL_RGBA8I_EXT: 6193 return MESA_FORMAT_RGBA_SINT8; 6194 case GL_RGBA16I_EXT: 6195 return MESA_FORMAT_RGBA_SINT16; 6196 case GL_RGBA32I_EXT: 6197 return MESA_FORMAT_RGBA_SINT32; 6198 case GL_RGBA8UI_EXT: 6199 return MESA_FORMAT_RGBA_UINT8; 6200 case GL_RGBA16UI_EXT: 6201 return MESA_FORMAT_RGBA_UINT16; 6202 case GL_RGBA32UI_EXT: 6203 return MESA_FORMAT_RGBA_UINT32; 6204 6205 case GL_RG8: 6206 return MESA_FORMAT_RG_UNORM8; 6207 case GL_RG16: 6208 if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx)) 6209 return MESA_FORMAT_NONE; 6210 return MESA_FORMAT_RG_UNORM16; 6211 case GL_RG16F: 6212 return MESA_FORMAT_RG_FLOAT16; 6213 case GL_RG32F: 6214 return MESA_FORMAT_RG_FLOAT32; 6215 case GL_RG8I: 6216 return MESA_FORMAT_RG_SINT8; 6217 case GL_RG16I: 6218 return MESA_FORMAT_RG_SINT16; 6219 case GL_RG32I: 6220 return MESA_FORMAT_RG_SINT32; 6221 case GL_RG8UI: 6222 return MESA_FORMAT_RG_UINT8; 6223 case GL_RG16UI: 6224 return MESA_FORMAT_RG_UINT16; 6225 case GL_RG32UI: 6226 return MESA_FORMAT_RG_UINT32; 6227 6228 case GL_R8: 6229 return MESA_FORMAT_R_UNORM8; 6230 case GL_R16: 6231 if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx)) 6232 return MESA_FORMAT_NONE; 6233 return MESA_FORMAT_R_UNORM16; 6234 case GL_R16F: 6235 return MESA_FORMAT_R_FLOAT16; 6236 case GL_R32F: 6237 return MESA_FORMAT_R_FLOAT32; 6238 case GL_R8I: 6239 return MESA_FORMAT_R_SINT8; 6240 case GL_R16I: 6241 return MESA_FORMAT_R_SINT16; 6242 case GL_R32I: 6243 return MESA_FORMAT_R_SINT32; 6244 case GL_R8UI: 6245 return MESA_FORMAT_R_UINT8; 6246 case GL_R16UI: 6247 return MESA_FORMAT_R_UINT16; 6248 case GL_R32UI: 6249 return MESA_FORMAT_R_UINT32; 6250 6251 default: 6252 return MESA_FORMAT_NONE; 6253 } 6254} 6255 6256 6257mesa_format 6258_mesa_validate_texbuffer_format(const struct gl_context *ctx, 6259 GLenum internalFormat) 6260{ 6261 mesa_format format = _mesa_get_texbuffer_format(ctx, internalFormat); 6262 GLenum datatype; 6263 6264 if (format == MESA_FORMAT_NONE) 6265 return MESA_FORMAT_NONE; 6266 6267 datatype = _mesa_get_format_datatype(format); 6268 6269 /* The GL_ARB_texture_buffer_object spec says: 6270 * 6271 * "If ARB_texture_float is not supported, references to the 6272 * floating-point internal formats provided by that extension should be 6273 * removed, and such formats may not be passed to TexBufferARB." 6274 * 6275 * As a result, GL_HALF_FLOAT internal format depends on both 6276 * GL_ARB_texture_float and GL_ARB_half_float_pixel. 6277 */ 6278 if ((datatype == GL_FLOAT || datatype == GL_HALF_FLOAT) && 6279 !ctx->Extensions.ARB_texture_float) 6280 return MESA_FORMAT_NONE; 6281 6282 if (!ctx->Extensions.ARB_texture_rg) { 6283 GLenum base_format = _mesa_get_format_base_format(format); 6284 if (base_format == GL_R || base_format == GL_RG) 6285 return MESA_FORMAT_NONE; 6286 } 6287 6288 if (!ctx->Extensions.ARB_texture_buffer_object_rgb32) { 6289 GLenum base_format = _mesa_get_format_base_format(format); 6290 if (base_format == GL_RGB) 6291 return MESA_FORMAT_NONE; 6292 } 6293 return format; 6294} 6295 6296 6297/** 6298 * Do work common to glTexBuffer, glTexBufferRange, glTextureBuffer 6299 * and glTextureBufferRange, including some error checking. 6300 */ 6301static void 6302texture_buffer_range(struct gl_context *ctx, 6303 struct gl_texture_object *texObj, 6304 GLenum internalFormat, 6305 struct gl_buffer_object *bufObj, 6306 GLintptr offset, GLsizeiptr size, 6307 const char *caller) 6308{ 6309 GLintptr oldOffset = texObj->BufferOffset; 6310 GLsizeiptr oldSize = texObj->BufferSize; 6311 mesa_format format; 6312 mesa_format old_format; 6313 6314 /* NOTE: ARB_texture_buffer_object might not be supported in 6315 * the compatibility profile. 6316 */ 6317 if (!_mesa_has_ARB_texture_buffer_object(ctx) && 6318 !_mesa_has_OES_texture_buffer(ctx)) { 6319 _mesa_error(ctx, GL_INVALID_OPERATION, 6320 "%s(ARB_texture_buffer_object is not" 6321 " implemented for the compatibility profile)", caller); 6322 return; 6323 } 6324 6325 if (texObj->HandleAllocated) { 6326 /* The ARB_bindless_texture spec says: 6327 * 6328 * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*, 6329 * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other 6330 * functions defined in terms of these, if the texture object to be 6331 * modified is referenced by one or more texture or image handles." 6332 */ 6333 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable texture)", caller); 6334 return; 6335 } 6336 6337 format = _mesa_validate_texbuffer_format(ctx, internalFormat); 6338 if (format == MESA_FORMAT_NONE) { 6339 _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat %s)", 6340 caller, _mesa_enum_to_string(internalFormat)); 6341 return; 6342 } 6343 6344 FLUSH_VERTICES(ctx, 0, GL_TEXTURE_BIT); 6345 6346 _mesa_lock_texture(ctx, texObj); 6347 { 6348 _mesa_reference_buffer_object_shared(ctx, &texObj->BufferObject, bufObj); 6349 texObj->BufferObjectFormat = internalFormat; 6350 old_format = texObj->_BufferObjectFormat; 6351 texObj->_BufferObjectFormat = format; 6352 texObj->BufferOffset = offset; 6353 texObj->BufferSize = size; 6354 } 6355 _mesa_unlock_texture(ctx, texObj); 6356 6357 if (old_format != format) { 6358 st_texture_release_all_sampler_views(st_context(ctx), texObj); 6359 } else { 6360 if (offset != oldOffset) { 6361 st_texture_release_all_sampler_views(st_context(ctx), texObj); 6362 } 6363 if (size != oldSize) { 6364 st_texture_release_all_sampler_views(st_context(ctx), texObj); 6365 } 6366 } 6367 6368 ctx->NewDriverState |= ST_NEW_SAMPLER_VIEWS; 6369 6370 if (bufObj) { 6371 bufObj->UsageHistory |= USAGE_TEXTURE_BUFFER; 6372 } 6373} 6374 6375 6376/** 6377 * Make sure the texture buffer target is GL_TEXTURE_BUFFER. 6378 * Return true if it is, and return false if it is not 6379 * (and throw INVALID ENUM as dictated in the OpenGL 4.5 6380 * core spec, 02.02.2015, PDF page 245). 6381 */ 6382static bool 6383check_texture_buffer_target(struct gl_context *ctx, GLenum target, 6384 const char *caller, bool dsa) 6385{ 6386 if (target != GL_TEXTURE_BUFFER_ARB) { 6387 _mesa_error(ctx, dsa ? GL_INVALID_OPERATION : GL_INVALID_ENUM, 6388 "%s(texture target is not GL_TEXTURE_BUFFER)", caller); 6389 return false; 6390 } 6391 else 6392 return true; 6393} 6394 6395/** 6396 * Check for errors related to the texture buffer range. 6397 * Return false if errors are found, true if none are found. 6398 */ 6399static bool 6400check_texture_buffer_range(struct gl_context *ctx, 6401 struct gl_buffer_object *bufObj, 6402 GLintptr offset, GLsizeiptr size, 6403 const char *caller) 6404{ 6405 /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 6406 * Textures (PDF page 245): 6407 * "An INVALID_VALUE error is generated if offset is negative, if 6408 * size is less than or equal to zero, or if offset + size is greater 6409 * than the value of BUFFER_SIZE for the buffer bound to target." 6410 */ 6411 if (offset < 0) { 6412 _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d < 0)", caller, 6413 (int) offset); 6414 return false; 6415 } 6416 6417 if (size <= 0) { 6418 _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d <= 0)", caller, 6419 (int) size); 6420 return false; 6421 } 6422 6423 if (offset + size > bufObj->Size) { 6424 _mesa_error(ctx, GL_INVALID_VALUE, 6425 "%s(offset=%d + size=%d > buffer_size=%d)", caller, 6426 (int) offset, (int) size, (int) bufObj->Size); 6427 return false; 6428 } 6429 6430 /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 6431 * Textures (PDF page 245): 6432 * "An INVALID_VALUE error is generated if offset is not an integer 6433 * multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT." 6434 */ 6435 if (offset % ctx->Const.TextureBufferOffsetAlignment) { 6436 _mesa_error(ctx, GL_INVALID_VALUE, 6437 "%s(invalid offset alignment)", caller); 6438 return false; 6439 } 6440 6441 return true; 6442} 6443 6444 6445/** GL_ARB_texture_buffer_object */ 6446void GLAPIENTRY 6447_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer) 6448{ 6449 struct gl_texture_object *texObj; 6450 struct gl_buffer_object *bufObj; 6451 6452 GET_CURRENT_CONTEXT(ctx); 6453 6454 /* Need to catch a bad target before it gets to 6455 * _mesa_get_current_tex_object. 6456 */ 6457 if (!check_texture_buffer_target(ctx, target, "glTexBuffer", false)) 6458 return; 6459 6460 if (buffer) { 6461 bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBuffer"); 6462 if (!bufObj) 6463 return; 6464 } else 6465 bufObj = NULL; 6466 6467 texObj = _mesa_get_current_tex_object(ctx, target); 6468 if (!texObj) 6469 return; 6470 6471 texture_buffer_range(ctx, texObj, internalFormat, bufObj, 0, 6472 buffer ? -1 : 0, "glTexBuffer"); 6473} 6474 6475 6476/** GL_ARB_texture_buffer_range */ 6477void GLAPIENTRY 6478_mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer, 6479 GLintptr offset, GLsizeiptr size) 6480{ 6481 struct gl_texture_object *texObj; 6482 struct gl_buffer_object *bufObj; 6483 6484 GET_CURRENT_CONTEXT(ctx); 6485 6486 /* Need to catch a bad target before it gets to 6487 * _mesa_get_current_tex_object. 6488 */ 6489 if (!check_texture_buffer_target(ctx, target, "glTexBufferRange", false)) 6490 return; 6491 6492 if (buffer) { 6493 bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBufferRange"); 6494 if (!bufObj) 6495 return; 6496 6497 if (!check_texture_buffer_range(ctx, bufObj, offset, size, 6498 "glTexBufferRange")) 6499 return; 6500 6501 } else { 6502 /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 6503 * Textures (PDF page 254): 6504 * "If buffer is zero, then any buffer object attached to the buffer 6505 * texture is detached, the values offset and size are ignored and 6506 * the state for offset and size for the buffer texture are reset to 6507 * zero." 6508 */ 6509 offset = 0; 6510 size = 0; 6511 bufObj = NULL; 6512 } 6513 6514 texObj = _mesa_get_current_tex_object(ctx, target); 6515 if (!texObj) 6516 return; 6517 6518 texture_buffer_range(ctx, texObj, internalFormat, bufObj, 6519 offset, size, "glTexBufferRange"); 6520} 6521 6522 6523/** GL_ARB_texture_buffer_range + GL_EXT_direct_state_access */ 6524void GLAPIENTRY 6525_mesa_TextureBufferRangeEXT(GLuint texture, GLenum target, GLenum internalFormat, 6526 GLuint buffer, GLintptr offset, GLsizeiptr size) 6527{ 6528 struct gl_texture_object *texObj; 6529 struct gl_buffer_object *bufObj; 6530 6531 GET_CURRENT_CONTEXT(ctx); 6532 6533 texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, 6534 "glTextureBufferRangeEXT"); 6535 if (!texObj) 6536 return; 6537 6538 if (!check_texture_buffer_target(ctx, target, "glTextureBufferRangeEXT", true)) 6539 return; 6540 6541 if (buffer) { 6542 bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBufferRangeEXT"); 6543 if (!bufObj) 6544 return; 6545 6546 if (!check_texture_buffer_range(ctx, bufObj, offset, size, 6547 "glTextureBufferRangeEXT")) 6548 return; 6549 6550 } else { 6551 /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 6552 * Textures (PDF page 254): 6553 * "If buffer is zero, then any buffer object attached to the buffer 6554 * texture is detached, the values offset and size are ignored and 6555 * the state for offset and size for the buffer texture are reset to 6556 * zero." 6557 */ 6558 offset = 0; 6559 size = 0; 6560 bufObj = NULL; 6561 } 6562 6563 texture_buffer_range(ctx, texObj, internalFormat, bufObj, 6564 offset, size, "glTextureBufferRangeEXT"); 6565} 6566 6567 6568void GLAPIENTRY 6569_mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer) 6570{ 6571 struct gl_texture_object *texObj; 6572 struct gl_buffer_object *bufObj; 6573 6574 GET_CURRENT_CONTEXT(ctx); 6575 6576 if (buffer) { 6577 bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBuffer"); 6578 if (!bufObj) 6579 return; 6580 } else 6581 bufObj = NULL; 6582 6583 /* Get the texture object by Name. */ 6584 texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBuffer"); 6585 if (!texObj) 6586 return; 6587 6588 if (!check_texture_buffer_target(ctx, texObj->Target, "glTextureBuffer", true)) 6589 return; 6590 6591 texture_buffer_range(ctx, texObj, internalFormat, 6592 bufObj, 0, buffer ? -1 : 0, "glTextureBuffer"); 6593} 6594 6595void GLAPIENTRY 6596_mesa_TextureBufferEXT(GLuint texture, GLenum target, 6597 GLenum internalFormat, GLuint buffer) 6598{ 6599 struct gl_texture_object *texObj; 6600 struct gl_buffer_object *bufObj; 6601 6602 GET_CURRENT_CONTEXT(ctx); 6603 6604 if (buffer) { 6605 bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBuffer"); 6606 if (!bufObj) 6607 return; 6608 } else 6609 bufObj = NULL; 6610 6611 /* Get the texture object by Name. */ 6612 texObj = _mesa_lookup_or_create_texture(ctx, target, texture, 6613 false, true, 6614 "glTextureBufferEXT"); 6615 6616 if (!texObj || 6617 !check_texture_buffer_target(ctx, texObj->Target, "glTextureBufferEXT", true)) 6618 return; 6619 6620 texture_buffer_range(ctx, texObj, internalFormat, 6621 bufObj, 0, buffer ? -1 : 0, "glTextureBufferEXT"); 6622} 6623 6624void GLAPIENTRY 6625_mesa_MultiTexBufferEXT(GLenum texunit, GLenum target, 6626 GLenum internalFormat, GLuint buffer) 6627{ 6628 struct gl_texture_object *texObj; 6629 struct gl_buffer_object *bufObj; 6630 6631 GET_CURRENT_CONTEXT(ctx); 6632 6633 if (buffer) { 6634 bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glMultiTexBufferEXT"); 6635 if (!bufObj) 6636 return; 6637 } else 6638 bufObj = NULL; 6639 6640 /* Get the texture object */ 6641 texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target, 6642 texunit - GL_TEXTURE0, 6643 true, 6644 "glMultiTexBufferEXT"); 6645 6646 if (!texObj || 6647 !check_texture_buffer_target(ctx, texObj->Target, "glMultiTexBufferEXT", false)) 6648 return; 6649 6650 texture_buffer_range(ctx, texObj, internalFormat, 6651 bufObj, 0, buffer ? -1 : 0, "glMultiTexBufferEXT"); 6652} 6653 6654void GLAPIENTRY 6655_mesa_TextureBufferRange(GLuint texture, GLenum internalFormat, GLuint buffer, 6656 GLintptr offset, GLsizeiptr size) 6657{ 6658 struct gl_texture_object *texObj; 6659 struct gl_buffer_object *bufObj; 6660 6661 GET_CURRENT_CONTEXT(ctx); 6662 6663 if (buffer) { 6664 bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, 6665 "glTextureBufferRange"); 6666 if (!bufObj) 6667 return; 6668 6669 if (!check_texture_buffer_range(ctx, bufObj, offset, size, 6670 "glTextureBufferRange")) 6671 return; 6672 6673 } else { 6674 /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 6675 * Textures (PDF page 254): 6676 * "If buffer is zero, then any buffer object attached to the buffer 6677 * texture is detached, the values offset and size are ignored and 6678 * the state for offset and size for the buffer texture are reset to 6679 * zero." 6680 */ 6681 offset = 0; 6682 size = 0; 6683 bufObj = NULL; 6684 } 6685 6686 /* Get the texture object by Name. */ 6687 texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBufferRange"); 6688 if (!texObj) 6689 return; 6690 6691 if (!check_texture_buffer_target(ctx, texObj->Target, 6692 "glTextureBufferRange", true)) 6693 return; 6694 6695 texture_buffer_range(ctx, texObj, internalFormat, 6696 bufObj, offset, size, "glTextureBufferRange"); 6697} 6698 6699GLboolean 6700_mesa_is_renderable_texture_format(const struct gl_context *ctx, 6701 GLenum internalformat) 6702{ 6703 /* Everything that is allowed for renderbuffers, 6704 * except for a base format of GL_STENCIL_INDEX, unless supported. 6705 */ 6706 GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat); 6707 if (ctx->Extensions.ARB_texture_stencil8) 6708 return baseFormat != 0; 6709 else 6710 return baseFormat != 0 && baseFormat != GL_STENCIL_INDEX; 6711} 6712 6713 6714/** GL_ARB_texture_multisample */ 6715static GLboolean 6716check_multisample_target(GLuint dims, GLenum target, bool dsa) 6717{ 6718 switch(target) { 6719 case GL_TEXTURE_2D_MULTISAMPLE: 6720 return dims == 2; 6721 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 6722 return dims == 2 && !dsa; 6723 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 6724 return dims == 3; 6725 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 6726 return dims == 3 && !dsa; 6727 default: 6728 return GL_FALSE; 6729 } 6730} 6731 6732 6733static void 6734texture_image_multisample(struct gl_context *ctx, GLuint dims, 6735 struct gl_texture_object *texObj, 6736 struct gl_memory_object *memObj, 6737 GLenum target, GLsizei samples, 6738 GLint internalformat, GLsizei width, 6739 GLsizei height, GLsizei depth, 6740 GLboolean fixedsamplelocations, 6741 GLboolean immutable, GLuint64 offset, 6742 const char *func) 6743{ 6744 struct gl_texture_image *texImage; 6745 GLboolean sizeOK, dimensionsOK, samplesOK; 6746 mesa_format texFormat; 6747 GLenum sample_count_error; 6748 bool dsa = strstr(func, "ture") ? true : false; 6749 6750 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) { 6751 _mesa_debug(ctx, "%s(target=%s, samples=%d, internalformat=%s)\n", func, 6752 _mesa_enum_to_string(target), samples, _mesa_enum_to_string(internalformat)); 6753 } 6754 6755 if (!((ctx->Extensions.ARB_texture_multisample 6756 && _mesa_is_desktop_gl(ctx))) && !_mesa_is_gles31(ctx)) { 6757 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); 6758 return; 6759 } 6760 6761 if (samples < 1) { 6762 _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples < 1)", func); 6763 return; 6764 } 6765 6766 if (!check_multisample_target(dims, target, dsa)) { 6767 GLenum err = dsa ? GL_INVALID_OPERATION : GL_INVALID_ENUM; 6768 _mesa_error(ctx, err, "%s(target=%s)", func, 6769 _mesa_enum_to_string(target)); 6770 return; 6771 } 6772 6773 /* check that the specified internalformat is color/depth/stencil-renderable; 6774 * refer GL3.1 spec 4.4.4 6775 */ 6776 6777 if (immutable && !_mesa_is_legal_tex_storage_format(ctx, internalformat)) { 6778 _mesa_error(ctx, GL_INVALID_ENUM, 6779 "%s(internalformat=%s not legal for immutable-format)", 6780 func, _mesa_enum_to_string(internalformat)); 6781 return; 6782 } 6783 6784 if (!_mesa_is_renderable_texture_format(ctx, internalformat)) { 6785 /* Page 172 of OpenGL ES 3.1 spec says: 6786 * "An INVALID_ENUM error is generated if sizedinternalformat is not 6787 * color-renderable, depth-renderable, or stencil-renderable (as 6788 * defined in section 9.4). 6789 * 6790 * (Same error is also defined for desktop OpenGL for multisample 6791 * teximage/texstorage functions.) 6792 */ 6793 _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalformat=%s)", func, 6794 _mesa_enum_to_string(internalformat)); 6795 return; 6796 } 6797 6798 sample_count_error = _mesa_check_sample_count(ctx, target, 6799 internalformat, samples, samples); 6800 samplesOK = sample_count_error == GL_NO_ERROR; 6801 6802 /* Page 254 of OpenGL 4.4 spec says: 6803 * "Proxy arrays for two-dimensional multisample and two-dimensional 6804 * multisample array textures are operated on in the same way when 6805 * TexImage2DMultisample is called with target specified as 6806 * PROXY_TEXTURE_2D_MULTISAMPLE, or TexImage3DMultisample is called 6807 * with target specified as PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY. 6808 * However, if samples is not supported, then no error is generated. 6809 */ 6810 if (!samplesOK && !_mesa_is_proxy_texture(target)) { 6811 _mesa_error(ctx, sample_count_error, "%s(samples=%d)", func, samples); 6812 return; 6813 } 6814 6815 if (!texObj) { 6816 texObj = _mesa_get_current_tex_object(ctx, target); 6817 if (!texObj) 6818 return; 6819 } 6820 6821 if (immutable && texObj->Name == 0) { 6822 _mesa_error(ctx, GL_INVALID_OPERATION, 6823 "%s(texture object 0)", 6824 func); 6825 return; 6826 } 6827 6828 texImage = _mesa_get_tex_image(ctx, texObj, 0, 0); 6829 6830 if (texImage == NULL) { 6831 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func); 6832 return; 6833 } 6834 6835 texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, 6836 internalformat, GL_NONE, GL_NONE); 6837 assert(texFormat != MESA_FORMAT_NONE); 6838 6839 dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, 6840 width, height, depth, 0); 6841 6842 sizeOK = st_TestProxyTexImage(ctx, target, 0, 0, texFormat, 6843 samples, width, height, depth); 6844 6845 if (_mesa_is_proxy_texture(target)) { 6846 if (samplesOK && dimensionsOK && sizeOK) { 6847 _mesa_init_teximage_fields_ms(ctx, texImage, width, height, depth, 0, 6848 internalformat, texFormat, 6849 samples, fixedsamplelocations); 6850 } 6851 else { 6852 /* clear all image fields */ 6853 clear_teximage_fields(texImage); 6854 } 6855 } 6856 else { 6857 if (!dimensionsOK) { 6858 _mesa_error(ctx, GL_INVALID_VALUE, 6859 "%s(invalid width=%d or height=%d)", func, width, height); 6860 return; 6861 } 6862 6863 if (!sizeOK) { 6864 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(texture too large)", func); 6865 return; 6866 } 6867 6868 /* Check if texObj->Immutable is set */ 6869 if (texObj->Immutable) { 6870 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable)", func); 6871 return; 6872 } 6873 6874 if (texObj->IsSparse && 6875 _mesa_sparse_texture_error_check(ctx, dims, texObj, texFormat, target, 0, 6876 width, height, depth, func)) 6877 return; /* error was recorded */ 6878 6879 st_FreeTextureImageBuffer(ctx, texImage); 6880 6881 _mesa_init_teximage_fields_ms(ctx, texImage, width, height, depth, 0, 6882 internalformat, texFormat, 6883 samples, fixedsamplelocations); 6884 6885 if (width > 0 && height > 0 && depth > 0) { 6886 if (memObj) { 6887 if (!st_SetTextureStorageForMemoryObject(ctx, texObj, 6888 memObj, 1, width, 6889 height, depth, 6890 offset)) { 6891 6892 _mesa_init_teximage_fields(ctx, texImage, 0, 0, 0, 0, 6893 internalformat, texFormat); 6894 } 6895 } else { 6896 if (!st_AllocTextureStorage(ctx, texObj, 1, 6897 width, height, depth)) { 6898 /* tidy up the texture image state. strictly speaking, 6899 * we're allowed to just leave this in whatever state we 6900 * like, but being tidy is good. 6901 */ 6902 _mesa_init_teximage_fields(ctx, texImage, 0, 0, 0, 0, 6903 internalformat, texFormat); 6904 } 6905 } 6906 } 6907 6908 texObj->External = GL_FALSE; 6909 texObj->Immutable |= immutable; 6910 6911 if (immutable) { 6912 _mesa_set_texture_view_state(ctx, texObj, target, 1); 6913 } 6914 6915 _mesa_update_fbo_texture(ctx, texObj, 0, 0); 6916 } 6917} 6918 6919 6920void GLAPIENTRY 6921_mesa_TexImage2DMultisample(GLenum target, GLsizei samples, 6922 GLenum internalformat, GLsizei width, 6923 GLsizei height, GLboolean fixedsamplelocations) 6924{ 6925 GET_CURRENT_CONTEXT(ctx); 6926 6927 texture_image_multisample(ctx, 2, NULL, NULL, target, samples, 6928 internalformat, width, height, 1, 6929 fixedsamplelocations, GL_FALSE, 0, 6930 "glTexImage2DMultisample"); 6931} 6932 6933 6934void GLAPIENTRY 6935_mesa_TexImage3DMultisample(GLenum target, GLsizei samples, 6936 GLenum internalformat, GLsizei width, 6937 GLsizei height, GLsizei depth, 6938 GLboolean fixedsamplelocations) 6939{ 6940 GET_CURRENT_CONTEXT(ctx); 6941 6942 texture_image_multisample(ctx, 3, NULL, NULL, target, samples, 6943 internalformat, width, height, depth, 6944 fixedsamplelocations, GL_FALSE, 0, 6945 "glTexImage3DMultisample"); 6946} 6947 6948static bool 6949valid_texstorage_ms_parameters(GLsizei width, GLsizei height, GLsizei depth, 6950 unsigned dims) 6951{ 6952 GET_CURRENT_CONTEXT(ctx); 6953 6954 if (!_mesa_valid_tex_storage_dim(width, height, depth)) { 6955 _mesa_error(ctx, GL_INVALID_VALUE, 6956 "glTexStorage%uDMultisample(width=%d,height=%d,depth=%d)", 6957 dims, width, height, depth); 6958 return false; 6959 } 6960 return true; 6961} 6962 6963void GLAPIENTRY 6964_mesa_TexStorage2DMultisample(GLenum target, GLsizei samples, 6965 GLenum internalformat, GLsizei width, 6966 GLsizei height, GLboolean fixedsamplelocations) 6967{ 6968 GET_CURRENT_CONTEXT(ctx); 6969 6970 if (!valid_texstorage_ms_parameters(width, height, 1, 2)) 6971 return; 6972 6973 texture_image_multisample(ctx, 2, NULL, NULL, target, samples, 6974 internalformat, width, height, 1, 6975 fixedsamplelocations, GL_TRUE, 0, 6976 "glTexStorage2DMultisample"); 6977} 6978 6979void GLAPIENTRY 6980_mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, 6981 GLenum internalformat, GLsizei width, 6982 GLsizei height, GLsizei depth, 6983 GLboolean fixedsamplelocations) 6984{ 6985 GET_CURRENT_CONTEXT(ctx); 6986 6987 if (!valid_texstorage_ms_parameters(width, height, depth, 3)) 6988 return; 6989 6990 texture_image_multisample(ctx, 3, NULL, NULL, target, samples, 6991 internalformat, width, height, depth, 6992 fixedsamplelocations, GL_TRUE, 0, 6993 "glTexStorage3DMultisample"); 6994} 6995 6996void GLAPIENTRY 6997_mesa_TextureStorage2DMultisample(GLuint texture, GLsizei samples, 6998 GLenum internalformat, GLsizei width, 6999 GLsizei height, 7000 GLboolean fixedsamplelocations) 7001{ 7002 struct gl_texture_object *texObj; 7003 GET_CURRENT_CONTEXT(ctx); 7004 7005 texObj = _mesa_lookup_texture_err(ctx, texture, 7006 "glTextureStorage2DMultisample"); 7007 if (!texObj) 7008 return; 7009 7010 if (!valid_texstorage_ms_parameters(width, height, 1, 2)) 7011 return; 7012 7013 texture_image_multisample(ctx, 2, texObj, NULL, texObj->Target, 7014 samples, internalformat, width, height, 1, 7015 fixedsamplelocations, GL_TRUE, 0, 7016 "glTextureStorage2DMultisample"); 7017} 7018 7019void GLAPIENTRY 7020_mesa_TextureStorage3DMultisample(GLuint texture, GLsizei samples, 7021 GLenum internalformat, GLsizei width, 7022 GLsizei height, GLsizei depth, 7023 GLboolean fixedsamplelocations) 7024{ 7025 struct gl_texture_object *texObj; 7026 GET_CURRENT_CONTEXT(ctx); 7027 7028 /* Get the texture object by Name. */ 7029 texObj = _mesa_lookup_texture_err(ctx, texture, 7030 "glTextureStorage3DMultisample"); 7031 if (!texObj) 7032 return; 7033 7034 if (!valid_texstorage_ms_parameters(width, height, depth, 3)) 7035 return; 7036 7037 texture_image_multisample(ctx, 3, texObj, NULL, texObj->Target, samples, 7038 internalformat, width, height, depth, 7039 fixedsamplelocations, GL_TRUE, 0, 7040 "glTextureStorage3DMultisample"); 7041} 7042 7043void GLAPIENTRY 7044_mesa_TextureStorage2DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, 7045 GLenum internalformat, GLsizei width, 7046 GLsizei height, 7047 GLboolean fixedsamplelocations) 7048{ 7049 struct gl_texture_object *texObj; 7050 GET_CURRENT_CONTEXT(ctx); 7051 7052 texObj = lookup_texture_ext_dsa(ctx, target, texture, 7053 "glTextureStorage2DMultisampleEXT"); 7054 if (!texObj) 7055 return; 7056 7057 if (!valid_texstorage_ms_parameters(width, height, 1, 2)) 7058 return; 7059 7060 texture_image_multisample(ctx, 2, texObj, NULL, texObj->Target, 7061 samples, internalformat, width, height, 1, 7062 fixedsamplelocations, GL_TRUE, 0, 7063 "glTextureStorage2DMultisampleEXT"); 7064} 7065 7066void GLAPIENTRY 7067_mesa_TextureStorage3DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, 7068 GLenum internalformat, GLsizei width, 7069 GLsizei height, GLsizei depth, 7070 GLboolean fixedsamplelocations) 7071{ 7072 struct gl_texture_object *texObj; 7073 GET_CURRENT_CONTEXT(ctx); 7074 7075 texObj = lookup_texture_ext_dsa(ctx, target, texture, 7076 "glTextureStorage3DMultisampleEXT"); 7077 if (!texObj) 7078 return; 7079 7080 if (!valid_texstorage_ms_parameters(width, height, depth, 3)) 7081 return; 7082 7083 texture_image_multisample(ctx, 3, texObj, NULL, texObj->Target, samples, 7084 internalformat, width, height, depth, 7085 fixedsamplelocations, GL_TRUE, 0, 7086 "glTextureStorage3DMultisampleEXT"); 7087} 7088 7089void 7090_mesa_texture_storage_ms_memory(struct gl_context *ctx, GLuint dims, 7091 struct gl_texture_object *texObj, 7092 struct gl_memory_object *memObj, 7093 GLenum target, GLsizei samples, 7094 GLenum internalFormat, GLsizei width, 7095 GLsizei height, GLsizei depth, 7096 GLboolean fixedSampleLocations, 7097 GLuint64 offset, const char* func) 7098{ 7099 assert(memObj); 7100 7101 texture_image_multisample(ctx, dims, texObj, memObj, target, samples, 7102 internalFormat, width, height, depth, 7103 fixedSampleLocations, GL_TRUE, offset, 7104 func); 7105} 7106