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 #include "imports.h" 42 #include "macros.h" 43 #include "mipmap.h" 44 #include "multisample.h" 45 #include "pixelstore.h" 46 #include "state.h" 47 #include "texcompress.h" 48 #include "texcompress_cpal.h" 49 #include "teximage.h" 50 #include "texobj.h" 51 #include "texstate.h" 52 #include "texstorage.h" 53 #include "textureview.h" 54 #include "mtypes.h" 55 #include "glformats.h" 56 #include "texstore.h" 57 #include "pbo.h" 58 59 60 /** 61 * State changes which we care about for glCopyTex[Sub]Image() calls. 62 * In particular, we care about pixel transfer state and buffer state 63 * (such as glReadBuffer to make sure we read from the right renderbuffer). 64 */ 65 #define NEW_COPY_TEX_STATE (_NEW_BUFFERS | _NEW_PIXEL) 66 67 /** 68 * Returns a corresponding internal floating point format for a given base 69 * format as specifed by OES_texture_float. In case of GL_FLOAT, the internal 70 * format needs to be a 32 bit component and in case of GL_HALF_FLOAT_OES it 71 * needs to be a 16 bit component. 72 * 73 * For example, given base format GL_RGBA, type GL_FLOAT return GL_RGBA32F_ARB. 74 */ 75 static GLenum 76 adjust_for_oes_float_texture(const struct gl_context *ctx, 77 GLenum format, GLenum type) 78 { 79 switch (type) { 80 case GL_FLOAT: 81 if (ctx->Extensions.OES_texture_float) { 82 switch (format) { 83 case GL_RGBA: 84 return GL_RGBA32F; 85 case GL_RGB: 86 return GL_RGB32F; 87 case GL_ALPHA: 88 return GL_ALPHA32F_ARB; 89 case GL_LUMINANCE: 90 return GL_LUMINANCE32F_ARB; 91 case GL_LUMINANCE_ALPHA: 92 return GL_LUMINANCE_ALPHA32F_ARB; 93 default: 94 break; 95 } 96 } 97 break; 98 99 case GL_HALF_FLOAT_OES: 100 if (ctx->Extensions.OES_texture_half_float) { 101 switch (format) { 102 case GL_RGBA: 103 return GL_RGBA16F; 104 case GL_RGB: 105 return GL_RGB16F; 106 case GL_ALPHA: 107 return GL_ALPHA16F_ARB; 108 case GL_LUMINANCE: 109 return GL_LUMINANCE16F_ARB; 110 case GL_LUMINANCE_ALPHA: 111 return GL_LUMINANCE_ALPHA16F_ARB; 112 default: 113 break; 114 } 115 } 116 break; 117 118 default: 119 break; 120 } 121 122 return format; 123 } 124 125 126 /** 127 * Install gl_texture_image in a gl_texture_object according to the target 128 * and level parameters. 129 * 130 * \param tObj texture object. 131 * \param target texture target. 132 * \param level image level. 133 * \param texImage texture image. 134 */ 135 static void 136 set_tex_image(struct gl_texture_object *tObj, 137 GLenum target, GLint level, 138 struct gl_texture_image *texImage) 139 { 140 const GLuint face = _mesa_tex_target_to_face(target); 141 142 assert(tObj); 143 assert(texImage); 144 if (target == GL_TEXTURE_RECTANGLE_NV || target == GL_TEXTURE_EXTERNAL_OES) 145 assert(level == 0); 146 147 tObj->Image[face][level] = texImage; 148 149 /* Set the 'back' pointer */ 150 texImage->TexObject = tObj; 151 texImage->Level = level; 152 texImage->Face = face; 153 } 154 155 156 /** 157 * Allocate a texture image structure. 158 * 159 * Called via ctx->Driver.NewTextureImage() unless overriden by a device 160 * driver. 161 * 162 * \return a pointer to gl_texture_image struct with all fields initialized to 163 * zero. 164 */ 165 struct gl_texture_image * 166 _mesa_new_texture_image( struct gl_context *ctx ) 167 { 168 (void) ctx; 169 return CALLOC_STRUCT(gl_texture_image); 170 } 171 172 173 /** 174 * Free a gl_texture_image and associated data. 175 * This function is a fallback called via ctx->Driver.DeleteTextureImage(). 176 * 177 * \param texImage texture image. 178 * 179 * Free the texture image structure and the associated image data. 180 */ 181 void 182 _mesa_delete_texture_image(struct gl_context *ctx, 183 struct gl_texture_image *texImage) 184 { 185 /* Free texImage->Data and/or any other driver-specific texture 186 * image storage. 187 */ 188 assert(ctx->Driver.FreeTextureImageBuffer); 189 ctx->Driver.FreeTextureImageBuffer( ctx, texImage ); 190 free(texImage); 191 } 192 193 194 /** 195 * Test if a target is a proxy target. 196 * 197 * \param target texture target. 198 * 199 * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise. 200 */ 201 GLboolean 202 _mesa_is_proxy_texture(GLenum target) 203 { 204 unsigned i; 205 static const GLenum targets[] = { 206 GL_PROXY_TEXTURE_1D, 207 GL_PROXY_TEXTURE_2D, 208 GL_PROXY_TEXTURE_3D, 209 GL_PROXY_TEXTURE_CUBE_MAP, 210 GL_PROXY_TEXTURE_RECTANGLE, 211 GL_PROXY_TEXTURE_1D_ARRAY, 212 GL_PROXY_TEXTURE_2D_ARRAY, 213 GL_PROXY_TEXTURE_CUBE_MAP_ARRAY, 214 GL_PROXY_TEXTURE_2D_MULTISAMPLE, 215 GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 216 }; 217 /* 218 * NUM_TEXTURE_TARGETS should match number of terms above, except there's no 219 * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES. 220 */ 221 STATIC_ASSERT(NUM_TEXTURE_TARGETS == ARRAY_SIZE(targets) + 2); 222 223 for (i = 0; i < ARRAY_SIZE(targets); ++i) 224 if (target == targets[i]) 225 return GL_TRUE; 226 return GL_FALSE; 227 } 228 229 230 /** 231 * Test if a target is an array target. 232 * 233 * \param target texture target. 234 * 235 * \return true if the target is an array target, false otherwise. 236 */ 237 bool 238 _mesa_is_array_texture(GLenum target) 239 { 240 switch (target) { 241 case GL_TEXTURE_1D_ARRAY: 242 case GL_TEXTURE_2D_ARRAY: 243 case GL_TEXTURE_CUBE_MAP_ARRAY: 244 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 245 return true; 246 default: 247 return false; 248 }; 249 } 250 251 /** 252 * Test if a target is a cube map. 253 * 254 * \param target texture target. 255 * 256 * \return true if the target is a cube map, false otherwise. 257 */ 258 bool 259 _mesa_is_cube_map_texture(GLenum target) 260 { 261 switch(target) { 262 case GL_TEXTURE_CUBE_MAP: 263 case GL_TEXTURE_CUBE_MAP_ARRAY: 264 return true; 265 default: 266 return false; 267 } 268 } 269 270 /** 271 * Return the proxy target which corresponds to the given texture target 272 */ 273 static GLenum 274 proxy_target(GLenum target) 275 { 276 switch (target) { 277 case GL_TEXTURE_1D: 278 case GL_PROXY_TEXTURE_1D: 279 return GL_PROXY_TEXTURE_1D; 280 case GL_TEXTURE_2D: 281 case GL_PROXY_TEXTURE_2D: 282 return GL_PROXY_TEXTURE_2D; 283 case GL_TEXTURE_3D: 284 case GL_PROXY_TEXTURE_3D: 285 return GL_PROXY_TEXTURE_3D; 286 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 287 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 288 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 289 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 290 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 291 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 292 case GL_TEXTURE_CUBE_MAP: 293 case GL_PROXY_TEXTURE_CUBE_MAP: 294 return GL_PROXY_TEXTURE_CUBE_MAP; 295 case GL_TEXTURE_RECTANGLE_NV: 296 case GL_PROXY_TEXTURE_RECTANGLE_NV: 297 return GL_PROXY_TEXTURE_RECTANGLE_NV; 298 case GL_TEXTURE_1D_ARRAY_EXT: 299 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 300 return GL_PROXY_TEXTURE_1D_ARRAY_EXT; 301 case GL_TEXTURE_2D_ARRAY_EXT: 302 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 303 return GL_PROXY_TEXTURE_2D_ARRAY_EXT; 304 case GL_TEXTURE_CUBE_MAP_ARRAY: 305 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 306 return GL_PROXY_TEXTURE_CUBE_MAP_ARRAY; 307 case GL_TEXTURE_2D_MULTISAMPLE: 308 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 309 return GL_PROXY_TEXTURE_2D_MULTISAMPLE; 310 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 311 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 312 return GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY; 313 default: 314 _mesa_problem(NULL, "unexpected target in proxy_target()"); 315 return 0; 316 } 317 } 318 319 320 321 322 /** 323 * Get a texture image pointer from a texture object, given a texture 324 * target and mipmap level. The target and level parameters should 325 * have already been error-checked. 326 * 327 * \param texObj texture unit. 328 * \param target texture target. 329 * \param level image level. 330 * 331 * \return pointer to the texture image structure, or NULL on failure. 332 */ 333 struct gl_texture_image * 334 _mesa_select_tex_image(const struct gl_texture_object *texObj, 335 GLenum target, GLint level) 336 { 337 const GLuint face = _mesa_tex_target_to_face(target); 338 339 assert(texObj); 340 assert(level >= 0); 341 assert(level < MAX_TEXTURE_LEVELS); 342 343 return texObj->Image[face][level]; 344 } 345 346 347 /** 348 * Like _mesa_select_tex_image() but if the image doesn't exist, allocate 349 * it and install it. Only return NULL if passed a bad parameter or run 350 * out of memory. 351 */ 352 struct gl_texture_image * 353 _mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, 354 GLenum target, GLint level) 355 { 356 struct gl_texture_image *texImage; 357 358 if (!texObj) 359 return NULL; 360 361 texImage = _mesa_select_tex_image(texObj, target, level); 362 if (!texImage) { 363 texImage = ctx->Driver.NewTextureImage(ctx); 364 if (!texImage) { 365 _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation"); 366 return NULL; 367 } 368 369 set_tex_image(texObj, target, level, texImage); 370 } 371 372 return texImage; 373 } 374 375 376 /** 377 * Return pointer to the specified proxy texture image. 378 * Note that proxy textures are per-context, not per-texture unit. 379 * \return pointer to texture image or NULL if invalid target, invalid 380 * level, or out of memory. 381 */ 382 static struct gl_texture_image * 383 get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level) 384 { 385 struct gl_texture_image *texImage; 386 GLuint texIndex; 387 388 if (level < 0) 389 return NULL; 390 391 switch (target) { 392 case GL_PROXY_TEXTURE_1D: 393 if (level >= ctx->Const.MaxTextureLevels) 394 return NULL; 395 texIndex = TEXTURE_1D_INDEX; 396 break; 397 case GL_PROXY_TEXTURE_2D: 398 if (level >= ctx->Const.MaxTextureLevels) 399 return NULL; 400 texIndex = TEXTURE_2D_INDEX; 401 break; 402 case GL_PROXY_TEXTURE_3D: 403 if (level >= ctx->Const.Max3DTextureLevels) 404 return NULL; 405 texIndex = TEXTURE_3D_INDEX; 406 break; 407 case GL_PROXY_TEXTURE_CUBE_MAP: 408 if (level >= ctx->Const.MaxCubeTextureLevels) 409 return NULL; 410 texIndex = TEXTURE_CUBE_INDEX; 411 break; 412 case GL_PROXY_TEXTURE_RECTANGLE_NV: 413 if (level > 0) 414 return NULL; 415 texIndex = TEXTURE_RECT_INDEX; 416 break; 417 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 418 if (level >= ctx->Const.MaxTextureLevels) 419 return NULL; 420 texIndex = TEXTURE_1D_ARRAY_INDEX; 421 break; 422 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 423 if (level >= ctx->Const.MaxTextureLevels) 424 return NULL; 425 texIndex = TEXTURE_2D_ARRAY_INDEX; 426 break; 427 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 428 if (level >= ctx->Const.MaxCubeTextureLevels) 429 return NULL; 430 texIndex = TEXTURE_CUBE_ARRAY_INDEX; 431 break; 432 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 433 if (level > 0) 434 return 0; 435 texIndex = TEXTURE_2D_MULTISAMPLE_INDEX; 436 break; 437 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 438 if (level > 0) 439 return 0; 440 texIndex = TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX; 441 break; 442 default: 443 return NULL; 444 } 445 446 texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level]; 447 if (!texImage) { 448 texImage = ctx->Driver.NewTextureImage(ctx); 449 if (!texImage) { 450 _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); 451 return NULL; 452 } 453 ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage; 454 /* Set the 'back' pointer */ 455 texImage->TexObject = ctx->Texture.ProxyTex[texIndex]; 456 } 457 return texImage; 458 } 459 460 461 /** 462 * Get the maximum number of allowed mipmap levels. 463 * 464 * \param ctx GL context. 465 * \param target texture target. 466 * 467 * \return the maximum number of allowed mipmap levels for the given 468 * texture target, or zero if passed a bad target. 469 * 470 * \sa gl_constants. 471 */ 472 GLint 473 _mesa_max_texture_levels(struct gl_context *ctx, GLenum target) 474 { 475 switch (target) { 476 case GL_TEXTURE_1D: 477 case GL_PROXY_TEXTURE_1D: 478 case GL_TEXTURE_2D: 479 case GL_PROXY_TEXTURE_2D: 480 return ctx->Const.MaxTextureLevels; 481 case GL_TEXTURE_3D: 482 case GL_PROXY_TEXTURE_3D: 483 return ctx->Const.Max3DTextureLevels; 484 case GL_TEXTURE_CUBE_MAP: 485 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 486 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 487 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 488 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 489 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 490 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 491 case GL_PROXY_TEXTURE_CUBE_MAP: 492 return ctx->Extensions.ARB_texture_cube_map 493 ? ctx->Const.MaxCubeTextureLevels : 0; 494 case GL_TEXTURE_RECTANGLE_NV: 495 case GL_PROXY_TEXTURE_RECTANGLE_NV: 496 return ctx->Extensions.NV_texture_rectangle ? 1 : 0; 497 case GL_TEXTURE_1D_ARRAY_EXT: 498 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 499 case GL_TEXTURE_2D_ARRAY_EXT: 500 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 501 return ctx->Extensions.EXT_texture_array 502 ? ctx->Const.MaxTextureLevels : 0; 503 case GL_TEXTURE_CUBE_MAP_ARRAY: 504 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 505 return _mesa_has_texture_cube_map_array(ctx) 506 ? ctx->Const.MaxCubeTextureLevels : 0; 507 case GL_TEXTURE_BUFFER: 508 return (_mesa_has_ARB_texture_buffer_object(ctx) || 509 _mesa_has_OES_texture_buffer(ctx)) ? 1 : 0; 510 case GL_TEXTURE_2D_MULTISAMPLE: 511 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 512 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 513 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 514 return (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx)) 515 && ctx->Extensions.ARB_texture_multisample 516 ? 1 : 0; 517 case GL_TEXTURE_EXTERNAL_OES: 518 /* fall-through */ 519 default: 520 return 0; /* bad target */ 521 } 522 } 523 524 525 /** 526 * Return number of dimensions per mipmap level for the given texture target. 527 */ 528 GLint 529 _mesa_get_texture_dimensions(GLenum target) 530 { 531 switch (target) { 532 case GL_TEXTURE_1D: 533 case GL_PROXY_TEXTURE_1D: 534 return 1; 535 case GL_TEXTURE_2D: 536 case GL_TEXTURE_RECTANGLE: 537 case GL_TEXTURE_CUBE_MAP: 538 case GL_PROXY_TEXTURE_2D: 539 case GL_PROXY_TEXTURE_RECTANGLE: 540 case GL_PROXY_TEXTURE_CUBE_MAP: 541 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 542 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 543 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 544 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 545 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 546 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 547 case GL_TEXTURE_1D_ARRAY: 548 case GL_PROXY_TEXTURE_1D_ARRAY: 549 case GL_TEXTURE_EXTERNAL_OES: 550 case GL_TEXTURE_2D_MULTISAMPLE: 551 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 552 return 2; 553 case GL_TEXTURE_3D: 554 case GL_PROXY_TEXTURE_3D: 555 case GL_TEXTURE_2D_ARRAY: 556 case GL_PROXY_TEXTURE_2D_ARRAY: 557 case GL_TEXTURE_CUBE_MAP_ARRAY: 558 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 559 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 560 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 561 return 3; 562 case GL_TEXTURE_BUFFER: 563 /* fall-through */ 564 default: 565 _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()", 566 target); 567 return 2; 568 } 569 } 570 571 572 /** 573 * Check if a texture target can have more than one layer. 574 */ 575 GLboolean 576 _mesa_tex_target_is_layered(GLenum target) 577 { 578 switch (target) { 579 case GL_TEXTURE_1D: 580 case GL_PROXY_TEXTURE_1D: 581 case GL_TEXTURE_2D: 582 case GL_PROXY_TEXTURE_2D: 583 case GL_TEXTURE_RECTANGLE: 584 case GL_PROXY_TEXTURE_RECTANGLE: 585 case GL_TEXTURE_2D_MULTISAMPLE: 586 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 587 case GL_TEXTURE_BUFFER: 588 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 589 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 590 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 591 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 592 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 593 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 594 case GL_TEXTURE_EXTERNAL_OES: 595 return GL_FALSE; 596 597 case GL_TEXTURE_3D: 598 case GL_PROXY_TEXTURE_3D: 599 case GL_TEXTURE_CUBE_MAP: 600 case GL_PROXY_TEXTURE_CUBE_MAP: 601 case GL_TEXTURE_1D_ARRAY: 602 case GL_PROXY_TEXTURE_1D_ARRAY: 603 case GL_TEXTURE_2D_ARRAY: 604 case GL_PROXY_TEXTURE_2D_ARRAY: 605 case GL_TEXTURE_CUBE_MAP_ARRAY: 606 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 607 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 608 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 609 return GL_TRUE; 610 611 default: 612 assert(!"Invalid texture target."); 613 return GL_FALSE; 614 } 615 } 616 617 618 /** 619 * Return the number of layers present in the given level of an array, 620 * cubemap or 3D texture. If the texture is not layered return zero. 621 */ 622 GLuint 623 _mesa_get_texture_layers(const struct gl_texture_object *texObj, GLint level) 624 { 625 assert(level >= 0 && level < MAX_TEXTURE_LEVELS); 626 627 switch (texObj->Target) { 628 case GL_TEXTURE_1D: 629 case GL_TEXTURE_2D: 630 case GL_TEXTURE_RECTANGLE: 631 case GL_TEXTURE_2D_MULTISAMPLE: 632 case GL_TEXTURE_BUFFER: 633 case GL_TEXTURE_EXTERNAL_OES: 634 return 0; 635 636 case GL_TEXTURE_CUBE_MAP: 637 return 6; 638 639 case GL_TEXTURE_1D_ARRAY: { 640 struct gl_texture_image *img = texObj->Image[0][level]; 641 return img ? img->Height : 0; 642 } 643 644 case GL_TEXTURE_3D: 645 case GL_TEXTURE_2D_ARRAY: 646 case GL_TEXTURE_CUBE_MAP_ARRAY: 647 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: { 648 struct gl_texture_image *img = texObj->Image[0][level]; 649 return img ? img->Depth : 0; 650 } 651 652 default: 653 assert(!"Invalid texture target."); 654 return 0; 655 } 656 } 657 658 659 /** 660 * Return the maximum number of mipmap levels for the given target 661 * and the dimensions. 662 * The dimensions are expected not to include the border. 663 */ 664 GLsizei 665 _mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height, 666 GLsizei depth) 667 { 668 GLsizei size; 669 670 switch (target) { 671 case GL_TEXTURE_1D: 672 case GL_TEXTURE_1D_ARRAY: 673 case GL_PROXY_TEXTURE_1D: 674 case GL_PROXY_TEXTURE_1D_ARRAY: 675 size = width; 676 break; 677 case GL_TEXTURE_CUBE_MAP: 678 case GL_TEXTURE_CUBE_MAP_ARRAY: 679 case GL_PROXY_TEXTURE_CUBE_MAP: 680 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 681 size = width; 682 break; 683 case GL_TEXTURE_2D: 684 case GL_TEXTURE_2D_ARRAY: 685 case GL_PROXY_TEXTURE_2D: 686 case GL_PROXY_TEXTURE_2D_ARRAY: 687 size = MAX2(width, height); 688 break; 689 case GL_TEXTURE_3D: 690 case GL_PROXY_TEXTURE_3D: 691 size = MAX3(width, height, depth); 692 break; 693 case GL_TEXTURE_RECTANGLE: 694 case GL_TEXTURE_EXTERNAL_OES: 695 case GL_TEXTURE_2D_MULTISAMPLE: 696 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 697 case GL_PROXY_TEXTURE_RECTANGLE: 698 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 699 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 700 return 1; 701 default: 702 assert(0); 703 return 1; 704 } 705 706 return _mesa_logbase2(size) + 1; 707 } 708 709 710 #if 000 /* not used anymore */ 711 /* 712 * glTexImage[123]D can accept a NULL image pointer. In this case we 713 * create a texture image with unspecified image contents per the OpenGL 714 * spec. 715 */ 716 static GLubyte * 717 make_null_texture(GLint width, GLint height, GLint depth, GLenum format) 718 { 719 const GLint components = _mesa_components_in_format(format); 720 const GLint numPixels = width * height * depth; 721 GLubyte *data = (GLubyte *) malloc(numPixels * components * sizeof(GLubyte)); 722 723 #ifdef DEBUG 724 /* 725 * Let's see if anyone finds this. If glTexImage2D() is called with 726 * a NULL image pointer then load the texture image with something 727 * interesting instead of leaving it indeterminate. 728 */ 729 if (data) { 730 static const char message[8][32] = { 731 " X X XXXXX XXX X ", 732 " XX XX X X X X X ", 733 " X X X X X X X ", 734 " X X XXXX XXX XXXXX ", 735 " X X X X X X ", 736 " X X X X X X X ", 737 " X X XXXXX XXX X X ", 738 " " 739 }; 740 741 GLubyte *imgPtr = data; 742 GLint h, i, j, k; 743 for (h = 0; h < depth; h++) { 744 for (i = 0; i < height; i++) { 745 GLint srcRow = 7 - (i % 8); 746 for (j = 0; j < width; j++) { 747 GLint srcCol = j % 32; 748 GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70; 749 for (k = 0; k < components; k++) { 750 *imgPtr++ = texel; 751 } 752 } 753 } 754 } 755 } 756 #endif 757 758 return data; 759 } 760 #endif 761 762 763 764 /** 765 * Set the size and format-related fields of a gl_texture_image struct 766 * to zero. This is used when a proxy texture test fails. 767 */ 768 static void 769 clear_teximage_fields(struct gl_texture_image *img) 770 { 771 assert(img); 772 img->_BaseFormat = 0; 773 img->InternalFormat = 0; 774 img->Border = 0; 775 img->Width = 0; 776 img->Height = 0; 777 img->Depth = 0; 778 img->Width2 = 0; 779 img->Height2 = 0; 780 img->Depth2 = 0; 781 img->WidthLog2 = 0; 782 img->HeightLog2 = 0; 783 img->DepthLog2 = 0; 784 img->TexFormat = MESA_FORMAT_NONE; 785 img->NumSamples = 0; 786 img->FixedSampleLocations = GL_TRUE; 787 } 788 789 790 /** 791 * Initialize basic fields of the gl_texture_image struct. 792 * 793 * \param ctx GL context. 794 * \param img texture image structure to be initialized. 795 * \param width image width. 796 * \param height image height. 797 * \param depth image depth. 798 * \param border image border. 799 * \param internalFormat internal format. 800 * \param format the actual hardware format (one of MESA_FORMAT_*) 801 * \param numSamples number of samples per texel, or zero for non-MS. 802 * \param fixedSampleLocations are sample locations fixed? 803 * 804 * Fills in the fields of \p img with the given information. 805 * Note: width, height and depth include the border. 806 */ 807 static void 808 init_teximage_fields_ms(struct gl_context *ctx, 809 struct gl_texture_image *img, 810 GLsizei width, GLsizei height, GLsizei depth, 811 GLint border, GLenum internalFormat, 812 mesa_format format, 813 GLuint numSamples, GLboolean fixedSampleLocations) 814 { 815 GLenum target; 816 assert(img); 817 assert(width >= 0); 818 assert(height >= 0); 819 assert(depth >= 0); 820 821 target = img->TexObject->Target; 822 img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat ); 823 assert(img->_BaseFormat != -1); 824 img->InternalFormat = internalFormat; 825 img->Border = border; 826 img->Width = width; 827 img->Height = height; 828 img->Depth = depth; 829 830 img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */ 831 img->WidthLog2 = _mesa_logbase2(img->Width2); 832 833 img->NumSamples = 0; 834 img->FixedSampleLocations = GL_TRUE; 835 836 switch(target) { 837 case GL_TEXTURE_1D: 838 case GL_TEXTURE_BUFFER: 839 case GL_PROXY_TEXTURE_1D: 840 if (height == 0) 841 img->Height2 = 0; 842 else 843 img->Height2 = 1; 844 img->HeightLog2 = 0; 845 if (depth == 0) 846 img->Depth2 = 0; 847 else 848 img->Depth2 = 1; 849 img->DepthLog2 = 0; 850 break; 851 case GL_TEXTURE_1D_ARRAY: 852 case GL_PROXY_TEXTURE_1D_ARRAY: 853 img->Height2 = height; /* no border */ 854 img->HeightLog2 = 0; /* not used */ 855 if (depth == 0) 856 img->Depth2 = 0; 857 else 858 img->Depth2 = 1; 859 img->DepthLog2 = 0; 860 break; 861 case GL_TEXTURE_2D: 862 case GL_TEXTURE_RECTANGLE: 863 case GL_TEXTURE_CUBE_MAP: 864 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 865 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 866 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 867 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 868 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 869 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 870 case GL_TEXTURE_EXTERNAL_OES: 871 case GL_PROXY_TEXTURE_2D: 872 case GL_PROXY_TEXTURE_RECTANGLE: 873 case GL_PROXY_TEXTURE_CUBE_MAP: 874 case GL_TEXTURE_2D_MULTISAMPLE: 875 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 876 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 877 img->HeightLog2 = _mesa_logbase2(img->Height2); 878 if (depth == 0) 879 img->Depth2 = 0; 880 else 881 img->Depth2 = 1; 882 img->DepthLog2 = 0; 883 break; 884 case GL_TEXTURE_2D_ARRAY: 885 case GL_PROXY_TEXTURE_2D_ARRAY: 886 case GL_TEXTURE_CUBE_MAP_ARRAY: 887 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 888 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 889 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 890 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 891 img->HeightLog2 = _mesa_logbase2(img->Height2); 892 img->Depth2 = depth; /* no border */ 893 img->DepthLog2 = 0; /* not used */ 894 break; 895 case GL_TEXTURE_3D: 896 case GL_PROXY_TEXTURE_3D: 897 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 898 img->HeightLog2 = _mesa_logbase2(img->Height2); 899 img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ 900 img->DepthLog2 = _mesa_logbase2(img->Depth2); 901 break; 902 default: 903 _mesa_problem(NULL, "invalid target 0x%x in _mesa_init_teximage_fields()", 904 target); 905 } 906 907 img->MaxNumLevels = 908 _mesa_get_tex_max_num_levels(target, 909 img->Width2, img->Height2, img->Depth2); 910 img->TexFormat = format; 911 img->NumSamples = numSamples; 912 img->FixedSampleLocations = fixedSampleLocations; 913 } 914 915 916 void 917 _mesa_init_teximage_fields(struct gl_context *ctx, 918 struct gl_texture_image *img, 919 GLsizei width, GLsizei height, GLsizei depth, 920 GLint border, GLenum internalFormat, 921 mesa_format format) 922 { 923 init_teximage_fields_ms(ctx, img, width, height, depth, border, 924 internalFormat, format, 0, GL_TRUE); 925 } 926 927 928 /** 929 * Free and clear fields of the gl_texture_image struct. 930 * 931 * \param ctx GL context. 932 * \param texImage texture image structure to be cleared. 933 * 934 * After the call, \p texImage will have no data associated with it. Its 935 * fields are cleared so that its parent object will test incomplete. 936 */ 937 void 938 _mesa_clear_texture_image(struct gl_context *ctx, 939 struct gl_texture_image *texImage) 940 { 941 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 942 clear_teximage_fields(texImage); 943 } 944 945 946 /** 947 * Check the width, height, depth and border of a texture image are legal. 948 * Used by all the glTexImage, glCompressedTexImage and glCopyTexImage 949 * functions. 950 * The target and level parameters will have already been validated. 951 * \return GL_TRUE if size is OK, GL_FALSE otherwise. 952 */ 953 GLboolean 954 _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target, 955 GLint level, GLint width, GLint height, 956 GLint depth, GLint border) 957 { 958 GLint maxSize; 959 960 switch (target) { 961 case GL_TEXTURE_1D: 962 case GL_PROXY_TEXTURE_1D: 963 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); /* level zero size */ 964 maxSize >>= level; /* level size */ 965 if (width < 2 * border || width > 2 * border + maxSize) 966 return GL_FALSE; 967 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 968 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 969 return GL_FALSE; 970 } 971 return GL_TRUE; 972 973 case GL_TEXTURE_2D: 974 case GL_PROXY_TEXTURE_2D: 975 case GL_TEXTURE_2D_MULTISAMPLE: 976 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 977 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 978 maxSize >>= level; 979 if (width < 2 * border || width > 2 * border + maxSize) 980 return GL_FALSE; 981 if (height < 2 * border || height > 2 * border + maxSize) 982 return GL_FALSE; 983 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 984 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 985 return GL_FALSE; 986 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 987 return GL_FALSE; 988 } 989 return GL_TRUE; 990 991 case GL_TEXTURE_3D: 992 case GL_PROXY_TEXTURE_3D: 993 maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); 994 maxSize >>= level; 995 if (width < 2 * border || width > 2 * border + maxSize) 996 return GL_FALSE; 997 if (height < 2 * border || height > 2 * border + maxSize) 998 return GL_FALSE; 999 if (depth < 2 * border || depth > 2 * border + maxSize) 1000 return GL_FALSE; 1001 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1002 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1003 return GL_FALSE; 1004 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 1005 return GL_FALSE; 1006 if (depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) 1007 return GL_FALSE; 1008 } 1009 return GL_TRUE; 1010 1011 case GL_TEXTURE_RECTANGLE_NV: 1012 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1013 if (level != 0) 1014 return GL_FALSE; 1015 maxSize = ctx->Const.MaxTextureRectSize; 1016 if (width < 0 || width > maxSize) 1017 return GL_FALSE; 1018 if (height < 0 || height > maxSize) 1019 return GL_FALSE; 1020 return GL_TRUE; 1021 1022 case GL_TEXTURE_CUBE_MAP: 1023 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1024 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1025 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1026 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1027 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1028 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1029 case GL_PROXY_TEXTURE_CUBE_MAP: 1030 maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); 1031 maxSize >>= level; 1032 if (width != height) 1033 return GL_FALSE; 1034 if (width < 2 * border || width > 2 * border + maxSize) 1035 return GL_FALSE; 1036 if (height < 2 * border || height > 2 * border + maxSize) 1037 return GL_FALSE; 1038 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1039 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1040 return GL_FALSE; 1041 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 1042 return GL_FALSE; 1043 } 1044 return GL_TRUE; 1045 1046 case GL_TEXTURE_1D_ARRAY_EXT: 1047 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1048 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1049 maxSize >>= level; 1050 if (width < 2 * border || width > 2 * border + maxSize) 1051 return GL_FALSE; 1052 if (height < 0 || height > ctx->Const.MaxArrayTextureLayers) 1053 return GL_FALSE; 1054 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1055 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1056 return GL_FALSE; 1057 } 1058 return GL_TRUE; 1059 1060 case GL_TEXTURE_2D_ARRAY_EXT: 1061 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1062 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1063 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 1064 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1065 maxSize >>= level; 1066 if (width < 2 * border || width > 2 * border + maxSize) 1067 return GL_FALSE; 1068 if (height < 2 * border || height > 2 * border + maxSize) 1069 return GL_FALSE; 1070 if (depth < 0 || depth > ctx->Const.MaxArrayTextureLayers) 1071 return GL_FALSE; 1072 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1073 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1074 return GL_FALSE; 1075 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 1076 return GL_FALSE; 1077 } 1078 return GL_TRUE; 1079 1080 case GL_TEXTURE_CUBE_MAP_ARRAY: 1081 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1082 maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); 1083 if (width < 2 * border || width > 2 * border + maxSize) 1084 return GL_FALSE; 1085 if (height < 2 * border || height > 2 * border + maxSize) 1086 return GL_FALSE; 1087 if (depth < 0 || depth > ctx->Const.MaxArrayTextureLayers || depth % 6) 1088 return GL_FALSE; 1089 if (width != height) 1090 return GL_FALSE; 1091 if (level >= ctx->Const.MaxCubeTextureLevels) 1092 return GL_FALSE; 1093 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1094 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1095 return GL_FALSE; 1096 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 1097 return GL_FALSE; 1098 } 1099 return GL_TRUE; 1100 default: 1101 _mesa_problem(ctx, "Invalid target in _mesa_legal_texture_dimensions()"); 1102 return GL_FALSE; 1103 } 1104 } 1105 1106 static bool 1107 error_check_subtexture_negative_dimensions(struct gl_context *ctx, 1108 GLuint dims, 1109 GLsizei subWidth, 1110 GLsizei subHeight, 1111 GLsizei subDepth, 1112 const char *func) 1113 { 1114 /* Check size */ 1115 if (subWidth < 0) { 1116 _mesa_error(ctx, GL_INVALID_VALUE, "%s(width=%d)", func, subWidth); 1117 return true; 1118 } 1119 1120 if (dims > 1 && subHeight < 0) { 1121 _mesa_error(ctx, GL_INVALID_VALUE, "%s(height=%d)", func, subHeight); 1122 return true; 1123 } 1124 1125 if (dims > 2 && subDepth < 0) { 1126 _mesa_error(ctx, GL_INVALID_VALUE, "%s(depth=%d)", func, subDepth); 1127 return true; 1128 } 1129 1130 return false; 1131 } 1132 1133 /** 1134 * Do error checking of xoffset, yoffset, zoffset, width, height and depth 1135 * for glTexSubImage, glCopyTexSubImage and glCompressedTexSubImage. 1136 * \param destImage the destination texture image. 1137 * \return GL_TRUE if error found, GL_FALSE otherwise. 1138 */ 1139 static GLboolean 1140 error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims, 1141 const struct gl_texture_image *destImage, 1142 GLint xoffset, GLint yoffset, GLint zoffset, 1143 GLsizei subWidth, GLsizei subHeight, 1144 GLsizei subDepth, const char *func) 1145 { 1146 const GLenum target = destImage->TexObject->Target; 1147 GLuint bw, bh, bd; 1148 1149 /* check xoffset and width */ 1150 if (xoffset < - (GLint) destImage->Border) { 1151 _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset)", func); 1152 return GL_TRUE; 1153 } 1154 1155 if (xoffset + subWidth > (GLint) destImage->Width) { 1156 _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset+width)", func); 1157 return GL_TRUE; 1158 } 1159 1160 /* check yoffset and height */ 1161 if (dims > 1) { 1162 GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destImage->Border; 1163 if (yoffset < -yBorder) { 1164 _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset)", func); 1165 return GL_TRUE; 1166 } 1167 if (yoffset + subHeight > (GLint) destImage->Height) { 1168 _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset+height)", func); 1169 return GL_TRUE; 1170 } 1171 } 1172 1173 /* check zoffset and depth */ 1174 if (dims > 2) { 1175 GLint depth; 1176 GLint zBorder = (target == GL_TEXTURE_2D_ARRAY || 1177 target == GL_TEXTURE_CUBE_MAP_ARRAY) ? 1178 0 : destImage->Border; 1179 1180 if (zoffset < -zBorder) { 1181 _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset)", func); 1182 return GL_TRUE; 1183 } 1184 1185 depth = (GLint) destImage->Depth; 1186 if (target == GL_TEXTURE_CUBE_MAP) 1187 depth = 6; 1188 if (zoffset + subDepth > depth) { 1189 _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset+depth)", func); 1190 return GL_TRUE; 1191 } 1192 } 1193 1194 /* 1195 * The OpenGL spec (and GL_ARB_texture_compression) says only whole 1196 * compressed texture images can be updated. But, that restriction may be 1197 * relaxed for particular compressed formats. At this time, all the 1198 * compressed formats supported by Mesa allow sub-textures to be updated 1199 * along compressed block boundaries. 1200 */ 1201 _mesa_get_format_block_size_3d(destImage->TexFormat, &bw, &bh, &bd); 1202 1203 if (bw != 1 || bh != 1 || bd != 1) { 1204 /* offset must be multiple of block size */ 1205 if ((xoffset % bw != 0) || (yoffset % bh != 0) || (zoffset % bd != 0)) { 1206 _mesa_error(ctx, GL_INVALID_OPERATION, 1207 "%s(xoffset = %d, yoffset = %d, zoffset = %d)", 1208 func, xoffset, yoffset, zoffset); 1209 return GL_TRUE; 1210 } 1211 1212 /* The size must be a multiple of bw x bh, or we must be using a 1213 * offset+size that exactly hits the edge of the image. This 1214 * is important for small mipmap levels (1x1, 2x1, etc) and for 1215 * NPOT textures. 1216 */ 1217 if ((subWidth % bw != 0) && 1218 (xoffset + subWidth != (GLint) destImage->Width)) { 1219 _mesa_error(ctx, GL_INVALID_OPERATION, 1220 "%s(width = %d)", func, subWidth); 1221 return GL_TRUE; 1222 } 1223 1224 if ((subHeight % bh != 0) && 1225 (yoffset + subHeight != (GLint) destImage->Height)) { 1226 _mesa_error(ctx, GL_INVALID_OPERATION, 1227 "%s(height = %d)", func, subHeight); 1228 return GL_TRUE; 1229 } 1230 1231 if ((subDepth % bd != 0) && 1232 (zoffset + subDepth != (GLint) destImage->Depth)) { 1233 _mesa_error(ctx, GL_INVALID_OPERATION, 1234 "%s(depth = %d)", func, subDepth); 1235 return GL_TRUE; 1236 } 1237 } 1238 1239 return GL_FALSE; 1240 } 1241 1242 1243 1244 1245 /** 1246 * This is the fallback for Driver.TestProxyTexImage() for doing device- 1247 * specific texture image size checks. 1248 * 1249 * A hardware driver might override this function if, for example, the 1250 * max 3D texture size is 512x512x64 (i.e. not a cube). 1251 * 1252 * Note that width, height, depth == 0 is not an error. However, a 1253 * texture with zero width/height/depth will be considered "incomplete" 1254 * and texturing will effectively be disabled. 1255 * 1256 * \param target any texture target/type 1257 * \param numLevels number of mipmap levels in the texture or 0 if not known 1258 * \param level as passed to glTexImage 1259 * \param format the MESA_FORMAT_x for the tex image 1260 * \param numSamples number of samples per texel 1261 * \param width as passed to glTexImage 1262 * \param height as passed to glTexImage 1263 * \param depth as passed to glTexImage 1264 * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable. 1265 */ 1266 GLboolean 1267 _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, 1268 GLuint numLevels, GLint level, 1269 mesa_format format, GLuint numSamples, 1270 GLint width, GLint height, GLint depth) 1271 { 1272 uint64_t bytes, mbytes; 1273 1274 if (numLevels > 0) { 1275 /* Compute total memory for a whole mipmap. This is the path 1276 * taken for glTexStorage(GL_PROXY_TEXTURE_x). 1277 */ 1278 unsigned l; 1279 1280 assert(level == 0); 1281 1282 bytes = 0; 1283 1284 for (l = 0; l < numLevels; l++) { 1285 GLint nextWidth, nextHeight, nextDepth; 1286 1287 bytes += _mesa_format_image_size64(format, width, height, depth); 1288 1289 if (_mesa_next_mipmap_level_size(target, 0, width, height, depth, 1290 &nextWidth, &nextHeight, 1291 &nextDepth)) { 1292 width = nextWidth; 1293 height = nextHeight; 1294 depth = nextDepth; 1295 } else { 1296 break; 1297 } 1298 } 1299 } else { 1300 /* We just compute the size of one mipmap level. This is the path 1301 * taken for glTexImage(GL_PROXY_TEXTURE_x). 1302 */ 1303 bytes = _mesa_format_image_size64(format, width, height, depth); 1304 } 1305 1306 bytes *= _mesa_num_tex_faces(target); 1307 bytes *= MAX2(1, numSamples); 1308 1309 mbytes = bytes / (1024 * 1024); /* convert to MB */ 1310 1311 /* We just check if the image size is less than MaxTextureMbytes. 1312 * Some drivers may do more specific checks. 1313 */ 1314 return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes; 1315 } 1316 1317 1318 /** 1319 * Return true if the format is only valid for glCompressedTexImage. 1320 */ 1321 static bool 1322 compressedteximage_only_format(const struct gl_context *ctx, GLenum format) 1323 { 1324 switch (format) { 1325 case GL_ETC1_RGB8_OES: 1326 case GL_PALETTE4_RGB8_OES: 1327 case GL_PALETTE4_RGBA8_OES: 1328 case GL_PALETTE4_R5_G6_B5_OES: 1329 case GL_PALETTE4_RGBA4_OES: 1330 case GL_PALETTE4_RGB5_A1_OES: 1331 case GL_PALETTE8_RGB8_OES: 1332 case GL_PALETTE8_RGBA8_OES: 1333 case GL_PALETTE8_R5_G6_B5_OES: 1334 case GL_PALETTE8_RGBA4_OES: 1335 case GL_PALETTE8_RGB5_A1_OES: 1336 return true; 1337 default: 1338 return false; 1339 } 1340 } 1341 1342 /** 1343 * Return true if the format doesn't support online compression. 1344 */ 1345 bool 1346 _mesa_format_no_online_compression(const struct gl_context *ctx, GLenum format) 1347 { 1348 return _mesa_is_astc_format(format) || 1349 _mesa_is_etc2_format(format) || 1350 compressedteximage_only_format(ctx, format); 1351 } 1352 1353 /* Writes to an GL error pointer if non-null and returns whether or not the 1354 * error is GL_NO_ERROR */ 1355 static bool 1356 write_error(GLenum *err_ptr, GLenum error) 1357 { 1358 if (err_ptr) 1359 *err_ptr = error; 1360 1361 return error == GL_NO_ERROR; 1362 } 1363 1364 /** 1365 * Helper function to determine whether a target and specific compression 1366 * format are supported. The error parameter returns GL_NO_ERROR if the 1367 * target can be compressed. Otherwise it returns either GL_INVALID_OPERATION 1368 * or GL_INVALID_ENUM, whichever is more appropriate. 1369 */ 1370 GLboolean 1371 _mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target, 1372 GLenum intFormat, GLenum *error) 1373 { 1374 GLboolean target_can_be_compresed = GL_FALSE; 1375 mesa_format format = _mesa_glenum_to_compressed_format(intFormat); 1376 enum mesa_format_layout layout = _mesa_get_format_layout(format); 1377 1378 switch (target) { 1379 case GL_TEXTURE_2D: 1380 case GL_PROXY_TEXTURE_2D: 1381 target_can_be_compresed = GL_TRUE; /* true for any compressed format so far */ 1382 break; 1383 case GL_PROXY_TEXTURE_CUBE_MAP: 1384 case GL_TEXTURE_CUBE_MAP: 1385 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1386 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1387 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1388 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1389 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1390 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1391 target_can_be_compresed = ctx->Extensions.ARB_texture_cube_map; 1392 break; 1393 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1394 case GL_TEXTURE_2D_ARRAY_EXT: 1395 target_can_be_compresed = ctx->Extensions.EXT_texture_array; 1396 break; 1397 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1398 case GL_TEXTURE_CUBE_MAP_ARRAY: 1399 /* From the KHR_texture_compression_astc_hdr spec: 1400 * 1401 * Add a second new column "3D Tex." which is empty for all non-ASTC 1402 * formats. If only the LDR profile is supported by the 1403 * implementation, this column is also empty for all ASTC formats. If 1404 * both the LDR and HDR profiles are supported only, this column is 1405 * checked for all ASTC formats. 1406 * 1407 * Add a third new column "Cube Map Array Tex." which is empty for all 1408 * non-ASTC formats, and checked for all ASTC formats. 1409 * 1410 * and, 1411 * 1412 * 'An INVALID_OPERATION error is generated by CompressedTexImage3D 1413 * if <internalformat> is TEXTURE_CUBE_MAP_ARRAY and the 1414 * "Cube Map Array" column of table 8.19 is *not* checked, or if 1415 * <internalformat> is TEXTURE_3D and the "3D Tex." column of table 1416 * 8.19 is *not* checked' 1417 * 1418 * The instances of <internalformat> above should say <target>. 1419 * 1420 * ETC2/EAC formats are the only alternative in GLES and thus such errors 1421 * have already been handled by normal ETC2/EAC behavior. 1422 */ 1423 1424 /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec: 1425 * 1426 * "The ETC2/EAC texture compression algorithm supports only 1427 * two-dimensional images. If internalformat is an ETC2/EAC format, 1428 * glCompressedTexImage3D will generate an INVALID_OPERATION error if 1429 * target is not TEXTURE_2D_ARRAY." 1430 * 1431 * This should also be applicable for glTexStorage3D(). Other available 1432 * targets for these functions are: TEXTURE_3D and TEXTURE_CUBE_MAP_ARRAY. 1433 */ 1434 if (layout == MESA_FORMAT_LAYOUT_ETC2 && _mesa_is_gles3(ctx)) 1435 return write_error(error, GL_INVALID_OPERATION); 1436 target_can_be_compresed = _mesa_has_texture_cube_map_array(ctx); 1437 break; 1438 case GL_TEXTURE_3D: 1439 switch (layout) { 1440 case MESA_FORMAT_LAYOUT_ETC2: 1441 /* See ETC2/EAC comment in case GL_TEXTURE_CUBE_MAP_ARRAY. */ 1442 if (_mesa_is_gles3(ctx)) 1443 return write_error(error, GL_INVALID_OPERATION); 1444 break; 1445 case MESA_FORMAT_LAYOUT_BPTC: 1446 target_can_be_compresed = ctx->Extensions.ARB_texture_compression_bptc; 1447 break; 1448 case MESA_FORMAT_LAYOUT_ASTC: 1449 target_can_be_compresed = 1450 ctx->Extensions.KHR_texture_compression_astc_hdr || 1451 ctx->Extensions.KHR_texture_compression_astc_sliced_3d; 1452 1453 /* Throw an INVALID_OPERATION error if the target is TEXTURE_3D and 1454 * neither of the above extensions are supported. See comment in 1455 * switch case GL_TEXTURE_CUBE_MAP_ARRAY for more info. 1456 */ 1457 if (!target_can_be_compresed) 1458 return write_error(error, GL_INVALID_OPERATION); 1459 break; 1460 default: 1461 break; 1462 } 1463 default: 1464 break; 1465 } 1466 return write_error(error, 1467 target_can_be_compresed ? GL_NO_ERROR : GL_INVALID_ENUM); 1468 } 1469 1470 1471 /** 1472 * Check if the given texture target value is legal for a 1473 * glTexImage1/2/3D call. 1474 */ 1475 static GLboolean 1476 legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target) 1477 { 1478 switch (dims) { 1479 case 1: 1480 switch (target) { 1481 case GL_TEXTURE_1D: 1482 case GL_PROXY_TEXTURE_1D: 1483 return _mesa_is_desktop_gl(ctx); 1484 default: 1485 return GL_FALSE; 1486 } 1487 case 2: 1488 switch (target) { 1489 case GL_TEXTURE_2D: 1490 return GL_TRUE; 1491 case GL_PROXY_TEXTURE_2D: 1492 return _mesa_is_desktop_gl(ctx); 1493 case GL_PROXY_TEXTURE_CUBE_MAP: 1494 return _mesa_is_desktop_gl(ctx) 1495 && ctx->Extensions.ARB_texture_cube_map; 1496 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1497 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1498 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1499 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1500 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1501 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1502 return ctx->Extensions.ARB_texture_cube_map; 1503 case GL_TEXTURE_RECTANGLE_NV: 1504 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1505 return _mesa_is_desktop_gl(ctx) 1506 && ctx->Extensions.NV_texture_rectangle; 1507 case GL_TEXTURE_1D_ARRAY_EXT: 1508 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1509 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array; 1510 default: 1511 return GL_FALSE; 1512 } 1513 case 3: 1514 switch (target) { 1515 case GL_TEXTURE_3D: 1516 return GL_TRUE; 1517 case GL_PROXY_TEXTURE_3D: 1518 return _mesa_is_desktop_gl(ctx); 1519 case GL_TEXTURE_2D_ARRAY_EXT: 1520 return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) 1521 || _mesa_is_gles3(ctx); 1522 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1523 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array; 1524 case GL_TEXTURE_CUBE_MAP_ARRAY: 1525 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1526 return _mesa_has_texture_cube_map_array(ctx); 1527 default: 1528 return GL_FALSE; 1529 } 1530 default: 1531 _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims); 1532 return GL_FALSE; 1533 } 1534 } 1535 1536 1537 /** 1538 * Check if the given texture target value is legal for a 1539 * glTexSubImage, glCopyTexSubImage or glCopyTexImage call. 1540 * The difference compared to legal_teximage_target() above is that 1541 * proxy targets are not supported. 1542 */ 1543 static GLboolean 1544 legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target, 1545 bool dsa) 1546 { 1547 switch (dims) { 1548 case 1: 1549 return _mesa_is_desktop_gl(ctx) && target == GL_TEXTURE_1D; 1550 case 2: 1551 switch (target) { 1552 case GL_TEXTURE_2D: 1553 return GL_TRUE; 1554 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1555 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1556 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1557 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1558 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1559 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1560 return ctx->Extensions.ARB_texture_cube_map; 1561 case GL_TEXTURE_RECTANGLE_NV: 1562 return _mesa_is_desktop_gl(ctx) 1563 && ctx->Extensions.NV_texture_rectangle; 1564 case GL_TEXTURE_1D_ARRAY_EXT: 1565 return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array; 1566 default: 1567 return GL_FALSE; 1568 } 1569 case 3: 1570 switch (target) { 1571 case GL_TEXTURE_3D: 1572 return GL_TRUE; 1573 case GL_TEXTURE_2D_ARRAY_EXT: 1574 return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) 1575 || _mesa_is_gles3(ctx); 1576 case GL_TEXTURE_CUBE_MAP_ARRAY: 1577 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1578 return _mesa_has_texture_cube_map_array(ctx); 1579 1580 /* Table 8.15 of the OpenGL 4.5 core profile spec 1581 * (20141030) says that TEXTURE_CUBE_MAP is valid for TextureSubImage3D 1582 * and CopyTextureSubImage3D. 1583 */ 1584 case GL_TEXTURE_CUBE_MAP: 1585 return dsa; 1586 default: 1587 return GL_FALSE; 1588 } 1589 default: 1590 _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()", 1591 dims); 1592 return GL_FALSE; 1593 } 1594 } 1595 1596 1597 /** 1598 * Helper function to determine if a texture object is mutable (in terms 1599 * of GL_ARB_texture_storage). 1600 */ 1601 static GLboolean 1602 mutable_tex_object(struct gl_context *ctx, GLenum target) 1603 { 1604 struct gl_texture_object *texObj = _mesa_get_current_tex_object(ctx, target); 1605 if (!texObj) 1606 return GL_FALSE; 1607 1608 return !texObj->Immutable; 1609 } 1610 1611 1612 /** 1613 * Return expected size of a compressed texture. 1614 */ 1615 static GLuint 1616 compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth, 1617 GLenum glformat) 1618 { 1619 mesa_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 1620 return _mesa_format_image_size(mesaFormat, width, height, depth); 1621 } 1622 1623 /** 1624 * Verify that a texture format is valid with a particular target 1625 * 1626 * In particular, textures with base format of \c GL_DEPTH_COMPONENT or 1627 * \c GL_DEPTH_STENCIL are only valid with certain, context dependent texture 1628 * targets. 1629 * 1630 * \param ctx GL context 1631 * \param target Texture target 1632 * \param internalFormat Internal format of the texture image 1633 * 1634 * \returns true if the combination is legal, false otherwise. 1635 */ 1636 bool 1637 _mesa_legal_texture_base_format_for_target(struct gl_context *ctx, 1638 GLenum target, GLenum internalFormat) 1639 { 1640 if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT 1641 || _mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_STENCIL 1642 || _mesa_base_tex_format(ctx, internalFormat) == GL_STENCIL_INDEX) { 1643 /* Section 3.8.3 (Texture Image Specification) of the OpenGL 3.3 Core 1644 * Profile spec says: 1645 * 1646 * "Textures with a base internal format of DEPTH_COMPONENT or 1647 * DEPTH_STENCIL are supported by texture image specification 1648 * commands only if target is TEXTURE_1D, TEXTURE_2D, 1649 * TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_RECTANGLE, 1650 * TEXTURE_CUBE_MAP, PROXY_TEXTURE_1D, PROXY_TEXTURE_2D, 1651 * PROXY_TEXTURE_1D_ARRAY, PROXY_TEXTURE_2D_ARRAY, 1652 * PROXY_TEXTURE_RECTANGLE, or PROXY_TEXTURE_CUBE_MAP. Using these 1653 * formats in conjunction with any other target will result in an 1654 * INVALID_OPERATION error." 1655 * 1656 * Cubemaps are only supported with desktop OpenGL version >= 3.0, 1657 * EXT_gpu_shader4, or, on OpenGL ES 2.0+, OES_depth_texture_cube_map. 1658 */ 1659 if (target != GL_TEXTURE_1D && 1660 target != GL_PROXY_TEXTURE_1D && 1661 target != GL_TEXTURE_2D && 1662 target != GL_PROXY_TEXTURE_2D && 1663 target != GL_TEXTURE_1D_ARRAY && 1664 target != GL_PROXY_TEXTURE_1D_ARRAY && 1665 target != GL_TEXTURE_2D_ARRAY && 1666 target != GL_PROXY_TEXTURE_2D_ARRAY && 1667 target != GL_TEXTURE_RECTANGLE_ARB && 1668 target != GL_PROXY_TEXTURE_RECTANGLE_ARB && 1669 !((_mesa_is_cube_face(target) || 1670 target == GL_TEXTURE_CUBE_MAP || 1671 target == GL_PROXY_TEXTURE_CUBE_MAP) && 1672 (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4 1673 || (ctx->API == API_OPENGLES2 && ctx->Extensions.OES_depth_texture_cube_map))) && 1674 !((target == GL_TEXTURE_CUBE_MAP_ARRAY || 1675 target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY) && 1676 _mesa_has_texture_cube_map_array(ctx))) { 1677 return false; 1678 } 1679 } 1680 1681 return true; 1682 } 1683 1684 static bool 1685 texture_formats_agree(GLenum internalFormat, 1686 GLenum format) 1687 { 1688 GLboolean colorFormat; 1689 GLboolean is_format_depth_or_depthstencil; 1690 GLboolean is_internalFormat_depth_or_depthstencil; 1691 1692 /* Even though there are no color-index textures, we still have to support 1693 * uploading color-index data and remapping it to RGB via the 1694 * GL_PIXEL_MAP_I_TO_[RGBA] tables. 1695 */ 1696 const GLboolean indexFormat = (format == GL_COLOR_INDEX); 1697 1698 is_internalFormat_depth_or_depthstencil = 1699 _mesa_is_depth_format(internalFormat) || 1700 _mesa_is_depthstencil_format(internalFormat); 1701 1702 is_format_depth_or_depthstencil = 1703 _mesa_is_depth_format(format) || 1704 _mesa_is_depthstencil_format(format); 1705 1706 colorFormat = _mesa_is_color_format(format); 1707 1708 if (_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) 1709 return false; 1710 1711 if (is_internalFormat_depth_or_depthstencil != 1712 is_format_depth_or_depthstencil) 1713 return false; 1714 1715 if (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) 1716 return false; 1717 1718 return true; 1719 } 1720 1721 /** 1722 * Test the combination of format, type and internal format arguments of 1723 * different texture operations on GLES. 1724 * 1725 * \param ctx GL context. 1726 * \param format pixel data format given by the user. 1727 * \param type pixel data type given by the user. 1728 * \param internalFormat internal format given by the user. 1729 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1730 * \param callerName name of the caller function to print in the error message 1731 * 1732 * \return true if a error is found, false otherwise 1733 * 1734 * Currently, it is used by texture_error_check() and texsubimage_error_check(). 1735 */ 1736 static bool 1737 texture_format_error_check_gles(struct gl_context *ctx, GLenum format, 1738 GLenum type, GLenum internalFormat, 1739 GLuint dimensions, const char *callerName) 1740 { 1741 GLenum err; 1742 1743 if (_mesa_is_gles3(ctx)) { 1744 err = _mesa_es3_error_check_format_and_type(ctx, format, type, 1745 internalFormat); 1746 if (err != GL_NO_ERROR) { 1747 _mesa_error(ctx, err, 1748 "%s(format = %s, type = %s, internalformat = %s)", 1749 callerName, _mesa_enum_to_string(format), 1750 _mesa_enum_to_string(type), 1751 _mesa_enum_to_string(internalFormat)); 1752 return true; 1753 } 1754 } 1755 else { 1756 err = _mesa_es_error_check_format_and_type(ctx, format, type, dimensions); 1757 if (err != GL_NO_ERROR) { 1758 _mesa_error(ctx, err, "%s(format = %s, type = %s)", 1759 callerName, _mesa_enum_to_string(format), 1760 _mesa_enum_to_string(type)); 1761 return true; 1762 } 1763 } 1764 1765 return false; 1766 } 1767 1768 /** 1769 * Test the glTexImage[123]D() parameters for errors. 1770 * 1771 * \param ctx GL context. 1772 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1773 * \param target texture target given by the user (already validated). 1774 * \param level image level given by the user. 1775 * \param internalFormat internal format given by the user. 1776 * \param format pixel data format given by the user. 1777 * \param type pixel data type given by the user. 1778 * \param width image width given by the user. 1779 * \param height image height given by the user. 1780 * \param depth image depth given by the user. 1781 * \param border image border given by the user. 1782 * 1783 * \return GL_TRUE if a error is found, GL_FALSE otherwise 1784 * 1785 * Verifies each of the parameters against the constants specified in 1786 * __struct gl_contextRec::Const and the supported extensions, and according 1787 * to the OpenGL specification. 1788 * Note that we don't fully error-check the width, height, depth values 1789 * here. That's done in _mesa_legal_texture_dimensions() which is used 1790 * by several other GL entrypoints. Plus, texture dims have a special 1791 * interaction with proxy textures. 1792 */ 1793 static GLboolean 1794 texture_error_check( struct gl_context *ctx, 1795 GLuint dimensions, GLenum target, 1796 GLint level, GLint internalFormat, 1797 GLenum format, GLenum type, 1798 GLint width, GLint height, 1799 GLint depth, GLint border, 1800 const GLvoid *pixels ) 1801 { 1802 GLenum err; 1803 1804 /* Note: for proxy textures, some error conditions immediately generate 1805 * a GL error in the usual way. But others do not generate a GL error. 1806 * Instead, they cause the width, height, depth, format fields of the 1807 * texture image to be zeroed-out. The GL spec seems to indicate that the 1808 * zero-out behaviour is only used in cases related to memory allocation. 1809 */ 1810 1811 /* level check */ 1812 if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 1813 _mesa_error(ctx, GL_INVALID_VALUE, 1814 "glTexImage%dD(level=%d)", dimensions, level); 1815 return GL_TRUE; 1816 } 1817 1818 /* Check border */ 1819 if (border < 0 || border > 1 || 1820 ((ctx->API != API_OPENGL_COMPAT || 1821 target == GL_TEXTURE_RECTANGLE_NV || 1822 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 1823 _mesa_error(ctx, GL_INVALID_VALUE, 1824 "glTexImage%dD(border=%d)", dimensions, border); 1825 return GL_TRUE; 1826 } 1827 1828 if (width < 0 || height < 0 || depth < 0) { 1829 _mesa_error(ctx, GL_INVALID_VALUE, 1830 "glTexImage%dD(width, height or depth < 0)", dimensions); 1831 return GL_TRUE; 1832 } 1833 1834 /* Check incoming image format and type */ 1835 err = _mesa_error_check_format_and_type(ctx, format, type); 1836 if (err != GL_NO_ERROR) { 1837 /* Prior to OpenGL-ES 2.0, an INVALID_VALUE is expected instead of 1838 * INVALID_ENUM. From page 73 OpenGL ES 1.1 spec: 1839 * 1840 * "Specifying a value for internalformat that is not one of the 1841 * above (acceptable) values generates the error INVALID VALUE." 1842 */ 1843 if (err == GL_INVALID_ENUM && _mesa_is_gles(ctx) && ctx->Version < 20) 1844 err = GL_INVALID_VALUE; 1845 1846 _mesa_error(ctx, err, 1847 "glTexImage%dD(incompatible format = %s, type = %s)", 1848 dimensions, _mesa_enum_to_string(format), 1849 _mesa_enum_to_string(type)); 1850 return GL_TRUE; 1851 } 1852 1853 /* Check internalFormat */ 1854 if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 1855 _mesa_error(ctx, GL_INVALID_VALUE, 1856 "glTexImage%dD(internalFormat=%s)", 1857 dimensions, _mesa_enum_to_string(internalFormat)); 1858 return GL_TRUE; 1859 } 1860 1861 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 1862 * combinations of format, internalFormat, and type that can be used. 1863 * Formats and types that require additional extensions (e.g., GL_FLOAT 1864 * requires GL_OES_texture_float) are filtered elsewhere. 1865 */ 1866 if (_mesa_is_gles(ctx) && 1867 texture_format_error_check_gles(ctx, format, type, internalFormat, 1868 dimensions, "glTexImage%dD")) { 1869 return GL_TRUE; 1870 } 1871 1872 /* validate the bound PBO, if any */ 1873 if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack, 1874 width, height, depth, format, type, 1875 INT_MAX, pixels, "glTexImage")) { 1876 return GL_TRUE; 1877 } 1878 1879 /* make sure internal format and format basically agree */ 1880 if (!texture_formats_agree(internalFormat, format)) { 1881 _mesa_error(ctx, GL_INVALID_OPERATION, 1882 "glTexImage%dD(incompatible internalFormat = %s, format = %s)", 1883 dimensions, _mesa_enum_to_string(internalFormat), 1884 _mesa_enum_to_string(format)); 1885 return GL_TRUE; 1886 } 1887 1888 /* additional checks for ycbcr textures */ 1889 if (internalFormat == GL_YCBCR_MESA) { 1890 assert(ctx->Extensions.MESA_ycbcr_texture); 1891 if (type != GL_UNSIGNED_SHORT_8_8_MESA && 1892 type != GL_UNSIGNED_SHORT_8_8_REV_MESA) { 1893 char message[100]; 1894 _mesa_snprintf(message, sizeof(message), 1895 "glTexImage%dD(format/type YCBCR mismatch)", 1896 dimensions); 1897 _mesa_error(ctx, GL_INVALID_ENUM, "%s", message); 1898 return GL_TRUE; /* error */ 1899 } 1900 if (target != GL_TEXTURE_2D && 1901 target != GL_PROXY_TEXTURE_2D && 1902 target != GL_TEXTURE_RECTANGLE_NV && 1903 target != GL_PROXY_TEXTURE_RECTANGLE_NV) { 1904 _mesa_error(ctx, GL_INVALID_ENUM, 1905 "glTexImage%dD(bad target for YCbCr texture)", 1906 dimensions); 1907 return GL_TRUE; 1908 } 1909 if (border != 0) { 1910 char message[100]; 1911 _mesa_snprintf(message, sizeof(message), 1912 "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)", 1913 dimensions, border); 1914 _mesa_error(ctx, GL_INVALID_VALUE, "%s", message); 1915 return GL_TRUE; 1916 } 1917 } 1918 1919 /* additional checks for depth textures */ 1920 if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalFormat)) { 1921 _mesa_error(ctx, GL_INVALID_OPERATION, 1922 "glTexImage%dD(bad target for texture)", dimensions); 1923 return GL_TRUE; 1924 } 1925 1926 /* additional checks for compressed textures */ 1927 if (_mesa_is_compressed_format(ctx, internalFormat)) { 1928 GLenum err; 1929 if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) { 1930 _mesa_error(ctx, err, 1931 "glTexImage%dD(target can't be compressed)", dimensions); 1932 return GL_TRUE; 1933 } 1934 if (_mesa_format_no_online_compression(ctx, internalFormat)) { 1935 _mesa_error(ctx, GL_INVALID_OPERATION, 1936 "glTexImage%dD(no compression for format)", dimensions); 1937 return GL_TRUE; 1938 } 1939 if (border != 0) { 1940 _mesa_error(ctx, GL_INVALID_OPERATION, 1941 "glTexImage%dD(border!=0)", dimensions); 1942 return GL_TRUE; 1943 } 1944 } 1945 1946 /* additional checks for integer textures */ 1947 if ((ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) && 1948 (_mesa_is_enum_format_integer(format) != 1949 _mesa_is_enum_format_integer(internalFormat))) { 1950 _mesa_error(ctx, GL_INVALID_OPERATION, 1951 "glTexImage%dD(integer/non-integer format mismatch)", 1952 dimensions); 1953 return GL_TRUE; 1954 } 1955 1956 if (!mutable_tex_object(ctx, target)) { 1957 _mesa_error(ctx, GL_INVALID_OPERATION, 1958 "glTexImage%dD(immutable texture)", dimensions); 1959 return GL_TRUE; 1960 } 1961 1962 /* if we get here, the parameters are OK */ 1963 return GL_FALSE; 1964 } 1965 1966 1967 /** 1968 * Error checking for glCompressedTexImage[123]D(). 1969 * Note that the width, height and depth values are not fully error checked 1970 * here. 1971 * \return GL_TRUE if a error is found, GL_FALSE otherwise 1972 */ 1973 static GLenum 1974 compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, 1975 GLenum target, GLint level, 1976 GLenum internalFormat, GLsizei width, 1977 GLsizei height, GLsizei depth, GLint border, 1978 GLsizei imageSize, const GLvoid *data) 1979 { 1980 const GLint maxLevels = _mesa_max_texture_levels(ctx, target); 1981 GLint expectedSize; 1982 GLenum error = GL_NO_ERROR; 1983 char *reason = ""; /* no error */ 1984 1985 if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &error)) { 1986 reason = "target"; 1987 goto error; 1988 } 1989 1990 /* This will detect any invalid internalFormat value */ 1991 if (!_mesa_is_compressed_format(ctx, internalFormat)) { 1992 _mesa_error(ctx, GL_INVALID_ENUM, 1993 "glCompressedTexImage%dD(internalFormat=%s)", 1994 dimensions, _mesa_enum_to_string(internalFormat)); 1995 return GL_TRUE; 1996 } 1997 1998 /* validate the bound PBO, if any */ 1999 if (!_mesa_validate_pbo_source_compressed(ctx, dimensions, &ctx->Unpack, 2000 imageSize, data, 2001 "glCompressedTexImage")) { 2002 return GL_TRUE; 2003 } 2004 2005 switch (internalFormat) { 2006 case GL_PALETTE4_RGB8_OES: 2007 case GL_PALETTE4_RGBA8_OES: 2008 case GL_PALETTE4_R5_G6_B5_OES: 2009 case GL_PALETTE4_RGBA4_OES: 2010 case GL_PALETTE4_RGB5_A1_OES: 2011 case GL_PALETTE8_RGB8_OES: 2012 case GL_PALETTE8_RGBA8_OES: 2013 case GL_PALETTE8_R5_G6_B5_OES: 2014 case GL_PALETTE8_RGBA4_OES: 2015 case GL_PALETTE8_RGB5_A1_OES: 2016 /* check level (note that level should be zero or less!) */ 2017 if (level > 0 || level < -maxLevels) { 2018 reason = "level"; 2019 error = GL_INVALID_VALUE; 2020 goto error; 2021 } 2022 2023 if (dimensions != 2) { 2024 reason = "compressed paletted textures must be 2D"; 2025 error = GL_INVALID_OPERATION; 2026 goto error; 2027 } 2028 2029 /* Figure out the expected texture size (in bytes). This will be 2030 * checked against the actual size later. 2031 */ 2032 expectedSize = _mesa_cpal_compressed_size(level, internalFormat, 2033 width, height); 2034 2035 /* This is for the benefit of the TestProxyTexImage below. It expects 2036 * level to be non-negative. OES_compressed_paletted_texture uses a 2037 * weird mechanism where the level specified to glCompressedTexImage2D 2038 * is -(n-1) number of levels in the texture, and the data specifies the 2039 * complete mipmap stack. This is done to ensure the palette is the 2040 * same for all levels. 2041 */ 2042 level = -level; 2043 break; 2044 2045 default: 2046 /* check level */ 2047 if (level < 0 || level >= maxLevels) { 2048 reason = "level"; 2049 error = GL_INVALID_VALUE; 2050 goto error; 2051 } 2052 2053 /* Figure out the expected texture size (in bytes). This will be 2054 * checked against the actual size later. 2055 */ 2056 expectedSize = compressed_tex_size(width, height, depth, internalFormat); 2057 break; 2058 } 2059 2060 /* This should really never fail */ 2061 if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 2062 reason = "internalFormat"; 2063 error = GL_INVALID_ENUM; 2064 goto error; 2065 } 2066 2067 /* No compressed formats support borders at this time */ 2068 if (border != 0) { 2069 reason = "border != 0"; 2070 error = GL_INVALID_VALUE; 2071 goto error; 2072 } 2073 2074 /* Check for invalid pixel storage modes */ 2075 if (!_mesa_compressed_pixel_storage_error_check(ctx, dimensions, 2076 &ctx->Unpack, 2077 "glCompressedTexImage")) { 2078 return GL_FALSE; 2079 } 2080 2081 /* check image size in bytes */ 2082 if (expectedSize != imageSize) { 2083 /* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...] 2084 * if <imageSize> is not consistent with the format, dimensions, and 2085 * contents of the specified image. 2086 */ 2087 reason = "imageSize inconsistent with width/height/format"; 2088 error = GL_INVALID_VALUE; 2089 goto error; 2090 } 2091 2092 if (!mutable_tex_object(ctx, target)) { 2093 reason = "immutable texture"; 2094 error = GL_INVALID_OPERATION; 2095 goto error; 2096 } 2097 2098 return GL_FALSE; 2099 2100 error: 2101 /* Note: not all error paths exit through here. */ 2102 _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", 2103 dimensions, reason); 2104 return GL_TRUE; 2105 } 2106 2107 2108 2109 /** 2110 * Test glTexSubImage[123]D() parameters for errors. 2111 * 2112 * \param ctx GL context. 2113 * \param dimensions texture image dimensions (must be 1, 2 or 3). 2114 * \param target texture target given by the user (already validated) 2115 * \param level image level given by the user. 2116 * \param xoffset sub-image x offset given by the user. 2117 * \param yoffset sub-image y offset given by the user. 2118 * \param zoffset sub-image z offset given by the user. 2119 * \param format pixel data format given by the user. 2120 * \param type pixel data type given by the user. 2121 * \param width image width given by the user. 2122 * \param height image height given by the user. 2123 * \param depth image depth given by the user. 2124 * 2125 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2126 * 2127 * Verifies each of the parameters against the constants specified in 2128 * __struct gl_contextRec::Const and the supported extensions, and according 2129 * to the OpenGL specification. 2130 */ 2131 static GLboolean 2132 texsubimage_error_check(struct gl_context *ctx, GLuint dimensions, 2133 struct gl_texture_object *texObj, 2134 GLenum target, GLint level, 2135 GLint xoffset, GLint yoffset, GLint zoffset, 2136 GLint width, GLint height, GLint depth, 2137 GLenum format, GLenum type, const GLvoid *pixels, 2138 bool dsa, const char *callerName) 2139 { 2140 struct gl_texture_image *texImage; 2141 GLenum err; 2142 2143 if (!texObj) { 2144 /* must be out of memory */ 2145 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", callerName); 2146 return GL_TRUE; 2147 } 2148 2149 /* level check */ 2150 if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 2151 _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", callerName, level); 2152 return GL_TRUE; 2153 } 2154 2155 if (error_check_subtexture_negative_dimensions(ctx, dimensions, 2156 width, height, depth, 2157 callerName)) { 2158 return GL_TRUE; 2159 } 2160 2161 texImage = _mesa_select_tex_image(texObj, target, level); 2162 if (!texImage) { 2163 /* non-existant texture level */ 2164 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture image)", 2165 callerName); 2166 return GL_TRUE; 2167 } 2168 2169 err = _mesa_error_check_format_and_type(ctx, format, type); 2170 if (err != GL_NO_ERROR) { 2171 _mesa_error(ctx, err, 2172 "%s(incompatible format = %s, type = %s)", 2173 callerName, _mesa_enum_to_string(format), 2174 _mesa_enum_to_string(type)); 2175 return GL_TRUE; 2176 } 2177 2178 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 2179 * combinations of format, internalFormat, and type that can be used. 2180 * Formats and types that require additional extensions (e.g., GL_FLOAT 2181 * requires GL_OES_texture_float) are filtered elsewhere. 2182 */ 2183 if (_mesa_is_gles(ctx) && 2184 texture_format_error_check_gles(ctx, format, type, 2185 texImage->InternalFormat, 2186 dimensions, callerName)) { 2187 return GL_TRUE; 2188 } 2189 2190 /* validate the bound PBO, if any */ 2191 if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack, 2192 width, height, depth, format, type, 2193 INT_MAX, pixels, callerName)) { 2194 return GL_TRUE; 2195 } 2196 2197 if (error_check_subtexture_dimensions(ctx, dimensions, 2198 texImage, xoffset, yoffset, zoffset, 2199 width, height, depth, callerName)) { 2200 return GL_TRUE; 2201 } 2202 2203 if (_mesa_is_format_compressed(texImage->TexFormat)) { 2204 if (_mesa_format_no_online_compression(ctx, texImage->InternalFormat)) { 2205 _mesa_error(ctx, GL_INVALID_OPERATION, 2206 "%s(no compression for format)", callerName); 2207 return GL_TRUE; 2208 } 2209 } 2210 2211 if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) { 2212 /* both source and dest must be integer-valued, or neither */ 2213 if (_mesa_is_format_integer_color(texImage->TexFormat) != 2214 _mesa_is_enum_format_integer(format)) { 2215 _mesa_error(ctx, GL_INVALID_OPERATION, 2216 "%s(integer/non-integer format mismatch)", callerName); 2217 return GL_TRUE; 2218 } 2219 } 2220 2221 return GL_FALSE; 2222 } 2223 2224 2225 /** 2226 * Test glCopyTexImage[12]D() parameters for errors. 2227 * 2228 * \param ctx GL context. 2229 * \param dimensions texture image dimensions (must be 1, 2 or 3). 2230 * \param target texture target given by the user. 2231 * \param level image level given by the user. 2232 * \param internalFormat internal format given by the user. 2233 * \param width image width given by the user. 2234 * \param height image height given by the user. 2235 * \param border texture border. 2236 * 2237 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2238 * 2239 * Verifies each of the parameters against the constants specified in 2240 * __struct gl_contextRec::Const and the supported extensions, and according 2241 * to the OpenGL specification. 2242 */ 2243 static GLboolean 2244 copytexture_error_check( struct gl_context *ctx, GLuint dimensions, 2245 GLenum target, GLint level, GLint internalFormat, 2246 GLint width, GLint height, GLint border ) 2247 { 2248 GLint baseFormat; 2249 GLint rb_base_format; 2250 struct gl_renderbuffer *rb; 2251 GLenum rb_internal_format; 2252 2253 /* check target */ 2254 if (!legal_texsubimage_target(ctx, dimensions, target, false)) { 2255 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)", 2256 dimensions, _mesa_enum_to_string(target)); 2257 return GL_TRUE; 2258 } 2259 2260 /* level check */ 2261 if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 2262 _mesa_error(ctx, GL_INVALID_VALUE, 2263 "glCopyTexImage%dD(level=%d)", dimensions, level); 2264 return GL_TRUE; 2265 } 2266 2267 /* Check that the source buffer is complete */ 2268 if (_mesa_is_user_fbo(ctx->ReadBuffer)) { 2269 if (ctx->ReadBuffer->_Status == 0) { 2270 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 2271 } 2272 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2273 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 2274 "glCopyTexImage%dD(invalid readbuffer)", dimensions); 2275 return GL_TRUE; 2276 } 2277 2278 if (ctx->ReadBuffer->Visual.samples > 0) { 2279 _mesa_error(ctx, GL_INVALID_OPERATION, 2280 "glCopyTexImage%dD(multisample FBO)", dimensions); 2281 return GL_TRUE; 2282 } 2283 } 2284 2285 /* Check border */ 2286 if (border < 0 || border > 1 || 2287 ((ctx->API != API_OPENGL_COMPAT || 2288 target == GL_TEXTURE_RECTANGLE_NV || 2289 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 2290 _mesa_error(ctx, GL_INVALID_VALUE, 2291 "glCopyTexImage%dD(border=%d)", dimensions, border); 2292 return GL_TRUE; 2293 } 2294 2295 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 2296 * internalFormat. 2297 */ 2298 if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) { 2299 switch (internalFormat) { 2300 case GL_ALPHA: 2301 case GL_RGB: 2302 case GL_RGBA: 2303 case GL_LUMINANCE: 2304 case GL_LUMINANCE_ALPHA: 2305 break; 2306 default: 2307 _mesa_error(ctx, GL_INVALID_ENUM, 2308 "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2309 _mesa_enum_to_string(internalFormat)); 2310 return GL_TRUE; 2311 } 2312 } else { 2313 /* 2314 * Section 8.6 (Alternate Texture Image Specification Commands) of the 2315 * OpenGL 4.5 (Compatibility Profile) spec says: 2316 * 2317 * "Parameters level, internalformat, and border are specified using 2318 * the same values, with the same meanings, as the corresponding 2319 * arguments of TexImage2D, except that internalformat may not be 2320 * specified as 1, 2, 3, or 4." 2321 */ 2322 if (internalFormat >= 1 && internalFormat <= 4) { 2323 _mesa_error(ctx, GL_INVALID_ENUM, 2324 "glCopyTexImage%dD(internalFormat=%d)", dimensions, 2325 internalFormat); 2326 return GL_TRUE; 2327 } 2328 } 2329 2330 baseFormat = _mesa_base_tex_format(ctx, internalFormat); 2331 if (baseFormat < 0) { 2332 _mesa_error(ctx, GL_INVALID_ENUM, 2333 "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2334 _mesa_enum_to_string(internalFormat)); 2335 return GL_TRUE; 2336 } 2337 2338 rb = _mesa_get_read_renderbuffer_for_format(ctx, internalFormat); 2339 if (rb == NULL) { 2340 _mesa_error(ctx, GL_INVALID_OPERATION, 2341 "glCopyTexImage%dD(read buffer)", dimensions); 2342 return GL_TRUE; 2343 } 2344 2345 rb_internal_format = rb->InternalFormat; 2346 rb_base_format = _mesa_base_tex_format(ctx, rb->InternalFormat); 2347 if (_mesa_is_color_format(internalFormat)) { 2348 if (rb_base_format < 0) { 2349 _mesa_error(ctx, GL_INVALID_VALUE, 2350 "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2351 _mesa_enum_to_string(internalFormat)); 2352 return GL_TRUE; 2353 } 2354 } 2355 2356 if (_mesa_is_gles(ctx)) { 2357 bool valid = true; 2358 if (_mesa_base_format_component_count(baseFormat) > 2359 _mesa_base_format_component_count(rb_base_format)) { 2360 valid = false; 2361 } 2362 if (baseFormat == GL_DEPTH_COMPONENT || 2363 baseFormat == GL_DEPTH_STENCIL || 2364 baseFormat == GL_STENCIL_INDEX || 2365 rb_base_format == GL_DEPTH_COMPONENT || 2366 rb_base_format == GL_DEPTH_STENCIL || 2367 rb_base_format == GL_STENCIL_INDEX || 2368 ((baseFormat == GL_LUMINANCE_ALPHA || 2369 baseFormat == GL_ALPHA) && 2370 rb_base_format != GL_RGBA) || 2371 internalFormat == GL_RGB9_E5) { 2372 valid = false; 2373 } 2374 if (internalFormat == GL_RGB9_E5) { 2375 valid = false; 2376 } 2377 if (!valid) { 2378 _mesa_error(ctx, GL_INVALID_OPERATION, 2379 "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2380 _mesa_enum_to_string(internalFormat)); 2381 return GL_TRUE; 2382 } 2383 } 2384 2385 if (_mesa_is_gles3(ctx)) { 2386 bool rb_is_srgb = false; 2387 bool dst_is_srgb = false; 2388 2389 if (ctx->Extensions.EXT_framebuffer_sRGB && 2390 _mesa_get_format_color_encoding(rb->Format) == GL_SRGB) { 2391 rb_is_srgb = true; 2392 } 2393 2394 if (_mesa_get_linear_internalformat(internalFormat) != internalFormat) { 2395 dst_is_srgb = true; 2396 } 2397 2398 if (rb_is_srgb != dst_is_srgb) { 2399 /* Page 137 (page 149 of the PDF) in section 3.8.5 of the 2400 * OpenGLES 3.0.0 spec says: 2401 * 2402 * "The error INVALID_OPERATION is also generated if the 2403 * value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the 2404 * framebuffer attachment corresponding to the read buffer 2405 * is LINEAR (see section 6.1.13) and internalformat is 2406 * one of the sRGB formats described in section 3.8.16, or 2407 * if the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is 2408 * SRGB and internalformat is not one of the sRGB formats." 2409 */ 2410 _mesa_error(ctx, GL_INVALID_OPERATION, 2411 "glCopyTexImage%dD(srgb usage mismatch)", dimensions); 2412 return GL_TRUE; 2413 } 2414 2415 /* Page 139, Table 3.15 of OpenGL ES 3.0 spec does not define ReadPixels 2416 * types for SNORM formats. Also, conversion to SNORM formats is not 2417 * allowed by Table 3.2 on Page 110. 2418 */ 2419 if (_mesa_is_enum_format_snorm(internalFormat)) { 2420 _mesa_error(ctx, GL_INVALID_OPERATION, 2421 "glCopyTexImage%dD(internalFormat=%s)", dimensions, 2422 _mesa_enum_to_string(internalFormat)); 2423 return GL_TRUE; 2424 } 2425 } 2426 2427 if (!_mesa_source_buffer_exists(ctx, baseFormat)) { 2428 _mesa_error(ctx, GL_INVALID_OPERATION, 2429 "glCopyTexImage%dD(missing readbuffer)", dimensions); 2430 return GL_TRUE; 2431 } 2432 2433 /* From the EXT_texture_integer spec: 2434 * 2435 * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage* 2436 * if the texture internalformat is an integer format and the read color 2437 * buffer is not an integer format, or if the internalformat is not an 2438 * integer format and the read color buffer is an integer format." 2439 */ 2440 if (_mesa_is_color_format(internalFormat)) { 2441 bool is_int = _mesa_is_enum_format_integer(internalFormat); 2442 bool is_rbint = _mesa_is_enum_format_integer(rb_internal_format); 2443 bool is_unorm = _mesa_is_enum_format_unorm(internalFormat); 2444 bool is_rbunorm = _mesa_is_enum_format_unorm(rb_internal_format); 2445 if (is_int || is_rbint) { 2446 if (is_int != is_rbint) { 2447 _mesa_error(ctx, GL_INVALID_OPERATION, 2448 "glCopyTexImage%dD(integer vs non-integer)", dimensions); 2449 return GL_TRUE; 2450 } else if (_mesa_is_gles(ctx) && 2451 _mesa_is_enum_format_unsigned_int(internalFormat) != 2452 _mesa_is_enum_format_unsigned_int(rb_internal_format)) { 2453 _mesa_error(ctx, GL_INVALID_OPERATION, 2454 "glCopyTexImage%dD(signed vs unsigned integer)", dimensions); 2455 return GL_TRUE; 2456 } 2457 } 2458 2459 /* From page 138 of OpenGL ES 3.0 spec: 2460 * "The error INVALID_OPERATION is generated if floating-point RGBA 2461 * data is required; if signed integer RGBA data is required and the 2462 * format of the current color buffer is not signed integer; if 2463 * unsigned integer RGBA data is required and the format of the 2464 * current color buffer is not unsigned integer; or if fixed-point 2465 * RGBA data is required and the format of the current color buffer 2466 * is not fixed-point. 2467 */ 2468 if (_mesa_is_gles(ctx) && is_unorm != is_rbunorm) 2469 _mesa_error(ctx, GL_INVALID_OPERATION, 2470 "glCopyTexImage%dD(unorm vs non-unorm)", dimensions); 2471 } 2472 2473 if (_mesa_is_compressed_format(ctx, internalFormat)) { 2474 GLenum err; 2475 if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) { 2476 _mesa_error(ctx, err, 2477 "glCopyTexImage%dD(target can't be compressed)", dimensions); 2478 return GL_TRUE; 2479 } 2480 if (_mesa_format_no_online_compression(ctx, internalFormat)) { 2481 _mesa_error(ctx, GL_INVALID_OPERATION, 2482 "glCopyTexImage%dD(no compression for format)", dimensions); 2483 return GL_TRUE; 2484 } 2485 if (border != 0) { 2486 _mesa_error(ctx, GL_INVALID_OPERATION, 2487 "glCopyTexImage%dD(border!=0)", dimensions); 2488 return GL_TRUE; 2489 } 2490 } 2491 2492 if (!mutable_tex_object(ctx, target)) { 2493 _mesa_error(ctx, GL_INVALID_OPERATION, 2494 "glCopyTexImage%dD(immutable texture)", dimensions); 2495 return GL_TRUE; 2496 } 2497 2498 /* if we get here, the parameters are OK */ 2499 return GL_FALSE; 2500 } 2501 2502 2503 /** 2504 * Test glCopyTexSubImage[12]D() parameters for errors. 2505 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2506 */ 2507 static GLboolean 2508 copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions, 2509 const struct gl_texture_object *texObj, 2510 GLenum target, GLint level, 2511 GLint xoffset, GLint yoffset, GLint zoffset, 2512 GLint width, GLint height, const char *caller) 2513 { 2514 struct gl_texture_image *texImage; 2515 2516 /* Check that the source buffer is complete */ 2517 if (_mesa_is_user_fbo(ctx->ReadBuffer)) { 2518 if (ctx->ReadBuffer->_Status == 0) { 2519 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 2520 } 2521 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2522 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 2523 "%s(invalid readbuffer)", caller); 2524 return GL_TRUE; 2525 } 2526 2527 if (ctx->ReadBuffer->Visual.samples > 0) { 2528 _mesa_error(ctx, GL_INVALID_OPERATION, 2529 "%s(multisample FBO)", caller); 2530 return GL_TRUE; 2531 } 2532 } 2533 2534 /* Check level */ 2535 if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 2536 _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", caller, level); 2537 return GL_TRUE; 2538 } 2539 2540 /* Get dest image pointers */ 2541 if (!texObj) { 2542 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", caller); 2543 return GL_TRUE; 2544 } 2545 2546 texImage = _mesa_select_tex_image(texObj, target, level); 2547 if (!texImage) { 2548 /* destination image does not exist */ 2549 _mesa_error(ctx, GL_INVALID_OPERATION, 2550 "%s(invalid texture image)", caller); 2551 return GL_TRUE; 2552 } 2553 2554 if (error_check_subtexture_negative_dimensions(ctx, dimensions, 2555 width, height, 1, caller)) { 2556 return GL_TRUE; 2557 } 2558 2559 if (error_check_subtexture_dimensions(ctx, dimensions, texImage, 2560 xoffset, yoffset, zoffset, 2561 width, height, 1, caller)) { 2562 return GL_TRUE; 2563 } 2564 2565 if (_mesa_is_format_compressed(texImage->TexFormat)) { 2566 if (_mesa_format_no_online_compression(ctx, texImage->InternalFormat)) { 2567 _mesa_error(ctx, GL_INVALID_OPERATION, 2568 "%s(no compression for format)", caller); 2569 return GL_TRUE; 2570 } 2571 } 2572 2573 if (texImage->InternalFormat == GL_YCBCR_MESA) { 2574 _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", caller); 2575 return GL_TRUE; 2576 } 2577 2578 if (!_mesa_source_buffer_exists(ctx, texImage->_BaseFormat)) { 2579 _mesa_error(ctx, GL_INVALID_OPERATION, 2580 "%s(missing readbuffer, format=%s)", caller, 2581 _mesa_enum_to_string(texImage->_BaseFormat)); 2582 return GL_TRUE; 2583 } 2584 2585 /* From the EXT_texture_integer spec: 2586 * 2587 * "INVALID_OPERATION is generated by CopyTexImage* and 2588 * CopyTexSubImage* if the texture internalformat is an integer format 2589 * and the read color buffer is not an integer format, or if the 2590 * internalformat is not an integer format and the read color buffer 2591 * is an integer format." 2592 */ 2593 if (_mesa_is_color_format(texImage->InternalFormat)) { 2594 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 2595 2596 if (_mesa_is_format_integer_color(rb->Format) != 2597 _mesa_is_format_integer_color(texImage->TexFormat)) { 2598 _mesa_error(ctx, GL_INVALID_OPERATION, 2599 "%s(integer vs non-integer)", caller); 2600 return GL_TRUE; 2601 } 2602 } 2603 2604 /* In the ES 3.2 specification's Table 8.13 (Valid CopyTexImage source 2605 * framebuffer/destination texture base internal format combinations), 2606 * all the entries for stencil are left blank (unsupported). 2607 */ 2608 if (_mesa_is_gles(ctx) && _mesa_is_stencil_format(texImage->_BaseFormat)) { 2609 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(stencil disallowed)", caller); 2610 return GL_TRUE; 2611 } 2612 2613 /* if we get here, the parameters are OK */ 2614 return GL_FALSE; 2615 } 2616 2617 2618 /** Callback info for walking over FBO hash table */ 2619 struct cb_info 2620 { 2621 struct gl_context *ctx; 2622 struct gl_texture_object *texObj; 2623 GLuint level, face; 2624 }; 2625 2626 2627 /** 2628 * Check render to texture callback. Called from _mesa_HashWalk(). 2629 */ 2630 static void 2631 check_rtt_cb(GLuint key, void *data, void *userData) 2632 { 2633 struct gl_framebuffer *fb = (struct gl_framebuffer *) data; 2634 const struct cb_info *info = (struct cb_info *) userData; 2635 struct gl_context *ctx = info->ctx; 2636 const struct gl_texture_object *texObj = info->texObj; 2637 const GLuint level = info->level, face = info->face; 2638 2639 /* If this is a user-created FBO */ 2640 if (_mesa_is_user_fbo(fb)) { 2641 GLuint i; 2642 /* check if any of the FBO's attachments point to 'texObj' */ 2643 for (i = 0; i < BUFFER_COUNT; i++) { 2644 struct gl_renderbuffer_attachment *att = fb->Attachment + i; 2645 if (att->Type == GL_TEXTURE && 2646 att->Texture == texObj && 2647 att->TextureLevel == level && 2648 att->CubeMapFace == face) { 2649 _mesa_update_texture_renderbuffer(ctx, fb, att); 2650 assert(att->Renderbuffer->TexImage); 2651 /* Mark fb status as indeterminate to force re-validation */ 2652 fb->_Status = 0; 2653 2654 /* Make sure that the revalidation actually happens if this is 2655 * being done to currently-bound buffers. 2656 */ 2657 if (fb == ctx->DrawBuffer || fb == ctx->ReadBuffer) 2658 ctx->NewState |= _NEW_BUFFERS; 2659 } 2660 } 2661 } 2662 } 2663 2664 2665 /** 2666 * When a texture image is specified we have to check if it's bound to 2667 * any framebuffer objects (render to texture) in order to detect changes 2668 * in size or format since that effects FBO completeness. 2669 * Any FBOs rendering into the texture must be re-validated. 2670 */ 2671 void 2672 _mesa_update_fbo_texture(struct gl_context *ctx, 2673 struct gl_texture_object *texObj, 2674 GLuint face, GLuint level) 2675 { 2676 /* Only check this texture if it's been marked as RenderToTexture */ 2677 if (texObj->_RenderToTexture) { 2678 struct cb_info info; 2679 info.ctx = ctx; 2680 info.texObj = texObj; 2681 info.level = level; 2682 info.face = face; 2683 _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info); 2684 } 2685 } 2686 2687 2688 /** 2689 * If the texture object's GenerateMipmap flag is set and we've 2690 * changed the texture base level image, regenerate the rest of the 2691 * mipmap levels now. 2692 */ 2693 static inline void 2694 check_gen_mipmap(struct gl_context *ctx, GLenum target, 2695 struct gl_texture_object *texObj, GLint level) 2696 { 2697 if (texObj->GenerateMipmap && 2698 level == texObj->BaseLevel && 2699 level < texObj->MaxLevel) { 2700 assert(ctx->Driver.GenerateMipmap); 2701 ctx->Driver.GenerateMipmap(ctx, target, texObj); 2702 } 2703 } 2704 2705 2706 /** Debug helper: override the user-requested internal format */ 2707 static GLenum 2708 override_internal_format(GLenum internalFormat, GLint width, GLint height) 2709 { 2710 #if 0 2711 if (internalFormat == GL_RGBA16F_ARB || 2712 internalFormat == GL_RGBA32F_ARB) { 2713 printf("Convert rgba float tex to int %d x %d\n", width, height); 2714 return GL_RGBA; 2715 } 2716 else if (internalFormat == GL_RGB16F_ARB || 2717 internalFormat == GL_RGB32F_ARB) { 2718 printf("Convert rgb float tex to int %d x %d\n", width, height); 2719 return GL_RGB; 2720 } 2721 else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB || 2722 internalFormat == GL_LUMINANCE_ALPHA32F_ARB) { 2723 printf("Convert luminance float tex to int %d x %d\n", width, height); 2724 return GL_LUMINANCE_ALPHA; 2725 } 2726 else if (internalFormat == GL_LUMINANCE16F_ARB || 2727 internalFormat == GL_LUMINANCE32F_ARB) { 2728 printf("Convert luminance float tex to int %d x %d\n", width, height); 2729 return GL_LUMINANCE; 2730 } 2731 else if (internalFormat == GL_ALPHA16F_ARB || 2732 internalFormat == GL_ALPHA32F_ARB) { 2733 printf("Convert luminance float tex to int %d x %d\n", width, height); 2734 return GL_ALPHA; 2735 } 2736 /* 2737 else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) { 2738 internalFormat = GL_RGBA; 2739 } 2740 */ 2741 else { 2742 return internalFormat; 2743 } 2744 #else 2745 return internalFormat; 2746 #endif 2747 } 2748 2749 2750 /** 2751 * Choose the actual hardware format for a texture image. 2752 * Try to use the same format as the previous image level when possible. 2753 * Otherwise, ask the driver for the best format. 2754 * It's important to try to choose a consistant format for all levels 2755 * for efficient texture memory layout/allocation. In particular, this 2756 * comes up during automatic mipmap generation. 2757 */ 2758 mesa_format 2759 _mesa_choose_texture_format(struct gl_context *ctx, 2760 struct gl_texture_object *texObj, 2761 GLenum target, GLint level, 2762 GLenum internalFormat, GLenum format, GLenum type) 2763 { 2764 mesa_format f; 2765 2766 /* see if we've already chosen a format for the previous level */ 2767 if (level > 0) { 2768 struct gl_texture_image *prevImage = 2769 _mesa_select_tex_image(texObj, target, level - 1); 2770 /* See if the prev level is defined and has an internal format which 2771 * matches the new internal format. 2772 */ 2773 if (prevImage && 2774 prevImage->Width > 0 && 2775 prevImage->InternalFormat == internalFormat) { 2776 /* use the same format */ 2777 assert(prevImage->TexFormat != MESA_FORMAT_NONE); 2778 return prevImage->TexFormat; 2779 } 2780 } 2781 2782 /* If the application requested compression to an S3TC format but we don't 2783 * have the DXTn library, force a generic compressed format instead. 2784 */ 2785 if (internalFormat != format && format != GL_NONE) { 2786 const GLenum before = internalFormat; 2787 2788 switch (internalFormat) { 2789 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 2790 if (!ctx->Mesa_DXTn) 2791 internalFormat = GL_COMPRESSED_RGB; 2792 break; 2793 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 2794 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 2795 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 2796 if (!ctx->Mesa_DXTn) 2797 internalFormat = GL_COMPRESSED_RGBA; 2798 break; 2799 default: 2800 break; 2801 } 2802 2803 if (before != internalFormat) { 2804 _mesa_warning(ctx, 2805 "DXT compression requested (%s), " 2806 "but libtxc_dxtn library not installed. Using %s " 2807 "instead.", 2808 _mesa_enum_to_string(before), 2809 _mesa_enum_to_string(internalFormat)); 2810 } 2811 } 2812 2813 /* choose format from scratch */ 2814 f = ctx->Driver.ChooseTextureFormat(ctx, target, internalFormat, 2815 format, type); 2816 assert(f != MESA_FORMAT_NONE); 2817 return f; 2818 } 2819 2820 2821 /** 2822 * Adjust pixel unpack params and image dimensions to strip off the 2823 * one-pixel texture border. 2824 * 2825 * Gallium and intel don't support texture borders. They've seldem been used 2826 * and seldom been implemented correctly anyway. 2827 * 2828 * \param unpackNew returns the new pixel unpack parameters 2829 */ 2830 static void 2831 strip_texture_border(GLenum target, 2832 GLint *width, GLint *height, GLint *depth, 2833 const struct gl_pixelstore_attrib *unpack, 2834 struct gl_pixelstore_attrib *unpackNew) 2835 { 2836 assert(width); 2837 assert(height); 2838 assert(depth); 2839 2840 *unpackNew = *unpack; 2841 2842 if (unpackNew->RowLength == 0) 2843 unpackNew->RowLength = *width; 2844 2845 if (unpackNew->ImageHeight == 0) 2846 unpackNew->ImageHeight = *height; 2847 2848 assert(*width >= 3); 2849 unpackNew->SkipPixels++; /* skip the border */ 2850 *width = *width - 2; /* reduce the width by two border pixels */ 2851 2852 /* The min height of a texture with a border is 3 */ 2853 if (*height >= 3 && target != GL_TEXTURE_1D_ARRAY) { 2854 unpackNew->SkipRows++; /* skip the border */ 2855 *height = *height - 2; /* reduce the height by two border pixels */ 2856 } 2857 2858 if (*depth >= 3 && 2859 target != GL_TEXTURE_2D_ARRAY && 2860 target != GL_TEXTURE_CUBE_MAP_ARRAY) { 2861 unpackNew->SkipImages++; /* skip the border */ 2862 *depth = *depth - 2; /* reduce the depth by two border pixels */ 2863 } 2864 } 2865 2866 2867 /** 2868 * Common code to implement all the glTexImage1D/2D/3D functions 2869 * as well as glCompressedTexImage1D/2D/3D. 2870 * \param compressed only GL_TRUE for glCompressedTexImage1D/2D/3D calls. 2871 * \param format the user's image format (only used if !compressed) 2872 * \param type the user's image type (only used if !compressed) 2873 * \param imageSize only used for glCompressedTexImage1D/2D/3D calls. 2874 */ 2875 static void 2876 teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, 2877 GLenum target, GLint level, GLint internalFormat, 2878 GLsizei width, GLsizei height, GLsizei depth, 2879 GLint border, GLenum format, GLenum type, 2880 GLsizei imageSize, const GLvoid *pixels) 2881 { 2882 const char *func = compressed ? "glCompressedTexImage" : "glTexImage"; 2883 struct gl_pixelstore_attrib unpack_no_border; 2884 const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; 2885 struct gl_texture_object *texObj; 2886 mesa_format texFormat; 2887 GLboolean dimensionsOK, sizeOK; 2888 2889 FLUSH_VERTICES(ctx, 0); 2890 2891 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) { 2892 if (compressed) 2893 _mesa_debug(ctx, 2894 "glCompressedTexImage%uD %s %d %s %d %d %d %d %p\n", 2895 dims, 2896 _mesa_enum_to_string(target), level, 2897 _mesa_enum_to_string(internalFormat), 2898 width, height, depth, border, pixels); 2899 else 2900 _mesa_debug(ctx, 2901 "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n", 2902 dims, 2903 _mesa_enum_to_string(target), level, 2904 _mesa_enum_to_string(internalFormat), 2905 width, height, depth, border, 2906 _mesa_enum_to_string(format), 2907 _mesa_enum_to_string(type), pixels); 2908 } 2909 2910 internalFormat = override_internal_format(internalFormat, width, height); 2911 2912 /* target error checking */ 2913 if (!legal_teximage_target(ctx, dims, target)) { 2914 _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)", 2915 func, dims, _mesa_enum_to_string(target)); 2916 return; 2917 } 2918 2919 /* general error checking */ 2920 if (compressed) { 2921 if (compressed_texture_error_check(ctx, dims, target, level, 2922 internalFormat, 2923 width, height, depth, 2924 border, imageSize, pixels)) 2925 return; 2926 } 2927 else { 2928 if (texture_error_check(ctx, dims, target, level, internalFormat, 2929 format, type, width, height, depth, border, 2930 pixels)) 2931 return; 2932 } 2933 2934 /* Here we convert a cpal compressed image into a regular glTexImage2D 2935 * call by decompressing the texture. If we really want to support cpal 2936 * textures in any driver this would have to be changed. 2937 */ 2938 if (ctx->API == API_OPENGLES && compressed && dims == 2) { 2939 switch (internalFormat) { 2940 case GL_PALETTE4_RGB8_OES: 2941 case GL_PALETTE4_RGBA8_OES: 2942 case GL_PALETTE4_R5_G6_B5_OES: 2943 case GL_PALETTE4_RGBA4_OES: 2944 case GL_PALETTE4_RGB5_A1_OES: 2945 case GL_PALETTE8_RGB8_OES: 2946 case GL_PALETTE8_RGBA8_OES: 2947 case GL_PALETTE8_R5_G6_B5_OES: 2948 case GL_PALETTE8_RGBA4_OES: 2949 case GL_PALETTE8_RGB5_A1_OES: 2950 _mesa_cpal_compressed_teximage2d(target, level, internalFormat, 2951 width, height, imageSize, pixels); 2952 return; 2953 } 2954 } 2955 2956 texObj = _mesa_get_current_tex_object(ctx, target); 2957 assert(texObj); 2958 2959 if (compressed) { 2960 /* For glCompressedTexImage() the driver has no choice about the 2961 * texture format since we'll never transcode the user's compressed 2962 * image data. The internalFormat was error checked earlier. 2963 */ 2964 texFormat = _mesa_glenum_to_compressed_format(internalFormat); 2965 } 2966 else { 2967 /* In case of HALF_FLOAT_OES or FLOAT_OES, find corresponding sized 2968 * internal floating point format for the given base format. 2969 */ 2970 if (_mesa_is_gles(ctx) && format == internalFormat) { 2971 if (type == GL_FLOAT) { 2972 texObj->_IsFloat = GL_TRUE; 2973 } else if (type == GL_HALF_FLOAT_OES || type == GL_HALF_FLOAT) { 2974 texObj->_IsHalfFloat = GL_TRUE; 2975 } 2976 2977 internalFormat = adjust_for_oes_float_texture(ctx, format, type); 2978 } 2979 2980 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 2981 internalFormat, format, type); 2982 } 2983 2984 assert(texFormat != MESA_FORMAT_NONE); 2985 2986 /* check that width, height, depth are legal for the mipmap level */ 2987 dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, level, width, 2988 height, depth, border); 2989 2990 /* check that the texture won't take too much memory, etc */ 2991 sizeOK = ctx->Driver.TestProxyTexImage(ctx, proxy_target(target), 2992 0, level, texFormat, 1, 2993 width, height, depth); 2994 2995 if (_mesa_is_proxy_texture(target)) { 2996 /* Proxy texture: just clear or set state depending on error checking */ 2997 struct gl_texture_image *texImage = 2998 get_proxy_tex_image(ctx, target, level); 2999 3000 if (!texImage) 3001 return; /* GL_OUT_OF_MEMORY already recorded */ 3002 3003 if (dimensionsOK && sizeOK) { 3004 _mesa_init_teximage_fields(ctx, texImage, width, height, depth, 3005 border, internalFormat, texFormat); 3006 } 3007 else { 3008 clear_teximage_fields(texImage); 3009 } 3010 } 3011 else { 3012 /* non-proxy target */ 3013 const GLuint face = _mesa_tex_target_to_face(target); 3014 struct gl_texture_image *texImage; 3015 3016 if (!dimensionsOK) { 3017 _mesa_error(ctx, GL_INVALID_VALUE, 3018 "%s%uD(invalid width or height or depth)", 3019 func, dims); 3020 return; 3021 } 3022 3023 if (!sizeOK) { 3024 _mesa_error(ctx, GL_OUT_OF_MEMORY, 3025 "%s%uD(image too large: %d x %d x %d, %s format)", 3026 func, dims, width, height, depth, 3027 _mesa_enum_to_string(internalFormat)); 3028 return; 3029 } 3030 3031 /* Allow a hardware driver to just strip out the border, to provide 3032 * reliable but slightly incorrect hardware rendering instead of 3033 * rarely-tested software fallback rendering. 3034 */ 3035 if (border && ctx->Const.StripTextureBorder) { 3036 strip_texture_border(target, &width, &height, &depth, unpack, 3037 &unpack_no_border); 3038 border = 0; 3039 unpack = &unpack_no_border; 3040 } 3041 3042 if (ctx->NewState & _NEW_PIXEL) 3043 _mesa_update_state(ctx); 3044 3045 _mesa_lock_texture(ctx, texObj); 3046 { 3047 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3048 3049 if (!texImage) { 3050 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims); 3051 } 3052 else { 3053 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 3054 3055 _mesa_init_teximage_fields(ctx, texImage, 3056 width, height, depth, 3057 border, internalFormat, texFormat); 3058 3059 /* Give the texture to the driver. <pixels> may be null. */ 3060 if (width > 0 && height > 0 && depth > 0) { 3061 if (compressed) { 3062 ctx->Driver.CompressedTexImage(ctx, dims, texImage, 3063 imageSize, pixels); 3064 } 3065 else { 3066 ctx->Driver.TexImage(ctx, dims, texImage, format, 3067 type, pixels, unpack); 3068 } 3069 } 3070 3071 check_gen_mipmap(ctx, target, texObj, level); 3072 3073 _mesa_update_fbo_texture(ctx, texObj, face, level); 3074 3075 _mesa_dirty_texobj(ctx, texObj); 3076 } 3077 } 3078 _mesa_unlock_texture(ctx, texObj); 3079 } 3080 } 3081 3082 3083 3084 /* 3085 * Called from the API. Note that width includes the border. 3086 */ 3087 void GLAPIENTRY 3088 _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, 3089 GLsizei width, GLint border, GLenum format, 3090 GLenum type, const GLvoid *pixels ) 3091 { 3092 GET_CURRENT_CONTEXT(ctx); 3093 teximage(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 1, 3094 border, format, type, 0, pixels); 3095 } 3096 3097 3098 void GLAPIENTRY 3099 _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 3100 GLsizei width, GLsizei height, GLint border, 3101 GLenum format, GLenum type, 3102 const GLvoid *pixels ) 3103 { 3104 GET_CURRENT_CONTEXT(ctx); 3105 teximage(ctx, GL_FALSE, 2, target, level, internalFormat, width, height, 1, 3106 border, format, type, 0, pixels); 3107 } 3108 3109 3110 /* 3111 * Called by the API or display list executor. 3112 * Note that width and height include the border. 3113 */ 3114 void GLAPIENTRY 3115 _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, 3116 GLsizei width, GLsizei height, GLsizei depth, 3117 GLint border, GLenum format, GLenum type, 3118 const GLvoid *pixels ) 3119 { 3120 GET_CURRENT_CONTEXT(ctx); 3121 teximage(ctx, GL_FALSE, 3, target, level, internalFormat, 3122 width, height, depth, 3123 border, format, type, 0, pixels); 3124 } 3125 3126 3127 void GLAPIENTRY 3128 _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, 3129 GLsizei width, GLsizei height, GLsizei depth, 3130 GLint border, GLenum format, GLenum type, 3131 const GLvoid *pixels ) 3132 { 3133 _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height, 3134 depth, border, format, type, pixels); 3135 } 3136 3137 3138 void GLAPIENTRY 3139 _mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) 3140 { 3141 struct gl_texture_object *texObj; 3142 struct gl_texture_image *texImage; 3143 bool valid_target; 3144 GET_CURRENT_CONTEXT(ctx); 3145 FLUSH_VERTICES(ctx, 0); 3146 3147 switch (target) { 3148 case GL_TEXTURE_2D: 3149 valid_target = ctx->Extensions.OES_EGL_image; 3150 break; 3151 case GL_TEXTURE_EXTERNAL_OES: 3152 valid_target = 3153 _mesa_is_gles(ctx) ? ctx->Extensions.OES_EGL_image_external : false; 3154 break; 3155 default: 3156 valid_target = false; 3157 break; 3158 } 3159 3160 if (!valid_target) { 3161 _mesa_error(ctx, GL_INVALID_ENUM, 3162 "glEGLImageTargetTexture2D(target=%d)", target); 3163 return; 3164 } 3165 3166 if (!image) { 3167 _mesa_error(ctx, GL_INVALID_OPERATION, 3168 "glEGLImageTargetTexture2D(image=%p)", image); 3169 return; 3170 } 3171 3172 if (ctx->NewState & _NEW_PIXEL) 3173 _mesa_update_state(ctx); 3174 3175 texObj = _mesa_get_current_tex_object(ctx, target); 3176 if (!texObj) 3177 return; 3178 3179 _mesa_lock_texture(ctx, texObj); 3180 3181 if (texObj->Immutable) { 3182 _mesa_error(ctx, GL_INVALID_OPERATION, 3183 "glEGLImageTargetTexture2D(texture is immutable)"); 3184 _mesa_unlock_texture(ctx, texObj); 3185 return; 3186 } 3187 3188 texImage = _mesa_get_tex_image(ctx, texObj, target, 0); 3189 if (!texImage) { 3190 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEGLImageTargetTexture2D"); 3191 } else { 3192 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 3193 3194 ctx->Driver.EGLImageTargetTexture2D(ctx, target, 3195 texObj, texImage, image); 3196 3197 _mesa_dirty_texobj(ctx, texObj); 3198 } 3199 _mesa_unlock_texture(ctx, texObj); 3200 } 3201 3202 3203 /** 3204 * Helper that implements the glTexSubImage1/2/3D() 3205 * and glTextureSubImage1/2/3D() functions. 3206 */ 3207 void 3208 _mesa_texture_sub_image(struct gl_context *ctx, GLuint dims, 3209 struct gl_texture_object *texObj, 3210 struct gl_texture_image *texImage, 3211 GLenum target, GLint level, 3212 GLint xoffset, GLint yoffset, GLint zoffset, 3213 GLsizei width, GLsizei height, GLsizei depth, 3214 GLenum format, GLenum type, const GLvoid *pixels, 3215 bool dsa) 3216 { 3217 FLUSH_VERTICES(ctx, 0); 3218 3219 if (ctx->NewState & _NEW_PIXEL) 3220 _mesa_update_state(ctx); 3221 3222 _mesa_lock_texture(ctx, texObj); 3223 { 3224 if (width > 0 && height > 0 && depth > 0) { 3225 /* If we have a border, offset=-1 is legal. Bias by border width. */ 3226 switch (dims) { 3227 case 3: 3228 if (target != GL_TEXTURE_2D_ARRAY) 3229 zoffset += texImage->Border; 3230 /* fall-through */ 3231 case 2: 3232 if (target != GL_TEXTURE_1D_ARRAY) 3233 yoffset += texImage->Border; 3234 /* fall-through */ 3235 case 1: 3236 xoffset += texImage->Border; 3237 } 3238 3239 ctx->Driver.TexSubImage(ctx, dims, texImage, 3240 xoffset, yoffset, zoffset, 3241 width, height, depth, 3242 format, type, pixels, &ctx->Unpack); 3243 3244 check_gen_mipmap(ctx, target, texObj, level); 3245 3246 /* NOTE: Don't signal _NEW_TEXTURE since we've only changed 3247 * the texel data, not the texture format, size, etc. 3248 */ 3249 } 3250 } 3251 _mesa_unlock_texture(ctx, texObj); 3252 } 3253 3254 /** 3255 * Implement all the glTexSubImage1/2/3D() functions. 3256 * Must split this out this way because of GL_TEXTURE_CUBE_MAP. 3257 */ 3258 static void 3259 texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, 3260 GLint xoffset, GLint yoffset, GLint zoffset, 3261 GLsizei width, GLsizei height, GLsizei depth, 3262 GLenum format, GLenum type, const GLvoid *pixels, 3263 const char *callerName) 3264 { 3265 struct gl_texture_object *texObj; 3266 struct gl_texture_image *texImage; 3267 3268 /* check target (proxies not allowed) */ 3269 if (!legal_texsubimage_target(ctx, dims, target, false)) { 3270 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)", 3271 dims, _mesa_enum_to_string(target)); 3272 return; 3273 } 3274 3275 texObj = _mesa_get_current_tex_object(ctx, target); 3276 if (!texObj) 3277 return; 3278 3279 if (texsubimage_error_check(ctx, dims, texObj, target, level, 3280 xoffset, yoffset, zoffset, 3281 width, height, depth, format, type, 3282 pixels, false, callerName)) { 3283 return; /* error was detected */ 3284 } 3285 3286 texImage = _mesa_select_tex_image(texObj, target, level); 3287 /* texsubimage_error_check ensures that texImage is not NULL */ 3288 3289 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3290 _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n", 3291 dims, 3292 _mesa_enum_to_string(target), level, 3293 xoffset, yoffset, zoffset, width, height, depth, 3294 _mesa_enum_to_string(format), 3295 _mesa_enum_to_string(type), pixels); 3296 3297 _mesa_texture_sub_image(ctx, dims, texObj, texImage, target, level, 3298 xoffset, yoffset, zoffset, width, height, depth, 3299 format, type, pixels, false); 3300 } 3301 3302 3303 /** 3304 * Implement all the glTextureSubImage1/2/3D() functions. 3305 * Must split this out this way because of GL_TEXTURE_CUBE_MAP. 3306 */ 3307 static void 3308 texturesubimage(struct gl_context *ctx, GLuint dims, 3309 GLuint texture, GLint level, 3310 GLint xoffset, GLint yoffset, GLint zoffset, 3311 GLsizei width, GLsizei height, GLsizei depth, 3312 GLenum format, GLenum type, const GLvoid *pixels, 3313 const char *callerName) 3314 { 3315 struct gl_texture_object *texObj; 3316 struct gl_texture_image *texImage; 3317 int i; 3318 3319 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3320 _mesa_debug(ctx, 3321 "glTextureSubImage%uD %d %d %d %d %d %d %d %d %s %s %p\n", 3322 dims, texture, level, 3323 xoffset, yoffset, zoffset, width, height, depth, 3324 _mesa_enum_to_string(format), 3325 _mesa_enum_to_string(type), pixels); 3326 3327 /* Get the texture object by Name. */ 3328 texObj = _mesa_lookup_texture(ctx, texture); 3329 if (!texObj) { 3330 _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureSubImage%uD(texture)", 3331 dims); 3332 return; 3333 } 3334 3335 /* check target (proxies not allowed) */ 3336 if (!legal_texsubimage_target(ctx, dims, texObj->Target, true)) { 3337 _mesa_error(ctx, GL_INVALID_ENUM, "%s(target=%s)", 3338 callerName, _mesa_enum_to_string(texObj->Target)); 3339 return; 3340 } 3341 3342 if (texsubimage_error_check(ctx, dims, texObj, texObj->Target, level, 3343 xoffset, yoffset, zoffset, 3344 width, height, depth, format, type, 3345 pixels, true, callerName)) { 3346 return; /* error was detected */ 3347 } 3348 3349 3350 /* Must handle special case GL_TEXTURE_CUBE_MAP. */ 3351 if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 3352 GLint imageStride; 3353 3354 /* 3355 * What do we do if the user created a texture with the following code 3356 * and then called this function with its handle? 3357 * 3358 * GLuint tex; 3359 * glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &tex); 3360 * glBindTexture(GL_TEXTURE_CUBE_MAP, tex); 3361 * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ...); 3362 * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ...); 3363 * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ...); 3364 * // Note: GL_TEXTURE_CUBE_MAP_NEGATIVE_Y not set, or given the 3365 * // wrong format, or given the wrong size, etc. 3366 * glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ...); 3367 * glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ...); 3368 * 3369 * A bug has been filed against the spec for this case. In the 3370 * meantime, we will check for cube completeness. 3371 * 3372 * According to Section 8.17 Texture Completeness in the OpenGL 4.5 3373 * Core Profile spec (30.10.2014): 3374 * "[A] cube map texture is cube complete if the 3375 * following conditions all hold true: The [base level] texture 3376 * images of each of the six cube map faces have identical, positive, 3377 * and square dimensions. The [base level] images were each specified 3378 * with the same internal format." 3379 * 3380 * It seems reasonable to check for cube completeness of an arbitrary 3381 * level here so that the image data has a consistent format and size. 3382 */ 3383 if (!_mesa_cube_level_complete(texObj, level)) { 3384 _mesa_error(ctx, GL_INVALID_OPERATION, 3385 "glTextureSubImage%uD(cube map incomplete)", 3386 dims); 3387 return; 3388 } 3389 3390 imageStride = _mesa_image_image_stride(&ctx->Unpack, width, height, 3391 format, type); 3392 /* Copy in each face. */ 3393 for (i = zoffset; i < zoffset + depth; ++i) { 3394 texImage = texObj->Image[i][level]; 3395 assert(texImage); 3396 3397 _mesa_texture_sub_image(ctx, 3, texObj, texImage, texObj->Target, 3398 level, xoffset, yoffset, 0, 3399 width, height, 1, format, 3400 type, pixels, true); 3401 pixels = (GLubyte *) pixels + imageStride; 3402 } 3403 } 3404 else { 3405 texImage = _mesa_select_tex_image(texObj, texObj->Target, level); 3406 assert(texImage); 3407 3408 _mesa_texture_sub_image(ctx, dims, texObj, texImage, texObj->Target, 3409 level, xoffset, yoffset, zoffset, 3410 width, height, depth, format, 3411 type, pixels, true); 3412 } 3413 } 3414 3415 3416 void GLAPIENTRY 3417 _mesa_TexSubImage1D( GLenum target, GLint level, 3418 GLint xoffset, GLsizei width, 3419 GLenum format, GLenum type, 3420 const GLvoid *pixels ) 3421 { 3422 GET_CURRENT_CONTEXT(ctx); 3423 texsubimage(ctx, 1, target, level, 3424 xoffset, 0, 0, 3425 width, 1, 1, 3426 format, type, pixels, "glTexSubImage1D"); 3427 } 3428 3429 3430 void GLAPIENTRY 3431 _mesa_TexSubImage2D( GLenum target, GLint level, 3432 GLint xoffset, GLint yoffset, 3433 GLsizei width, GLsizei height, 3434 GLenum format, GLenum type, 3435 const GLvoid *pixels ) 3436 { 3437 GET_CURRENT_CONTEXT(ctx); 3438 texsubimage(ctx, 2, target, level, 3439 xoffset, yoffset, 0, 3440 width, height, 1, 3441 format, type, pixels, "glTexSubImage2D"); 3442 } 3443 3444 3445 3446 void GLAPIENTRY 3447 _mesa_TexSubImage3D( GLenum target, GLint level, 3448 GLint xoffset, GLint yoffset, GLint zoffset, 3449 GLsizei width, GLsizei height, GLsizei depth, 3450 GLenum format, GLenum type, 3451 const GLvoid *pixels ) 3452 { 3453 GET_CURRENT_CONTEXT(ctx); 3454 texsubimage(ctx, 3, target, level, 3455 xoffset, yoffset, zoffset, 3456 width, height, depth, 3457 format, type, pixels, "glTexSubImage3D"); 3458 } 3459 3460 void GLAPIENTRY 3461 _mesa_TextureSubImage1D(GLuint texture, GLint level, 3462 GLint xoffset, GLsizei width, 3463 GLenum format, GLenum type, 3464 const GLvoid *pixels) 3465 { 3466 GET_CURRENT_CONTEXT(ctx); 3467 texturesubimage(ctx, 1, texture, level, 3468 xoffset, 0, 0, 3469 width, 1, 1, 3470 format, type, pixels, "glTextureSubImage1D"); 3471 } 3472 3473 3474 void GLAPIENTRY 3475 _mesa_TextureSubImage2D(GLuint texture, GLint level, 3476 GLint xoffset, GLint yoffset, 3477 GLsizei width, GLsizei height, 3478 GLenum format, GLenum type, 3479 const GLvoid *pixels) 3480 { 3481 GET_CURRENT_CONTEXT(ctx); 3482 texturesubimage(ctx, 2, texture, level, 3483 xoffset, yoffset, 0, 3484 width, height, 1, 3485 format, type, pixels, "glTextureSubImage2D"); 3486 } 3487 3488 3489 void GLAPIENTRY 3490 _mesa_TextureSubImage3D(GLuint texture, GLint level, 3491 GLint xoffset, GLint yoffset, GLint zoffset, 3492 GLsizei width, GLsizei height, GLsizei depth, 3493 GLenum format, GLenum type, 3494 const GLvoid *pixels) 3495 { 3496 GET_CURRENT_CONTEXT(ctx); 3497 texturesubimage(ctx, 3, texture, level, 3498 xoffset, yoffset, zoffset, 3499 width, height, depth, 3500 format, type, pixels, "glTextureSubImage3D"); 3501 } 3502 3503 3504 /** 3505 * For glCopyTexSubImage, return the source renderbuffer to copy texel data 3506 * from. This depends on whether the texture contains color or depth values. 3507 */ 3508 static struct gl_renderbuffer * 3509 get_copy_tex_image_source(struct gl_context *ctx, mesa_format texFormat) 3510 { 3511 if (_mesa_get_format_bits(texFormat, GL_DEPTH_BITS) > 0) { 3512 /* reading from depth/stencil buffer */ 3513 return ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 3514 } else if (_mesa_get_format_bits(texFormat, GL_STENCIL_BITS) > 0) { 3515 return ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; 3516 } else { 3517 /* copying from color buffer */ 3518 return ctx->ReadBuffer->_ColorReadBuffer; 3519 } 3520 } 3521 3522 static void 3523 copytexsubimage_by_slice(struct gl_context *ctx, 3524 struct gl_texture_image *texImage, 3525 GLuint dims, 3526 GLint xoffset, GLint yoffset, GLint zoffset, 3527 struct gl_renderbuffer *rb, 3528 GLint x, GLint y, 3529 GLsizei width, GLsizei height) 3530 { 3531 if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) { 3532 int slice; 3533 3534 /* For 1D arrays, we copy each scanline of the source rectangle into the 3535 * next array slice. 3536 */ 3537 assert(zoffset == 0); 3538 3539 for (slice = 0; slice < height; slice++) { 3540 assert(yoffset + slice < texImage->Height); 3541 ctx->Driver.CopyTexSubImage(ctx, 2, texImage, 3542 xoffset, 0, yoffset + slice, 3543 rb, x, y + slice, width, 1); 3544 } 3545 } else { 3546 ctx->Driver.CopyTexSubImage(ctx, dims, texImage, 3547 xoffset, yoffset, zoffset, 3548 rb, x, y, width, height); 3549 } 3550 } 3551 3552 static GLboolean 3553 formats_differ_in_component_sizes(mesa_format f1, mesa_format f2) 3554 { 3555 GLint f1_r_bits = _mesa_get_format_bits(f1, GL_RED_BITS); 3556 GLint f1_g_bits = _mesa_get_format_bits(f1, GL_GREEN_BITS); 3557 GLint f1_b_bits = _mesa_get_format_bits(f1, GL_BLUE_BITS); 3558 GLint f1_a_bits = _mesa_get_format_bits(f1, GL_ALPHA_BITS); 3559 3560 GLint f2_r_bits = _mesa_get_format_bits(f2, GL_RED_BITS); 3561 GLint f2_g_bits = _mesa_get_format_bits(f2, GL_GREEN_BITS); 3562 GLint f2_b_bits = _mesa_get_format_bits(f2, GL_BLUE_BITS); 3563 GLint f2_a_bits = _mesa_get_format_bits(f2, GL_ALPHA_BITS); 3564 3565 if ((f1_r_bits && f2_r_bits && f1_r_bits != f2_r_bits) 3566 || (f1_g_bits && f2_g_bits && f1_g_bits != f2_g_bits) 3567 || (f1_b_bits && f2_b_bits && f1_b_bits != f2_b_bits) 3568 || (f1_a_bits && f2_a_bits && f1_a_bits != f2_a_bits)) 3569 return GL_TRUE; 3570 3571 return GL_FALSE; 3572 } 3573 3574 3575 /** 3576 * Check if the given texture format and size arguments match those 3577 * of the texture image. 3578 * \param return true if arguments match, false otherwise. 3579 */ 3580 static bool 3581 can_avoid_reallocation(const struct gl_texture_image *texImage, 3582 GLenum internalFormat, 3583 mesa_format texFormat, GLint x, GLint y, GLsizei width, 3584 GLsizei height, GLint border) 3585 { 3586 if (texImage->InternalFormat != internalFormat) 3587 return false; 3588 if (texImage->TexFormat != texFormat) 3589 return false; 3590 if (texImage->Border != border) 3591 return false; 3592 if (texImage->Width2 != width) 3593 return false; 3594 if (texImage->Height2 != height) 3595 return false; 3596 return true; 3597 } 3598 3599 /** 3600 * Implement the glCopyTexImage1/2D() functions. 3601 */ 3602 static void 3603 copyteximage(struct gl_context *ctx, GLuint dims, 3604 GLenum target, GLint level, GLenum internalFormat, 3605 GLint x, GLint y, GLsizei width, GLsizei height, GLint border ) 3606 { 3607 struct gl_texture_object *texObj; 3608 struct gl_texture_image *texImage; 3609 const GLuint face = _mesa_tex_target_to_face(target); 3610 mesa_format texFormat; 3611 struct gl_renderbuffer *rb; 3612 3613 FLUSH_VERTICES(ctx, 0); 3614 3615 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3616 _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n", 3617 dims, 3618 _mesa_enum_to_string(target), level, 3619 _mesa_enum_to_string(internalFormat), 3620 x, y, width, height, border); 3621 3622 if (ctx->NewState & NEW_COPY_TEX_STATE) 3623 _mesa_update_state(ctx); 3624 3625 if (copytexture_error_check(ctx, dims, target, level, internalFormat, 3626 width, height, border)) 3627 return; 3628 3629 if (!_mesa_legal_texture_dimensions(ctx, target, level, width, height, 3630 1, border)) { 3631 _mesa_error(ctx, GL_INVALID_VALUE, 3632 "glCopyTexImage%uD(invalid width or height)", dims); 3633 return; 3634 } 3635 3636 texObj = _mesa_get_current_tex_object(ctx, target); 3637 assert(texObj); 3638 3639 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 3640 internalFormat, GL_NONE, GL_NONE); 3641 3642 /* First check if reallocating the texture buffer can be avoided. 3643 * Without the realloc the copy can be 20x faster. 3644 */ 3645 _mesa_lock_texture(ctx, texObj); 3646 { 3647 texImage = _mesa_select_tex_image(texObj, target, level); 3648 if (texImage && can_avoid_reallocation(texImage, internalFormat, texFormat, 3649 x, y, width, height, border)) { 3650 _mesa_unlock_texture(ctx, texObj); 3651 return _mesa_copy_texture_sub_image(ctx, dims, texObj, target, level, 3652 0, 0, 0, x, y, width, height, 3653 "CopyTexImage"); 3654 } 3655 } 3656 _mesa_unlock_texture(ctx, texObj); 3657 _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_LOW, "glCopyTexImage " 3658 "can't avoid reallocating texture storage\n"); 3659 3660 rb = _mesa_get_read_renderbuffer_for_format(ctx, internalFormat); 3661 3662 if (_mesa_is_gles3(ctx)) { 3663 if (_mesa_is_enum_format_unsized(internalFormat)) { 3664 /* Conversion from GL_RGB10_A2 source buffer format is not allowed in 3665 * OpenGL ES 3.0. Khronos bug# 9807. 3666 */ 3667 if (rb->InternalFormat == GL_RGB10_A2) { 3668 _mesa_error(ctx, GL_INVALID_OPERATION, 3669 "glCopyTexImage%uD(Reading from GL_RGB10_A2 buffer" 3670 " and writing to unsized internal format)", dims); 3671 return; 3672 } 3673 } 3674 /* From Page 139 of OpenGL ES 3.0 spec: 3675 * "If internalformat is sized, the internal format of the new texel 3676 * array is internalformat, and this is also the new texel arrays 3677 * effective internal format. If the component sizes of internalformat 3678 * do not exactly match the corresponding component sizes of the source 3679 * buffers effective internal format, described below, an 3680 * INVALID_OPERATION error is generated. If internalformat is unsized, 3681 * the internal format of the new texel array is the effective internal 3682 * format of the source buffer, and this is also the new texel arrays 3683 * effective internal format. 3684 */ 3685 else if (formats_differ_in_component_sizes (texFormat, rb->Format)) { 3686 _mesa_error(ctx, GL_INVALID_OPERATION, 3687 "glCopyTexImage%uD(componenet size changed in" 3688 " internal format)", dims); 3689 return; 3690 } 3691 } 3692 3693 assert(texFormat != MESA_FORMAT_NONE); 3694 3695 if (!ctx->Driver.TestProxyTexImage(ctx, proxy_target(target), 3696 0, level, texFormat, 1, 3697 width, height, 1)) { 3698 _mesa_error(ctx, GL_OUT_OF_MEMORY, 3699 "glCopyTexImage%uD(image too large)", dims); 3700 return; 3701 } 3702 3703 if (border && ctx->Const.StripTextureBorder) { 3704 x += border; 3705 width -= border * 2; 3706 if (dims == 2) { 3707 y += border; 3708 height -= border * 2; 3709 } 3710 border = 0; 3711 } 3712 3713 _mesa_lock_texture(ctx, texObj); 3714 { 3715 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3716 3717 if (!texImage) { 3718 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); 3719 } 3720 else { 3721 GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0; 3722 3723 /* Free old texture image */ 3724 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 3725 3726 _mesa_init_teximage_fields(ctx, texImage, width, height, 1, 3727 border, internalFormat, texFormat); 3728 3729 if (width && height) { 3730 /* Allocate texture memory (no pixel data yet) */ 3731 ctx->Driver.AllocTextureImageBuffer(ctx, texImage); 3732 3733 if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY, 3734 &width, &height)) { 3735 struct gl_renderbuffer *srcRb = 3736 get_copy_tex_image_source(ctx, texImage->TexFormat); 3737 3738 copytexsubimage_by_slice(ctx, texImage, dims, 3739 dstX, dstY, dstZ, 3740 srcRb, srcX, srcY, width, height); 3741 } 3742 3743 check_gen_mipmap(ctx, target, texObj, level); 3744 } 3745 3746 _mesa_update_fbo_texture(ctx, texObj, face, level); 3747 3748 _mesa_dirty_texobj(ctx, texObj); 3749 } 3750 } 3751 _mesa_unlock_texture(ctx, texObj); 3752 } 3753 3754 3755 3756 void GLAPIENTRY 3757 _mesa_CopyTexImage1D( GLenum target, GLint level, 3758 GLenum internalFormat, 3759 GLint x, GLint y, 3760 GLsizei width, GLint border ) 3761 { 3762 GET_CURRENT_CONTEXT(ctx); 3763 copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border); 3764 } 3765 3766 3767 3768 void GLAPIENTRY 3769 _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, 3770 GLint x, GLint y, GLsizei width, GLsizei height, 3771 GLint border ) 3772 { 3773 GET_CURRENT_CONTEXT(ctx); 3774 copyteximage(ctx, 2, target, level, internalFormat, 3775 x, y, width, height, border); 3776 } 3777 3778 /** 3779 * Implementation for glCopyTex(ture)SubImage1/2/3D() functions. 3780 */ 3781 void 3782 _mesa_copy_texture_sub_image(struct gl_context *ctx, GLuint dims, 3783 struct gl_texture_object *texObj, 3784 GLenum target, GLint level, 3785 GLint xoffset, GLint yoffset, GLint zoffset, 3786 GLint x, GLint y, 3787 GLsizei width, GLsizei height, 3788 const char *caller) 3789 { 3790 struct gl_texture_image *texImage; 3791 3792 FLUSH_VERTICES(ctx, 0); 3793 3794 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3795 _mesa_debug(ctx, "%s %s %d %d %d %d %d %d %d %d\n", caller, 3796 _mesa_enum_to_string(target), 3797 level, xoffset, yoffset, zoffset, x, y, width, height); 3798 3799 if (ctx->NewState & NEW_COPY_TEX_STATE) 3800 _mesa_update_state(ctx); 3801 3802 if (copytexsubimage_error_check(ctx, dims, texObj, target, level, 3803 xoffset, yoffset, zoffset, 3804 width, height, caller)) { 3805 return; 3806 } 3807 3808 _mesa_lock_texture(ctx, texObj); 3809 { 3810 texImage = _mesa_select_tex_image(texObj, target, level); 3811 3812 /* If we have a border, offset=-1 is legal. Bias by border width. */ 3813 switch (dims) { 3814 case 3: 3815 if (target != GL_TEXTURE_2D_ARRAY) 3816 zoffset += texImage->Border; 3817 /* fall-through */ 3818 case 2: 3819 if (target != GL_TEXTURE_1D_ARRAY) 3820 yoffset += texImage->Border; 3821 /* fall-through */ 3822 case 1: 3823 xoffset += texImage->Border; 3824 } 3825 3826 if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, 3827 &width, &height)) { 3828 struct gl_renderbuffer *srcRb = 3829 get_copy_tex_image_source(ctx, texImage->TexFormat); 3830 3831 copytexsubimage_by_slice(ctx, texImage, dims, 3832 xoffset, yoffset, zoffset, 3833 srcRb, x, y, width, height); 3834 3835 check_gen_mipmap(ctx, target, texObj, level); 3836 3837 /* NOTE: Don't signal _NEW_TEXTURE since we've only changed 3838 * the texel data, not the texture format, size, etc. 3839 */ 3840 } 3841 } 3842 _mesa_unlock_texture(ctx, texObj); 3843 } 3844 3845 void GLAPIENTRY 3846 _mesa_CopyTexSubImage1D( GLenum target, GLint level, 3847 GLint xoffset, GLint x, GLint y, GLsizei width ) 3848 { 3849 struct gl_texture_object* texObj; 3850 const char *self = "glCopyTexSubImage1D"; 3851 GET_CURRENT_CONTEXT(ctx); 3852 3853 /* Check target (proxies not allowed). Target must be checked prior to 3854 * calling _mesa_get_current_tex_object. 3855 */ 3856 if (!legal_texsubimage_target(ctx, 1, target, false)) { 3857 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self, 3858 _mesa_enum_to_string(target)); 3859 return; 3860 } 3861 3862 texObj = _mesa_get_current_tex_object(ctx, target); 3863 if (!texObj) 3864 return; 3865 3866 _mesa_copy_texture_sub_image(ctx, 1, texObj, target, level, xoffset, 0, 0, 3867 x, y, width, 1, self); 3868 } 3869 3870 3871 3872 void GLAPIENTRY 3873 _mesa_CopyTexSubImage2D( GLenum target, GLint level, 3874 GLint xoffset, GLint yoffset, 3875 GLint x, GLint y, GLsizei width, GLsizei height ) 3876 { 3877 struct gl_texture_object* texObj; 3878 const char *self = "glCopyTexSubImage2D"; 3879 GET_CURRENT_CONTEXT(ctx); 3880 3881 /* Check target (proxies not allowed). Target must be checked prior to 3882 * calling _mesa_get_current_tex_object. 3883 */ 3884 if (!legal_texsubimage_target(ctx, 2, target, false)) { 3885 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self, 3886 _mesa_enum_to_string(target)); 3887 return; 3888 } 3889 3890 texObj = _mesa_get_current_tex_object(ctx, target); 3891 if (!texObj) 3892 return; 3893 3894 _mesa_copy_texture_sub_image(ctx, 2, texObj, target, level, 3895 xoffset, yoffset, 0, 3896 x, y, width, height, self); 3897 } 3898 3899 3900 3901 void GLAPIENTRY 3902 _mesa_CopyTexSubImage3D( GLenum target, GLint level, 3903 GLint xoffset, GLint yoffset, GLint zoffset, 3904 GLint x, GLint y, GLsizei width, GLsizei height ) 3905 { 3906 struct gl_texture_object* texObj; 3907 const char *self = "glCopyTexSubImage3D"; 3908 GET_CURRENT_CONTEXT(ctx); 3909 3910 /* Check target (proxies not allowed). Target must be checked prior to 3911 * calling _mesa_get_current_tex_object. 3912 */ 3913 if (!legal_texsubimage_target(ctx, 3, target, false)) { 3914 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self, 3915 _mesa_enum_to_string(target)); 3916 return; 3917 } 3918 3919 texObj = _mesa_get_current_tex_object(ctx, target); 3920 if (!texObj) 3921 return; 3922 3923 _mesa_copy_texture_sub_image(ctx, 3, texObj, target, level, 3924 xoffset, yoffset, zoffset, 3925 x, y, width, height, self); 3926 } 3927 3928 void GLAPIENTRY 3929 _mesa_CopyTextureSubImage1D(GLuint texture, GLint level, 3930 GLint xoffset, GLint x, GLint y, GLsizei width) 3931 { 3932 struct gl_texture_object* texObj; 3933 const char *self = "glCopyTextureSubImage1D"; 3934 GET_CURRENT_CONTEXT(ctx); 3935 3936 texObj = _mesa_lookup_texture_err(ctx, texture, self); 3937 if (!texObj) 3938 return; 3939 3940 /* Check target (proxies not allowed). */ 3941 if (!legal_texsubimage_target(ctx, 1, texObj->Target, true)) { 3942 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self, 3943 _mesa_enum_to_string(texObj->Target)); 3944 return; 3945 } 3946 3947 _mesa_copy_texture_sub_image(ctx, 1, texObj, texObj->Target, level, 3948 xoffset, 0, 0, x, y, width, 1, self); 3949 } 3950 3951 void GLAPIENTRY 3952 _mesa_CopyTextureSubImage2D(GLuint texture, GLint level, 3953 GLint xoffset, GLint yoffset, 3954 GLint x, GLint y, GLsizei width, GLsizei height) 3955 { 3956 struct gl_texture_object* texObj; 3957 const char *self = "glCopyTextureSubImage2D"; 3958 GET_CURRENT_CONTEXT(ctx); 3959 3960 texObj = _mesa_lookup_texture_err(ctx, texture, self); 3961 if (!texObj) 3962 return; 3963 3964 /* Check target (proxies not allowed). */ 3965 if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) { 3966 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self, 3967 _mesa_enum_to_string(texObj->Target)); 3968 return; 3969 } 3970 3971 _mesa_copy_texture_sub_image(ctx, 2, texObj, texObj->Target, level, 3972 xoffset, yoffset, 0, 3973 x, y, width, height, self); 3974 } 3975 3976 3977 3978 void GLAPIENTRY 3979 _mesa_CopyTextureSubImage3D(GLuint texture, GLint level, 3980 GLint xoffset, GLint yoffset, GLint zoffset, 3981 GLint x, GLint y, GLsizei width, GLsizei height) 3982 { 3983 struct gl_texture_object* texObj; 3984 const char *self = "glCopyTextureSubImage3D"; 3985 GET_CURRENT_CONTEXT(ctx); 3986 3987 texObj = _mesa_lookup_texture_err(ctx, texture, self); 3988 if (!texObj) 3989 return; 3990 3991 /* Check target (proxies not allowed). */ 3992 if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) { 3993 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self, 3994 _mesa_enum_to_string(texObj->Target)); 3995 return; 3996 } 3997 3998 if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 3999 /* Act like CopyTexSubImage2D */ 4000 _mesa_copy_texture_sub_image(ctx, 2, texObj, 4001 GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset, 4002 level, xoffset, yoffset, 0, 4003 x, y, width, height, self); 4004 } 4005 else 4006 _mesa_copy_texture_sub_image(ctx, 3, texObj, texObj->Target, level, 4007 xoffset, yoffset, zoffset, 4008 x, y, width, height, self); 4009 } 4010 4011 static bool 4012 check_clear_tex_image(struct gl_context *ctx, 4013 const char *function, 4014 struct gl_texture_image *texImage, 4015 GLenum format, GLenum type, 4016 const void *data, 4017 GLubyte *clearValue) 4018 { 4019 struct gl_texture_object *texObj = texImage->TexObject; 4020 static const GLubyte zeroData[MAX_PIXEL_BYTES]; 4021 GLenum internalFormat = texImage->InternalFormat; 4022 GLenum err; 4023 4024 if (texObj->Target == GL_TEXTURE_BUFFER) { 4025 _mesa_error(ctx, GL_INVALID_OPERATION, 4026 "%s(buffer texture)", function); 4027 return false; 4028 } 4029 4030 if (_mesa_is_compressed_format(ctx, internalFormat)) { 4031 _mesa_error(ctx, GL_INVALID_OPERATION, 4032 "%s(compressed texture)", function); 4033 return false; 4034 } 4035 4036 err = _mesa_error_check_format_and_type(ctx, format, type); 4037 if (err != GL_NO_ERROR) { 4038 _mesa_error(ctx, err, 4039 "%s(incompatible format = %s, type = %s)", 4040 function, 4041 _mesa_enum_to_string(format), 4042 _mesa_enum_to_string(type)); 4043 return false; 4044 } 4045 4046 /* make sure internal format and format basically agree */ 4047 if (!texture_formats_agree(internalFormat, format)) { 4048 _mesa_error(ctx, GL_INVALID_OPERATION, 4049 "%s(incompatible internalFormat = %s, format = %s)", 4050 function, 4051 _mesa_enum_to_string(internalFormat), 4052 _mesa_enum_to_string(format)); 4053 return false; 4054 } 4055 4056 if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) { 4057 /* both source and dest must be integer-valued, or neither */ 4058 if (_mesa_is_format_integer_color(texImage->TexFormat) != 4059 _mesa_is_enum_format_integer(format)) { 4060 _mesa_error(ctx, GL_INVALID_OPERATION, 4061 "%s(integer/non-integer format mismatch)", 4062 function); 4063 return false; 4064 } 4065 } 4066 4067 if (!_mesa_texstore(ctx, 4068 1, /* dims */ 4069 texImage->_BaseFormat, 4070 texImage->TexFormat, 4071 0, /* dstRowStride */ 4072 &clearValue, 4073 1, 1, 1, /* srcWidth/Height/Depth */ 4074 format, type, 4075 data ? data : zeroData, 4076 &ctx->DefaultPacking)) { 4077 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid format)", function); 4078 return false; 4079 } 4080 4081 return true; 4082 } 4083 4084 static struct gl_texture_object * 4085 get_tex_obj_for_clear(struct gl_context *ctx, 4086 const char *function, 4087 GLuint texture) 4088 { 4089 struct gl_texture_object *texObj; 4090 4091 if (texture == 0) { 4092 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(zero texture)", function); 4093 return NULL; 4094 } 4095 4096 texObj = _mesa_lookup_texture(ctx, texture); 4097 4098 if (texObj == NULL) { 4099 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", function); 4100 return NULL; 4101 } 4102 4103 if (texObj->Target == 0) { 4104 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unbound tex)", function); 4105 return NULL; 4106 } 4107 4108 return texObj; 4109 } 4110 4111 static int 4112 get_tex_images_for_clear(struct gl_context *ctx, 4113 const char *function, 4114 struct gl_texture_object *texObj, 4115 GLint level, 4116 struct gl_texture_image **texImages) 4117 { 4118 GLenum target; 4119 int i; 4120 4121 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 4122 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function); 4123 return 0; 4124 } 4125 4126 if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 4127 for (i = 0; i < MAX_FACES; i++) { 4128 target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; 4129 4130 texImages[i] = _mesa_select_tex_image(texObj, target, level); 4131 if (texImages[i] == NULL) { 4132 _mesa_error(ctx, GL_INVALID_OPERATION, 4133 "%s(invalid level)", function); 4134 return 0; 4135 } 4136 } 4137 4138 return MAX_FACES; 4139 } 4140 4141 texImages[0] = _mesa_select_tex_image(texObj, texObj->Target, level); 4142 4143 if (texImages[0] == NULL) { 4144 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function); 4145 return 0; 4146 } 4147 4148 return 1; 4149 } 4150 4151 void GLAPIENTRY 4152 _mesa_ClearTexSubImage( GLuint texture, GLint level, 4153 GLint xoffset, GLint yoffset, GLint zoffset, 4154 GLsizei width, GLsizei height, GLsizei depth, 4155 GLenum format, GLenum type, const void *data ) 4156 { 4157 GET_CURRENT_CONTEXT(ctx); 4158 struct gl_texture_object *texObj; 4159 struct gl_texture_image *texImages[MAX_FACES]; 4160 GLubyte clearValue[MAX_FACES][MAX_PIXEL_BYTES]; 4161 int i, numImages; 4162 int minDepth, maxDepth; 4163 4164 texObj = get_tex_obj_for_clear(ctx, "glClearTexSubImage", texture); 4165 4166 if (texObj == NULL) 4167 return; 4168 4169 _mesa_lock_texture(ctx, texObj); 4170 4171 numImages = get_tex_images_for_clear(ctx, "glClearTexSubImage", 4172 texObj, level, texImages); 4173 if (numImages == 0) 4174 goto out; 4175 4176 if (numImages == 1) { 4177 minDepth = -(int) texImages[0]->Border; 4178 maxDepth = texImages[0]->Depth; 4179 } else { 4180 minDepth = 0; 4181 maxDepth = numImages; 4182 } 4183 4184 if (xoffset < -(GLint) texImages[0]->Border || 4185 yoffset < -(GLint) texImages[0]->Border || 4186 zoffset < minDepth || 4187 width < 0 || 4188 height < 0 || 4189 depth < 0 || 4190 xoffset + width > texImages[0]->Width || 4191 yoffset + height > texImages[0]->Height || 4192 zoffset + depth > maxDepth) { 4193 _mesa_error(ctx, GL_INVALID_OPERATION, 4194 "glClearSubTexImage(invalid dimensions)"); 4195 goto out; 4196 } 4197 4198 if (numImages == 1) { 4199 if (check_clear_tex_image(ctx, "glClearTexSubImage", 4200 texImages[0], 4201 format, type, data, clearValue[0])) { 4202 ctx->Driver.ClearTexSubImage(ctx, 4203 texImages[0], 4204 xoffset, yoffset, zoffset, 4205 width, height, depth, 4206 data ? clearValue[0] : NULL); 4207 } 4208 } else { 4209 for (i = zoffset; i < zoffset + depth; i++) { 4210 if (!check_clear_tex_image(ctx, "glClearTexSubImage", 4211 texImages[i], 4212 format, type, data, clearValue[i])) 4213 goto out; 4214 } 4215 for (i = zoffset; i < zoffset + depth; i++) { 4216 ctx->Driver.ClearTexSubImage(ctx, 4217 texImages[i], 4218 xoffset, yoffset, 0, 4219 width, height, 1, 4220 data ? clearValue[i] : NULL); 4221 } 4222 } 4223 4224 out: 4225 _mesa_unlock_texture(ctx, texObj); 4226 } 4227 4228 void GLAPIENTRY 4229 _mesa_ClearTexImage( GLuint texture, GLint level, 4230 GLenum format, GLenum type, const void *data ) 4231 { 4232 GET_CURRENT_CONTEXT(ctx); 4233 struct gl_texture_object *texObj; 4234 struct gl_texture_image *texImages[MAX_FACES]; 4235 GLubyte clearValue[MAX_FACES][MAX_PIXEL_BYTES]; 4236 int i, numImages; 4237 4238 texObj = get_tex_obj_for_clear(ctx, "glClearTexImage", texture); 4239 4240 if (texObj == NULL) 4241 return; 4242 4243 _mesa_lock_texture(ctx, texObj); 4244 4245 numImages = get_tex_images_for_clear(ctx, "glClearTexImage", 4246 texObj, level, texImages); 4247 4248 for (i = 0; i < numImages; i++) { 4249 if (!check_clear_tex_image(ctx, "glClearTexImage", 4250 texImages[i], 4251 format, type, data, 4252 clearValue[i])) 4253 goto out; 4254 } 4255 4256 for (i = 0; i < numImages; i++) { 4257 ctx->Driver.ClearTexSubImage(ctx, texImages[i], 4258 -(GLint) texImages[i]->Border, /* xoffset */ 4259 -(GLint) texImages[i]->Border, /* yoffset */ 4260 -(GLint) texImages[i]->Border, /* zoffset */ 4261 texImages[i]->Width, 4262 texImages[i]->Height, 4263 texImages[i]->Depth, 4264 data ? clearValue[i] : NULL); 4265 } 4266 4267 out: 4268 _mesa_unlock_texture(ctx, texObj); 4269 } 4270 4271 4272 4273 4274 /**********************************************************************/ 4275 /****** Compressed Textures ******/ 4276 /**********************************************************************/ 4277 4278 4279 /** 4280 * Target checking for glCompressedTexSubImage[123]D(). 4281 * \return GL_TRUE if error, GL_FALSE if no error 4282 * Must come before other error checking so that the texture object can 4283 * be correctly retrieved using _mesa_get_current_tex_object. 4284 */ 4285 static GLboolean 4286 compressed_subtexture_target_check(struct gl_context *ctx, GLenum target, 4287 GLint dims, GLenum format, bool dsa, 4288 const char *caller) 4289 { 4290 GLboolean targetOK; 4291 4292 if (dsa && target == GL_TEXTURE_RECTANGLE) { 4293 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", caller, 4294 _mesa_enum_to_string(target)); 4295 return GL_TRUE; 4296 } 4297 4298 switch (dims) { 4299 case 2: 4300 switch (target) { 4301 case GL_TEXTURE_2D: 4302 targetOK = GL_TRUE; 4303 break; 4304 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 4305 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 4306 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 4307 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 4308 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 4309 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 4310 targetOK = ctx->Extensions.ARB_texture_cube_map; 4311 break; 4312 default: 4313 targetOK = GL_FALSE; 4314 break; 4315 } 4316 break; 4317 case 3: 4318 switch (target) { 4319 case GL_TEXTURE_CUBE_MAP: 4320 targetOK = dsa && ctx->Extensions.ARB_texture_cube_map; 4321 break; 4322 case GL_TEXTURE_2D_ARRAY: 4323 targetOK = _mesa_is_gles3(ctx) || 4324 (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array); 4325 break; 4326 case GL_TEXTURE_CUBE_MAP_ARRAY: 4327 targetOK = _mesa_has_texture_cube_map_array(ctx); 4328 break; 4329 case GL_TEXTURE_3D: 4330 targetOK = GL_TRUE; 4331 /* 4332 * OpenGL 4.5 spec (30.10.2014) says in Section 8.7 Compressed Texture 4333 * Images: 4334 * "An INVALID_OPERATION error is generated by 4335 * CompressedTex*SubImage3D if the internal format of the texture 4336 * is one of the EAC, ETC2, or RGTC formats and either border is 4337 * non-zero, or the effective target for the texture is not 4338 * TEXTURE_2D_ARRAY." 4339 * 4340 * NOTE: that's probably a spec error. It should probably say 4341 * "... or the effective target for the texture is not 4342 * TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP, nor 4343 * GL_TEXTURE_CUBE_MAP_ARRAY." 4344 * since those targets are 2D images and they support all compression 4345 * formats. 4346 * 4347 * Instead of listing all these, just list those which are allowed, 4348 * which is (at this time) only bptc. Otherwise we'd say s3tc (and 4349 * more) are valid here, which they are not, but of course not 4350 * mentioned by core spec. 4351 */ 4352 switch (format) { 4353 /* These are the only 3D compression formats supported at this time */ 4354 case GL_COMPRESSED_RGBA_BPTC_UNORM: 4355 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: 4356 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: 4357 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: 4358 /* valid format */ 4359 break; 4360 default: 4361 /* invalid format */ 4362 _mesa_error(ctx, GL_INVALID_OPERATION, 4363 "%s(invalid target %s for format %s)", caller, 4364 _mesa_enum_to_string(target), 4365 _mesa_enum_to_string(format)); 4366 return GL_TRUE; 4367 } 4368 break; 4369 default: 4370 targetOK = GL_FALSE; 4371 } 4372 4373 break; 4374 default: 4375 assert(dims == 1); 4376 /* no 1D compressed textures at this time */ 4377 targetOK = GL_FALSE; 4378 break; 4379 } 4380 4381 if (!targetOK) { 4382 _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", caller, 4383 _mesa_enum_to_string(target)); 4384 return GL_TRUE; 4385 } 4386 4387 return GL_FALSE; 4388 } 4389 4390 /** 4391 * Error checking for glCompressedTexSubImage[123]D(). 4392 * \return GL_TRUE if error, GL_FALSE if no error 4393 */ 4394 static GLboolean 4395 compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, 4396 const struct gl_texture_object *texObj, 4397 GLenum target, GLint level, 4398 GLint xoffset, GLint yoffset, GLint zoffset, 4399 GLsizei width, GLsizei height, GLsizei depth, 4400 GLenum format, GLsizei imageSize, 4401 const GLvoid *data, const char *callerName) 4402 { 4403 struct gl_texture_image *texImage; 4404 GLint expectedSize; 4405 4406 /* this will catch any invalid compressed format token */ 4407 if (!_mesa_is_compressed_format(ctx, format)) { 4408 _mesa_error(ctx, GL_INVALID_ENUM, 4409 "%s(format)", callerName); 4410 return GL_TRUE; 4411 } 4412 4413 if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { 4414 _mesa_error(ctx, GL_INVALID_VALUE, 4415 "%s(level=%d)", 4416 callerName, level); 4417 return GL_TRUE; 4418 } 4419 4420 /* validate the bound PBO, if any */ 4421 if (!_mesa_validate_pbo_source_compressed(ctx, dims, &ctx->Unpack, 4422 imageSize, data, callerName)) { 4423 return GL_TRUE; 4424 } 4425 4426 /* Check for invalid pixel storage modes */ 4427 if (!_mesa_compressed_pixel_storage_error_check(ctx, dims, 4428 &ctx->Unpack, callerName)) { 4429 return GL_TRUE; 4430 } 4431 4432 expectedSize = compressed_tex_size(width, height, depth, format); 4433 if (expectedSize != imageSize) { 4434 _mesa_error(ctx, GL_INVALID_VALUE, 4435 "%s(size=%d)", 4436 callerName, imageSize); 4437 return GL_TRUE; 4438 } 4439 4440 texImage = _mesa_select_tex_image(texObj, target, level); 4441 if (!texImage) { 4442 _mesa_error(ctx, GL_INVALID_OPERATION, 4443 "%s(invalid texture image)", 4444 callerName); 4445 return GL_TRUE; 4446 } 4447 4448 if ((GLint) format != texImage->InternalFormat) { 4449 _mesa_error(ctx, GL_INVALID_OPERATION, 4450 "%s(format=%s)", 4451 callerName, _mesa_enum_to_string(format)); 4452 return GL_TRUE; 4453 } 4454 4455 if (compressedteximage_only_format(ctx, format)) { 4456 _mesa_error(ctx, GL_INVALID_OPERATION, 4457 "%s(format=%s cannot be updated)", 4458 callerName, _mesa_enum_to_string(format)); 4459 return GL_TRUE; 4460 } 4461 4462 if (error_check_subtexture_negative_dimensions(ctx, dims, 4463 width, height, depth, 4464 callerName)) { 4465 return GL_TRUE; 4466 } 4467 4468 if (error_check_subtexture_dimensions(ctx, dims, 4469 texImage, xoffset, yoffset, zoffset, 4470 width, height, depth, 4471 callerName)) { 4472 return GL_TRUE; 4473 } 4474 4475 return GL_FALSE; 4476 } 4477 4478 4479 void GLAPIENTRY 4480 _mesa_CompressedTexImage1D(GLenum target, GLint level, 4481 GLenum internalFormat, GLsizei width, 4482 GLint border, GLsizei imageSize, 4483 const GLvoid *data) 4484 { 4485 GET_CURRENT_CONTEXT(ctx); 4486 teximage(ctx, GL_TRUE, 1, target, level, internalFormat, 4487 width, 1, 1, border, GL_NONE, GL_NONE, imageSize, data); 4488 } 4489 4490 4491 void GLAPIENTRY 4492 _mesa_CompressedTexImage2D(GLenum target, GLint level, 4493 GLenum internalFormat, GLsizei width, 4494 GLsizei height, GLint border, GLsizei imageSize, 4495 const GLvoid *data) 4496 { 4497 GET_CURRENT_CONTEXT(ctx); 4498 teximage(ctx, GL_TRUE, 2, target, level, internalFormat, 4499 width, height, 1, border, GL_NONE, GL_NONE, imageSize, data); 4500 } 4501 4502 4503 void GLAPIENTRY 4504 _mesa_CompressedTexImage3D(GLenum target, GLint level, 4505 GLenum internalFormat, GLsizei width, 4506 GLsizei height, GLsizei depth, GLint border, 4507 GLsizei imageSize, const GLvoid *data) 4508 { 4509 GET_CURRENT_CONTEXT(ctx); 4510 teximage(ctx, GL_TRUE, 3, target, level, internalFormat, 4511 width, height, depth, border, GL_NONE, GL_NONE, imageSize, data); 4512 } 4513 4514 4515 /** 4516 * Common helper for glCompressedTexSubImage1/2/3D() and 4517 * glCompressedTextureSubImage1/2/3D(). 4518 */ 4519 void 4520 _mesa_compressed_texture_sub_image(struct gl_context *ctx, GLuint dims, 4521 struct gl_texture_object *texObj, 4522 struct gl_texture_image *texImage, 4523 GLenum target, GLint level, 4524 GLint xoffset, GLint yoffset, 4525 GLint zoffset, 4526 GLsizei width, GLsizei height, 4527 GLsizei depth, 4528 GLenum format, GLsizei imageSize, 4529 const GLvoid *data) 4530 { 4531 FLUSH_VERTICES(ctx, 0); 4532 4533 _mesa_lock_texture(ctx, texObj); 4534 { 4535 if (width > 0 && height > 0 && depth > 0) { 4536 ctx->Driver.CompressedTexSubImage(ctx, dims, texImage, 4537 xoffset, yoffset, zoffset, 4538 width, height, depth, 4539 format, imageSize, data); 4540 4541 check_gen_mipmap(ctx, target, texObj, level); 4542 4543 /* NOTE: Don't signal _NEW_TEXTURE since we've only changed 4544 * the texel data, not the texture format, size, etc. 4545 */ 4546 } 4547 } 4548 _mesa_unlock_texture(ctx, texObj); 4549 } 4550 4551 4552 void GLAPIENTRY 4553 _mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, 4554 GLsizei width, GLenum format, 4555 GLsizei imageSize, const GLvoid *data) 4556 { 4557 struct gl_texture_object *texObj; 4558 struct gl_texture_image *texImage; 4559 4560 GET_CURRENT_CONTEXT(ctx); 4561 4562 if (compressed_subtexture_target_check(ctx, target, 1, format, false, 4563 "glCompressedTexSubImage1D")) { 4564 return; 4565 } 4566 4567 texObj = _mesa_get_current_tex_object(ctx, target); 4568 if (!texObj) 4569 return; 4570 4571 if (compressed_subtexture_error_check(ctx, 1, texObj, target, 4572 level, xoffset, 0, 0, 4573 width, 1, 1, 4574 format, imageSize, data, 4575 "glCompressedTexSubImage1D")) { 4576 return; 4577 } 4578 4579 texImage = _mesa_select_tex_image(texObj, target, level); 4580 assert(texImage); 4581 4582 _mesa_compressed_texture_sub_image(ctx, 1, texObj, texImage, target, level, 4583 xoffset, 0, 0, width, 1, 1, 4584 format, imageSize, data); 4585 } 4586 4587 void GLAPIENTRY 4588 _mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, 4589 GLsizei width, GLenum format, 4590 GLsizei imageSize, const GLvoid *data) 4591 { 4592 struct gl_texture_object *texObj; 4593 struct gl_texture_image *texImage; 4594 4595 GET_CURRENT_CONTEXT(ctx); 4596 4597 texObj = _mesa_lookup_texture_err(ctx, texture, 4598 "glCompressedTextureSubImage1D"); 4599 if (!texObj) 4600 return; 4601 4602 if (compressed_subtexture_target_check(ctx, texObj->Target, 1, format, true, 4603 "glCompressedTextureSubImage1D")) { 4604 return; 4605 } 4606 4607 if (compressed_subtexture_error_check(ctx, 1, texObj, texObj->Target, 4608 level, xoffset, 0, 0, 4609 width, 1, 1, 4610 format, imageSize, data, 4611 "glCompressedTextureSubImage1D")) { 4612 return; 4613 } 4614 4615 texImage = _mesa_select_tex_image(texObj, texObj->Target, level); 4616 assert(texImage); 4617 4618 _mesa_compressed_texture_sub_image(ctx, 1, texObj, texImage, 4619 texObj->Target, level, 4620 xoffset, 0, 0, width, 1, 1, 4621 format, imageSize, data); 4622 } 4623 4624 4625 void GLAPIENTRY 4626 _mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, 4627 GLint yoffset, GLsizei width, GLsizei height, 4628 GLenum format, GLsizei imageSize, 4629 const GLvoid *data) 4630 { 4631 struct gl_texture_object *texObj; 4632 struct gl_texture_image *texImage; 4633 4634 GET_CURRENT_CONTEXT(ctx); 4635 4636 if (compressed_subtexture_target_check(ctx, target, 2, format, false, 4637 "glCompressedTexSubImage2D")) { 4638 return; 4639 } 4640 4641 texObj = _mesa_get_current_tex_object(ctx, target); 4642 if (!texObj) 4643 return; 4644 4645 if (compressed_subtexture_error_check(ctx, 2, texObj, target, 4646 level, xoffset, yoffset, 0, 4647 width, height, 1, 4648 format, imageSize, data, 4649 "glCompressedTexSubImage2D")) { 4650 return; 4651 } 4652 4653 4654 texImage = _mesa_select_tex_image(texObj, target, level); 4655 assert(texImage); 4656 4657 _mesa_compressed_texture_sub_image(ctx, 2, texObj, texImage, target, level, 4658 xoffset, yoffset, 0, width, height, 1, 4659 format, imageSize, data); 4660 } 4661 4662 void GLAPIENTRY 4663 _mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, 4664 GLint yoffset, 4665 GLsizei width, GLsizei height, 4666 GLenum format, GLsizei imageSize, 4667 const GLvoid *data) 4668 { 4669 struct gl_texture_object *texObj; 4670 struct gl_texture_image *texImage; 4671 4672 GET_CURRENT_CONTEXT(ctx); 4673 4674 texObj = _mesa_lookup_texture_err(ctx, texture, 4675 "glCompressedTextureSubImage2D"); 4676 if (!texObj) 4677 return; 4678 4679 if (compressed_subtexture_target_check(ctx, texObj->Target, 2, format, true, 4680 "glCompressedTextureSubImage2D")) { 4681 return; 4682 } 4683 4684 if (compressed_subtexture_error_check(ctx, 2, texObj, texObj->Target, 4685 level, xoffset, yoffset, 0, 4686 width, height, 1, 4687 format, imageSize, data, 4688 "glCompressedTextureSubImage2D")) { 4689 return; 4690 } 4691 4692 texImage = _mesa_select_tex_image(texObj, texObj->Target, level); 4693 assert(texImage); 4694 4695 _mesa_compressed_texture_sub_image(ctx, 2, texObj, texImage, 4696 texObj->Target, level, 4697 xoffset, yoffset, 0, width, height, 1, 4698 format, imageSize, data); 4699 } 4700 4701 void GLAPIENTRY 4702 _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, 4703 GLint yoffset, GLint zoffset, GLsizei width, 4704 GLsizei height, GLsizei depth, GLenum format, 4705 GLsizei imageSize, const GLvoid *data) 4706 { 4707 struct gl_texture_object *texObj; 4708 struct gl_texture_image *texImage; 4709 4710 GET_CURRENT_CONTEXT(ctx); 4711 4712 if (compressed_subtexture_target_check(ctx, target, 3, format, false, 4713 "glCompressedTexSubImage3D")) { 4714 return; 4715 } 4716 4717 texObj = _mesa_get_current_tex_object(ctx, target); 4718 if (!texObj) 4719 return; 4720 4721 if (compressed_subtexture_error_check(ctx, 3, texObj, target, 4722 level, xoffset, yoffset, zoffset, 4723 width, height, depth, 4724 format, imageSize, data, 4725 "glCompressedTexSubImage3D")) { 4726 return; 4727 } 4728 4729 4730 texImage = _mesa_select_tex_image(texObj, target, level); 4731 assert(texImage); 4732 4733 _mesa_compressed_texture_sub_image(ctx, 3, texObj, texImage, target, level, 4734 xoffset, yoffset, zoffset, 4735 width, height, depth, 4736 format, imageSize, data); 4737 } 4738 4739 void GLAPIENTRY 4740 _mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, 4741 GLint yoffset, GLint zoffset, GLsizei width, 4742 GLsizei height, GLsizei depth, 4743 GLenum format, GLsizei imageSize, 4744 const GLvoid *data) 4745 { 4746 struct gl_texture_object *texObj; 4747 struct gl_texture_image *texImage; 4748 4749 GET_CURRENT_CONTEXT(ctx); 4750 4751 texObj = _mesa_lookup_texture_err(ctx, texture, 4752 "glCompressedTextureSubImage3D"); 4753 if (!texObj) 4754 return; 4755 4756 if (compressed_subtexture_target_check(ctx, texObj->Target, 3, format, true, 4757 "glCompressedTextureSubImage3D")) { 4758 return; 4759 } 4760 4761 if (compressed_subtexture_error_check(ctx, 3, texObj, texObj->Target, 4762 level, xoffset, yoffset, zoffset, 4763 width, height, depth, 4764 format, imageSize, data, 4765 "glCompressedTextureSubImage3D")) { 4766 return; 4767 } 4768 4769 /* Must handle special case GL_TEXTURE_CUBE_MAP. */ 4770 if (texObj->Target == GL_TEXTURE_CUBE_MAP) { 4771 const char *pixels = data; 4772 int i; 4773 GLint image_stride; 4774 4775 /* Make sure the texture object is a proper cube. 4776 * (See texturesubimage in teximage.c for details on why this check is 4777 * performed.) 4778 */ 4779 if (!_mesa_cube_level_complete(texObj, level)) { 4780 _mesa_error(ctx, GL_INVALID_OPERATION, 4781 "glCompressedTextureSubImage3D(cube map incomplete)"); 4782 return; 4783 } 4784 4785 /* Copy in each face. */ 4786 for (i = 0; i < 6; ++i) { 4787 texImage = texObj->Image[i][level]; 4788 assert(texImage); 4789 4790 _mesa_compressed_texture_sub_image(ctx, 3, texObj, texImage, 4791 texObj->Target, level, 4792 xoffset, yoffset, zoffset, 4793 width, height, 1, 4794 format, imageSize, pixels); 4795 4796 /* Compressed images don't have a client format */ 4797 image_stride = _mesa_format_image_size(texImage->TexFormat, 4798 texImage->Width, 4799 texImage->Height, 1); 4800 4801 pixels += image_stride; 4802 imageSize -= image_stride; 4803 } 4804 } 4805 else { 4806 texImage = _mesa_select_tex_image(texObj, texObj->Target, level); 4807 assert(texImage); 4808 4809 _mesa_compressed_texture_sub_image(ctx, 3, texObj, texImage, 4810 texObj->Target, level, 4811 xoffset, yoffset, zoffset, 4812 width, height, depth, 4813 format, imageSize, data); 4814 } 4815 } 4816 4817 static mesa_format 4818 get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) 4819 { 4820 if (ctx->API == API_OPENGL_COMPAT) { 4821 switch (internalFormat) { 4822 case GL_ALPHA8: 4823 return MESA_FORMAT_A_UNORM8; 4824 case GL_ALPHA16: 4825 return MESA_FORMAT_A_UNORM16; 4826 case GL_ALPHA16F_ARB: 4827 return MESA_FORMAT_A_FLOAT16; 4828 case GL_ALPHA32F_ARB: 4829 return MESA_FORMAT_A_FLOAT32; 4830 case GL_ALPHA8I_EXT: 4831 return MESA_FORMAT_A_SINT8; 4832 case GL_ALPHA16I_EXT: 4833 return MESA_FORMAT_A_SINT16; 4834 case GL_ALPHA32I_EXT: 4835 return MESA_FORMAT_A_SINT32; 4836 case GL_ALPHA8UI_EXT: 4837 return MESA_FORMAT_A_UINT8; 4838 case GL_ALPHA16UI_EXT: 4839 return MESA_FORMAT_A_UINT16; 4840 case GL_ALPHA32UI_EXT: 4841 return MESA_FORMAT_A_UINT32; 4842 case GL_LUMINANCE8: 4843 return MESA_FORMAT_L_UNORM8; 4844 case GL_LUMINANCE16: 4845 return MESA_FORMAT_L_UNORM16; 4846 case GL_LUMINANCE16F_ARB: 4847 return MESA_FORMAT_L_FLOAT16; 4848 case GL_LUMINANCE32F_ARB: 4849 return MESA_FORMAT_L_FLOAT32; 4850 case GL_LUMINANCE8I_EXT: 4851 return MESA_FORMAT_L_SINT8; 4852 case GL_LUMINANCE16I_EXT: 4853 return MESA_FORMAT_L_SINT16; 4854 case GL_LUMINANCE32I_EXT: 4855 return MESA_FORMAT_L_SINT32; 4856 case GL_LUMINANCE8UI_EXT: 4857 return MESA_FORMAT_L_UINT8; 4858 case GL_LUMINANCE16UI_EXT: 4859 return MESA_FORMAT_L_UINT16; 4860 case GL_LUMINANCE32UI_EXT: 4861 return MESA_FORMAT_L_UINT32; 4862 case GL_LUMINANCE8_ALPHA8: 4863 return MESA_FORMAT_L8A8_UNORM; 4864 case GL_LUMINANCE16_ALPHA16: 4865 return MESA_FORMAT_L16A16_UNORM; 4866 case GL_LUMINANCE_ALPHA16F_ARB: 4867 return MESA_FORMAT_LA_FLOAT16; 4868 case GL_LUMINANCE_ALPHA32F_ARB: 4869 return MESA_FORMAT_LA_FLOAT32; 4870 case GL_LUMINANCE_ALPHA8I_EXT: 4871 return MESA_FORMAT_LA_SINT8; 4872 case GL_LUMINANCE_ALPHA16I_EXT: 4873 return MESA_FORMAT_LA_SINT16; 4874 case GL_LUMINANCE_ALPHA32I_EXT: 4875 return MESA_FORMAT_LA_SINT32; 4876 case GL_LUMINANCE_ALPHA8UI_EXT: 4877 return MESA_FORMAT_LA_UINT8; 4878 case GL_LUMINANCE_ALPHA16UI_EXT: 4879 return MESA_FORMAT_LA_UINT16; 4880 case GL_LUMINANCE_ALPHA32UI_EXT: 4881 return MESA_FORMAT_LA_UINT32; 4882 case GL_INTENSITY8: 4883 return MESA_FORMAT_I_UNORM8; 4884 case GL_INTENSITY16: 4885 return MESA_FORMAT_I_UNORM16; 4886 case GL_INTENSITY16F_ARB: 4887 return MESA_FORMAT_I_FLOAT16; 4888 case GL_INTENSITY32F_ARB: 4889 return MESA_FORMAT_I_FLOAT32; 4890 case GL_INTENSITY8I_EXT: 4891 return MESA_FORMAT_I_SINT8; 4892 case GL_INTENSITY16I_EXT: 4893 return MESA_FORMAT_I_SINT16; 4894 case GL_INTENSITY32I_EXT: 4895 return MESA_FORMAT_I_SINT32; 4896 case GL_INTENSITY8UI_EXT: 4897 return MESA_FORMAT_I_UINT8; 4898 case GL_INTENSITY16UI_EXT: 4899 return MESA_FORMAT_I_UINT16; 4900 case GL_INTENSITY32UI_EXT: 4901 return MESA_FORMAT_I_UINT32; 4902 default: 4903 break; 4904 } 4905 } 4906 4907 if (_mesa_has_ARB_texture_buffer_object_rgb32(ctx) || 4908 _mesa_has_OES_texture_buffer(ctx)) { 4909 switch (internalFormat) { 4910 case GL_RGB32F: 4911 return MESA_FORMAT_RGB_FLOAT32; 4912 case GL_RGB32UI: 4913 return MESA_FORMAT_RGB_UINT32; 4914 case GL_RGB32I: 4915 return MESA_FORMAT_RGB_SINT32; 4916 default: 4917 break; 4918 } 4919 } 4920 4921 switch (internalFormat) { 4922 case GL_RGBA8: 4923 return MESA_FORMAT_R8G8B8A8_UNORM; 4924 case GL_RGBA16: 4925 if (_mesa_is_gles(ctx)) 4926 return MESA_FORMAT_NONE; 4927 return MESA_FORMAT_RGBA_UNORM16; 4928 case GL_RGBA16F_ARB: 4929 return MESA_FORMAT_RGBA_FLOAT16; 4930 case GL_RGBA32F_ARB: 4931 return MESA_FORMAT_RGBA_FLOAT32; 4932 case GL_RGBA8I_EXT: 4933 return MESA_FORMAT_RGBA_SINT8; 4934 case GL_RGBA16I_EXT: 4935 return MESA_FORMAT_RGBA_SINT16; 4936 case GL_RGBA32I_EXT: 4937 return MESA_FORMAT_RGBA_SINT32; 4938 case GL_RGBA8UI_EXT: 4939 return MESA_FORMAT_RGBA_UINT8; 4940 case GL_RGBA16UI_EXT: 4941 return MESA_FORMAT_RGBA_UINT16; 4942 case GL_RGBA32UI_EXT: 4943 return MESA_FORMAT_RGBA_UINT32; 4944 4945 case GL_RG8: 4946 return MESA_FORMAT_R8G8_UNORM; 4947 case GL_RG16: 4948 if (_mesa_is_gles(ctx)) 4949 return MESA_FORMAT_NONE; 4950 return MESA_FORMAT_R16G16_UNORM; 4951 case GL_RG16F: 4952 return MESA_FORMAT_RG_FLOAT16; 4953 case GL_RG32F: 4954 return MESA_FORMAT_RG_FLOAT32; 4955 case GL_RG8I: 4956 return MESA_FORMAT_RG_SINT8; 4957 case GL_RG16I: 4958 return MESA_FORMAT_RG_SINT16; 4959 case GL_RG32I: 4960 return MESA_FORMAT_RG_SINT32; 4961 case GL_RG8UI: 4962 return MESA_FORMAT_RG_UINT8; 4963 case GL_RG16UI: 4964 return MESA_FORMAT_RG_UINT16; 4965 case GL_RG32UI: 4966 return MESA_FORMAT_RG_UINT32; 4967 4968 case GL_R8: 4969 return MESA_FORMAT_R_UNORM8; 4970 case GL_R16: 4971 if (_mesa_is_gles(ctx)) 4972 return MESA_FORMAT_NONE; 4973 return MESA_FORMAT_R_UNORM16; 4974 case GL_R16F: 4975 return MESA_FORMAT_R_FLOAT16; 4976 case GL_R32F: 4977 return MESA_FORMAT_R_FLOAT32; 4978 case GL_R8I: 4979 return MESA_FORMAT_R_SINT8; 4980 case GL_R16I: 4981 return MESA_FORMAT_R_SINT16; 4982 case GL_R32I: 4983 return MESA_FORMAT_R_SINT32; 4984 case GL_R8UI: 4985 return MESA_FORMAT_R_UINT8; 4986 case GL_R16UI: 4987 return MESA_FORMAT_R_UINT16; 4988 case GL_R32UI: 4989 return MESA_FORMAT_R_UINT32; 4990 4991 default: 4992 return MESA_FORMAT_NONE; 4993 } 4994 } 4995 4996 4997 mesa_format 4998 _mesa_validate_texbuffer_format(const struct gl_context *ctx, 4999 GLenum internalFormat) 5000 { 5001 mesa_format format = get_texbuffer_format(ctx, internalFormat); 5002 GLenum datatype; 5003 5004 if (format == MESA_FORMAT_NONE) 5005 return MESA_FORMAT_NONE; 5006 5007 datatype = _mesa_get_format_datatype(format); 5008 5009 /* The GL_ARB_texture_buffer_object spec says: 5010 * 5011 * "If ARB_texture_float is not supported, references to the 5012 * floating-point internal formats provided by that extension should be 5013 * removed, and such formats may not be passed to TexBufferARB." 5014 * 5015 * As a result, GL_HALF_FLOAT internal format depends on both 5016 * GL_ARB_texture_float and GL_ARB_half_float_pixel. 5017 */ 5018 if ((datatype == GL_FLOAT || datatype == GL_HALF_FLOAT) && 5019 !ctx->Extensions.ARB_texture_float) 5020 return MESA_FORMAT_NONE; 5021 5022 if (!ctx->Extensions.ARB_texture_rg) { 5023 GLenum base_format = _mesa_get_format_base_format(format); 5024 if (base_format == GL_R || base_format == GL_RG) 5025 return MESA_FORMAT_NONE; 5026 } 5027 5028 if (!ctx->Extensions.ARB_texture_buffer_object_rgb32) { 5029 GLenum base_format = _mesa_get_format_base_format(format); 5030 if (base_format == GL_RGB) 5031 return MESA_FORMAT_NONE; 5032 } 5033 return format; 5034 } 5035 5036 5037 /** 5038 * Do work common to glTexBuffer, glTexBufferRange, glTextureBuffer 5039 * and glTextureBufferRange, including some error checking. 5040 */ 5041 static void 5042 texture_buffer_range(struct gl_context *ctx, 5043 struct gl_texture_object *texObj, 5044 GLenum internalFormat, 5045 struct gl_buffer_object *bufObj, 5046 GLintptr offset, GLsizeiptr size, 5047 const char *caller) 5048 { 5049 GLintptr oldOffset = texObj->BufferOffset; 5050 GLsizeiptr oldSize = texObj->BufferSize; 5051 mesa_format format; 5052 5053 /* NOTE: ARB_texture_buffer_object has interactions with 5054 * the compatibility profile that are not implemented. 5055 */ 5056 if (!_mesa_has_ARB_texture_buffer_object(ctx) && 5057 !_mesa_has_OES_texture_buffer(ctx)) { 5058 _mesa_error(ctx, GL_INVALID_OPERATION, 5059 "%s(ARB_texture_buffer_object is not" 5060 " implemented for the compatibility profile)", caller); 5061 return; 5062 } 5063 5064 format = _mesa_validate_texbuffer_format(ctx, internalFormat); 5065 if (format == MESA_FORMAT_NONE) { 5066 _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat %s)", 5067 caller, _mesa_enum_to_string(internalFormat)); 5068 return; 5069 } 5070 5071 FLUSH_VERTICES(ctx, 0); 5072 5073 _mesa_lock_texture(ctx, texObj); 5074 { 5075 _mesa_reference_buffer_object(ctx, &texObj->BufferObject, bufObj); 5076 texObj->BufferObjectFormat = internalFormat; 5077 texObj->_BufferObjectFormat = format; 5078 texObj->BufferOffset = offset; 5079 texObj->BufferSize = size; 5080 } 5081 _mesa_unlock_texture(ctx, texObj); 5082 5083 if (ctx->Driver.TexParameter) { 5084 if (offset != oldOffset) { 5085 ctx->Driver.TexParameter(ctx, texObj, GL_TEXTURE_BUFFER_OFFSET); 5086 } 5087 if (size != oldSize) { 5088 ctx->Driver.TexParameter(ctx, texObj, GL_TEXTURE_BUFFER_SIZE); 5089 } 5090 } 5091 5092 ctx->NewDriverState |= ctx->DriverFlags.NewTextureBuffer; 5093 5094 if (bufObj) { 5095 bufObj->UsageHistory |= USAGE_TEXTURE_BUFFER; 5096 } 5097 } 5098 5099 5100 /** 5101 * Make sure the texture buffer target is GL_TEXTURE_BUFFER. 5102 * Return true if it is, and return false if it is not 5103 * (and throw INVALID ENUM as dictated in the OpenGL 4.5 5104 * core spec, 02.02.2015, PDF page 245). 5105 */ 5106 static bool 5107 check_texture_buffer_target(struct gl_context *ctx, GLenum target, 5108 const char *caller) 5109 { 5110 if (target != GL_TEXTURE_BUFFER_ARB) { 5111 _mesa_error(ctx, GL_INVALID_ENUM, 5112 "%s(texture target is not GL_TEXTURE_BUFFER)", caller); 5113 return false; 5114 } 5115 else 5116 return true; 5117 } 5118 5119 /** 5120 * Check for errors related to the texture buffer range. 5121 * Return false if errors are found, true if none are found. 5122 */ 5123 static bool 5124 check_texture_buffer_range(struct gl_context *ctx, 5125 struct gl_buffer_object *bufObj, 5126 GLintptr offset, GLsizeiptr size, 5127 const char *caller) 5128 { 5129 /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 5130 * Textures (PDF page 245): 5131 * "An INVALID_VALUE error is generated if offset is negative, if 5132 * size is less than or equal to zero, or if offset + size is greater 5133 * than the value of BUFFER_SIZE for the buffer bound to target." 5134 */ 5135 if (offset < 0) { 5136 _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d < 0)", caller, 5137 (int) offset); 5138 return false; 5139 } 5140 5141 if (size <= 0) { 5142 _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d <= 0)", caller, 5143 (int) size); 5144 return false; 5145 } 5146 5147 if (offset + size > bufObj->Size) { 5148 _mesa_error(ctx, GL_INVALID_VALUE, 5149 "%s(offset=%d + size=%d > buffer_size=%d)", caller, 5150 (int) offset, (int) size, (int) bufObj->Size); 5151 return false; 5152 } 5153 5154 /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 5155 * Textures (PDF page 245): 5156 * "An INVALID_VALUE error is generated if offset is not an integer 5157 * multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT." 5158 */ 5159 if (offset % ctx->Const.TextureBufferOffsetAlignment) { 5160 _mesa_error(ctx, GL_INVALID_VALUE, 5161 "%s(invalid offset alignment)", caller); 5162 return false; 5163 } 5164 5165 return true; 5166 } 5167 5168 5169 /** GL_ARB_texture_buffer_object */ 5170 void GLAPIENTRY 5171 _mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer) 5172 { 5173 struct gl_texture_object *texObj; 5174 struct gl_buffer_object *bufObj; 5175 5176 GET_CURRENT_CONTEXT(ctx); 5177 5178 /* Need to catch a bad target before it gets to 5179 * _mesa_get_current_tex_object. 5180 */ 5181 if (!check_texture_buffer_target(ctx, target, "glTexBuffer")) 5182 return; 5183 5184 if (buffer) { 5185 bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBuffer"); 5186 if (!bufObj) 5187 return; 5188 } else 5189 bufObj = NULL; 5190 5191 texObj = _mesa_get_current_tex_object(ctx, target); 5192 if (!texObj) 5193 return; 5194 5195 texture_buffer_range(ctx, texObj, internalFormat, bufObj, 0, 5196 buffer ? -1 : 0, "glTexBuffer"); 5197 } 5198 5199 5200 /** GL_ARB_texture_buffer_range */ 5201 void GLAPIENTRY 5202 _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer, 5203 GLintptr offset, GLsizeiptr size) 5204 { 5205 struct gl_texture_object *texObj; 5206 struct gl_buffer_object *bufObj; 5207 5208 GET_CURRENT_CONTEXT(ctx); 5209 5210 /* Need to catch a bad target before it gets to 5211 * _mesa_get_current_tex_object. 5212 */ 5213 if (!check_texture_buffer_target(ctx, target, "glTexBufferRange")) 5214 return; 5215 5216 if (buffer) { 5217 bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBufferRange"); 5218 if (!bufObj) 5219 return; 5220 5221 if (!check_texture_buffer_range(ctx, bufObj, offset, size, 5222 "glTexBufferRange")) 5223 return; 5224 5225 } else { 5226 /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 5227 * Textures (PDF page 254): 5228 * "If buffer is zero, then any buffer object attached to the buffer 5229 * texture is detached, the values offset and size are ignored and 5230 * the state for offset and size for the buffer texture are reset to 5231 * zero." 5232 */ 5233 offset = 0; 5234 size = 0; 5235 bufObj = NULL; 5236 } 5237 5238 texObj = _mesa_get_current_tex_object(ctx, target); 5239 if (!texObj) 5240 return; 5241 5242 texture_buffer_range(ctx, texObj, internalFormat, bufObj, 5243 offset, size, "glTexBufferRange"); 5244 } 5245 5246 void GLAPIENTRY 5247 _mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer) 5248 { 5249 struct gl_texture_object *texObj; 5250 struct gl_buffer_object *bufObj; 5251 5252 GET_CURRENT_CONTEXT(ctx); 5253 5254 if (buffer) { 5255 bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBuffer"); 5256 if (!bufObj) 5257 return; 5258 } else 5259 bufObj = NULL; 5260 5261 /* Get the texture object by Name. */ 5262 texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBuffer"); 5263 if (!texObj) 5264 return; 5265 5266 if (!check_texture_buffer_target(ctx, texObj->Target, "glTextureBuffer")) 5267 return; 5268 5269 texture_buffer_range(ctx, texObj, internalFormat, 5270 bufObj, 0, buffer ? -1 : 0, "glTextureBuffer"); 5271 } 5272 5273 void GLAPIENTRY 5274 _mesa_TextureBufferRange(GLuint texture, GLenum internalFormat, GLuint buffer, 5275 GLintptr offset, GLsizeiptr size) 5276 { 5277 struct gl_texture_object *texObj; 5278 struct gl_buffer_object *bufObj; 5279 5280 GET_CURRENT_CONTEXT(ctx); 5281 5282 if (buffer) { 5283 bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, 5284 "glTextureBufferRange"); 5285 if (!bufObj) 5286 return; 5287 5288 if (!check_texture_buffer_range(ctx, bufObj, offset, size, 5289 "glTextureBufferRange")) 5290 return; 5291 5292 } else { 5293 /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer 5294 * Textures (PDF page 254): 5295 * "If buffer is zero, then any buffer object attached to the buffer 5296 * texture is detached, the values offset and size are ignored and 5297 * the state for offset and size for the buffer texture are reset to 5298 * zero." 5299 */ 5300 offset = 0; 5301 size = 0; 5302 bufObj = NULL; 5303 } 5304 5305 /* Get the texture object by Name. */ 5306 texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBufferRange"); 5307 if (!texObj) 5308 return; 5309 5310 if (!check_texture_buffer_target(ctx, texObj->Target, 5311 "glTextureBufferRange")) 5312 return; 5313 5314 texture_buffer_range(ctx, texObj, internalFormat, 5315 bufObj, offset, size, "glTextureBufferRange"); 5316 } 5317 5318 GLboolean 5319 _mesa_is_renderable_texture_format(struct gl_context *ctx, GLenum internalformat) 5320 { 5321 /* Everything that is allowed for renderbuffers, 5322 * except for a base format of GL_STENCIL_INDEX, unless supported. 5323 */ 5324 GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat); 5325 if (ctx->Extensions.ARB_texture_stencil8) 5326 return baseFormat != 0; 5327 else 5328 return baseFormat != 0 && baseFormat != GL_STENCIL_INDEX; 5329 } 5330 5331 5332 /** GL_ARB_texture_multisample */ 5333 static GLboolean 5334 check_multisample_target(GLuint dims, GLenum target, bool dsa) 5335 { 5336 switch(target) { 5337 case GL_TEXTURE_2D_MULTISAMPLE: 5338 return dims == 2; 5339 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 5340 return dims == 2 && !dsa; 5341 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 5342 return dims == 3; 5343 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 5344 return dims == 3 && !dsa; 5345 default: 5346 return GL_FALSE; 5347 } 5348 } 5349 5350 5351 static void 5352 texture_image_multisample(struct gl_context *ctx, GLuint dims, 5353 struct gl_texture_object *texObj, 5354 GLenum target, GLsizei samples, 5355 GLint internalformat, GLsizei width, 5356 GLsizei height, GLsizei depth, 5357 GLboolean fixedsamplelocations, 5358 GLboolean immutable, const char *func) 5359 { 5360 struct gl_texture_image *texImage; 5361 GLboolean sizeOK, dimensionsOK, samplesOK; 5362 mesa_format texFormat; 5363 GLenum sample_count_error; 5364 bool dsa = strstr(func, "ture") ? true : false; 5365 5366 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) { 5367 _mesa_debug(ctx, "%s(target=%s, samples=%d)\n", func, 5368 _mesa_enum_to_string(target), samples); 5369 } 5370 5371 if (!((ctx->Extensions.ARB_texture_multisample 5372 && _mesa_is_desktop_gl(ctx))) && !_mesa_is_gles31(ctx)) { 5373 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); 5374 return; 5375 } 5376 5377 if (samples < 1) { 5378 _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples < 1)", func); 5379 return; 5380 } 5381 5382 if (!check_multisample_target(dims, target, dsa)) { 5383 if (dsa) { 5384 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target)", func); 5385 return; 5386 } 5387 else { 5388 _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); 5389 return; 5390 } 5391 } 5392 5393 /* check that the specified internalformat is color/depth/stencil-renderable; 5394 * refer GL3.1 spec 4.4.4 5395 */ 5396 5397 if (immutable && !_mesa_is_legal_tex_storage_format(ctx, internalformat)) { 5398 _mesa_error(ctx, GL_INVALID_ENUM, 5399 "%s(internalformat=%s not legal for immutable-format)", 5400 func, _mesa_enum_to_string(internalformat)); 5401 return; 5402 } 5403 5404 if (!_mesa_is_renderable_texture_format(ctx, internalformat)) { 5405 /* Page 172 of OpenGL ES 3.1 spec says: 5406 * "An INVALID_ENUM error is generated if sizedinternalformat is not 5407 * color-renderable, depth-renderable, or stencil-renderable (as 5408 * defined in section 9.4). 5409 * 5410 * (Same error is also defined for desktop OpenGL for multisample 5411 * teximage/texstorage functions.) 5412 */ 5413 _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalformat=%s)", func, 5414 _mesa_enum_to_string(internalformat)); 5415 return; 5416 } 5417 5418 sample_count_error = _mesa_check_sample_count(ctx, target, 5419 internalformat, samples); 5420 samplesOK = sample_count_error == GL_NO_ERROR; 5421 5422 /* Page 254 of OpenGL 4.4 spec says: 5423 * "Proxy arrays for two-dimensional multisample and two-dimensional 5424 * multisample array textures are operated on in the same way when 5425 * TexImage2DMultisample is called with target specified as 5426 * PROXY_TEXTURE_2D_MULTISAMPLE, or TexImage3DMultisample is called 5427 * with target specified as PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY. 5428 * However, if samples is not supported, then no error is generated. 5429 */ 5430 if (!samplesOK && !_mesa_is_proxy_texture(target)) { 5431 _mesa_error(ctx, sample_count_error, "%s(samples)", func); 5432 return; 5433 } 5434 5435 if (immutable && (!texObj || (texObj->Name == 0))) { 5436 _mesa_error(ctx, GL_INVALID_OPERATION, 5437 "%s(texture object 0)", 5438 func); 5439 return; 5440 } 5441 5442 texImage = _mesa_get_tex_image(ctx, texObj, 0, 0); 5443 5444 if (texImage == NULL) { 5445 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func); 5446 return; 5447 } 5448 5449 texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, 5450 internalformat, GL_NONE, GL_NONE); 5451 assert(texFormat != MESA_FORMAT_NONE); 5452 5453 dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, 5454 width, height, depth, 0); 5455 5456 sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, 0, texFormat, 5457 samples, width, height, depth); 5458 5459 if (_mesa_is_proxy_texture(target)) { 5460 if (samplesOK && dimensionsOK && sizeOK) { 5461 init_teximage_fields_ms(ctx, texImage, width, height, depth, 0, 5462 internalformat, texFormat, 5463 samples, fixedsamplelocations); 5464 } 5465 else { 5466 /* clear all image fields */ 5467 clear_teximage_fields(texImage); 5468 } 5469 } 5470 else { 5471 if (!dimensionsOK) { 5472 _mesa_error(ctx, GL_INVALID_VALUE, 5473 "%s(invalid width or height)", func); 5474 return; 5475 } 5476 5477 if (!sizeOK) { 5478 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(texture too large)", func); 5479 return; 5480 } 5481 5482 /* Check if texObj->Immutable is set */ 5483 if (texObj->Immutable) { 5484 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable)", func); 5485 return; 5486 } 5487 5488 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 5489 5490 init_teximage_fields_ms(ctx, texImage, width, height, depth, 0, 5491 internalformat, texFormat, 5492 samples, fixedsamplelocations); 5493 5494 if (width > 0 && height > 0 && depth > 0) { 5495 if (!ctx->Driver.AllocTextureStorage(ctx, texObj, 1, 5496 width, height, depth)) { 5497 /* tidy up the texture image state. strictly speaking, 5498 * we're allowed to just leave this in whatever state we 5499 * like, but being tidy is good. 5500 */ 5501 _mesa_init_teximage_fields(ctx, texImage, 5502 0, 0, 0, 0, GL_NONE, MESA_FORMAT_NONE); 5503 } 5504 } 5505 5506 texObj->Immutable |= immutable; 5507 5508 if (immutable) { 5509 _mesa_set_texture_view_state(ctx, texObj, target, 1); 5510 } 5511 5512 _mesa_update_fbo_texture(ctx, texObj, 0, 0); 5513 } 5514 } 5515 5516 5517 void GLAPIENTRY 5518 _mesa_TexImage2DMultisample(GLenum target, GLsizei samples, 5519 GLenum internalformat, GLsizei width, 5520 GLsizei height, GLboolean fixedsamplelocations) 5521 { 5522 struct gl_texture_object *texObj; 5523 GET_CURRENT_CONTEXT(ctx); 5524 5525 texObj = _mesa_get_current_tex_object(ctx, target); 5526 if (!texObj) 5527 return; 5528 5529 texture_image_multisample(ctx, 2, texObj, target, samples, 5530 internalformat, width, height, 1, 5531 fixedsamplelocations, GL_FALSE, 5532 "glTexImage2DMultisample"); 5533 } 5534 5535 5536 void GLAPIENTRY 5537 _mesa_TexImage3DMultisample(GLenum target, GLsizei samples, 5538 GLenum internalformat, GLsizei width, 5539 GLsizei height, GLsizei depth, 5540 GLboolean fixedsamplelocations) 5541 { 5542 struct gl_texture_object *texObj; 5543 GET_CURRENT_CONTEXT(ctx); 5544 5545 texObj = _mesa_get_current_tex_object(ctx, target); 5546 if (!texObj) 5547 return; 5548 5549 texture_image_multisample(ctx, 3, texObj, target, samples, 5550 internalformat, width, height, depth, 5551 fixedsamplelocations, GL_FALSE, 5552 "glTexImage3DMultisample"); 5553 } 5554 5555 static bool 5556 valid_texstorage_ms_parameters(GLsizei width, GLsizei height, GLsizei depth, 5557 GLsizei samples, unsigned dims) 5558 { 5559 GET_CURRENT_CONTEXT(ctx); 5560 5561 if (!_mesa_valid_tex_storage_dim(width, height, depth)) { 5562 _mesa_error(ctx, GL_INVALID_VALUE, 5563 "glTexStorage%uDMultisample(width=%d,height=%d,depth=%d)", 5564 dims, width, height, depth); 5565 return false; 5566 } 5567 return true; 5568 } 5569 5570 void GLAPIENTRY 5571 _mesa_TexStorage2DMultisample(GLenum target, GLsizei samples, 5572 GLenum internalformat, GLsizei width, 5573 GLsizei height, GLboolean fixedsamplelocations) 5574 { 5575 struct gl_texture_object *texObj; 5576 GET_CURRENT_CONTEXT(ctx); 5577 5578 texObj = _mesa_get_current_tex_object(ctx, target); 5579 if (!texObj) 5580 return; 5581 5582 if (!valid_texstorage_ms_parameters(width, height, 1, samples, 2)) 5583 return; 5584 5585 texture_image_multisample(ctx, 2, texObj, target, samples, 5586 internalformat, width, height, 1, 5587 fixedsamplelocations, GL_TRUE, 5588 "glTexStorage2DMultisample"); 5589 } 5590 5591 void GLAPIENTRY 5592 _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, 5593 GLenum internalformat, GLsizei width, 5594 GLsizei height, GLsizei depth, 5595 GLboolean fixedsamplelocations) 5596 { 5597 struct gl_texture_object *texObj; 5598 GET_CURRENT_CONTEXT(ctx); 5599 5600 texObj = _mesa_get_current_tex_object(ctx, target); 5601 if (!texObj) 5602 return; 5603 5604 if (!valid_texstorage_ms_parameters(width, height, depth, samples, 3)) 5605 return; 5606 5607 texture_image_multisample(ctx, 3, texObj, target, samples, 5608 internalformat, width, height, depth, 5609 fixedsamplelocations, GL_TRUE, 5610 "glTexStorage3DMultisample"); 5611 } 5612 5613 void GLAPIENTRY 5614 _mesa_TextureStorage2DMultisample(GLuint texture, GLsizei samples, 5615 GLenum internalformat, GLsizei width, 5616 GLsizei height, 5617 GLboolean fixedsamplelocations) 5618 { 5619 struct gl_texture_object *texObj; 5620 GET_CURRENT_CONTEXT(ctx); 5621 5622 texObj = _mesa_lookup_texture_err(ctx, texture, 5623 "glTextureStorage2DMultisample"); 5624 if (!texObj) 5625 return; 5626 5627 if (!valid_texstorage_ms_parameters(width, height, 1, samples, 2)) 5628 return; 5629 5630 texture_image_multisample(ctx, 2, texObj, texObj->Target, samples, 5631 internalformat, width, height, 1, 5632 fixedsamplelocations, GL_TRUE, 5633 "glTextureStorage2DMultisample"); 5634 } 5635 5636 void GLAPIENTRY 5637 _mesa_TextureStorage3DMultisample(GLuint texture, GLsizei samples, 5638 GLenum internalformat, GLsizei width, 5639 GLsizei height, GLsizei depth, 5640 GLboolean fixedsamplelocations) 5641 { 5642 struct gl_texture_object *texObj; 5643 GET_CURRENT_CONTEXT(ctx); 5644 5645 /* Get the texture object by Name. */ 5646 texObj = _mesa_lookup_texture_err(ctx, texture, 5647 "glTextureStorage3DMultisample"); 5648 if (!texObj) 5649 return; 5650 5651 if (!valid_texstorage_ms_parameters(width, height, depth, samples, 3)) 5652 return; 5653 5654 texture_image_multisample(ctx, 3, texObj, texObj->Target, samples, 5655 internalformat, width, height, depth, 5656 fixedsamplelocations, GL_TRUE, 5657 "glTextureStorage3DMultisample"); 5658 } 5659