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