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