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