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