teximage.c revision d47a6ada9ca9670c60fc141fabadf40c63031c08
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 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26/** 27 * \file teximage.c 28 * Texture image-related functions. 29 */ 30 31#include <stdbool.h> 32#include "glheader.h" 33#include "bufferobj.h" 34#include "context.h" 35#include "enums.h" 36#include "fbobject.h" 37#include "framebuffer.h" 38#include "hash.h" 39#include "image.h" 40#include "imports.h" 41#include "macros.h" 42#include "mfeatures.h" 43#include "state.h" 44#include "texcompress.h" 45#include "texcompress_cpal.h" 46#include "teximage.h" 47#include "texobj.h" 48#include "texstate.h" 49#include "mtypes.h" 50#include "glformats.h" 51 52 53/* Inexplicably, GL_HALF_FLOAT_OES has a different value than GL_HALF_FLOAT. 54 */ 55#ifndef GL_HALF_FLOAT_OES 56#define GL_HALF_FLOAT_OES 0x8D61 57#endif 58 59/** 60 * State changes which we care about for glCopyTex[Sub]Image() calls. 61 * In particular, we care about pixel transfer state and buffer state 62 * (such as glReadBuffer to make sure we read from the right renderbuffer). 63 */ 64#define NEW_COPY_TEX_STATE (_NEW_BUFFERS | _NEW_PIXEL) 65 66 67 68/** 69 * Return the simple base format for a given internal texture format. 70 * For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA. 71 * 72 * \param ctx GL context. 73 * \param internalFormat the internal texture format token or 1, 2, 3, or 4. 74 * 75 * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE, 76 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA), or -1 if invalid enum. 77 * 78 * This is the format which is used during texture application (i.e. the 79 * texture format and env mode determine the arithmetic used. 80 */ 81GLint 82_mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) 83{ 84 switch (internalFormat) { 85 case GL_ALPHA: 86 case GL_ALPHA4: 87 case GL_ALPHA8: 88 case GL_ALPHA12: 89 case GL_ALPHA16: 90 return GL_ALPHA; 91 case 1: 92 case GL_LUMINANCE: 93 case GL_LUMINANCE4: 94 case GL_LUMINANCE8: 95 case GL_LUMINANCE12: 96 case GL_LUMINANCE16: 97 return GL_LUMINANCE; 98 case 2: 99 case GL_LUMINANCE_ALPHA: 100 case GL_LUMINANCE4_ALPHA4: 101 case GL_LUMINANCE6_ALPHA2: 102 case GL_LUMINANCE8_ALPHA8: 103 case GL_LUMINANCE12_ALPHA4: 104 case GL_LUMINANCE12_ALPHA12: 105 case GL_LUMINANCE16_ALPHA16: 106 return GL_LUMINANCE_ALPHA; 107 case GL_INTENSITY: 108 case GL_INTENSITY4: 109 case GL_INTENSITY8: 110 case GL_INTENSITY12: 111 case GL_INTENSITY16: 112 return GL_INTENSITY; 113 case 3: 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 case GL_RGBA: 125 case GL_RGBA2: 126 case GL_RGBA4: 127 case GL_RGB5_A1: 128 case GL_RGBA8: 129 case GL_RGB10_A2: 130 case GL_RGBA12: 131 case GL_RGBA16: 132 return GL_RGBA; 133 default: 134 ; /* fallthrough */ 135 } 136 137 /* GL_BGRA can be an internal format *only* in OpenGL ES (1.x or 2.0). 138 */ 139 if (_mesa_is_gles(ctx)) { 140 switch (internalFormat) { 141 case GL_BGRA: 142 return GL_RGBA; 143 default: 144 ; /* fallthrough */ 145 } 146 } 147 148 if (ctx->Extensions.ARB_ES2_compatibility) { 149 switch (internalFormat) { 150 case GL_RGB565: 151 return GL_RGB; 152 default: 153 ; /* fallthrough */ 154 } 155 } 156 157 if (ctx->Extensions.ARB_depth_texture) { 158 switch (internalFormat) { 159 case GL_DEPTH_COMPONENT: 160 case GL_DEPTH_COMPONENT16: 161 case GL_DEPTH_COMPONENT24: 162 case GL_DEPTH_COMPONENT32: 163 return GL_DEPTH_COMPONENT; 164 default: 165 ; /* fallthrough */ 166 } 167 } 168 169 switch (internalFormat) { 170 case GL_COMPRESSED_ALPHA: 171 return GL_ALPHA; 172 case GL_COMPRESSED_LUMINANCE: 173 return GL_LUMINANCE; 174 case GL_COMPRESSED_LUMINANCE_ALPHA: 175 return GL_LUMINANCE_ALPHA; 176 case GL_COMPRESSED_INTENSITY: 177 return GL_INTENSITY; 178 case GL_COMPRESSED_RGB: 179 return GL_RGB; 180 case GL_COMPRESSED_RGBA: 181 return GL_RGBA; 182 default: 183 ; /* fallthrough */ 184 } 185 186 if (ctx->Extensions.TDFX_texture_compression_FXT1) { 187 switch (internalFormat) { 188 case GL_COMPRESSED_RGB_FXT1_3DFX: 189 return GL_RGB; 190 case GL_COMPRESSED_RGBA_FXT1_3DFX: 191 return GL_RGBA; 192 default: 193 ; /* fallthrough */ 194 } 195 } 196 197 if (ctx->Extensions.EXT_texture_compression_s3tc) { 198 switch (internalFormat) { 199 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 200 return GL_RGB; 201 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 202 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 203 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: 204 return GL_RGBA; 205 default: 206 ; /* fallthrough */ 207 } 208 } 209 210 if (ctx->Extensions.S3_s3tc) { 211 switch (internalFormat) { 212 case GL_RGB_S3TC: 213 case GL_RGB4_S3TC: 214 return GL_RGB; 215 case GL_RGBA_S3TC: 216 case GL_RGBA4_S3TC: 217 return GL_RGBA; 218 default: 219 ; /* fallthrough */ 220 } 221 } 222 223 if (ctx->Extensions.MESA_ycbcr_texture) { 224 if (internalFormat == GL_YCBCR_MESA) 225 return GL_YCBCR_MESA; 226 } 227 228 if (ctx->Extensions.ARB_texture_float) { 229 switch (internalFormat) { 230 case GL_ALPHA16F_ARB: 231 case GL_ALPHA32F_ARB: 232 return GL_ALPHA; 233 case GL_RGBA16F_ARB: 234 case GL_RGBA32F_ARB: 235 return GL_RGBA; 236 case GL_RGB16F_ARB: 237 case GL_RGB32F_ARB: 238 return GL_RGB; 239 case GL_INTENSITY16F_ARB: 240 case GL_INTENSITY32F_ARB: 241 return GL_INTENSITY; 242 case GL_LUMINANCE16F_ARB: 243 case GL_LUMINANCE32F_ARB: 244 return GL_LUMINANCE; 245 case GL_LUMINANCE_ALPHA16F_ARB: 246 case GL_LUMINANCE_ALPHA32F_ARB: 247 return GL_LUMINANCE_ALPHA; 248 default: 249 ; /* fallthrough */ 250 } 251 } 252 253 if (ctx->Extensions.ATI_envmap_bumpmap) { 254 switch (internalFormat) { 255 case GL_DUDV_ATI: 256 case GL_DU8DV8_ATI: 257 return GL_DUDV_ATI; 258 default: 259 ; /* fallthrough */ 260 } 261 } 262 263 if (ctx->Extensions.EXT_texture_snorm) { 264 switch (internalFormat) { 265 case GL_RED_SNORM: 266 case GL_R8_SNORM: 267 case GL_R16_SNORM: 268 return GL_RED; 269 case GL_RG_SNORM: 270 case GL_RG8_SNORM: 271 case GL_RG16_SNORM: 272 return GL_RG; 273 case GL_RGB_SNORM: 274 case GL_RGB8_SNORM: 275 case GL_RGB16_SNORM: 276 return GL_RGB; 277 case GL_RGBA_SNORM: 278 case GL_RGBA8_SNORM: 279 case GL_RGBA16_SNORM: 280 return GL_RGBA; 281 case GL_ALPHA_SNORM: 282 case GL_ALPHA8_SNORM: 283 case GL_ALPHA16_SNORM: 284 return GL_ALPHA; 285 case GL_LUMINANCE_SNORM: 286 case GL_LUMINANCE8_SNORM: 287 case GL_LUMINANCE16_SNORM: 288 return GL_LUMINANCE; 289 case GL_LUMINANCE_ALPHA_SNORM: 290 case GL_LUMINANCE8_ALPHA8_SNORM: 291 case GL_LUMINANCE16_ALPHA16_SNORM: 292 return GL_LUMINANCE_ALPHA; 293 case GL_INTENSITY_SNORM: 294 case GL_INTENSITY8_SNORM: 295 case GL_INTENSITY16_SNORM: 296 return GL_INTENSITY; 297 default: 298 ; /* fallthrough */ 299 } 300 } 301 302 if (ctx->Extensions.EXT_packed_depth_stencil) { 303 switch (internalFormat) { 304 case GL_DEPTH_STENCIL_EXT: 305 case GL_DEPTH24_STENCIL8_EXT: 306 return GL_DEPTH_STENCIL_EXT; 307 default: 308 ; /* fallthrough */ 309 } 310 } 311 312#if FEATURE_EXT_texture_sRGB 313 if (ctx->Extensions.EXT_texture_sRGB) { 314 switch (internalFormat) { 315 case GL_SRGB_EXT: 316 case GL_SRGB8_EXT: 317 case GL_COMPRESSED_SRGB_EXT: 318 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: 319 return GL_RGB; 320 case GL_SRGB_ALPHA_EXT: 321 case GL_SRGB8_ALPHA8_EXT: 322 case GL_COMPRESSED_SRGB_ALPHA_EXT: 323 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: 324 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: 325 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: 326 return GL_RGBA; 327 case GL_SLUMINANCE_ALPHA_EXT: 328 case GL_SLUMINANCE8_ALPHA8_EXT: 329 case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: 330 return GL_LUMINANCE_ALPHA; 331 case GL_SLUMINANCE_EXT: 332 case GL_SLUMINANCE8_EXT: 333 case GL_COMPRESSED_SLUMINANCE_EXT: 334 return GL_LUMINANCE; 335 default: 336 ; /* fallthrough */ 337 } 338 } 339#endif /* FEATURE_EXT_texture_sRGB */ 340 341 if (ctx->Version >= 30 || 342 ctx->Extensions.EXT_texture_integer) { 343 switch (internalFormat) { 344 case GL_RGBA8UI_EXT: 345 case GL_RGBA16UI_EXT: 346 case GL_RGBA32UI_EXT: 347 case GL_RGBA8I_EXT: 348 case GL_RGBA16I_EXT: 349 case GL_RGBA32I_EXT: 350 case GL_RGB10_A2UI: 351 return GL_RGBA; 352 case GL_RGB8UI_EXT: 353 case GL_RGB16UI_EXT: 354 case GL_RGB32UI_EXT: 355 case GL_RGB8I_EXT: 356 case GL_RGB16I_EXT: 357 case GL_RGB32I_EXT: 358 return GL_RGB; 359 } 360 } 361 362 if (ctx->Extensions.EXT_texture_integer) { 363 switch (internalFormat) { 364 case GL_ALPHA8UI_EXT: 365 case GL_ALPHA16UI_EXT: 366 case GL_ALPHA32UI_EXT: 367 case GL_ALPHA8I_EXT: 368 case GL_ALPHA16I_EXT: 369 case GL_ALPHA32I_EXT: 370 return GL_ALPHA; 371 case GL_INTENSITY8UI_EXT: 372 case GL_INTENSITY16UI_EXT: 373 case GL_INTENSITY32UI_EXT: 374 case GL_INTENSITY8I_EXT: 375 case GL_INTENSITY16I_EXT: 376 case GL_INTENSITY32I_EXT: 377 return GL_INTENSITY; 378 case GL_LUMINANCE8UI_EXT: 379 case GL_LUMINANCE16UI_EXT: 380 case GL_LUMINANCE32UI_EXT: 381 case GL_LUMINANCE8I_EXT: 382 case GL_LUMINANCE16I_EXT: 383 case GL_LUMINANCE32I_EXT: 384 return GL_LUMINANCE; 385 case GL_LUMINANCE_ALPHA8UI_EXT: 386 case GL_LUMINANCE_ALPHA16UI_EXT: 387 case GL_LUMINANCE_ALPHA32UI_EXT: 388 case GL_LUMINANCE_ALPHA8I_EXT: 389 case GL_LUMINANCE_ALPHA16I_EXT: 390 case GL_LUMINANCE_ALPHA32I_EXT: 391 return GL_LUMINANCE_ALPHA; 392 default: 393 ; /* fallthrough */ 394 } 395 } 396 397 if (ctx->Extensions.ARB_texture_rg) { 398 switch (internalFormat) { 399 case GL_R16F: 400 /* R16F depends on both ARB_half_float_pixel and ARB_texture_float. 401 */ 402 if (!ctx->Extensions.ARB_half_float_pixel) 403 break; 404 /* FALLTHROUGH */ 405 case GL_R32F: 406 if (!ctx->Extensions.ARB_texture_float) 407 break; 408 return GL_RED; 409 case GL_R8I: 410 case GL_R8UI: 411 case GL_R16I: 412 case GL_R16UI: 413 case GL_R32I: 414 case GL_R32UI: 415 if (ctx->Version < 30 && !ctx->Extensions.EXT_texture_integer) 416 break; 417 /* FALLTHROUGH */ 418 case GL_R8: 419 case GL_R16: 420 case GL_RED: 421 case GL_COMPRESSED_RED: 422 return GL_RED; 423 424 case GL_RG16F: 425 /* RG16F depends on both ARB_half_float_pixel and ARB_texture_float. 426 */ 427 if (!ctx->Extensions.ARB_half_float_pixel) 428 break; 429 /* FALLTHROUGH */ 430 case GL_RG32F: 431 if (!ctx->Extensions.ARB_texture_float) 432 break; 433 return GL_RG; 434 case GL_RG8I: 435 case GL_RG8UI: 436 case GL_RG16I: 437 case GL_RG16UI: 438 case GL_RG32I: 439 case GL_RG32UI: 440 if (ctx->Version < 30 && !ctx->Extensions.EXT_texture_integer) 441 break; 442 /* FALLTHROUGH */ 443 case GL_RG: 444 case GL_RG8: 445 case GL_RG16: 446 case GL_COMPRESSED_RG: 447 return GL_RG; 448 default: 449 ; /* fallthrough */ 450 } 451 } 452 453 if (ctx->Extensions.EXT_texture_shared_exponent) { 454 switch (internalFormat) { 455 case GL_RGB9_E5_EXT: 456 return GL_RGB; 457 default: 458 ; /* fallthrough */ 459 } 460 } 461 462 if (ctx->Extensions.EXT_packed_float) { 463 switch (internalFormat) { 464 case GL_R11F_G11F_B10F_EXT: 465 return GL_RGB; 466 default: 467 ; /* fallthrough */ 468 } 469 } 470 471 if (ctx->Extensions.ARB_depth_buffer_float) { 472 switch (internalFormat) { 473 case GL_DEPTH_COMPONENT32F: 474 return GL_DEPTH_COMPONENT; 475 case GL_DEPTH32F_STENCIL8: 476 return GL_DEPTH_STENCIL; 477 default: 478 ; /* fallthrough */ 479 } 480 } 481 482 if (ctx->Extensions.ARB_texture_compression_rgtc) { 483 switch (internalFormat) { 484 case GL_COMPRESSED_RED_RGTC1: 485 case GL_COMPRESSED_SIGNED_RED_RGTC1: 486 return GL_RED; 487 case GL_COMPRESSED_RG_RGTC2: 488 case GL_COMPRESSED_SIGNED_RG_RGTC2: 489 return GL_RG; 490 default: 491 ; /* fallthrough */ 492 } 493 } 494 495 if (ctx->Extensions.EXT_texture_compression_latc) { 496 switch (internalFormat) { 497 case GL_COMPRESSED_LUMINANCE_LATC1_EXT: 498 case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT: 499 return GL_LUMINANCE; 500 case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: 501 case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT: 502 return GL_LUMINANCE_ALPHA; 503 default: 504 ; /* fallthrough */ 505 } 506 } 507 508 if (ctx->Extensions.ATI_texture_compression_3dc) { 509 switch (internalFormat) { 510 case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI: 511 return GL_LUMINANCE_ALPHA; 512 default: 513 ; /* fallthrough */ 514 } 515 } 516 517 if (ctx->Extensions.OES_compressed_ETC1_RGB8_texture) { 518 switch (internalFormat) { 519 case GL_ETC1_RGB8_OES: 520 return GL_RGB; 521 default: 522 ; /* fallthrough */ 523 } 524 } 525 526 if (ctx->API == API_OPENGLES) { 527 switch (internalFormat) { 528 case GL_PALETTE4_RGB8_OES: 529 case GL_PALETTE4_R5_G6_B5_OES: 530 case GL_PALETTE8_RGB8_OES: 531 case GL_PALETTE8_R5_G6_B5_OES: 532 return GL_RGB; 533 case GL_PALETTE4_RGBA8_OES: 534 case GL_PALETTE8_RGB5_A1_OES: 535 case GL_PALETTE4_RGBA4_OES: 536 case GL_PALETTE4_RGB5_A1_OES: 537 case GL_PALETTE8_RGBA8_OES: 538 case GL_PALETTE8_RGBA4_OES: 539 return GL_RGBA; 540 default: 541 ; /* fallthrough */ 542 } 543 } 544 545 return -1; /* error */ 546} 547 548 549/** 550 * For cube map faces, return a face index in [0,5]. 551 * For other targets return 0; 552 */ 553GLuint 554_mesa_tex_target_to_face(GLenum target) 555{ 556 if (_mesa_is_cube_face(target)) 557 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; 558 else 559 return 0; 560} 561 562 563 564/** 565 * Install gl_texture_image in a gl_texture_object according to the target 566 * and level parameters. 567 * 568 * \param tObj texture object. 569 * \param target texture target. 570 * \param level image level. 571 * \param texImage texture image. 572 */ 573static void 574set_tex_image(struct gl_texture_object *tObj, 575 GLenum target, GLint level, 576 struct gl_texture_image *texImage) 577{ 578 const GLuint face = _mesa_tex_target_to_face(target); 579 580 ASSERT(tObj); 581 ASSERT(texImage); 582 if (target == GL_TEXTURE_RECTANGLE_NV || target == GL_TEXTURE_EXTERNAL_OES) 583 assert(level == 0); 584 585 tObj->Image[face][level] = texImage; 586 587 /* Set the 'back' pointer */ 588 texImage->TexObject = tObj; 589 texImage->Level = level; 590 texImage->Face = face; 591} 592 593 594/** 595 * Allocate a texture image structure. 596 * 597 * Called via ctx->Driver.NewTextureImage() unless overriden by a device 598 * driver. 599 * 600 * \return a pointer to gl_texture_image struct with all fields initialized to 601 * zero. 602 */ 603struct gl_texture_image * 604_mesa_new_texture_image( struct gl_context *ctx ) 605{ 606 (void) ctx; 607 return CALLOC_STRUCT(gl_texture_image); 608} 609 610 611/** 612 * Free a gl_texture_image and associated data. 613 * This function is a fallback called via ctx->Driver.DeleteTextureImage(). 614 * 615 * \param texImage texture image. 616 * 617 * Free the texture image structure and the associated image data. 618 */ 619void 620_mesa_delete_texture_image(struct gl_context *ctx, 621 struct gl_texture_image *texImage) 622{ 623 /* Free texImage->Data and/or any other driver-specific texture 624 * image storage. 625 */ 626 ASSERT(ctx->Driver.FreeTextureImageBuffer); 627 ctx->Driver.FreeTextureImageBuffer( ctx, texImage ); 628 free(texImage); 629} 630 631 632/** 633 * Test if a target is a proxy target. 634 * 635 * \param target texture target. 636 * 637 * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise. 638 */ 639GLboolean 640_mesa_is_proxy_texture(GLenum target) 641{ 642 /* 643 * NUM_TEXTURE_TARGETS should match number of terms below, except there's no 644 * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES. 645 */ 646 assert(NUM_TEXTURE_TARGETS == 7 + 2); 647 648 return (target == GL_PROXY_TEXTURE_1D || 649 target == GL_PROXY_TEXTURE_2D || 650 target == GL_PROXY_TEXTURE_3D || 651 target == GL_PROXY_TEXTURE_CUBE_MAP_ARB || 652 target == GL_PROXY_TEXTURE_RECTANGLE_NV || 653 target == GL_PROXY_TEXTURE_1D_ARRAY_EXT || 654 target == GL_PROXY_TEXTURE_2D_ARRAY_EXT); 655} 656 657 658/** 659 * Return the proxy target which corresponds to the given texture target 660 */ 661static GLenum 662get_proxy_target(GLenum target) 663{ 664 switch (target) { 665 case GL_TEXTURE_1D: 666 case GL_PROXY_TEXTURE_1D: 667 return GL_PROXY_TEXTURE_1D; 668 case GL_TEXTURE_2D: 669 case GL_PROXY_TEXTURE_2D: 670 return GL_PROXY_TEXTURE_2D; 671 case GL_TEXTURE_3D: 672 case GL_PROXY_TEXTURE_3D: 673 return GL_PROXY_TEXTURE_3D; 674 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 675 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 676 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 677 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 678 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 679 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 680 case GL_TEXTURE_CUBE_MAP_ARB: 681 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 682 return GL_PROXY_TEXTURE_CUBE_MAP_ARB; 683 case GL_TEXTURE_RECTANGLE_NV: 684 case GL_PROXY_TEXTURE_RECTANGLE_NV: 685 return GL_PROXY_TEXTURE_RECTANGLE_NV; 686 case GL_TEXTURE_1D_ARRAY_EXT: 687 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 688 return GL_PROXY_TEXTURE_1D_ARRAY_EXT; 689 case GL_TEXTURE_2D_ARRAY_EXT: 690 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 691 return GL_PROXY_TEXTURE_2D_ARRAY_EXT; 692 default: 693 _mesa_problem(NULL, "unexpected target in get_proxy_target()"); 694 return 0; 695 } 696} 697 698 699/** 700 * Get the texture object that corresponds to the target of the given 701 * texture unit. The target should have already been checked for validity. 702 * 703 * \param ctx GL context. 704 * \param texUnit texture unit. 705 * \param target texture target. 706 * 707 * \return pointer to the texture object on success, or NULL on failure. 708 */ 709struct gl_texture_object * 710_mesa_select_tex_object(struct gl_context *ctx, 711 const struct gl_texture_unit *texUnit, 712 GLenum target) 713{ 714 const GLboolean arrayTex = (ctx->Extensions.MESA_texture_array || 715 ctx->Extensions.EXT_texture_array); 716 717 switch (target) { 718 case GL_TEXTURE_1D: 719 return texUnit->CurrentTex[TEXTURE_1D_INDEX]; 720 case GL_PROXY_TEXTURE_1D: 721 return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; 722 case GL_TEXTURE_2D: 723 return texUnit->CurrentTex[TEXTURE_2D_INDEX]; 724 case GL_PROXY_TEXTURE_2D: 725 return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; 726 case GL_TEXTURE_3D: 727 return texUnit->CurrentTex[TEXTURE_3D_INDEX]; 728 case GL_PROXY_TEXTURE_3D: 729 return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; 730 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 731 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 732 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 733 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 734 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 735 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 736 case GL_TEXTURE_CUBE_MAP_ARB: 737 return ctx->Extensions.ARB_texture_cube_map 738 ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL; 739 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 740 return ctx->Extensions.ARB_texture_cube_map 741 ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; 742 case GL_TEXTURE_RECTANGLE_NV: 743 return ctx->Extensions.NV_texture_rectangle 744 ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL; 745 case GL_PROXY_TEXTURE_RECTANGLE_NV: 746 return ctx->Extensions.NV_texture_rectangle 747 ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL; 748 case GL_TEXTURE_1D_ARRAY_EXT: 749 return arrayTex ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL; 750 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 751 return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL; 752 case GL_TEXTURE_2D_ARRAY_EXT: 753 return arrayTex ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL; 754 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 755 return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL; 756 case GL_TEXTURE_BUFFER: 757 return ctx->Extensions.ARB_texture_buffer_object 758 ? texUnit->CurrentTex[TEXTURE_BUFFER_INDEX] : NULL; 759 case GL_TEXTURE_EXTERNAL_OES: 760 return ctx->Extensions.OES_EGL_image_external 761 ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL; 762 default: 763 _mesa_problem(NULL, "bad target in _mesa_select_tex_object()"); 764 return NULL; 765 } 766} 767 768 769/** 770 * Return pointer to texture object for given target on current texture unit. 771 */ 772struct gl_texture_object * 773_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) 774{ 775 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); 776 return _mesa_select_tex_object(ctx, texUnit, target); 777} 778 779 780/** 781 * Get a texture image pointer from a texture object, given a texture 782 * target and mipmap level. The target and level parameters should 783 * have already been error-checked. 784 * 785 * \param ctx GL context. 786 * \param texObj texture unit. 787 * \param target texture target. 788 * \param level image level. 789 * 790 * \return pointer to the texture image structure, or NULL on failure. 791 */ 792struct gl_texture_image * 793_mesa_select_tex_image(struct gl_context *ctx, 794 const struct gl_texture_object *texObj, 795 GLenum target, GLint level) 796{ 797 const GLuint face = _mesa_tex_target_to_face(target); 798 799 ASSERT(texObj); 800 ASSERT(level >= 0); 801 ASSERT(level < MAX_TEXTURE_LEVELS); 802 803 return texObj->Image[face][level]; 804} 805 806 807/** 808 * Like _mesa_select_tex_image() but if the image doesn't exist, allocate 809 * it and install it. Only return NULL if passed a bad parameter or run 810 * out of memory. 811 */ 812struct gl_texture_image * 813_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, 814 GLenum target, GLint level) 815{ 816 struct gl_texture_image *texImage; 817 818 if (!texObj) 819 return NULL; 820 821 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 822 if (!texImage) { 823 texImage = ctx->Driver.NewTextureImage(ctx); 824 if (!texImage) { 825 _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation"); 826 return NULL; 827 } 828 829 set_tex_image(texObj, target, level, texImage); 830 } 831 832 return texImage; 833} 834 835 836/** 837 * Return pointer to the specified proxy texture image. 838 * Note that proxy textures are per-context, not per-texture unit. 839 * \return pointer to texture image or NULL if invalid target, invalid 840 * level, or out of memory. 841 */ 842static struct gl_texture_image * 843get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level) 844{ 845 struct gl_texture_image *texImage; 846 GLuint texIndex; 847 848 if (level < 0) 849 return NULL; 850 851 switch (target) { 852 case GL_PROXY_TEXTURE_1D: 853 if (level >= ctx->Const.MaxTextureLevels) 854 return NULL; 855 texIndex = TEXTURE_1D_INDEX; 856 break; 857 case GL_PROXY_TEXTURE_2D: 858 if (level >= ctx->Const.MaxTextureLevels) 859 return NULL; 860 texIndex = TEXTURE_2D_INDEX; 861 break; 862 case GL_PROXY_TEXTURE_3D: 863 if (level >= ctx->Const.Max3DTextureLevels) 864 return NULL; 865 texIndex = TEXTURE_3D_INDEX; 866 break; 867 case GL_PROXY_TEXTURE_CUBE_MAP: 868 if (level >= ctx->Const.MaxCubeTextureLevels) 869 return NULL; 870 texIndex = TEXTURE_CUBE_INDEX; 871 break; 872 case GL_PROXY_TEXTURE_RECTANGLE_NV: 873 if (level > 0) 874 return NULL; 875 texIndex = TEXTURE_RECT_INDEX; 876 break; 877 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 878 if (level >= ctx->Const.MaxTextureLevels) 879 return NULL; 880 texIndex = TEXTURE_1D_ARRAY_INDEX; 881 break; 882 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 883 if (level >= ctx->Const.MaxTextureLevels) 884 return NULL; 885 texIndex = TEXTURE_2D_ARRAY_INDEX; 886 break; 887 default: 888 return NULL; 889 } 890 891 texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level]; 892 if (!texImage) { 893 texImage = ctx->Driver.NewTextureImage(ctx); 894 if (!texImage) { 895 _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); 896 return NULL; 897 } 898 ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage; 899 /* Set the 'back' pointer */ 900 texImage->TexObject = ctx->Texture.ProxyTex[texIndex]; 901 } 902 return texImage; 903} 904 905 906/** 907 * Get the maximum number of allowed mipmap levels. 908 * 909 * \param ctx GL context. 910 * \param target texture target. 911 * 912 * \return the maximum number of allowed mipmap levels for the given 913 * texture target, or zero if passed a bad target. 914 * 915 * \sa gl_constants. 916 */ 917GLint 918_mesa_max_texture_levels(struct gl_context *ctx, GLenum target) 919{ 920 switch (target) { 921 case GL_TEXTURE_1D: 922 case GL_PROXY_TEXTURE_1D: 923 case GL_TEXTURE_2D: 924 case GL_PROXY_TEXTURE_2D: 925 return ctx->Const.MaxTextureLevels; 926 case GL_TEXTURE_3D: 927 case GL_PROXY_TEXTURE_3D: 928 return ctx->Const.Max3DTextureLevels; 929 case GL_TEXTURE_CUBE_MAP: 930 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 931 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 932 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 933 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 934 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 935 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 936 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 937 return ctx->Extensions.ARB_texture_cube_map 938 ? ctx->Const.MaxCubeTextureLevels : 0; 939 case GL_TEXTURE_RECTANGLE_NV: 940 case GL_PROXY_TEXTURE_RECTANGLE_NV: 941 return ctx->Extensions.NV_texture_rectangle ? 1 : 0; 942 case GL_TEXTURE_1D_ARRAY_EXT: 943 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 944 case GL_TEXTURE_2D_ARRAY_EXT: 945 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 946 return (ctx->Extensions.MESA_texture_array || 947 ctx->Extensions.EXT_texture_array) 948 ? ctx->Const.MaxTextureLevels : 0; 949 case GL_TEXTURE_BUFFER: 950 return _mesa_is_desktop_gl(ctx) && 951 (ctx->Extensions.ARB_texture_buffer_object || 952 (ctx->Version >= 31)) ? 1 : 0; 953 case GL_TEXTURE_EXTERNAL_OES: 954 /* fall-through */ 955 default: 956 return 0; /* bad target */ 957 } 958} 959 960 961/** 962 * Return number of dimensions per mipmap level for the given texture target. 963 */ 964GLint 965_mesa_get_texture_dimensions(GLenum target) 966{ 967 switch (target) { 968 case GL_TEXTURE_1D: 969 case GL_PROXY_TEXTURE_1D: 970 return 1; 971 case GL_TEXTURE_2D: 972 case GL_TEXTURE_RECTANGLE: 973 case GL_TEXTURE_CUBE_MAP: 974 case GL_PROXY_TEXTURE_2D: 975 case GL_PROXY_TEXTURE_RECTANGLE: 976 case GL_PROXY_TEXTURE_CUBE_MAP: 977 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 978 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 979 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 980 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 981 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 982 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 983 case GL_TEXTURE_1D_ARRAY: 984 case GL_PROXY_TEXTURE_1D_ARRAY: 985 case GL_TEXTURE_EXTERNAL_OES: 986 return 2; 987 case GL_TEXTURE_3D: 988 case GL_PROXY_TEXTURE_3D: 989 case GL_TEXTURE_2D_ARRAY: 990 case GL_PROXY_TEXTURE_2D_ARRAY: 991 return 3; 992 case GL_TEXTURE_BUFFER: 993 /* fall-through */ 994 default: 995 _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()", 996 target); 997 return 2; 998 } 999} 1000 1001 1002 1003 1004#if 000 /* not used anymore */ 1005/* 1006 * glTexImage[123]D can accept a NULL image pointer. In this case we 1007 * create a texture image with unspecified image contents per the OpenGL 1008 * spec. 1009 */ 1010static GLubyte * 1011make_null_texture(GLint width, GLint height, GLint depth, GLenum format) 1012{ 1013 const GLint components = _mesa_components_in_format(format); 1014 const GLint numPixels = width * height * depth; 1015 GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte)); 1016 1017#ifdef DEBUG 1018 /* 1019 * Let's see if anyone finds this. If glTexImage2D() is called with 1020 * a NULL image pointer then load the texture image with something 1021 * interesting instead of leaving it indeterminate. 1022 */ 1023 if (data) { 1024 static const char message[8][32] = { 1025 " X X XXXXX XXX X ", 1026 " XX XX X X X X X ", 1027 " X X X X X X X ", 1028 " X X XXXX XXX XXXXX ", 1029 " X X X X X X ", 1030 " X X X X X X X ", 1031 " X X XXXXX XXX X X ", 1032 " " 1033 }; 1034 1035 GLubyte *imgPtr = data; 1036 GLint h, i, j, k; 1037 for (h = 0; h < depth; h++) { 1038 for (i = 0; i < height; i++) { 1039 GLint srcRow = 7 - (i % 8); 1040 for (j = 0; j < width; j++) { 1041 GLint srcCol = j % 32; 1042 GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70; 1043 for (k = 0; k < components; k++) { 1044 *imgPtr++ = texel; 1045 } 1046 } 1047 } 1048 } 1049 } 1050#endif 1051 1052 return data; 1053} 1054#endif 1055 1056 1057 1058/** 1059 * Set the size and format-related fields of a gl_texture_image struct 1060 * to zero. This is used when a proxy texture test fails. 1061 */ 1062static void 1063clear_teximage_fields(struct gl_texture_image *img) 1064{ 1065 ASSERT(img); 1066 img->_BaseFormat = 0; 1067 img->InternalFormat = 0; 1068 img->Border = 0; 1069 img->Width = 0; 1070 img->Height = 0; 1071 img->Depth = 0; 1072 img->Width2 = 0; 1073 img->Height2 = 0; 1074 img->Depth2 = 0; 1075 img->WidthLog2 = 0; 1076 img->HeightLog2 = 0; 1077 img->DepthLog2 = 0; 1078 img->TexFormat = MESA_FORMAT_NONE; 1079} 1080 1081 1082/** 1083 * Initialize basic fields of the gl_texture_image struct. 1084 * 1085 * \param ctx GL context. 1086 * \param img texture image structure to be initialized. 1087 * \param width image width. 1088 * \param height image height. 1089 * \param depth image depth. 1090 * \param border image border. 1091 * \param internalFormat internal format. 1092 * \param format the actual hardware format (one of MESA_FORMAT_*) 1093 * 1094 * Fills in the fields of \p img with the given information. 1095 * Note: width, height and depth include the border. 1096 */ 1097void 1098_mesa_init_teximage_fields(struct gl_context *ctx, 1099 struct gl_texture_image *img, 1100 GLsizei width, GLsizei height, GLsizei depth, 1101 GLint border, GLenum internalFormat, 1102 gl_format format) 1103{ 1104 GLenum target; 1105 ASSERT(img); 1106 ASSERT(width >= 0); 1107 ASSERT(height >= 0); 1108 ASSERT(depth >= 0); 1109 1110 target = img->TexObject->Target; 1111 img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat ); 1112 ASSERT(img->_BaseFormat > 0); 1113 img->InternalFormat = internalFormat; 1114 img->Border = border; 1115 img->Width = width; 1116 img->Height = height; 1117 img->Depth = depth; 1118 1119 img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */ 1120 img->WidthLog2 = _mesa_logbase2(img->Width2); 1121 1122 switch(target) { 1123 case GL_TEXTURE_1D: 1124 case GL_TEXTURE_BUFFER: 1125 case GL_PROXY_TEXTURE_1D: 1126 if (height == 0) 1127 img->Height2 = 0; 1128 else 1129 img->Height2 = 1; 1130 img->HeightLog2 = 0; 1131 if (depth == 0) 1132 img->Depth2 = 0; 1133 else 1134 img->Depth2 = 1; 1135 img->DepthLog2 = 0; 1136 break; 1137 case GL_TEXTURE_1D_ARRAY: 1138 case GL_PROXY_TEXTURE_1D_ARRAY: 1139 img->Height2 = height; /* no border */ 1140 img->HeightLog2 = 0; /* not used */ 1141 if (depth == 0) 1142 img->Depth2 = 0; 1143 else 1144 img->Depth2 = 1; 1145 img->DepthLog2 = 0; 1146 break; 1147 case GL_TEXTURE_2D: 1148 case GL_TEXTURE_RECTANGLE: 1149 case GL_TEXTURE_CUBE_MAP: 1150 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1151 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1152 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1153 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1154 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1155 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1156 case GL_TEXTURE_EXTERNAL_OES: 1157 case GL_PROXY_TEXTURE_2D: 1158 case GL_PROXY_TEXTURE_RECTANGLE: 1159 case GL_PROXY_TEXTURE_CUBE_MAP: 1160 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 1161 img->HeightLog2 = _mesa_logbase2(img->Height2); 1162 if (depth == 0) 1163 img->Depth2 = 0; 1164 else 1165 img->Depth2 = 1; 1166 img->DepthLog2 = 0; 1167 break; 1168 case GL_TEXTURE_2D_ARRAY: 1169 case GL_PROXY_TEXTURE_2D_ARRAY: 1170 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 1171 img->HeightLog2 = _mesa_logbase2(img->Height2); 1172 img->Depth2 = depth; /* no border */ 1173 img->DepthLog2 = 0; /* not used */ 1174 break; 1175 case GL_TEXTURE_3D: 1176 case GL_PROXY_TEXTURE_3D: 1177 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 1178 img->HeightLog2 = _mesa_logbase2(img->Height2); 1179 img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ 1180 img->DepthLog2 = _mesa_logbase2(img->Depth2); 1181 break; 1182 default: 1183 _mesa_problem(NULL, "invalid target 0x%x in _mesa_init_teximage_fields()", 1184 target); 1185 } 1186 1187 img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); 1188 img->TexFormat = format; 1189} 1190 1191 1192/** 1193 * Free and clear fields of the gl_texture_image struct. 1194 * 1195 * \param ctx GL context. 1196 * \param texImage texture image structure to be cleared. 1197 * 1198 * After the call, \p texImage will have no data associated with it. Its 1199 * fields are cleared so that its parent object will test incomplete. 1200 */ 1201void 1202_mesa_clear_texture_image(struct gl_context *ctx, 1203 struct gl_texture_image *texImage) 1204{ 1205 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 1206 clear_teximage_fields(texImage); 1207} 1208 1209 1210/** 1211 * This is the fallback for Driver.TestProxyTexImage(). Test the texture 1212 * level, width, height and depth against the ctx->Const limits for textures. 1213 * 1214 * A hardware driver might override this function if, for example, the 1215 * max 3D texture size is 512x512x64 (i.e. not a cube). 1216 * 1217 * Note that width, height, depth == 0 is not an error. However, a 1218 * texture with zero width/height/depth will be considered "incomplete" 1219 * and texturing will effectively be disabled. 1220 * 1221 * \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D, 1222 * GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV, 1223 * GL_PROXY_TEXTURE_CUBE_MAP_ARB. 1224 * \param level as passed to glTexImage 1225 * \param internalFormat as passed to glTexImage 1226 * \param format as passed to glTexImage 1227 * \param type as passed to glTexImage 1228 * \param width as passed to glTexImage 1229 * \param height as passed to glTexImage 1230 * \param depth as passed to glTexImage 1231 * \param border as passed to glTexImage 1232 * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable. 1233 */ 1234GLboolean 1235_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, 1236 GLint internalFormat, GLenum format, GLenum type, 1237 GLint width, GLint height, GLint depth, GLint border) 1238{ 1239 GLint maxSize; 1240 1241 (void) internalFormat; 1242 (void) format; 1243 (void) type; 1244 1245 switch (target) { 1246 case GL_PROXY_TEXTURE_1D: 1247 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1248 if (width < 2 * border || width > 2 * border + maxSize) 1249 return GL_FALSE; 1250 if (level >= ctx->Const.MaxTextureLevels) 1251 return GL_FALSE; 1252 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1253 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1254 return GL_FALSE; 1255 } 1256 return GL_TRUE; 1257 1258 case GL_PROXY_TEXTURE_2D: 1259 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1260 if (width < 2 * border || width > 2 * border + maxSize) 1261 return GL_FALSE; 1262 if (height < 2 * border || height > 2 * border + maxSize) 1263 return GL_FALSE; 1264 if (level >= ctx->Const.MaxTextureLevels) 1265 return GL_FALSE; 1266 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1267 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1268 return GL_FALSE; 1269 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 1270 return GL_FALSE; 1271 } 1272 return GL_TRUE; 1273 1274 case GL_PROXY_TEXTURE_3D: 1275 maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); 1276 if (width < 2 * border || width > 2 * border + maxSize) 1277 return GL_FALSE; 1278 if (height < 2 * border || height > 2 * border + maxSize) 1279 return GL_FALSE; 1280 if (depth < 2 * border || depth > 2 * border + maxSize) 1281 return GL_FALSE; 1282 if (level >= ctx->Const.Max3DTextureLevels) 1283 return GL_FALSE; 1284 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1285 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1286 return GL_FALSE; 1287 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 1288 return GL_FALSE; 1289 if (depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) 1290 return GL_FALSE; 1291 } 1292 return GL_TRUE; 1293 1294 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1295 maxSize = ctx->Const.MaxTextureRectSize; 1296 if (width < 0 || width > maxSize) 1297 return GL_FALSE; 1298 if (height < 0 || height > maxSize) 1299 return GL_FALSE; 1300 if (level != 0) 1301 return GL_FALSE; 1302 return GL_TRUE; 1303 1304 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 1305 maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); 1306 if (width < 2 * border || width > 2 * border + maxSize) 1307 return GL_FALSE; 1308 if (height < 2 * border || height > 2 * border + maxSize) 1309 return GL_FALSE; 1310 if (level >= ctx->Const.MaxCubeTextureLevels) 1311 return GL_FALSE; 1312 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1313 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1314 return GL_FALSE; 1315 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 1316 return GL_FALSE; 1317 } 1318 return GL_TRUE; 1319 1320 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1321 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1322 if (width < 2 * border || width > 2 * border + maxSize) 1323 return GL_FALSE; 1324 if (height < 1 || height > ctx->Const.MaxArrayTextureLayers) 1325 return GL_FALSE; 1326 if (level >= ctx->Const.MaxTextureLevels) 1327 return GL_FALSE; 1328 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1329 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1330 return GL_FALSE; 1331 } 1332 return GL_TRUE; 1333 1334 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1335 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1336 if (width < 2 * border || width > 2 * border + maxSize) 1337 return GL_FALSE; 1338 if (height < 2 * border || height > 2 * border + maxSize) 1339 return GL_FALSE; 1340 if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers) 1341 return GL_FALSE; 1342 if (level >= ctx->Const.MaxTextureLevels) 1343 return GL_FALSE; 1344 if (!ctx->Extensions.ARB_texture_non_power_of_two) { 1345 if (width > 0 && !_mesa_is_pow_two(width - 2 * border)) 1346 return GL_FALSE; 1347 if (height > 0 && !_mesa_is_pow_two(height - 2 * border)) 1348 return GL_FALSE; 1349 } 1350 return GL_TRUE; 1351 1352 default: 1353 _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage"); 1354 return GL_FALSE; 1355 } 1356} 1357 1358 1359/** 1360 * Check if the memory used by the texture would exceed the driver's limit. 1361 * This lets us support a max 3D texture size of 8K (for example) but 1362 * prevents allocating a full 8K x 8K x 8K texture. 1363 * XXX this could be rolled into the proxy texture size test (above) but 1364 * we don't have the actual texture internal format at that point. 1365 */ 1366static GLboolean 1367legal_texture_size(struct gl_context *ctx, gl_format format, 1368 GLint width, GLint height, GLint depth) 1369{ 1370 uint64_t bytes = _mesa_format_image_size64(format, width, height, depth); 1371 uint64_t mbytes = bytes / (1024 * 1024); /* convert to MB */ 1372 return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes; 1373} 1374 1375 1376/** 1377 * Return true if the format is only valid for glCompressedTexImage. 1378 */ 1379static GLboolean 1380compressedteximage_only_format(const struct gl_context *ctx, GLenum format) 1381{ 1382 switch (format) { 1383 case GL_ETC1_RGB8_OES: 1384 case GL_PALETTE4_RGB8_OES: 1385 case GL_PALETTE4_RGBA8_OES: 1386 case GL_PALETTE4_R5_G6_B5_OES: 1387 case GL_PALETTE4_RGBA4_OES: 1388 case GL_PALETTE4_RGB5_A1_OES: 1389 case GL_PALETTE8_RGB8_OES: 1390 case GL_PALETTE8_RGBA8_OES: 1391 case GL_PALETTE8_R5_G6_B5_OES: 1392 case GL_PALETTE8_RGBA4_OES: 1393 case GL_PALETTE8_RGB5_A1_OES: 1394 return GL_TRUE; 1395 default: 1396 return GL_FALSE; 1397 } 1398} 1399 1400 1401/** 1402 * Helper function to determine whether a target and specific compression 1403 * format are supported. 1404 */ 1405static GLboolean 1406target_can_be_compressed(const struct gl_context *ctx, GLenum target, 1407 GLenum intFormat) 1408{ 1409 (void) intFormat; /* not used yet */ 1410 1411 switch (target) { 1412 case GL_TEXTURE_2D: 1413 case GL_PROXY_TEXTURE_2D: 1414 return GL_TRUE; /* true for any compressed format so far */ 1415 case GL_PROXY_TEXTURE_CUBE_MAP: 1416 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1417 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1418 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1419 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1420 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1421 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1422 return ctx->Extensions.ARB_texture_cube_map; 1423 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1424 case GL_TEXTURE_2D_ARRAY_EXT: 1425 return (ctx->Extensions.MESA_texture_array || 1426 ctx->Extensions.EXT_texture_array); 1427 default: 1428 return GL_FALSE; 1429 } 1430} 1431 1432 1433/** 1434 * Check if the given texture target value is legal for a 1435 * glTexImage1/2/3D call. 1436 */ 1437static GLboolean 1438legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target) 1439{ 1440 switch (dims) { 1441 case 1: 1442 switch (target) { 1443 case GL_TEXTURE_1D: 1444 case GL_PROXY_TEXTURE_1D: 1445 return _mesa_is_desktop_gl(ctx); 1446 default: 1447 return GL_FALSE; 1448 } 1449 case 2: 1450 switch (target) { 1451 case GL_TEXTURE_2D: 1452 return GL_TRUE; 1453 case GL_PROXY_TEXTURE_2D: 1454 return _mesa_is_desktop_gl(ctx); 1455 case GL_PROXY_TEXTURE_CUBE_MAP: 1456 return _mesa_is_desktop_gl(ctx) 1457 && ctx->Extensions.ARB_texture_cube_map; 1458 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1459 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1460 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1461 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1462 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1463 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1464 return ctx->Extensions.ARB_texture_cube_map; 1465 case GL_TEXTURE_RECTANGLE_NV: 1466 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1467 return _mesa_is_desktop_gl(ctx) 1468 && ctx->Extensions.NV_texture_rectangle; 1469 case GL_TEXTURE_1D_ARRAY_EXT: 1470 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1471 return _mesa_is_desktop_gl(ctx) 1472 && (ctx->Extensions.MESA_texture_array || 1473 ctx->Extensions.EXT_texture_array); 1474 default: 1475 return GL_FALSE; 1476 } 1477 case 3: 1478 switch (target) { 1479 case GL_TEXTURE_3D: 1480 return GL_TRUE; 1481 case GL_PROXY_TEXTURE_3D: 1482 return _mesa_is_desktop_gl(ctx); 1483 case GL_TEXTURE_2D_ARRAY_EXT: 1484 return (_mesa_is_desktop_gl(ctx) 1485 && (ctx->Extensions.MESA_texture_array || 1486 ctx->Extensions.EXT_texture_array)) 1487 || _mesa_is_gles3(ctx); 1488 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1489 return _mesa_is_desktop_gl(ctx) 1490 && (ctx->Extensions.MESA_texture_array || 1491 ctx->Extensions.EXT_texture_array); 1492 default: 1493 return GL_FALSE; 1494 } 1495 default: 1496 _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims); 1497 return GL_FALSE; 1498 } 1499} 1500 1501 1502/** 1503 * Check if the given texture target value is legal for a 1504 * glTexSubImage, glCopyTexSubImage or glCopyTexImage call. 1505 * The difference compared to legal_teximage_target() above is that 1506 * proxy targets are not supported. 1507 */ 1508static GLboolean 1509legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target) 1510{ 1511 switch (dims) { 1512 case 1: 1513 return _mesa_is_desktop_gl(ctx) && target == GL_TEXTURE_1D; 1514 case 2: 1515 switch (target) { 1516 case GL_TEXTURE_2D: 1517 return GL_TRUE; 1518 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1519 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1520 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1521 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1522 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1523 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1524 return ctx->Extensions.ARB_texture_cube_map; 1525 case GL_TEXTURE_RECTANGLE_NV: 1526 return _mesa_is_desktop_gl(ctx) 1527 && ctx->Extensions.NV_texture_rectangle; 1528 case GL_TEXTURE_1D_ARRAY_EXT: 1529 return _mesa_is_desktop_gl(ctx) 1530 && (ctx->Extensions.MESA_texture_array || 1531 ctx->Extensions.EXT_texture_array); 1532 default: 1533 return GL_FALSE; 1534 } 1535 case 3: 1536 switch (target) { 1537 case GL_TEXTURE_3D: 1538 return GL_TRUE; 1539 case GL_TEXTURE_2D_ARRAY_EXT: 1540 return (_mesa_is_desktop_gl(ctx) 1541 && (ctx->Extensions.MESA_texture_array || 1542 ctx->Extensions.EXT_texture_array)) 1543 || _mesa_is_gles3(ctx); 1544 default: 1545 return GL_FALSE; 1546 } 1547 default: 1548 _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()", 1549 dims); 1550 return GL_FALSE; 1551 } 1552} 1553 1554 1555/** 1556 * Helper function to determine if a texture object is mutable (in terms 1557 * of GL_ARB_texture_storage). 1558 */ 1559static GLboolean 1560mutable_tex_object(struct gl_context *ctx, GLenum target) 1561{ 1562 if (ctx->Extensions.ARB_texture_storage) { 1563 struct gl_texture_object *texObj = 1564 _mesa_get_current_tex_object(ctx, target); 1565 return !texObj->Immutable; 1566 } 1567 return GL_TRUE; 1568} 1569 1570 1571GLenum 1572_mesa_es_error_check_format_and_type(GLenum format, GLenum type, 1573 unsigned dimensions) 1574{ 1575 bool type_valid = true; 1576 1577 switch (format) { 1578 case GL_ALPHA: 1579 case GL_LUMINANCE: 1580 case GL_LUMINANCE_ALPHA: 1581 type_valid = (type == GL_UNSIGNED_BYTE 1582 || type == GL_FLOAT 1583 || type == GL_HALF_FLOAT_OES); 1584 break; 1585 1586 case GL_RGB: 1587 type_valid = (type == GL_UNSIGNED_BYTE 1588 || type == GL_UNSIGNED_SHORT_5_6_5 1589 || type == GL_FLOAT 1590 || type == GL_HALF_FLOAT_OES); 1591 break; 1592 1593 case GL_RGBA: 1594 type_valid = (type == GL_UNSIGNED_BYTE 1595 || type == GL_UNSIGNED_SHORT_4_4_4_4 1596 || type == GL_UNSIGNED_SHORT_5_5_5_1 1597 || type == GL_FLOAT 1598 || type == GL_HALF_FLOAT_OES 1599 || type == GL_UNSIGNED_INT_2_10_10_10_REV); 1600 break; 1601 1602 case GL_DEPTH_COMPONENT: 1603 /* This format is filtered against invalid dimensionalities elsewhere. 1604 */ 1605 type_valid = (type == GL_UNSIGNED_SHORT 1606 || type == GL_UNSIGNED_INT); 1607 break; 1608 1609 case GL_DEPTH_STENCIL: 1610 /* This format is filtered against invalid dimensionalities elsewhere. 1611 */ 1612 type_valid = (type == GL_UNSIGNED_INT_24_8); 1613 break; 1614 1615 case GL_BGRA_EXT: 1616 type_valid = (type == GL_UNSIGNED_BYTE); 1617 1618 /* This feels like a bug in the EXT_texture_format_BGRA8888 spec, but 1619 * the format does not appear to be allowed for 3D textures in OpenGL 1620 * ES. 1621 */ 1622 if (dimensions != 2) 1623 return GL_INVALID_VALUE; 1624 1625 break; 1626 1627 default: 1628 return GL_INVALID_VALUE; 1629 } 1630 1631 return type_valid ? GL_NO_ERROR : GL_INVALID_OPERATION; 1632} 1633 1634 1635 1636/** 1637 * Return expected size of a compressed texture. 1638 */ 1639static GLuint 1640compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth, 1641 GLenum glformat) 1642{ 1643 gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 1644 return _mesa_format_image_size(mesaFormat, width, height, depth); 1645} 1646 1647 1648/* 1649 * Return compressed texture block size, in pixels. 1650 */ 1651static void 1652get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh) 1653{ 1654 gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 1655 _mesa_get_format_block_size(mesaFormat, bw, bh); 1656} 1657 1658 1659/** 1660 * Special value returned by error some texture error checking functions when 1661 * an error is detected and the proxy texture image's width/height/depth/format 1662 * fields should be zeroed-out. 1663 */ 1664#define PROXY_ERROR 2 1665 1666 1667/** 1668 * Test the glTexImage[123]D() parameters for errors. 1669 * 1670 * \param ctx GL context. 1671 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1672 * \param target texture target given by the user. 1673 * \param level image level given by the user. 1674 * \param internalFormat internal format given by the user. 1675 * \param format pixel data format given by the user. 1676 * \param type pixel data type given by the user. 1677 * \param width image width given by the user. 1678 * \param height image height given by the user. 1679 * \param depth image depth given by the user. 1680 * \param border image border given by the user. 1681 * 1682 * \return PROXY_ERROR if there's an error that should zero-out the proxy image, 1683 * GL_TRUE if a regular GL error is found, or GL_FALSE if no error, 1684 * 1685 * Verifies each of the parameters against the constants specified in 1686 * __struct gl_contextRec::Const and the supported extensions, and according 1687 * to the OpenGL specification. 1688 */ 1689static GLenum 1690texture_error_check( struct gl_context *ctx, 1691 GLuint dimensions, GLenum target, 1692 GLint level, GLint internalFormat, 1693 GLenum format, GLenum type, 1694 GLint width, GLint height, 1695 GLint depth, GLint border ) 1696{ 1697 const GLenum proxyTarget = get_proxy_target(target); 1698 const GLboolean isProxy = target == proxyTarget; 1699 GLboolean sizeOK = GL_TRUE; 1700 GLboolean colorFormat; 1701 GLenum err; 1702 1703 /* Even though there are no color-index textures, we still have to support 1704 * uploading color-index data and remapping it to RGB via the 1705 * GL_PIXEL_MAP_I_TO_[RGBA] tables. 1706 */ 1707 const GLboolean indexFormat = (format == GL_COLOR_INDEX); 1708 1709 /* Note: for proxy textures, some error conditions immediately generate 1710 * a GL error in the usual way. But others do not generate a GL error. 1711 * Instead, they cause the width, height, depth, format fields of the 1712 * texture image to be zeroed-out. The GL spec seems to indicate that the 1713 * zero-out behaviour is only used in cases related to memory allocation. 1714 */ 1715 1716 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ 1717 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1718 _mesa_error(ctx, GL_INVALID_VALUE, 1719 "glTexImage%dD(level=%d)", dimensions, level); 1720 return GL_TRUE; 1721 } 1722 1723 /* Check border */ 1724 if (border < 0 || border > 1 || 1725 ((ctx->API != API_OPENGL || 1726 target == GL_TEXTURE_RECTANGLE_NV || 1727 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 1728 _mesa_error(ctx, GL_INVALID_VALUE, 1729 "glTexImage%dD(border=%d)", dimensions, border); 1730 return GL_TRUE; 1731 } 1732 1733 if (width < 0 || height < 0 || depth < 0) { 1734 _mesa_error(ctx, GL_INVALID_VALUE, 1735 "glTexImage%dD(width, height or depth < 0)", dimensions); 1736 return GL_TRUE; 1737 } 1738 1739 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 1740 * combinations of format, internalFormat, and type that can be used. 1741 * Formats and types that require additional extensions (e.g., GL_FLOAT 1742 * requires GL_OES_texture_float) are filtered elsewhere. 1743 */ 1744 if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) { 1745 if (format != internalFormat) { 1746 _mesa_error(ctx, GL_INVALID_OPERATION, 1747 "glTexImage%dD(format = %s, internalFormat = %s)", 1748 dimensions, 1749 _mesa_lookup_enum_by_nr(format), 1750 _mesa_lookup_enum_by_nr(internalFormat)); 1751 return GL_TRUE; 1752 } 1753 1754 err = _mesa_es_error_check_format_and_type(format, type, dimensions); 1755 if (err != GL_NO_ERROR) { 1756 _mesa_error(ctx, err, 1757 "glTexImage%dD(format = %s, type = %s)", 1758 dimensions, 1759 _mesa_lookup_enum_by_nr(format), 1760 _mesa_lookup_enum_by_nr(type)); 1761 return GL_TRUE; 1762 } 1763 } 1764 1765 /* Do this simple check before calling the TestProxyTexImage() function */ 1766 if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { 1767 sizeOK = (width == height); 1768 } 1769 1770 /* 1771 * Use the proxy texture driver hook to see if the size/level/etc are 1772 * legal. 1773 */ 1774 sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level, 1775 internalFormat, format, 1776 type, width, height, 1777 depth, border); 1778 if (!sizeOK) { 1779 if (isProxy) { 1780 /* No GL error is recorded, but we need to zero-out the image dims */ 1781 return PROXY_ERROR; 1782 } 1783 else { 1784 _mesa_error(ctx, GL_INVALID_VALUE, 1785 "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)", 1786 dimensions, level, width, height, depth); 1787 return GL_TRUE; 1788 } 1789 } 1790 1791 /* Check internalFormat */ 1792 if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 1793 _mesa_error(ctx, GL_INVALID_VALUE, 1794 "glTexImage%dD(internalFormat=%s)", 1795 dimensions, _mesa_lookup_enum_by_nr(internalFormat)); 1796 return GL_TRUE; 1797 } 1798 1799 /* Check incoming image format and type */ 1800 err = _mesa_error_check_format_and_type(ctx, format, type); 1801 if (err != GL_NO_ERROR) { 1802 _mesa_error(ctx, err, 1803 "glTexImage%dD(incompatible format 0x%x, type 0x%x)", 1804 dimensions, format, type); 1805 return GL_TRUE; 1806 } 1807 1808 /* make sure internal format and format basically agree */ 1809 colorFormat = _mesa_is_color_format(format); 1810 if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) || 1811 (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) || 1812 (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) || 1813 (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) || 1814 (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) { 1815 _mesa_error(ctx, GL_INVALID_OPERATION, 1816 "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)", 1817 dimensions, internalFormat, format); 1818 return GL_TRUE; 1819 } 1820 1821 /* additional checks for ycbcr textures */ 1822 if (internalFormat == GL_YCBCR_MESA) { 1823 ASSERT(ctx->Extensions.MESA_ycbcr_texture); 1824 if (type != GL_UNSIGNED_SHORT_8_8_MESA && 1825 type != GL_UNSIGNED_SHORT_8_8_REV_MESA) { 1826 char message[100]; 1827 _mesa_snprintf(message, sizeof(message), 1828 "glTexImage%dD(format/type YCBCR mismatch)", 1829 dimensions); 1830 _mesa_error(ctx, GL_INVALID_ENUM, "%s", message); 1831 return GL_TRUE; /* error */ 1832 } 1833 if (target != GL_TEXTURE_2D && 1834 target != GL_PROXY_TEXTURE_2D && 1835 target != GL_TEXTURE_RECTANGLE_NV && 1836 target != GL_PROXY_TEXTURE_RECTANGLE_NV) { 1837 _mesa_error(ctx, GL_INVALID_ENUM, 1838 "glTexImage%dD(bad target for YCbCr texture)", 1839 dimensions); 1840 return GL_TRUE; 1841 } 1842 if (border != 0) { 1843 char message[100]; 1844 _mesa_snprintf(message, sizeof(message), 1845 "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)", 1846 dimensions, border); 1847 _mesa_error(ctx, GL_INVALID_VALUE, "%s", message); 1848 return GL_TRUE; 1849 } 1850 } 1851 1852 /* additional checks for depth textures */ 1853 if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) { 1854 /* Only 1D, 2D, rect, array and cube textures supported, not 3D 1855 * Cubemaps are only supported for GL version > 3.0 or with EXT_gpu_shader4 */ 1856 if (target != GL_TEXTURE_1D && 1857 target != GL_PROXY_TEXTURE_1D && 1858 target != GL_TEXTURE_2D && 1859 target != GL_PROXY_TEXTURE_2D && 1860 target != GL_TEXTURE_1D_ARRAY && 1861 target != GL_PROXY_TEXTURE_1D_ARRAY && 1862 target != GL_TEXTURE_2D_ARRAY && 1863 target != GL_PROXY_TEXTURE_2D_ARRAY && 1864 target != GL_TEXTURE_RECTANGLE_ARB && 1865 target != GL_PROXY_TEXTURE_RECTANGLE_ARB && 1866 !((_mesa_is_cube_face(target) || target == GL_PROXY_TEXTURE_CUBE_MAP) && 1867 (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))) { 1868 _mesa_error(ctx, GL_INVALID_ENUM, 1869 "glTexImage%dD(bad target for depth texture)", 1870 dimensions); 1871 return GL_TRUE; 1872 } 1873 } 1874 1875 /* additional checks for compressed textures */ 1876 if (_mesa_is_compressed_format(ctx, internalFormat)) { 1877 if (!target_can_be_compressed(ctx, target, internalFormat)) { 1878 _mesa_error(ctx, GL_INVALID_ENUM, 1879 "glTexImage%dD(target can't be compressed)", dimensions); 1880 return GL_TRUE; 1881 } 1882 if (compressedteximage_only_format(ctx, internalFormat)) { 1883 _mesa_error(ctx, GL_INVALID_OPERATION, 1884 "glTexImage%dD(no compression for format)", dimensions); 1885 return GL_TRUE; 1886 } 1887 if (border != 0) { 1888 _mesa_error(ctx, GL_INVALID_OPERATION, 1889 "glTexImage%dD(border!=0)", dimensions); 1890 return GL_TRUE; 1891 } 1892 } 1893 1894 /* additional checks for integer textures */ 1895 if ((ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) && 1896 (_mesa_is_enum_format_integer(format) != 1897 _mesa_is_enum_format_integer(internalFormat))) { 1898 _mesa_error(ctx, GL_INVALID_OPERATION, 1899 "glTexImage%dD(integer/non-integer format mismatch)", 1900 dimensions); 1901 return GL_TRUE; 1902 } 1903 1904 if (!mutable_tex_object(ctx, target)) { 1905 _mesa_error(ctx, GL_INVALID_OPERATION, 1906 "glTexImage%dD(immutable texture)", dimensions); 1907 return GL_TRUE; 1908 } 1909 1910 /* if we get here, the parameters are OK */ 1911 return GL_FALSE; 1912} 1913 1914 1915/** 1916 * Error checking for glCompressedTexImage[123]D(). 1917 * \param reason returns reason for error, if any 1918 * \return error code or GL_NO_ERROR or PROXY_ERROR. 1919 */ 1920static GLenum 1921compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, 1922 GLenum target, GLint level, 1923 GLenum internalFormat, GLsizei width, 1924 GLsizei height, GLsizei depth, GLint border, 1925 GLsizei imageSize) 1926{ 1927 const GLenum proxyTarget = get_proxy_target(target); 1928 const GLint maxLevels = _mesa_max_texture_levels(ctx, target); 1929 GLint expectedSize; 1930 GLenum choose_format; 1931 GLenum choose_type; 1932 GLenum proxy_format; 1933 GLenum error = GL_NO_ERROR; 1934 char *reason = ""; /* no error */ 1935 1936 if (!target_can_be_compressed(ctx, target, internalFormat)) { 1937 reason = "target"; 1938 error = GL_INVALID_ENUM; 1939 goto error; 1940 } 1941 1942 /* This will detect any invalid internalFormat value */ 1943 if (!_mesa_is_compressed_format(ctx, internalFormat)) { 1944 reason = "internalFormat"; 1945 error = GL_INVALID_ENUM; 1946 goto error; 1947 } 1948 1949 switch (internalFormat) { 1950#if FEATURE_ES 1951 case GL_PALETTE4_RGB8_OES: 1952 case GL_PALETTE4_RGBA8_OES: 1953 case GL_PALETTE4_R5_G6_B5_OES: 1954 case GL_PALETTE4_RGBA4_OES: 1955 case GL_PALETTE4_RGB5_A1_OES: 1956 case GL_PALETTE8_RGB8_OES: 1957 case GL_PALETTE8_RGBA8_OES: 1958 case GL_PALETTE8_R5_G6_B5_OES: 1959 case GL_PALETTE8_RGBA4_OES: 1960 case GL_PALETTE8_RGB5_A1_OES: 1961 _mesa_cpal_compressed_format_type(internalFormat, &choose_format, 1962 &choose_type); 1963 proxy_format = choose_format; 1964 1965 /* check level (note that level should be zero or less!) */ 1966 if (level > 0 || level < -maxLevels) { 1967 reason = "level"; 1968 error = GL_INVALID_VALUE; 1969 goto error; 1970 } 1971 1972 if (dimensions != 2) { 1973 reason = "compressed paletted textures must be 2D"; 1974 error = GL_INVALID_OPERATION; 1975 goto error; 1976 } 1977 1978 /* Figure out the expected texture size (in bytes). This will be 1979 * checked against the actual size later. 1980 */ 1981 expectedSize = _mesa_cpal_compressed_size(level, internalFormat, 1982 width, height); 1983 1984 /* This is for the benefit of the TestProxyTexImage below. It expects 1985 * level to be non-negative. OES_compressed_paletted_texture uses a 1986 * weird mechanism where the level specified to glCompressedTexImage2D 1987 * is -(n-1) number of levels in the texture, and the data specifies the 1988 * complete mipmap stack. This is done to ensure the palette is the 1989 * same for all levels. 1990 */ 1991 level = -level; 1992 break; 1993#endif 1994 1995 default: 1996 choose_format = GL_NONE; 1997 choose_type = GL_NONE; 1998 proxy_format = internalFormat; 1999 2000 /* check level */ 2001 if (level < 0 || level >= maxLevels) { 2002 reason = "level"; 2003 error = GL_INVALID_VALUE; 2004 goto error; 2005 } 2006 2007 /* Figure out the expected texture size (in bytes). This will be 2008 * checked against the actual size later. 2009 */ 2010 expectedSize = compressed_tex_size(width, height, depth, internalFormat); 2011 break; 2012 } 2013 2014 /* This should really never fail */ 2015 if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 2016 reason = "internalFormat"; 2017 error = GL_INVALID_ENUM; 2018 goto error; 2019 } 2020 2021 /* No compressed formats support borders at this time */ 2022 if (border != 0) { 2023 reason = "border != 0"; 2024 error = GL_INVALID_VALUE; 2025 goto error; 2026 } 2027 2028 /* For cube map, width must equal height */ 2029 if (_mesa_is_cube_face(target) && width != height) { 2030 reason = "width != height"; 2031 error = GL_INVALID_VALUE; 2032 goto error; 2033 } 2034 2035 /* check image size against compression block size */ 2036 { 2037 gl_format texFormat = 2038 ctx->Driver.ChooseTextureFormat(ctx, target, proxy_format, 2039 choose_format, choose_type); 2040 GLuint bw, bh; 2041 2042 _mesa_get_format_block_size(texFormat, &bw, &bh); 2043 if ((width > bw && width % bw > 0) || 2044 (height > bh && height % bh > 0)) { 2045 /* 2046 * Per GL_ARB_texture_compression: GL_INVALID_OPERATION is 2047 * generated [...] if any parameter combinations are not 2048 * supported by the specific compressed internal format. 2049 */ 2050 reason = "invalid width or height for compression format"; 2051 error = GL_INVALID_OPERATION; 2052 goto error; 2053 } 2054 } 2055 2056 /* check image sizes */ 2057 if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level, 2058 proxy_format, choose_format, 2059 choose_type, 2060 width, height, depth, border)) { 2061 /* See error comment above */ 2062 if (target == proxyTarget) { 2063 return PROXY_ERROR; 2064 } 2065 reason = "invalid width, height or format"; 2066 error = GL_INVALID_OPERATION; 2067 goto error; 2068 } 2069 2070 /* check image size in bytes */ 2071 if (expectedSize != imageSize) { 2072 /* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...] 2073 * if <imageSize> is not consistent with the format, dimensions, and 2074 * contents of the specified image. 2075 */ 2076 reason = "imageSize inconsistant with width/height/format"; 2077 error = GL_INVALID_VALUE; 2078 goto error; 2079 } 2080 2081 if (!mutable_tex_object(ctx, target)) { 2082 reason = "immutable texture"; 2083 error = GL_INVALID_OPERATION; 2084 goto error; 2085 } 2086 2087 return GL_NO_ERROR; 2088 2089error: 2090 _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", dimensions, reason); 2091 return error; 2092} 2093 2094 2095 2096/** 2097 * Test glTexSubImage[123]D() parameters for errors. 2098 * 2099 * \param ctx GL context. 2100 * \param dimensions texture image dimensions (must be 1, 2 or 3). 2101 * \param target texture target given by the user. 2102 * \param level image level given by the user. 2103 * \param xoffset sub-image x offset given by the user. 2104 * \param yoffset sub-image y offset given by the user. 2105 * \param zoffset sub-image z offset given by the user. 2106 * \param format pixel data format given by the user. 2107 * \param type pixel data type given by the user. 2108 * \param width image width given by the user. 2109 * \param height image height given by the user. 2110 * \param depth image depth given by the user. 2111 * 2112 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2113 * 2114 * Verifies each of the parameters against the constants specified in 2115 * __struct gl_contextRec::Const and the supported extensions, and according 2116 * to the OpenGL specification. 2117 */ 2118static GLboolean 2119subtexture_error_check( struct gl_context *ctx, GLuint dimensions, 2120 GLenum target, GLint level, 2121 GLint xoffset, GLint yoffset, GLint zoffset, 2122 GLint width, GLint height, GLint depth, 2123 GLenum format, GLenum type ) 2124{ 2125 GLenum err; 2126 2127 /* Basic level check */ 2128 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 2129 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level); 2130 return GL_TRUE; 2131 } 2132 2133 /* Check for negative sizes */ 2134 if (width < 0) { 2135 _mesa_error(ctx, GL_INVALID_VALUE, 2136 "glTexSubImage%dD(width=%d)", dimensions, width); 2137 return GL_TRUE; 2138 } 2139 if (height < 0 && dimensions > 1) { 2140 _mesa_error(ctx, GL_INVALID_VALUE, 2141 "glTexSubImage%dD(height=%d)", dimensions, height); 2142 return GL_TRUE; 2143 } 2144 if (depth < 0 && dimensions > 2) { 2145 _mesa_error(ctx, GL_INVALID_VALUE, 2146 "glTexSubImage%dD(depth=%d)", dimensions, depth); 2147 return GL_TRUE; 2148 } 2149 2150 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 2151 * combinations of format and type that can be used. Formats and types 2152 * that require additional extensions (e.g., GL_FLOAT requires 2153 * GL_OES_texture_float) are filtered elsewhere. 2154 */ 2155 if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) { 2156 err = _mesa_es_error_check_format_and_type(format, type, dimensions); 2157 if (err != GL_NO_ERROR) { 2158 _mesa_error(ctx, err, 2159 "glTexSubImage%dD(format = %s, type = %s)", 2160 dimensions, 2161 _mesa_lookup_enum_by_nr(format), 2162 _mesa_lookup_enum_by_nr(type)); 2163 return GL_TRUE; 2164 } 2165 } 2166 2167 err = _mesa_error_check_format_and_type(ctx, format, type); 2168 if (err != GL_NO_ERROR) { 2169 _mesa_error(ctx, err, 2170 "glTexSubImage%dD(incompatible format 0x%x, type 0x%x)", 2171 dimensions, format, type); 2172 return GL_TRUE; 2173 } 2174 2175 return GL_FALSE; 2176} 2177 2178 2179/** 2180 * Do second part of glTexSubImage which depends on the destination texture. 2181 * \return GL_TRUE if error recorded, GL_FALSE otherwise 2182 */ 2183static GLboolean 2184subtexture_error_check2( struct gl_context *ctx, GLuint dimensions, 2185 GLenum target, GLint level, 2186 GLint xoffset, GLint yoffset, GLint zoffset, 2187 GLint width, GLint height, GLint depth, 2188 GLenum format, GLenum type, 2189 const struct gl_texture_image *destTex ) 2190{ 2191 if (!destTex) { 2192 /* undefined image level */ 2193 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions); 2194 return GL_TRUE; 2195 } 2196 2197 if (xoffset < -((GLint)destTex->Border)) { 2198 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)", 2199 dimensions); 2200 return GL_TRUE; 2201 } 2202 if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) { 2203 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)", 2204 dimensions); 2205 return GL_TRUE; 2206 } 2207 if (dimensions > 1) { 2208 GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destTex->Border; 2209 if (yoffset < -yBorder) { 2210 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)", 2211 dimensions); 2212 return GL_TRUE; 2213 } 2214 if (yoffset + height > (GLint) destTex->Height + yBorder) { 2215 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)", 2216 dimensions); 2217 return GL_TRUE; 2218 } 2219 } 2220 if (dimensions > 2) { 2221 GLint zBorder = (target == GL_TEXTURE_2D_ARRAY) ? 0 : destTex->Border; 2222 if (zoffset < -zBorder) { 2223 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)"); 2224 return GL_TRUE; 2225 } 2226 if (zoffset + depth > (GLint) destTex->Depth + zBorder) { 2227 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)"); 2228 return GL_TRUE; 2229 } 2230 } 2231 2232 if (_mesa_is_format_compressed(destTex->TexFormat)) { 2233 GLuint bw, bh; 2234 2235 if (compressedteximage_only_format(ctx, destTex->InternalFormat)) { 2236 _mesa_error(ctx, GL_INVALID_OPERATION, 2237 "glTexSubImage%dD(no compression for format)", dimensions); 2238 return GL_TRUE; 2239 } 2240 2241 /* do tests which depend on compression block size */ 2242 _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh); 2243 2244 /* offset must be multiple of block size */ 2245 if ((xoffset % bw != 0) || (yoffset % bh != 0)) { 2246 _mesa_error(ctx, GL_INVALID_OPERATION, 2247 "glTexSubImage%dD(xoffset = %d, yoffset = %d)", 2248 dimensions, xoffset, yoffset); 2249 return GL_TRUE; 2250 } 2251 /* size must be multiple of bw by bh or equal to whole texture size */ 2252 if ((width % bw != 0) && (GLuint) width != destTex->Width) { 2253 _mesa_error(ctx, GL_INVALID_OPERATION, 2254 "glTexSubImage%dD(width = %d)", dimensions, width); 2255 return GL_TRUE; 2256 } 2257 if ((height % bh != 0) && (GLuint) height != destTex->Height) { 2258 _mesa_error(ctx, GL_INVALID_OPERATION, 2259 "glTexSubImage%dD(height = %d)", dimensions, height); 2260 return GL_TRUE; 2261 } 2262 } 2263 2264 if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) { 2265 /* both source and dest must be integer-valued, or neither */ 2266 if (_mesa_is_format_integer_color(destTex->TexFormat) != 2267 _mesa_is_enum_format_integer(format)) { 2268 _mesa_error(ctx, GL_INVALID_OPERATION, 2269 "glTexSubImage%dD(integer/non-integer format mismatch)", 2270 dimensions); 2271 return GL_TRUE; 2272 } 2273 } 2274 2275 return GL_FALSE; 2276} 2277 2278 2279/** 2280 * Test glCopyTexImage[12]D() parameters for errors. 2281 * 2282 * \param ctx GL context. 2283 * \param dimensions texture image dimensions (must be 1, 2 or 3). 2284 * \param target texture target given by the user. 2285 * \param level image level given by the user. 2286 * \param internalFormat internal format given by the user. 2287 * \param width image width given by the user. 2288 * \param height image height given by the user. 2289 * \param border texture border. 2290 * 2291 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2292 * 2293 * Verifies each of the parameters against the constants specified in 2294 * __struct gl_contextRec::Const and the supported extensions, and according 2295 * to the OpenGL specification. 2296 */ 2297static GLboolean 2298copytexture_error_check( struct gl_context *ctx, GLuint dimensions, 2299 GLenum target, GLint level, GLint internalFormat, 2300 GLint width, GLint height, GLint border ) 2301{ 2302 const GLenum proxyTarget = get_proxy_target(target); 2303 const GLenum type = GL_FLOAT; 2304 GLboolean sizeOK; 2305 GLint baseFormat; 2306 2307 /* check target */ 2308 if (!legal_texsubimage_target(ctx, dimensions, target)) { 2309 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)", 2310 dimensions, _mesa_lookup_enum_by_nr(target)); 2311 return GL_TRUE; 2312 } 2313 2314 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ 2315 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 2316 _mesa_error(ctx, GL_INVALID_VALUE, 2317 "glCopyTexImage%dD(level=%d)", dimensions, level); 2318 return GL_TRUE; 2319 } 2320 2321 /* Check that the source buffer is complete */ 2322 if (_mesa_is_user_fbo(ctx->ReadBuffer)) { 2323 if (ctx->ReadBuffer->_Status == 0) { 2324 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 2325 } 2326 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2327 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 2328 "glCopyTexImage%dD(invalid readbuffer)", dimensions); 2329 return GL_TRUE; 2330 } 2331 2332 if (ctx->ReadBuffer->Visual.samples > 0) { 2333 _mesa_error(ctx, GL_INVALID_OPERATION, 2334 "glCopyTexImage%dD(multisample FBO)", 2335 dimensions); 2336 return GL_TRUE; 2337 } 2338 } 2339 2340 /* Check border */ 2341 if (border < 0 || border > 1 || 2342 ((ctx->API != API_OPENGL || 2343 target == GL_TEXTURE_RECTANGLE_NV || 2344 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 2345 _mesa_error(ctx, GL_INVALID_VALUE, 2346 "glCopyTexImage%dD(border=%d)", dimensions, border); 2347 return GL_TRUE; 2348 } 2349 2350 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the 2351 * internalFormat. 2352 */ 2353 if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) { 2354 switch (internalFormat) { 2355 case GL_ALPHA: 2356 case GL_RGB: 2357 case GL_RGBA: 2358 case GL_LUMINANCE: 2359 case GL_LUMINANCE_ALPHA: 2360 break; 2361 default: 2362 _mesa_error(ctx, GL_INVALID_VALUE, 2363 "glCopyTexImage%dD(internalFormat)", dimensions); 2364 return GL_TRUE; 2365 } 2366 } 2367 2368 baseFormat = _mesa_base_tex_format(ctx, internalFormat); 2369 if (baseFormat < 0) { 2370 _mesa_error(ctx, GL_INVALID_VALUE, 2371 "glCopyTexImage%dD(internalFormat)", dimensions); 2372 return GL_TRUE; 2373 } 2374 2375 if (!_mesa_source_buffer_exists(ctx, baseFormat)) { 2376 _mesa_error(ctx, GL_INVALID_OPERATION, 2377 "glCopyTexImage%dD(missing readbuffer)", dimensions); 2378 return GL_TRUE; 2379 } 2380 2381 /* From the EXT_texture_integer spec: 2382 * 2383 * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage* 2384 * if the texture internalformat is an integer format and the read color 2385 * buffer is not an integer format, or if the internalformat is not an 2386 * integer format and the read color buffer is an integer format." 2387 */ 2388 if (_mesa_is_color_format(internalFormat)) { 2389 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 2390 2391 if (_mesa_is_enum_format_integer(rb->InternalFormat) != 2392 _mesa_is_enum_format_integer(internalFormat)) { 2393 _mesa_error(ctx, GL_INVALID_OPERATION, 2394 "glCopyTexImage%dD(integer vs non-integer)", dimensions); 2395 return GL_TRUE; 2396 } 2397 } 2398 2399 /* Do size, level checking */ 2400 sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) 2401 ? (width == height) : 1; 2402 2403 sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level, 2404 internalFormat, baseFormat, 2405 type, width, height, 2406 1, border); 2407 2408 if (!sizeOK) { 2409 if (dimensions == 1) { 2410 _mesa_error(ctx, GL_INVALID_VALUE, 2411 "glCopyTexImage1D(width=%d)", width); 2412 } 2413 else { 2414 ASSERT(dimensions == 2); 2415 _mesa_error(ctx, GL_INVALID_VALUE, 2416 "glCopyTexImage2D(width=%d, height=%d)", width, height); 2417 } 2418 return GL_TRUE; 2419 } 2420 2421 if (_mesa_is_compressed_format(ctx, internalFormat)) { 2422 if (!target_can_be_compressed(ctx, target, internalFormat)) { 2423 _mesa_error(ctx, GL_INVALID_ENUM, 2424 "glCopyTexImage%dD(target)", dimensions); 2425 return GL_TRUE; 2426 } 2427 if (compressedteximage_only_format(ctx, internalFormat)) { 2428 _mesa_error(ctx, GL_INVALID_OPERATION, 2429 "glCopyTexImage%dD(no compression for format)", dimensions); 2430 return GL_TRUE; 2431 } 2432 if (border != 0) { 2433 _mesa_error(ctx, GL_INVALID_OPERATION, 2434 "glCopyTexImage%dD(border!=0)", dimensions); 2435 return GL_TRUE; 2436 } 2437 } 2438 2439 if (!mutable_tex_object(ctx, target)) { 2440 _mesa_error(ctx, GL_INVALID_OPERATION, 2441 "glCopyTexImage%dD(immutable texture)", dimensions); 2442 return GL_TRUE; 2443 } 2444 2445 /* if we get here, the parameters are OK */ 2446 return GL_FALSE; 2447} 2448 2449 2450/** 2451 * Test glCopyTexSubImage[12]D() parameters for errors. 2452 * Note that this is the first part of error checking. 2453 * See also copytexsubimage_error_check2() below for the second part. 2454 * 2455 * \param ctx GL context. 2456 * \param dimensions texture image dimensions (must be 1, 2 or 3). 2457 * \param target texture target given by the user. 2458 * \param level image level given by the user. 2459 * 2460 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2461 */ 2462static GLboolean 2463copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions, 2464 GLenum target, GLint level) 2465{ 2466 /* Check that the source buffer is complete */ 2467 if (_mesa_is_user_fbo(ctx->ReadBuffer)) { 2468 if (ctx->ReadBuffer->_Status == 0) { 2469 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 2470 } 2471 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2472 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 2473 "glCopyTexImage%dD(invalid readbuffer)", dimensions); 2474 return GL_TRUE; 2475 } 2476 2477 if (ctx->ReadBuffer->Visual.samples > 0) { 2478 _mesa_error(ctx, GL_INVALID_OPERATION, 2479 "glCopyTexSubImage%dD(multisample FBO)", 2480 dimensions); 2481 return GL_TRUE; 2482 } 2483 } 2484 2485 /* check target (proxies not allowed) */ 2486 if (!legal_texsubimage_target(ctx, dimensions, target)) { 2487 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)", 2488 dimensions, _mesa_lookup_enum_by_nr(target)); 2489 return GL_TRUE; 2490 } 2491 2492 /* Check level */ 2493 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 2494 _mesa_error(ctx, GL_INVALID_VALUE, 2495 "glCopyTexSubImage%dD(level=%d)", dimensions, level); 2496 return GL_TRUE; 2497 } 2498 2499 return GL_FALSE; 2500} 2501 2502 2503/** 2504 * Second part of error checking for glCopyTexSubImage[12]D(). 2505 * \param xoffset sub-image x offset given by the user. 2506 * \param yoffset sub-image y offset given by the user. 2507 * \param zoffset sub-image z offset given by the user. 2508 * \param width image width given by the user. 2509 * \param height image height given by the user. 2510 */ 2511static GLboolean 2512copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions, 2513 GLenum target, GLint level, 2514 GLint xoffset, GLint yoffset, GLint zoffset, 2515 GLsizei width, GLsizei height, 2516 const struct gl_texture_image *teximage ) 2517{ 2518 /* check that dest tex image exists */ 2519 if (!teximage) { 2520 _mesa_error(ctx, GL_INVALID_OPERATION, 2521 "glCopyTexSubImage%dD(undefined texture level: %d)", 2522 dimensions, level); 2523 return GL_TRUE; 2524 } 2525 2526 /* Check size */ 2527 if (width < 0) { 2528 _mesa_error(ctx, GL_INVALID_VALUE, 2529 "glCopyTexSubImage%dD(width=%d)", dimensions, width); 2530 return GL_TRUE; 2531 } 2532 if (dimensions > 1 && height < 0) { 2533 _mesa_error(ctx, GL_INVALID_VALUE, 2534 "glCopyTexSubImage%dD(height=%d)", dimensions, height); 2535 return GL_TRUE; 2536 } 2537 2538 /* check x/y offsets */ 2539 if (xoffset < -((GLint)teximage->Border)) { 2540 _mesa_error(ctx, GL_INVALID_VALUE, 2541 "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset); 2542 return GL_TRUE; 2543 } 2544 if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) { 2545 _mesa_error(ctx, GL_INVALID_VALUE, 2546 "glCopyTexSubImage%dD(xoffset+width)", dimensions); 2547 return GL_TRUE; 2548 } 2549 if (dimensions > 1) { 2550 GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : teximage->Border; 2551 if (yoffset < -yBorder) { 2552 _mesa_error(ctx, GL_INVALID_VALUE, 2553 "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset); 2554 return GL_TRUE; 2555 } 2556 /* NOTE: we're adding the border here, not subtracting! */ 2557 if (yoffset + height > (GLint) teximage->Height + yBorder) { 2558 _mesa_error(ctx, GL_INVALID_VALUE, 2559 "glCopyTexSubImage%dD(yoffset+height)", dimensions); 2560 return GL_TRUE; 2561 } 2562 } 2563 2564 /* check z offset */ 2565 if (dimensions > 2) { 2566 GLint zBorder = (target == GL_TEXTURE_2D_ARRAY) ? 0 : teximage->Border; 2567 if (zoffset < -zBorder) { 2568 _mesa_error(ctx, GL_INVALID_VALUE, 2569 "glCopyTexSubImage%dD(zoffset)", dimensions); 2570 return GL_TRUE; 2571 } 2572 if (zoffset > (GLint) teximage->Depth + zBorder) { 2573 _mesa_error(ctx, GL_INVALID_VALUE, 2574 "glCopyTexSubImage%dD(zoffset+depth)", dimensions); 2575 return GL_TRUE; 2576 } 2577 } 2578 2579 if (_mesa_is_format_compressed(teximage->TexFormat)) { 2580 if (compressedteximage_only_format(ctx, teximage->InternalFormat)) { 2581 _mesa_error(ctx, GL_INVALID_OPERATION, 2582 "glCopyTexSubImage%dD(no compression for format)", dimensions); 2583 return GL_TRUE; 2584 } 2585 /* offset must be multiple of 4 */ 2586 if ((xoffset & 3) || (yoffset & 3)) { 2587 _mesa_error(ctx, GL_INVALID_VALUE, 2588 "glCopyTexSubImage%dD(xoffset or yoffset)", dimensions); 2589 return GL_TRUE; 2590 } 2591 /* size must be multiple of 4 */ 2592 if ((width & 3) != 0 && (GLuint) width != teximage->Width) { 2593 _mesa_error(ctx, GL_INVALID_VALUE, 2594 "glCopyTexSubImage%dD(width)", dimensions); 2595 return GL_TRUE; 2596 } 2597 if ((height & 3) != 0 && (GLuint) height != teximage->Height) { 2598 _mesa_error(ctx, GL_INVALID_VALUE, 2599 "glCopyTexSubImage%dD(height)", dimensions); 2600 return GL_TRUE; 2601 } 2602 } 2603 2604 if (teximage->InternalFormat == GL_YCBCR_MESA) { 2605 _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D"); 2606 return GL_TRUE; 2607 } 2608 2609 if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) { 2610 _mesa_error(ctx, GL_INVALID_OPERATION, 2611 "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)", 2612 dimensions, teximage->_BaseFormat); 2613 return GL_TRUE; 2614 } 2615 2616 /* From the EXT_texture_integer spec: 2617 * 2618 * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage* 2619 * if the texture internalformat is an integer format and the read color 2620 * buffer is not an integer format, or if the internalformat is not an 2621 * integer format and the read color buffer is an integer format." 2622 */ 2623 if (_mesa_is_color_format(teximage->InternalFormat)) { 2624 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 2625 2626 if (_mesa_is_format_integer_color(rb->Format) != 2627 _mesa_is_format_integer_color(teximage->TexFormat)) { 2628 _mesa_error(ctx, GL_INVALID_OPERATION, 2629 "glCopyTexImage%dD(integer vs non-integer)", dimensions); 2630 return GL_TRUE; 2631 } 2632 } 2633 2634 /* if we get here, the parameters are OK */ 2635 return GL_FALSE; 2636} 2637 2638 2639/** Callback info for walking over FBO hash table */ 2640struct cb_info 2641{ 2642 struct gl_context *ctx; 2643 struct gl_texture_object *texObj; 2644 GLuint level, face; 2645}; 2646 2647 2648/** 2649 * Check render to texture callback. Called from _mesa_HashWalk(). 2650 */ 2651static void 2652check_rtt_cb(GLuint key, void *data, void *userData) 2653{ 2654 struct gl_framebuffer *fb = (struct gl_framebuffer *) data; 2655 const struct cb_info *info = (struct cb_info *) userData; 2656 struct gl_context *ctx = info->ctx; 2657 const struct gl_texture_object *texObj = info->texObj; 2658 const GLuint level = info->level, face = info->face; 2659 2660 /* If this is a user-created FBO */ 2661 if (_mesa_is_user_fbo(fb)) { 2662 GLuint i; 2663 /* check if any of the FBO's attachments point to 'texObj' */ 2664 for (i = 0; i < BUFFER_COUNT; i++) { 2665 struct gl_renderbuffer_attachment *att = fb->Attachment + i; 2666 if (att->Type == GL_TEXTURE && 2667 att->Texture == texObj && 2668 att->TextureLevel == level && 2669 att->CubeMapFace == face) { 2670 ASSERT(_mesa_get_attachment_teximage(att)); 2671 /* Tell driver about the new renderbuffer texture */ 2672 ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att); 2673 /* Mark fb status as indeterminate to force re-validation */ 2674 fb->_Status = 0; 2675 } 2676 } 2677 } 2678} 2679 2680 2681/** 2682 * When a texture image is specified we have to check if it's bound to 2683 * any framebuffer objects (render to texture) in order to detect changes 2684 * in size or format since that effects FBO completeness. 2685 * Any FBOs rendering into the texture must be re-validated. 2686 */ 2687void 2688_mesa_update_fbo_texture(struct gl_context *ctx, 2689 struct gl_texture_object *texObj, 2690 GLuint face, GLuint level) 2691{ 2692 /* Only check this texture if it's been marked as RenderToTexture */ 2693 if (texObj->_RenderToTexture) { 2694 struct cb_info info; 2695 info.ctx = ctx; 2696 info.texObj = texObj; 2697 info.level = level; 2698 info.face = face; 2699 _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info); 2700 } 2701} 2702 2703 2704/** 2705 * If the texture object's GenerateMipmap flag is set and we've 2706 * changed the texture base level image, regenerate the rest of the 2707 * mipmap levels now. 2708 */ 2709static inline void 2710check_gen_mipmap(struct gl_context *ctx, GLenum target, 2711 struct gl_texture_object *texObj, GLint level) 2712{ 2713 ASSERT(target != GL_TEXTURE_CUBE_MAP); 2714 if (texObj->GenerateMipmap && 2715 level == texObj->BaseLevel && 2716 level < texObj->MaxLevel) { 2717 ASSERT(ctx->Driver.GenerateMipmap); 2718 ctx->Driver.GenerateMipmap(ctx, target, texObj); 2719 } 2720} 2721 2722 2723/** Debug helper: override the user-requested internal format */ 2724static GLenum 2725override_internal_format(GLenum internalFormat, GLint width, GLint height) 2726{ 2727#if 0 2728 if (internalFormat == GL_RGBA16F_ARB || 2729 internalFormat == GL_RGBA32F_ARB) { 2730 printf("Convert rgba float tex to int %d x %d\n", width, height); 2731 return GL_RGBA; 2732 } 2733 else if (internalFormat == GL_RGB16F_ARB || 2734 internalFormat == GL_RGB32F_ARB) { 2735 printf("Convert rgb float tex to int %d x %d\n", width, height); 2736 return GL_RGB; 2737 } 2738 else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB || 2739 internalFormat == GL_LUMINANCE_ALPHA32F_ARB) { 2740 printf("Convert luminance float tex to int %d x %d\n", width, height); 2741 return GL_LUMINANCE_ALPHA; 2742 } 2743 else if (internalFormat == GL_LUMINANCE16F_ARB || 2744 internalFormat == GL_LUMINANCE32F_ARB) { 2745 printf("Convert luminance float tex to int %d x %d\n", width, height); 2746 return GL_LUMINANCE; 2747 } 2748 else if (internalFormat == GL_ALPHA16F_ARB || 2749 internalFormat == GL_ALPHA32F_ARB) { 2750 printf("Convert luminance float tex to int %d x %d\n", width, height); 2751 return GL_ALPHA; 2752 } 2753 /* 2754 else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) { 2755 internalFormat = GL_RGBA; 2756 } 2757 */ 2758 else { 2759 return internalFormat; 2760 } 2761#else 2762 return internalFormat; 2763#endif 2764} 2765 2766 2767/** 2768 * Choose the actual hardware format for a texture image. 2769 * Try to use the same format as the previous image level when possible. 2770 * Otherwise, ask the driver for the best format. 2771 * It's important to try to choose a consistant format for all levels 2772 * for efficient texture memory layout/allocation. In particular, this 2773 * comes up during automatic mipmap generation. 2774 */ 2775gl_format 2776_mesa_choose_texture_format(struct gl_context *ctx, 2777 struct gl_texture_object *texObj, 2778 GLenum target, GLint level, 2779 GLenum internalFormat, GLenum format, GLenum type) 2780{ 2781 gl_format f; 2782 2783 /* see if we've already chosen a format for the previous level */ 2784 if (level > 0) { 2785 struct gl_texture_image *prevImage = 2786 _mesa_select_tex_image(ctx, texObj, target, level - 1); 2787 /* See if the prev level is defined and has an internal format which 2788 * matches the new internal format. 2789 */ 2790 if (prevImage && 2791 prevImage->Width > 0 && 2792 prevImage->InternalFormat == internalFormat) { 2793 /* use the same format */ 2794 ASSERT(prevImage->TexFormat != MESA_FORMAT_NONE); 2795 return prevImage->TexFormat; 2796 } 2797 } 2798 2799 /* choose format from scratch */ 2800 f = ctx->Driver.ChooseTextureFormat(ctx, texObj->Target, internalFormat, 2801 format, type); 2802 ASSERT(f != MESA_FORMAT_NONE); 2803 return f; 2804} 2805 2806/** 2807 * Adjust pixel unpack params and image dimensions to strip off the 2808 * one-pixel texture border. 2809 * 2810 * Gallium and intel don't support texture borders. They've seldem been used 2811 * and seldom been implemented correctly anyway. 2812 * 2813 * \param unpackNew returns the new pixel unpack parameters 2814 */ 2815static void 2816strip_texture_border(GLenum target, 2817 GLint *width, GLint *height, GLint *depth, 2818 const struct gl_pixelstore_attrib *unpack, 2819 struct gl_pixelstore_attrib *unpackNew) 2820{ 2821 assert(width); 2822 assert(height); 2823 assert(depth); 2824 2825 *unpackNew = *unpack; 2826 2827 if (unpackNew->RowLength == 0) 2828 unpackNew->RowLength = *width; 2829 2830 if (unpackNew->ImageHeight == 0) 2831 unpackNew->ImageHeight = *height; 2832 2833 assert(*width >= 3); 2834 unpackNew->SkipPixels++; /* skip the border */ 2835 *width = *width - 2; /* reduce the width by two border pixels */ 2836 2837 /* The min height of a texture with a border is 3 */ 2838 if (*height >= 3 && target != GL_TEXTURE_1D_ARRAY) { 2839 unpackNew->SkipRows++; /* skip the border */ 2840 *height = *height - 2; /* reduce the height by two border pixels */ 2841 } 2842 2843 if (*depth >= 3 && target != GL_TEXTURE_2D_ARRAY) { 2844 unpackNew->SkipImages++; /* skip the border */ 2845 *depth = *depth - 2; /* reduce the depth by two border pixels */ 2846 } 2847} 2848 2849 2850/** 2851 * Common code to implement all the glTexImage1D/2D/3D functions 2852 * as well as glCompressedTexImage1D/2D/3D. 2853 * \param compressed only GL_TRUE for glCompressedTexImage1D/2D/3D calls. 2854 * \param format the user's image format (only used if !compressed) 2855 * \param type the user's image type (only used if !compressed) 2856 * \param imageSize only used for glCompressedTexImage1D/2D/3D calls. 2857 */ 2858static void 2859teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, 2860 GLenum target, GLint level, GLint internalFormat, 2861 GLsizei width, GLsizei height, GLsizei depth, 2862 GLint border, GLenum format, GLenum type, 2863 GLsizei imageSize, const GLvoid *pixels) 2864{ 2865 const char *func = compressed ? "glCompressedTexImage" : "glTexImage"; 2866 GLenum error; 2867 struct gl_pixelstore_attrib unpack_no_border; 2868 const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; 2869 2870 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2871 2872 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) { 2873 if (compressed) 2874 _mesa_debug(ctx, 2875 "glCompressedTexImage%uD %s %d %s %d %d %d %d %p\n", 2876 dims, 2877 _mesa_lookup_enum_by_nr(target), level, 2878 _mesa_lookup_enum_by_nr(internalFormat), 2879 width, height, depth, border, pixels); 2880 else 2881 _mesa_debug(ctx, 2882 "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n", 2883 dims, 2884 _mesa_lookup_enum_by_nr(target), level, 2885 _mesa_lookup_enum_by_nr(internalFormat), 2886 width, height, depth, border, 2887 _mesa_lookup_enum_by_nr(format), 2888 _mesa_lookup_enum_by_nr(type), pixels); 2889 } 2890 2891 internalFormat = override_internal_format(internalFormat, width, height); 2892 2893 /* target error checking */ 2894 if (!legal_teximage_target(ctx, dims, target)) { 2895 _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)", 2896 func, dims, _mesa_lookup_enum_by_nr(target)); 2897 return; 2898 } 2899 2900 /* general error checking */ 2901 if (compressed) { 2902 error = compressed_texture_error_check(ctx, dims, target, level, 2903 internalFormat, 2904 width, height, depth, 2905 border, imageSize); 2906 } 2907 else { 2908 error = texture_error_check(ctx, dims, target, level, internalFormat, 2909 format, type, width, height, depth, border); 2910 } 2911 2912#if FEATURE_ES 2913 /* Here we convert a cpal compressed image into a regular glTexImage2D 2914 * call by decompressing the texture. If we really want to support cpal 2915 * textures in any driver this would have to be changed. 2916 */ 2917 if (compressed && !error && dims == 2) { 2918 switch (internalFormat) { 2919 case GL_PALETTE4_RGB8_OES: 2920 case GL_PALETTE4_RGBA8_OES: 2921 case GL_PALETTE4_R5_G6_B5_OES: 2922 case GL_PALETTE4_RGBA4_OES: 2923 case GL_PALETTE4_RGB5_A1_OES: 2924 case GL_PALETTE8_RGB8_OES: 2925 case GL_PALETTE8_RGBA8_OES: 2926 case GL_PALETTE8_R5_G6_B5_OES: 2927 case GL_PALETTE8_RGBA4_OES: 2928 case GL_PALETTE8_RGB5_A1_OES: 2929 _mesa_cpal_compressed_teximage2d(target, level, internalFormat, 2930 width, height, imageSize, pixels); 2931 return; 2932 } 2933 } 2934#endif 2935 2936 if (_mesa_is_proxy_texture(target)) { 2937 /* Proxy texture: just clear or set state depending on error checking */ 2938 struct gl_texture_image *texImage = 2939 get_proxy_tex_image(ctx, target, level); 2940 gl_format texFormat = MESA_FORMAT_NONE; 2941 2942 if (!error) { 2943 /* No parameter errors. Choose a texture format and see if we 2944 * can really allocate the texture. 2945 */ 2946 struct gl_texture_object *texObj = 2947 _mesa_get_current_tex_object(ctx, target); 2948 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 2949 internalFormat, format, type); 2950 if (!legal_texture_size(ctx, texFormat, width, height, depth)) { 2951 error = PROXY_ERROR; 2952 } 2953 } 2954 2955 if (error == PROXY_ERROR) { 2956 /* image too large, etc. Clear all proxy texture image parameters. */ 2957 if (texImage) 2958 clear_teximage_fields(texImage); 2959 } 2960 else if (error == GL_FALSE) { 2961 /* no error: store the teximage parameters */ 2962 if (texImage) 2963 _mesa_init_teximage_fields(ctx, texImage, width, height, depth, 2964 border, internalFormat, texFormat); 2965 } 2966 else { 2967 /* other, regular error (was already recorded) */ 2968 } 2969 } 2970 else { 2971 /* non-proxy target */ 2972 const GLuint face = _mesa_tex_target_to_face(target); 2973 struct gl_texture_object *texObj; 2974 struct gl_texture_image *texImage; 2975 2976 if (error) { 2977 return; /* error was recorded */ 2978 } 2979 2980 /* Allow a hardware driver to just strip out the border, to provide 2981 * reliable but slightly incorrect hardware rendering instead of 2982 * rarely-tested software fallback rendering. 2983 */ 2984 if (border && ctx->Const.StripTextureBorder) { 2985 strip_texture_border(target, &width, &height, &depth, unpack, 2986 &unpack_no_border); 2987 border = 0; 2988 unpack = &unpack_no_border; 2989 } 2990 2991 if (ctx->NewState & _NEW_PIXEL) 2992 _mesa_update_state(ctx); 2993 2994 texObj = _mesa_get_current_tex_object(ctx, target); 2995 2996 _mesa_lock_texture(ctx, texObj); 2997 { 2998 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2999 3000 if (!texImage) { 3001 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims); 3002 } 3003 else { 3004 gl_format texFormat; 3005 3006 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 3007 3008 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 3009 internalFormat, format, 3010 type); 3011 3012 if (legal_texture_size(ctx, texFormat, width, height, depth)) { 3013 _mesa_init_teximage_fields(ctx, texImage, 3014 width, height, depth, 3015 border, internalFormat, texFormat); 3016 3017 /* Give the texture to the driver. <pixels> may be null. */ 3018 if (compressed) { 3019 ctx->Driver.CompressedTexImage(ctx, dims, texImage, 3020 imageSize, pixels); 3021 } 3022 else { 3023 ctx->Driver.TexImage(ctx, dims, texImage, format, 3024 type, pixels, unpack); 3025 } 3026 3027 check_gen_mipmap(ctx, target, texObj, level); 3028 3029 _mesa_update_fbo_texture(ctx, texObj, face, level); 3030 3031 _mesa_dirty_texobj(ctx, texObj, GL_TRUE); 3032 } 3033 else { 3034 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims); 3035 } 3036 } 3037 } 3038 _mesa_unlock_texture(ctx, texObj); 3039 } 3040} 3041 3042 3043/* 3044 * Called from the API. Note that width includes the border. 3045 */ 3046void GLAPIENTRY 3047_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, 3048 GLsizei width, GLint border, GLenum format, 3049 GLenum type, const GLvoid *pixels ) 3050{ 3051 GET_CURRENT_CONTEXT(ctx); 3052 teximage(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 1, 3053 border, format, type, 0, pixels); 3054} 3055 3056 3057void GLAPIENTRY 3058_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 3059 GLsizei width, GLsizei height, GLint border, 3060 GLenum format, GLenum type, 3061 const GLvoid *pixels ) 3062{ 3063 GET_CURRENT_CONTEXT(ctx); 3064 teximage(ctx, GL_FALSE, 2, target, level, internalFormat, width, height, 1, 3065 border, format, type, 0, pixels); 3066} 3067 3068 3069/* 3070 * Called by the API or display list executor. 3071 * Note that width and height include the border. 3072 */ 3073void GLAPIENTRY 3074_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, 3075 GLsizei width, GLsizei height, GLsizei depth, 3076 GLint border, GLenum format, GLenum type, 3077 const GLvoid *pixels ) 3078{ 3079 GET_CURRENT_CONTEXT(ctx); 3080 teximage(ctx, GL_FALSE, 3, target, level, internalFormat, 3081 width, height, depth, 3082 border, format, type, 0, pixels); 3083} 3084 3085 3086void GLAPIENTRY 3087_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, 3088 GLsizei width, GLsizei height, GLsizei depth, 3089 GLint border, GLenum format, GLenum type, 3090 const GLvoid *pixels ) 3091{ 3092 _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height, 3093 depth, border, format, type, pixels); 3094} 3095 3096 3097#if FEATURE_OES_EGL_image 3098void GLAPIENTRY 3099_mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) 3100{ 3101 struct gl_texture_object *texObj; 3102 struct gl_texture_image *texImage; 3103 bool valid_target; 3104 GET_CURRENT_CONTEXT(ctx); 3105 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3106 3107 switch (target) { 3108 case GL_TEXTURE_2D: 3109 valid_target = ctx->Extensions.OES_EGL_image; 3110 break; 3111 case GL_TEXTURE_EXTERNAL_OES: 3112 valid_target = ctx->Extensions.OES_EGL_image_external; 3113 break; 3114 default: 3115 valid_target = false; 3116 break; 3117 } 3118 3119 if (!valid_target) { 3120 _mesa_error(ctx, GL_INVALID_ENUM, 3121 "glEGLImageTargetTexture2D(target=%d)", target); 3122 return; 3123 } 3124 3125 if (ctx->NewState & _NEW_PIXEL) 3126 _mesa_update_state(ctx); 3127 3128 texObj = _mesa_get_current_tex_object(ctx, target); 3129 _mesa_lock_texture(ctx, texObj); 3130 3131 if (texObj->Immutable) { 3132 _mesa_error(ctx, GL_INVALID_OPERATION, 3133 "glEGLImageTargetTexture2D(texture is immutable)"); 3134 _mesa_unlock_texture(ctx, texObj); 3135 return; 3136 } 3137 3138 texImage = _mesa_get_tex_image(ctx, texObj, target, 0); 3139 if (!texImage) { 3140 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEGLImageTargetTexture2D"); 3141 } else { 3142 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 3143 3144 ctx->Driver.EGLImageTargetTexture2D(ctx, target, 3145 texObj, texImage, image); 3146 3147 _mesa_dirty_texobj(ctx, texObj, GL_TRUE); 3148 } 3149 _mesa_unlock_texture(ctx, texObj); 3150 3151} 3152#endif 3153 3154 3155 3156/** 3157 * Implement all the glTexSubImage1/2/3D() functions. 3158 */ 3159static void 3160texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, 3161 GLint xoffset, GLint yoffset, GLint zoffset, 3162 GLsizei width, GLsizei height, GLsizei depth, 3163 GLenum format, GLenum type, const GLvoid *pixels ) 3164{ 3165 struct gl_texture_object *texObj; 3166 struct gl_texture_image *texImage; 3167 3168 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3169 3170 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3171 _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n", 3172 dims, 3173 _mesa_lookup_enum_by_nr(target), level, 3174 xoffset, yoffset, zoffset, width, height, depth, 3175 _mesa_lookup_enum_by_nr(format), 3176 _mesa_lookup_enum_by_nr(type), pixels); 3177 3178 /* check target (proxies not allowed) */ 3179 if (!legal_texsubimage_target(ctx, dims, target)) { 3180 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)", 3181 dims, _mesa_lookup_enum_by_nr(target)); 3182 return; 3183 } 3184 3185 if (ctx->NewState & _NEW_PIXEL) 3186 _mesa_update_state(ctx); 3187 3188 if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset, 3189 width, height, depth, format, type)) { 3190 return; /* error was detected */ 3191 } 3192 3193 texObj = _mesa_get_current_tex_object(ctx, target); 3194 3195 _mesa_lock_texture(ctx, texObj); 3196 { 3197 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3198 3199 if (subtexture_error_check2(ctx, dims, target, level, 3200 xoffset, yoffset, zoffset, 3201 width, height, depth, 3202 format, type, texImage)) { 3203 /* error was recorded */ 3204 } 3205 else if (width > 0 && height > 0 && depth > 0) { 3206 /* If we have a border, offset=-1 is legal. Bias by border width. */ 3207 switch (dims) { 3208 case 3: 3209 if (target != GL_TEXTURE_2D_ARRAY) 3210 zoffset += texImage->Border; 3211 /* fall-through */ 3212 case 2: 3213 if (target != GL_TEXTURE_1D_ARRAY) 3214 yoffset += texImage->Border; 3215 /* fall-through */ 3216 case 1: 3217 xoffset += texImage->Border; 3218 } 3219 3220 ctx->Driver.TexSubImage(ctx, dims, texImage, 3221 xoffset, yoffset, zoffset, 3222 width, height, depth, 3223 format, type, pixels, &ctx->Unpack); 3224 3225 check_gen_mipmap(ctx, target, texObj, level); 3226 3227 ctx->NewState |= _NEW_TEXTURE; 3228 } 3229 } 3230 _mesa_unlock_texture(ctx, texObj); 3231} 3232 3233 3234void GLAPIENTRY 3235_mesa_TexSubImage1D( GLenum target, GLint level, 3236 GLint xoffset, GLsizei width, 3237 GLenum format, GLenum type, 3238 const GLvoid *pixels ) 3239{ 3240 GET_CURRENT_CONTEXT(ctx); 3241 texsubimage(ctx, 1, target, level, 3242 xoffset, 0, 0, 3243 width, 1, 1, 3244 format, type, pixels); 3245} 3246 3247 3248void GLAPIENTRY 3249_mesa_TexSubImage2D( GLenum target, GLint level, 3250 GLint xoffset, GLint yoffset, 3251 GLsizei width, GLsizei height, 3252 GLenum format, GLenum type, 3253 const GLvoid *pixels ) 3254{ 3255 GET_CURRENT_CONTEXT(ctx); 3256 texsubimage(ctx, 2, target, level, 3257 xoffset, yoffset, 0, 3258 width, height, 1, 3259 format, type, pixels); 3260} 3261 3262 3263 3264void GLAPIENTRY 3265_mesa_TexSubImage3D( GLenum target, GLint level, 3266 GLint xoffset, GLint yoffset, GLint zoffset, 3267 GLsizei width, GLsizei height, GLsizei depth, 3268 GLenum format, GLenum type, 3269 const GLvoid *pixels ) 3270{ 3271 GET_CURRENT_CONTEXT(ctx); 3272 texsubimage(ctx, 3, target, level, 3273 xoffset, yoffset, zoffset, 3274 width, height, depth, 3275 format, type, pixels); 3276} 3277 3278 3279 3280/** 3281 * For glCopyTexSubImage, return the source renderbuffer to copy texel data 3282 * from. This depends on whether the texture contains color or depth values. 3283 */ 3284static struct gl_renderbuffer * 3285get_copy_tex_image_source(struct gl_context *ctx, gl_format texFormat) 3286{ 3287 if (_mesa_get_format_bits(texFormat, GL_DEPTH_BITS) > 0) { 3288 /* reading from depth/stencil buffer */ 3289 return ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 3290 } 3291 else { 3292 /* copying from color buffer */ 3293 return ctx->ReadBuffer->_ColorReadBuffer; 3294 } 3295} 3296 3297 3298 3299/** 3300 * Implement the glCopyTexImage1/2D() functions. 3301 */ 3302static void 3303copyteximage(struct gl_context *ctx, GLuint dims, 3304 GLenum target, GLint level, GLenum internalFormat, 3305 GLint x, GLint y, GLsizei width, GLsizei height, GLint border ) 3306{ 3307 struct gl_texture_object *texObj; 3308 struct gl_texture_image *texImage; 3309 const GLuint face = _mesa_tex_target_to_face(target); 3310 3311 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3312 3313 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3314 _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n", 3315 dims, 3316 _mesa_lookup_enum_by_nr(target), level, 3317 _mesa_lookup_enum_by_nr(internalFormat), 3318 x, y, width, height, border); 3319 3320 if (ctx->NewState & NEW_COPY_TEX_STATE) 3321 _mesa_update_state(ctx); 3322 3323 if (copytexture_error_check(ctx, dims, target, level, internalFormat, 3324 width, height, border)) 3325 return; 3326 3327 texObj = _mesa_get_current_tex_object(ctx, target); 3328 3329 if (border && ctx->Const.StripTextureBorder) { 3330 x += border; 3331 width -= border * 2; 3332 if (dims == 2) { 3333 y += border; 3334 height -= border * 2; 3335 } 3336 border = 0; 3337 } 3338 3339 _mesa_lock_texture(ctx, texObj); 3340 { 3341 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3342 3343 if (!texImage) { 3344 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); 3345 } 3346 else { 3347 /* choose actual hw format */ 3348 gl_format texFormat = _mesa_choose_texture_format(ctx, texObj, 3349 target, level, 3350 internalFormat, 3351 GL_NONE, GL_NONE); 3352 3353 if (legal_texture_size(ctx, texFormat, width, height, 1)) { 3354 GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0; 3355 3356 /* Free old texture image */ 3357 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 3358 3359 _mesa_init_teximage_fields(ctx, texImage, width, height, 1, 3360 border, internalFormat, texFormat); 3361 3362 /* Allocate texture memory (no pixel data yet) */ 3363 ctx->Driver.TexImage(ctx, dims, texImage, 3364 GL_NONE, GL_NONE, 3365 NULL, &ctx->Unpack); 3366 3367 if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY, 3368 &width, &height)) { 3369 struct gl_renderbuffer *srcRb = 3370 get_copy_tex_image_source(ctx, texImage->TexFormat); 3371 3372 ctx->Driver.CopyTexSubImage(ctx, dims, texImage, dstX, dstY, dstZ, 3373 srcRb, srcX, srcY, width, height); 3374 } 3375 3376 check_gen_mipmap(ctx, target, texObj, level); 3377 3378 _mesa_update_fbo_texture(ctx, texObj, face, level); 3379 3380 _mesa_dirty_texobj(ctx, texObj, GL_TRUE); 3381 } 3382 else { 3383 /* probably too large of image */ 3384 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); 3385 } 3386 } 3387 } 3388 _mesa_unlock_texture(ctx, texObj); 3389} 3390 3391 3392 3393void GLAPIENTRY 3394_mesa_CopyTexImage1D( GLenum target, GLint level, 3395 GLenum internalFormat, 3396 GLint x, GLint y, 3397 GLsizei width, GLint border ) 3398{ 3399 GET_CURRENT_CONTEXT(ctx); 3400 copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border); 3401} 3402 3403 3404 3405void GLAPIENTRY 3406_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, 3407 GLint x, GLint y, GLsizei width, GLsizei height, 3408 GLint border ) 3409{ 3410 GET_CURRENT_CONTEXT(ctx); 3411 copyteximage(ctx, 2, target, level, internalFormat, 3412 x, y, width, height, border); 3413} 3414 3415 3416 3417/** 3418 * Implementation for glCopyTexSubImage1/2/3D() functions. 3419 */ 3420static void 3421copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, 3422 GLint xoffset, GLint yoffset, GLint zoffset, 3423 GLint x, GLint y, GLsizei width, GLsizei height) 3424{ 3425 struct gl_texture_object *texObj; 3426 struct gl_texture_image *texImage; 3427 3428 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3429 3430 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3431 _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n", 3432 dims, 3433 _mesa_lookup_enum_by_nr(target), 3434 level, xoffset, yoffset, zoffset, x, y, width, height); 3435 3436 if (ctx->NewState & NEW_COPY_TEX_STATE) 3437 _mesa_update_state(ctx); 3438 3439 if (copytexsubimage_error_check1(ctx, dims, target, level)) 3440 return; 3441 3442 texObj = _mesa_get_current_tex_object(ctx, target); 3443 3444 _mesa_lock_texture(ctx, texObj); 3445 { 3446 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3447 3448 if (copytexsubimage_error_check2(ctx, dims, target, level, xoffset, yoffset, 3449 zoffset, width, height, texImage)) { 3450 /* error was recored */ 3451 } 3452 else { 3453 /* If we have a border, offset=-1 is legal. Bias by border width. */ 3454 switch (dims) { 3455 case 3: 3456 if (target != GL_TEXTURE_2D_ARRAY) 3457 zoffset += texImage->Border; 3458 /* fall-through */ 3459 case 2: 3460 if (target != GL_TEXTURE_1D_ARRAY) 3461 yoffset += texImage->Border; 3462 /* fall-through */ 3463 case 1: 3464 xoffset += texImage->Border; 3465 } 3466 3467 if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, 3468 &width, &height)) { 3469 struct gl_renderbuffer *srcRb = 3470 get_copy_tex_image_source(ctx, texImage->TexFormat); 3471 3472 ctx->Driver.CopyTexSubImage(ctx, dims, texImage, 3473 xoffset, yoffset, zoffset, 3474 srcRb, x, y, width, height); 3475 3476 check_gen_mipmap(ctx, target, texObj, level); 3477 3478 ctx->NewState |= _NEW_TEXTURE; 3479 } 3480 } 3481 } 3482 _mesa_unlock_texture(ctx, texObj); 3483} 3484 3485 3486void GLAPIENTRY 3487_mesa_CopyTexSubImage1D( GLenum target, GLint level, 3488 GLint xoffset, GLint x, GLint y, GLsizei width ) 3489{ 3490 GET_CURRENT_CONTEXT(ctx); 3491 copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1); 3492} 3493 3494 3495 3496void GLAPIENTRY 3497_mesa_CopyTexSubImage2D( GLenum target, GLint level, 3498 GLint xoffset, GLint yoffset, 3499 GLint x, GLint y, GLsizei width, GLsizei height ) 3500{ 3501 GET_CURRENT_CONTEXT(ctx); 3502 copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y, 3503 width, height); 3504} 3505 3506 3507 3508void GLAPIENTRY 3509_mesa_CopyTexSubImage3D( GLenum target, GLint level, 3510 GLint xoffset, GLint yoffset, GLint zoffset, 3511 GLint x, GLint y, GLsizei width, GLsizei height ) 3512{ 3513 GET_CURRENT_CONTEXT(ctx); 3514 copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, 3515 x, y, width, height); 3516} 3517 3518 3519 3520 3521/**********************************************************************/ 3522/****** Compressed Textures ******/ 3523/**********************************************************************/ 3524 3525 3526/** 3527 * Error checking for glCompressedTexSubImage[123]D(). 3528 * \warning There are some bad assumptions here about the size of compressed 3529 * texture tiles (multiple of 4) used to test the validity of the 3530 * offset and size parameters. 3531 * \return error code or GL_NO_ERROR. 3532 */ 3533static GLenum 3534compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions, 3535 GLenum target, GLint level, 3536 GLint xoffset, GLint yoffset, GLint zoffset, 3537 GLsizei width, GLsizei height, GLsizei depth, 3538 GLenum format, GLsizei imageSize) 3539{ 3540 GLint expectedSize, maxLevels = 0, maxTextureSize; 3541 GLuint bw, bh; 3542 (void) zoffset; 3543 3544 if (dimensions == 1) { 3545 /* 1D compressed textures not allowed */ 3546 return GL_INVALID_ENUM; 3547 } 3548 else if (dimensions == 2) { 3549 if (target == GL_PROXY_TEXTURE_2D) { 3550 maxLevels = ctx->Const.MaxTextureLevels; 3551 } 3552 else if (target == GL_TEXTURE_2D) { 3553 maxLevels = ctx->Const.MaxTextureLevels; 3554 } 3555 else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { 3556 if (!ctx->Extensions.ARB_texture_cube_map) 3557 return GL_INVALID_ENUM; /*target*/ 3558 maxLevels = ctx->Const.MaxCubeTextureLevels; 3559 } 3560 else if (_mesa_is_cube_face(target)) { 3561 if (!ctx->Extensions.ARB_texture_cube_map) 3562 return GL_INVALID_ENUM; /*target*/ 3563 maxLevels = ctx->Const.MaxCubeTextureLevels; 3564 } 3565 else { 3566 return GL_INVALID_ENUM; /*target*/ 3567 } 3568 } 3569 else if (dimensions == 3) { 3570 /* 3D compressed textures not allowed */ 3571 return GL_INVALID_ENUM; 3572 } 3573 3574 maxTextureSize = 1 << (maxLevels - 1); 3575 3576 /* this will catch any invalid compressed format token */ 3577 if (!_mesa_is_compressed_format(ctx, format)) 3578 return GL_INVALID_ENUM; 3579 3580 if (width < 1 || width > maxTextureSize) 3581 return GL_INVALID_VALUE; 3582 3583 if ((height < 1 || height > maxTextureSize) 3584 && dimensions > 1) 3585 return GL_INVALID_VALUE; 3586 3587 if (level < 0 || level >= maxLevels) 3588 return GL_INVALID_VALUE; 3589 3590 /* 3591 * do checks which depend on compression block size 3592 */ 3593 get_compressed_block_size(format, &bw, &bh); 3594 3595 if ((xoffset % bw != 0) || (yoffset % bh != 0)) 3596 return GL_INVALID_VALUE; 3597 3598 if ((width % bw != 0) && width != 2 && width != 1) 3599 return GL_INVALID_VALUE; 3600 3601 if ((height % bh != 0) && height != 2 && height != 1) 3602 return GL_INVALID_VALUE; 3603 3604 expectedSize = compressed_tex_size(width, height, depth, format); 3605 if (expectedSize != imageSize) 3606 return GL_INVALID_VALUE; 3607 3608 return GL_NO_ERROR; 3609} 3610 3611 3612/** 3613 * Do second part of glCompressedTexSubImage error checking. 3614 * \return GL_TRUE if error found, GL_FALSE otherwise. 3615 */ 3616static GLboolean 3617compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims, 3618 GLsizei width, GLsizei height, 3619 GLsizei depth, GLenum format, 3620 struct gl_texture_image *texImage) 3621{ 3622 3623 if ((GLint) format != texImage->InternalFormat) { 3624 _mesa_error(ctx, GL_INVALID_OPERATION, 3625 "glCompressedTexSubImage%uD(format=0x%x)", dims, format); 3626 return GL_TRUE; 3627 } 3628 3629 if (compressedteximage_only_format(ctx, format)) { 3630 _mesa_error(ctx, GL_INVALID_OPERATION, 3631 "glCompressedTexSubImage%uD(format=0x%x cannot be updated)" 3632 , dims, format); 3633 return GL_TRUE; 3634 } 3635 3636 if (((width == 1 || width == 2) && 3637 width != (GLsizei) texImage->Width) || 3638 (width > (GLsizei) texImage->Width)) { 3639 _mesa_error(ctx, GL_INVALID_VALUE, 3640 "glCompressedTexSubImage%uD(width=%d)", dims, width); 3641 return GL_TRUE; 3642 } 3643 3644 if (dims >= 2) { 3645 if (((height == 1 || height == 2) && 3646 height != (GLsizei) texImage->Height) || 3647 (height > (GLsizei) texImage->Height)) { 3648 _mesa_error(ctx, GL_INVALID_VALUE, 3649 "glCompressedTexSubImage%uD(height=%d)", dims, height); 3650 return GL_TRUE; 3651 } 3652 } 3653 3654 if (dims >= 3) { 3655 if (((depth == 1 || depth == 2) && 3656 depth != (GLsizei) texImage->Depth) || 3657 (depth > (GLsizei) texImage->Depth)) { 3658 _mesa_error(ctx, GL_INVALID_VALUE, 3659 "glCompressedTexSubImage%uD(depth=%d)", dims, depth); 3660 return GL_TRUE; 3661 } 3662 } 3663 3664 return GL_FALSE; 3665} 3666 3667 3668void GLAPIENTRY 3669_mesa_CompressedTexImage1DARB(GLenum target, GLint level, 3670 GLenum internalFormat, GLsizei width, 3671 GLint border, GLsizei imageSize, 3672 const GLvoid *data) 3673{ 3674 GET_CURRENT_CONTEXT(ctx); 3675 teximage(ctx, GL_TRUE, 1, target, level, internalFormat, 3676 width, 1, 1, border, GL_NONE, GL_NONE, imageSize, data); 3677} 3678 3679 3680void GLAPIENTRY 3681_mesa_CompressedTexImage2DARB(GLenum target, GLint level, 3682 GLenum internalFormat, GLsizei width, 3683 GLsizei height, GLint border, GLsizei imageSize, 3684 const GLvoid *data) 3685{ 3686 GET_CURRENT_CONTEXT(ctx); 3687 teximage(ctx, GL_TRUE, 2, target, level, internalFormat, 3688 width, height, 1, border, GL_NONE, GL_NONE, imageSize, data); 3689} 3690 3691 3692void GLAPIENTRY 3693_mesa_CompressedTexImage3DARB(GLenum target, GLint level, 3694 GLenum internalFormat, GLsizei width, 3695 GLsizei height, GLsizei depth, GLint border, 3696 GLsizei imageSize, const GLvoid *data) 3697{ 3698 GET_CURRENT_CONTEXT(ctx); 3699 teximage(ctx, GL_TRUE, 3, target, level, internalFormat, 3700 width, height, depth, border, GL_NONE, GL_NONE, imageSize, data); 3701} 3702 3703 3704/** 3705 * Common helper for glCompressedTexSubImage1/2/3D(). 3706 */ 3707static void 3708compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, 3709 GLint xoffset, GLint yoffset, GLint zoffset, 3710 GLsizei width, GLsizei height, GLsizei depth, 3711 GLenum format, GLsizei imageSize, const GLvoid *data) 3712{ 3713 struct gl_texture_object *texObj; 3714 struct gl_texture_image *texImage; 3715 GLenum error; 3716 GET_CURRENT_CONTEXT(ctx); 3717 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3718 3719 error = compressed_subtexture_error_check(ctx, dims, target, level, 3720 xoffset, 0, 0, /* pos */ 3721 width, height, depth, /* size */ 3722 format, imageSize); 3723 if (error) { 3724 _mesa_error(ctx, error, "glCompressedTexSubImage%uD", dims); 3725 return; 3726 } 3727 3728 texObj = _mesa_get_current_tex_object(ctx, target); 3729 3730 _mesa_lock_texture(ctx, texObj); 3731 { 3732 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3733 assert(texImage); 3734 3735 if (compressed_subtexture_error_check2(ctx, dims, width, height, depth, 3736 format, texImage)) { 3737 /* error was recorded */ 3738 } 3739 else if (width > 0 && height > 0 && depth > 0) { 3740 ctx->Driver.CompressedTexSubImage(ctx, dims, texImage, 3741 xoffset, yoffset, zoffset, 3742 width, height, depth, 3743 format, imageSize, data); 3744 3745 check_gen_mipmap(ctx, target, texObj, level); 3746 3747 ctx->NewState |= _NEW_TEXTURE; 3748 } 3749 } 3750 _mesa_unlock_texture(ctx, texObj); 3751} 3752 3753 3754void GLAPIENTRY 3755_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, 3756 GLsizei width, GLenum format, 3757 GLsizei imageSize, const GLvoid *data) 3758{ 3759 compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1, 3760 format, imageSize, data); 3761} 3762 3763 3764void GLAPIENTRY 3765_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, 3766 GLint yoffset, GLsizei width, GLsizei height, 3767 GLenum format, GLsizei imageSize, 3768 const GLvoid *data) 3769{ 3770 compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0, 3771 width, height, 1, format, imageSize, data); 3772} 3773 3774 3775void GLAPIENTRY 3776_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, 3777 GLint yoffset, GLint zoffset, GLsizei width, 3778 GLsizei height, GLsizei depth, GLenum format, 3779 GLsizei imageSize, const GLvoid *data) 3780{ 3781 compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset, 3782 width, height, depth, format, imageSize, data); 3783} 3784 3785static gl_format 3786get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) 3787{ 3788 switch (internalFormat) { 3789 case GL_ALPHA8: 3790 return MESA_FORMAT_A8; 3791 case GL_ALPHA16: 3792 return MESA_FORMAT_A16; 3793 case GL_ALPHA16F_ARB: 3794 return MESA_FORMAT_ALPHA_FLOAT16; 3795 case GL_ALPHA32F_ARB: 3796 return MESA_FORMAT_ALPHA_FLOAT32; 3797 case GL_ALPHA8I_EXT: 3798 return MESA_FORMAT_ALPHA_INT8; 3799 case GL_ALPHA16I_EXT: 3800 return MESA_FORMAT_ALPHA_INT16; 3801 case GL_ALPHA32I_EXT: 3802 return MESA_FORMAT_ALPHA_INT32; 3803 case GL_ALPHA8UI_EXT: 3804 return MESA_FORMAT_ALPHA_UINT8; 3805 case GL_ALPHA16UI_EXT: 3806 return MESA_FORMAT_ALPHA_UINT16; 3807 case GL_ALPHA32UI_EXT: 3808 return MESA_FORMAT_ALPHA_UINT32; 3809 case GL_LUMINANCE8: 3810 return MESA_FORMAT_L8; 3811 case GL_LUMINANCE16: 3812 return MESA_FORMAT_L16; 3813 case GL_LUMINANCE16F_ARB: 3814 return MESA_FORMAT_LUMINANCE_FLOAT16; 3815 case GL_LUMINANCE32F_ARB: 3816 return MESA_FORMAT_LUMINANCE_FLOAT32; 3817 case GL_LUMINANCE8I_EXT: 3818 return MESA_FORMAT_LUMINANCE_INT8; 3819 case GL_LUMINANCE16I_EXT: 3820 return MESA_FORMAT_LUMINANCE_INT16; 3821 case GL_LUMINANCE32I_EXT: 3822 return MESA_FORMAT_LUMINANCE_INT32; 3823 case GL_LUMINANCE8UI_EXT: 3824 return MESA_FORMAT_LUMINANCE_UINT8; 3825 case GL_LUMINANCE16UI_EXT: 3826 return MESA_FORMAT_LUMINANCE_UINT16; 3827 case GL_LUMINANCE32UI_EXT: 3828 return MESA_FORMAT_LUMINANCE_UINT32; 3829 case GL_LUMINANCE8_ALPHA8: 3830 return MESA_FORMAT_AL88; 3831 case GL_LUMINANCE16_ALPHA16: 3832 return MESA_FORMAT_AL1616; 3833 case GL_LUMINANCE_ALPHA16F_ARB: 3834 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16; 3835 case GL_LUMINANCE_ALPHA32F_ARB: 3836 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32; 3837 case GL_LUMINANCE_ALPHA8I_EXT: 3838 return MESA_FORMAT_LUMINANCE_ALPHA_INT8; 3839 case GL_LUMINANCE_ALPHA16I_EXT: 3840 return MESA_FORMAT_LUMINANCE_ALPHA_INT8; 3841 case GL_LUMINANCE_ALPHA32I_EXT: 3842 return MESA_FORMAT_LUMINANCE_ALPHA_INT16; 3843 case GL_LUMINANCE_ALPHA8UI_EXT: 3844 return MESA_FORMAT_LUMINANCE_ALPHA_UINT8; 3845 case GL_LUMINANCE_ALPHA16UI_EXT: 3846 return MESA_FORMAT_LUMINANCE_ALPHA_UINT16; 3847 case GL_LUMINANCE_ALPHA32UI_EXT: 3848 return MESA_FORMAT_LUMINANCE_ALPHA_UINT32; 3849 case GL_INTENSITY8: 3850 return MESA_FORMAT_I8; 3851 case GL_INTENSITY16: 3852 return MESA_FORMAT_I16; 3853 case GL_INTENSITY16F_ARB: 3854 return MESA_FORMAT_INTENSITY_FLOAT16; 3855 case GL_INTENSITY32F_ARB: 3856 return MESA_FORMAT_INTENSITY_FLOAT32; 3857 case GL_INTENSITY8I_EXT: 3858 return MESA_FORMAT_INTENSITY_INT8; 3859 case GL_INTENSITY16I_EXT: 3860 return MESA_FORMAT_INTENSITY_INT16; 3861 case GL_INTENSITY32I_EXT: 3862 return MESA_FORMAT_INTENSITY_INT32; 3863 case GL_INTENSITY8UI_EXT: 3864 return MESA_FORMAT_INTENSITY_UINT8; 3865 case GL_INTENSITY16UI_EXT: 3866 return MESA_FORMAT_INTENSITY_UINT16; 3867 case GL_INTENSITY32UI_EXT: 3868 return MESA_FORMAT_INTENSITY_UINT32; 3869 case GL_RGBA8: 3870 return MESA_FORMAT_RGBA8888_REV; 3871 case GL_RGBA16: 3872 return MESA_FORMAT_RGBA_16; 3873 case GL_RGBA16F_ARB: 3874 return MESA_FORMAT_RGBA_FLOAT16; 3875 case GL_RGBA32F_ARB: 3876 return MESA_FORMAT_RGBA_FLOAT32; 3877 case GL_RGBA8I_EXT: 3878 return MESA_FORMAT_RGBA_INT8; 3879 case GL_RGBA16I_EXT: 3880 return MESA_FORMAT_RGBA_INT16; 3881 case GL_RGBA32I_EXT: 3882 return MESA_FORMAT_RGBA_INT32; 3883 case GL_RGBA8UI_EXT: 3884 return MESA_FORMAT_RGBA_UINT8; 3885 case GL_RGBA16UI_EXT: 3886 return MESA_FORMAT_RGBA_UINT16; 3887 case GL_RGBA32UI_EXT: 3888 return MESA_FORMAT_RGBA_UINT32; 3889 3890 case GL_RG8: 3891 return MESA_FORMAT_GR88; 3892 case GL_RG16: 3893 return MESA_FORMAT_RG1616; 3894 case GL_RG16F: 3895 return MESA_FORMAT_RG_FLOAT16; 3896 case GL_RG32F: 3897 return MESA_FORMAT_RG_FLOAT32; 3898 case GL_RG8I: 3899 return MESA_FORMAT_RG_INT8; 3900 case GL_RG16I: 3901 return MESA_FORMAT_RG_INT16; 3902 case GL_RG32I: 3903 return MESA_FORMAT_RG_INT32; 3904 case GL_RG8UI: 3905 return MESA_FORMAT_RG_UINT8; 3906 case GL_RG16UI: 3907 return MESA_FORMAT_RG_UINT16; 3908 case GL_RG32UI: 3909 return MESA_FORMAT_RG_UINT32; 3910 3911 case GL_R8: 3912 return MESA_FORMAT_R8; 3913 case GL_R16: 3914 return MESA_FORMAT_R16; 3915 case GL_R16F: 3916 return MESA_FORMAT_R_FLOAT16; 3917 case GL_R32F: 3918 return MESA_FORMAT_R_FLOAT32; 3919 case GL_R8I: 3920 return MESA_FORMAT_R_INT8; 3921 case GL_R16I: 3922 return MESA_FORMAT_R_INT16; 3923 case GL_R32I: 3924 return MESA_FORMAT_R_INT32; 3925 case GL_R8UI: 3926 return MESA_FORMAT_R_UINT8; 3927 case GL_R16UI: 3928 return MESA_FORMAT_R_UINT16; 3929 case GL_R32UI: 3930 return MESA_FORMAT_R_UINT32; 3931 3932 default: 3933 return MESA_FORMAT_NONE; 3934 } 3935} 3936 3937static gl_format 3938validate_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) 3939{ 3940 gl_format format = get_texbuffer_format(ctx, internalFormat); 3941 GLenum datatype; 3942 3943 if (format == MESA_FORMAT_NONE) 3944 return MESA_FORMAT_NONE; 3945 3946 datatype = _mesa_get_format_datatype(format); 3947 if (datatype == GL_FLOAT && !ctx->Extensions.ARB_texture_float) 3948 return MESA_FORMAT_NONE; 3949 3950 if (datatype == GL_HALF_FLOAT && !ctx->Extensions.ARB_half_float_pixel) 3951 return MESA_FORMAT_NONE; 3952 3953 /* The GL_ARB_texture_rg and GL_ARB_texture_buffer_object specs don't make 3954 * any mention of R/RG formats, but they appear in the GL 3.1 core 3955 * specification. 3956 */ 3957 if (ctx->Version <= 30) { 3958 GLenum base_format = _mesa_get_format_base_format(format); 3959 3960 if (base_format == GL_R || base_format == GL_RG) 3961 return MESA_FORMAT_NONE; 3962 } 3963 return format; 3964} 3965 3966 3967/** GL_ARB_texture_buffer_object */ 3968void GLAPIENTRY 3969_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer) 3970{ 3971 struct gl_texture_object *texObj; 3972 struct gl_buffer_object *bufObj; 3973 gl_format format; 3974 3975 GET_CURRENT_CONTEXT(ctx); 3976 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3977 3978 if (!ctx->Extensions.ARB_texture_buffer_object) { 3979 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer"); 3980 return; 3981 } 3982 3983 if (target != GL_TEXTURE_BUFFER_ARB) { 3984 _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)"); 3985 return; 3986 } 3987 3988 format = validate_texbuffer_format(ctx, internalFormat); 3989 if (format == MESA_FORMAT_NONE) { 3990 _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(internalFormat 0x%x)", 3991 internalFormat); 3992 return; 3993 } 3994 3995 bufObj = _mesa_lookup_bufferobj(ctx, buffer); 3996 if (buffer && !bufObj) { 3997 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer(buffer %u)", buffer); 3998 return; 3999 } 4000 4001 texObj = _mesa_get_current_tex_object(ctx, target); 4002 4003 _mesa_lock_texture(ctx, texObj); 4004 { 4005 _mesa_reference_buffer_object(ctx, &texObj->BufferObject, bufObj); 4006 texObj->BufferObjectFormat = internalFormat; 4007 texObj->_BufferObjectFormat = format; 4008 } 4009 _mesa_unlock_texture(ctx, texObj); 4010} 4011