teximage.c revision 3c59febf05e6af80d63e5b9a478a11b275ac429c
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#if 000 /* not used anymore */ 892/* 893 * glTexImage[123]D can accept a NULL image pointer. In this case we 894 * create a texture image with unspecified image contents per the OpenGL 895 * spec. 896 */ 897static GLubyte * 898make_null_texture(GLint width, GLint height, GLint depth, GLenum format) 899{ 900 const GLint components = _mesa_components_in_format(format); 901 const GLint numPixels = width * height * depth; 902 GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte)); 903 904#ifdef DEBUG 905 /* 906 * Let's see if anyone finds this. If glTexImage2D() is called with 907 * a NULL image pointer then load the texture image with something 908 * interesting instead of leaving it indeterminate. 909 */ 910 if (data) { 911 static const char message[8][32] = { 912 " X X XXXXX XXX X ", 913 " XX XX X X X X X ", 914 " X X X X X X X ", 915 " X X XXXX XXX XXXXX ", 916 " X X X X X X ", 917 " X X X X X X X ", 918 " X X XXXXX XXX X X ", 919 " " 920 }; 921 922 GLubyte *imgPtr = data; 923 GLint h, i, j, k; 924 for (h = 0; h < depth; h++) { 925 for (i = 0; i < height; i++) { 926 GLint srcRow = 7 - (i % 8); 927 for (j = 0; j < width; j++) { 928 GLint srcCol = j % 32; 929 GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70; 930 for (k = 0; k < components; k++) { 931 *imgPtr++ = texel; 932 } 933 } 934 } 935 } 936 } 937#endif 938 939 return data; 940} 941#endif 942 943 944 945/** 946 * Reset the fields of a gl_texture_image struct to zero. 947 * 948 * \param img texture image structure. 949 * 950 * This is called when a proxy texture test fails, we set all the 951 * image members (except DriverData) to zero. 952 * It's also used in glTexImage[123]D as a safeguard to be sure all 953 * required fields get initialized properly by the Driver.TexImage[123]D 954 * functions. 955 */ 956static void 957clear_teximage_fields(struct gl_texture_image *img) 958{ 959 ASSERT(img); 960 img->_BaseFormat = 0; 961 img->InternalFormat = 0; 962 img->Border = 0; 963 img->Width = 0; 964 img->Height = 0; 965 img->Depth = 0; 966 img->RowStride = 0; 967 if (img->ImageOffsets) { 968 free(img->ImageOffsets); 969 img->ImageOffsets = NULL; 970 } 971 img->Width2 = 0; 972 img->Height2 = 0; 973 img->Depth2 = 0; 974 img->WidthLog2 = 0; 975 img->HeightLog2 = 0; 976 img->DepthLog2 = 0; 977 img->Data = NULL; 978 img->TexFormat = MESA_FORMAT_NONE; 979 img->FetchTexelc = NULL; 980 img->FetchTexelf = NULL; 981} 982 983 984/** 985 * Initialize basic fields of the gl_texture_image struct. 986 * 987 * \param ctx GL context. 988 * \param target texture target (GL_TEXTURE_1D, GL_TEXTURE_RECTANGLE, etc). 989 * \param img texture image structure to be initialized. 990 * \param width image width. 991 * \param height image height. 992 * \param depth image depth. 993 * \param border image border. 994 * \param internalFormat internal format. 995 * 996 * Fills in the fields of \p img with the given information. 997 * Note: width, height and depth include the border. 998 */ 999void 1000_mesa_init_teximage_fields(struct gl_context *ctx, GLenum target, 1001 struct gl_texture_image *img, 1002 GLsizei width, GLsizei height, GLsizei depth, 1003 GLint border, GLenum internalFormat) 1004{ 1005 GLint i; 1006 1007 ASSERT(img); 1008 ASSERT(width >= 0); 1009 ASSERT(height >= 0); 1010 ASSERT(depth >= 0); 1011 1012 img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat ); 1013 ASSERT(img->_BaseFormat > 0); 1014 img->InternalFormat = internalFormat; 1015 img->Border = border; 1016 img->Width = width; 1017 img->Height = height; 1018 img->Depth = depth; 1019 1020 img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */ 1021 img->WidthLog2 = logbase2(img->Width2); 1022 1023 if (height == 1) { /* 1-D texture */ 1024 img->Height2 = 1; 1025 img->HeightLog2 = 0; 1026 } 1027 else { 1028 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ 1029 img->HeightLog2 = logbase2(img->Height2); 1030 } 1031 1032 if (depth == 1) { /* 2-D texture */ 1033 img->Depth2 = 1; 1034 img->DepthLog2 = 0; 1035 } 1036 else { 1037 img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ 1038 img->DepthLog2 = logbase2(img->Depth2); 1039 } 1040 1041 img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); 1042 1043 if ((width == 1 || _mesa_is_pow_two(img->Width2)) && 1044 (height == 1 || _mesa_is_pow_two(img->Height2)) && 1045 (depth == 1 || _mesa_is_pow_two(img->Depth2))) 1046 img->_IsPowerOfTwo = GL_TRUE; 1047 else 1048 img->_IsPowerOfTwo = GL_FALSE; 1049 1050 /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */ 1051 img->RowStride = width; 1052 /* Allocate the ImageOffsets array and initialize to typical values. 1053 * We allocate the array for 1D/2D textures too in order to avoid special- 1054 * case code in the texstore routines. 1055 */ 1056 if (img->ImageOffsets) 1057 free(img->ImageOffsets); 1058 img->ImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint)); 1059 for (i = 0; i < depth; i++) { 1060 img->ImageOffsets[i] = i * width * height; 1061 } 1062 1063 /* Compute Width/Height/DepthScale for mipmap lod computation */ 1064 if (target == GL_TEXTURE_RECTANGLE_NV) { 1065 /* scale = 1.0 since texture coords directly map to texels */ 1066 img->WidthScale = 1.0; 1067 img->HeightScale = 1.0; 1068 img->DepthScale = 1.0; 1069 } 1070 else { 1071 img->WidthScale = (GLfloat) img->Width; 1072 img->HeightScale = (GLfloat) img->Height; 1073 img->DepthScale = (GLfloat) img->Depth; 1074 } 1075 1076 img->FetchTexelc = NULL; 1077 img->FetchTexelf = NULL; 1078} 1079 1080 1081/** 1082 * Free and clear fields of the gl_texture_image struct. 1083 * 1084 * \param ctx GL context. 1085 * \param texImage texture image structure to be cleared. 1086 * 1087 * After the call, \p texImage will have no data associated with it. Its 1088 * fields are cleared so that its parent object will test incomplete. 1089 */ 1090void 1091_mesa_clear_texture_image(struct gl_context *ctx, 1092 struct gl_texture_image *texImage) 1093{ 1094 ctx->Driver.FreeTexImageData(ctx, texImage); 1095 clear_teximage_fields(texImage); 1096} 1097 1098 1099/** 1100 * This is the fallback for Driver.TestProxyTexImage(). Test the texture 1101 * level, width, height and depth against the ctx->Const limits for textures. 1102 * 1103 * A hardware driver might override this function if, for example, the 1104 * max 3D texture size is 512x512x64 (i.e. not a cube). 1105 * 1106 * Note that width, height, depth == 0 is not an error. However, a 1107 * texture with zero width/height/depth will be considered "incomplete" 1108 * and texturing will effectively be disabled. 1109 * 1110 * \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D, 1111 * GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV, 1112 * GL_PROXY_TEXTURE_CUBE_MAP_ARB. 1113 * \param level as passed to glTexImage 1114 * \param internalFormat as passed to glTexImage 1115 * \param format as passed to glTexImage 1116 * \param type as passed to glTexImage 1117 * \param width as passed to glTexImage 1118 * \param height as passed to glTexImage 1119 * \param depth as passed to glTexImage 1120 * \param border as passed to glTexImage 1121 * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable. 1122 */ 1123GLboolean 1124_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level, 1125 GLint internalFormat, GLenum format, GLenum type, 1126 GLint width, GLint height, GLint depth, GLint border) 1127{ 1128 GLint maxSize; 1129 1130 (void) internalFormat; 1131 (void) format; 1132 (void) type; 1133 1134 switch (target) { 1135 case GL_PROXY_TEXTURE_1D: 1136 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1137 if (width < 2 * border || width > 2 + maxSize || 1138 (!ctx->Extensions.ARB_texture_non_power_of_two && 1139 width >0 && !_mesa_is_pow_two(width - 2 * border)) || 1140 level >= ctx->Const.MaxTextureLevels) { 1141 /* bad width or level */ 1142 return GL_FALSE; 1143 } 1144 return GL_TRUE; 1145 case GL_PROXY_TEXTURE_2D: 1146 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1147 if (width < 2 * border || width > 2 + maxSize || 1148 (!ctx->Extensions.ARB_texture_non_power_of_two && 1149 width > 0 && !_mesa_is_pow_two(width - 2 * border)) || 1150 height < 2 * border || height > 2 + maxSize || 1151 (!ctx->Extensions.ARB_texture_non_power_of_two && 1152 height > 0 && !_mesa_is_pow_two(height - 2 * border)) || 1153 level >= ctx->Const.MaxTextureLevels) { 1154 /* bad width or height or level */ 1155 return GL_FALSE; 1156 } 1157 return GL_TRUE; 1158 case GL_PROXY_TEXTURE_3D: 1159 maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1); 1160 if (width < 2 * border || width > 2 + maxSize || 1161 (!ctx->Extensions.ARB_texture_non_power_of_two && 1162 width > 0 && !_mesa_is_pow_two(width - 2 * border)) || 1163 height < 2 * border || height > 2 + maxSize || 1164 (!ctx->Extensions.ARB_texture_non_power_of_two && 1165 height > 0 && !_mesa_is_pow_two(height - 2 * border)) || 1166 depth < 2 * border || depth > 2 + maxSize || 1167 (!ctx->Extensions.ARB_texture_non_power_of_two && 1168 depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) || 1169 level >= ctx->Const.Max3DTextureLevels) { 1170 /* bad width or height or depth or level */ 1171 return GL_FALSE; 1172 } 1173 return GL_TRUE; 1174 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1175 if (width < 0 || width > ctx->Const.MaxTextureRectSize || 1176 height < 0 || height > ctx->Const.MaxTextureRectSize || 1177 level != 0) { 1178 /* bad width or height or level */ 1179 return GL_FALSE; 1180 } 1181 return GL_TRUE; 1182 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 1183 maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1); 1184 if (width < 2 * border || width > 2 + maxSize || 1185 (!ctx->Extensions.ARB_texture_non_power_of_two && 1186 width > 0 && !_mesa_is_pow_two(width - 2 * border)) || 1187 height < 2 * border || height > 2 + maxSize || 1188 (!ctx->Extensions.ARB_texture_non_power_of_two && 1189 height > 0 && !_mesa_is_pow_two(height - 2 * border)) || 1190 level >= ctx->Const.MaxCubeTextureLevels) { 1191 /* bad width or height */ 1192 return GL_FALSE; 1193 } 1194 return GL_TRUE; 1195 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1196 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1197 if (width < 2 * border || width > 2 + maxSize || 1198 (!ctx->Extensions.ARB_texture_non_power_of_two && 1199 width > 0 && !_mesa_is_pow_two(width - 2 * border)) || 1200 level >= ctx->Const.MaxTextureLevels) { 1201 /* bad width or level */ 1202 return GL_FALSE; 1203 } 1204 1205 if (height < 1 || height > ctx->Const.MaxArrayTextureLayers) { 1206 return GL_FALSE; 1207 } 1208 return GL_TRUE; 1209 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1210 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); 1211 if (width < 2 * border || width > 2 + maxSize || 1212 (!ctx->Extensions.ARB_texture_non_power_of_two && 1213 width > 0 && !_mesa_is_pow_two(width - 2 * border)) || 1214 height < 2 * border || height > 2 + maxSize || 1215 (!ctx->Extensions.ARB_texture_non_power_of_two && 1216 height > 0 && !_mesa_is_pow_two(height - 2 * border)) || 1217 level >= ctx->Const.MaxTextureLevels) { 1218 /* bad width or height or level */ 1219 return GL_FALSE; 1220 } 1221 if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers) { 1222 return GL_FALSE; 1223 } 1224 return GL_TRUE; 1225 default: 1226 _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage"); 1227 return GL_FALSE; 1228 } 1229} 1230 1231 1232/** 1233 * Helper function to determine whether a target supports compressed textures 1234 */ 1235static GLboolean 1236target_can_be_compressed(struct gl_context *ctx, GLenum target) 1237{ 1238 switch (target) { 1239 case GL_TEXTURE_2D: 1240 case GL_PROXY_TEXTURE_2D: 1241 return GL_TRUE; 1242 case GL_PROXY_TEXTURE_CUBE_MAP: 1243 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1244 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1245 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1246 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1247 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1248 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1249 return ctx->Extensions.ARB_texture_cube_map; 1250 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1251 case GL_TEXTURE_2D_ARRAY_EXT: 1252 return ctx->Extensions.MESA_texture_array; 1253 default: 1254 return GL_FALSE; 1255 } 1256} 1257 1258 1259/** 1260 * Test the glTexImage[123]D() parameters for errors. 1261 * 1262 * \param ctx GL context. 1263 * \param target texture target given by the user. 1264 * \param level image level given by the user. 1265 * \param internalFormat internal format given by the user. 1266 * \param format pixel data format given by the user. 1267 * \param type pixel data type given by the user. 1268 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1269 * \param width image width given by the user. 1270 * \param height image height given by the user. 1271 * \param depth image depth given by the user. 1272 * \param border image border given by the user. 1273 * 1274 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 1275 * 1276 * Verifies each of the parameters against the constants specified in 1277 * __struct gl_contextRec::Const and the supported extensions, and according 1278 * to the OpenGL specification. 1279 */ 1280static GLboolean 1281texture_error_check( struct gl_context *ctx, GLenum target, 1282 GLint level, GLint internalFormat, 1283 GLenum format, GLenum type, 1284 GLuint dimensions, 1285 GLint width, GLint height, 1286 GLint depth, GLint border ) 1287{ 1288 const GLboolean isProxy = _mesa_is_proxy_texture(target); 1289 GLboolean sizeOK = GL_TRUE; 1290 GLboolean colorFormat, indexFormat; 1291 GLenum proxy_target; 1292 1293 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ 1294 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1295 if (!isProxy) { 1296 _mesa_error(ctx, GL_INVALID_VALUE, 1297 "glTexImage%dD(level=%d)", dimensions, level); 1298 } 1299 return GL_TRUE; 1300 } 1301 1302 /* Check border */ 1303 if (border < 0 || border > 1 || 1304 ((target == GL_TEXTURE_RECTANGLE_NV || 1305 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 1306 if (!isProxy) { 1307 _mesa_error(ctx, GL_INVALID_VALUE, 1308 "glTexImage%dD(border=%d)", dimensions, border); 1309 } 1310 return GL_TRUE; 1311 } 1312 1313 if (width < 0 || height < 0 || depth < 0) { 1314 if (!isProxy) { 1315 _mesa_error(ctx, GL_INVALID_VALUE, 1316 "glTexImage%dD(width, height or depth < 0)", dimensions); 1317 } 1318 return GL_TRUE; 1319 } 1320 1321 /* Check target and call ctx->Driver.TestProxyTexImage() to check the 1322 * level, width, height and depth. 1323 */ 1324 if (dimensions == 1) { 1325 if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) { 1326 proxy_target = GL_PROXY_TEXTURE_1D; 1327 height = 1; 1328 depth = 1; 1329 } 1330 else { 1331 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); 1332 return GL_TRUE; 1333 } 1334 } 1335 else if (dimensions == 2) { 1336 depth = 1; 1337 if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) { 1338 proxy_target = GL_PROXY_TEXTURE_2D; 1339 } 1340 else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB || 1341 (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1342 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { 1343 if (!ctx->Extensions.ARB_texture_cube_map) { 1344 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); 1345 return GL_TRUE; 1346 } 1347 proxy_target = GL_PROXY_TEXTURE_CUBE_MAP_ARB; 1348 sizeOK = (width == height); 1349 } 1350 else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV || 1351 target == GL_TEXTURE_RECTANGLE_NV) { 1352 if (!ctx->Extensions.NV_texture_rectangle) { 1353 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); 1354 return GL_TRUE; 1355 } 1356 proxy_target = GL_PROXY_TEXTURE_RECTANGLE_NV; 1357 } 1358 else if (target == GL_PROXY_TEXTURE_1D_ARRAY_EXT || 1359 target == GL_TEXTURE_1D_ARRAY_EXT) { 1360 proxy_target = GL_PROXY_TEXTURE_1D_ARRAY_EXT; 1361 } 1362 else { 1363 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); 1364 return GL_TRUE; 1365 } 1366 } 1367 else if (dimensions == 3) { 1368 if (target == GL_PROXY_TEXTURE_3D || target == GL_TEXTURE_3D) { 1369 proxy_target = GL_PROXY_TEXTURE_3D; 1370 } 1371 else if (target == GL_PROXY_TEXTURE_2D_ARRAY_EXT || 1372 target == GL_TEXTURE_2D_ARRAY_EXT) { 1373 proxy_target = GL_PROXY_TEXTURE_2D_ARRAY_EXT; 1374 } 1375 else { 1376 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); 1377 return GL_TRUE; 1378 } 1379 } 1380 else { 1381 _mesa_problem( ctx, "bad dims in texture_error_check" ); 1382 return GL_TRUE; 1383 } 1384 1385 sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxy_target, level, 1386 internalFormat, format, 1387 type, width, height, 1388 depth, border); 1389 if (!sizeOK) { 1390 if (!isProxy) { 1391 _mesa_error(ctx, GL_INVALID_VALUE, 1392 "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)", 1393 dimensions, level, width, height, depth); 1394 } 1395 return GL_TRUE; 1396 } 1397 1398 /* Check internalFormat */ 1399 if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 1400 if (!isProxy) { 1401 _mesa_error(ctx, GL_INVALID_VALUE, 1402 "glTexImage%dD(internalFormat=%s)", 1403 dimensions, _mesa_lookup_enum_by_nr(internalFormat)); 1404 } 1405 return GL_TRUE; 1406 } 1407 1408 /* Check incoming image format and type */ 1409 if (!_mesa_is_legal_format_and_type(ctx, format, type)) { 1410 /* Normally, GL_INVALID_OPERATION is generated by a format/type 1411 * mismatch (see the 1.2 spec page 94, sec 3.6.4.). But with the 1412 * GL_EXT_texture_integer extension, some combinations should generate 1413 * GL_INVALID_ENUM instead (grr!). 1414 */ 1415 if (!isProxy) { 1416 GLenum error = _mesa_is_integer_format(format) 1417 ? GL_INVALID_ENUM : GL_INVALID_OPERATION; 1418 _mesa_error(ctx, error, 1419 "glTexImage%dD(incompatible format 0x%x, type 0x%x)", 1420 dimensions, format, type); 1421 } 1422 return GL_TRUE; 1423 } 1424 1425 /* make sure internal format and format basically agree */ 1426 colorFormat = _mesa_is_color_format(format); 1427 indexFormat = _mesa_is_index_format(format); 1428 if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) || 1429 (_mesa_is_index_format(internalFormat) && !indexFormat) || 1430 (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) || 1431 (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) || 1432 (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) || 1433 (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) { 1434 if (!isProxy) 1435 _mesa_error(ctx, GL_INVALID_OPERATION, 1436 "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)", 1437 dimensions, internalFormat, format); 1438 return GL_TRUE; 1439 } 1440 1441 /* additional checks for ycbcr textures */ 1442 if (internalFormat == GL_YCBCR_MESA) { 1443 ASSERT(ctx->Extensions.MESA_ycbcr_texture); 1444 if (type != GL_UNSIGNED_SHORT_8_8_MESA && 1445 type != GL_UNSIGNED_SHORT_8_8_REV_MESA) { 1446 char message[100]; 1447 _mesa_snprintf(message, sizeof(message), 1448 "glTexImage%dD(format/type YCBCR mismatch", dimensions); 1449 _mesa_error(ctx, GL_INVALID_ENUM, "%s", message); 1450 return GL_TRUE; /* error */ 1451 } 1452 if (target != GL_TEXTURE_2D && 1453 target != GL_PROXY_TEXTURE_2D && 1454 target != GL_TEXTURE_RECTANGLE_NV && 1455 target != GL_PROXY_TEXTURE_RECTANGLE_NV) { 1456 if (!isProxy) 1457 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)"); 1458 return GL_TRUE; 1459 } 1460 if (border != 0) { 1461 if (!isProxy) { 1462 char message[100]; 1463 _mesa_snprintf(message, sizeof(message), 1464 "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)", 1465 dimensions, border); 1466 _mesa_error(ctx, GL_INVALID_VALUE, "%s", message); 1467 } 1468 return GL_TRUE; 1469 } 1470 } 1471 1472 /* additional checks for depth textures */ 1473 if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) { 1474 /* Only 1D, 2D and rectangular textures supported, not 3D or cubes */ 1475 if (target != GL_TEXTURE_1D && 1476 target != GL_PROXY_TEXTURE_1D && 1477 target != GL_TEXTURE_2D && 1478 target != GL_PROXY_TEXTURE_2D && 1479 target != GL_TEXTURE_RECTANGLE_ARB && 1480 target != GL_PROXY_TEXTURE_RECTANGLE_ARB) { 1481 if (!isProxy) 1482 _mesa_error(ctx, GL_INVALID_ENUM, 1483 "glTexImage(target/internalFormat)"); 1484 return GL_TRUE; 1485 } 1486 } 1487 1488 /* additional checks for compressed textures */ 1489 if (_mesa_is_compressed_format(ctx, internalFormat)) { 1490 if (!target_can_be_compressed(ctx, target) && !isProxy) { 1491 _mesa_error(ctx, GL_INVALID_ENUM, 1492 "glTexImage%dD(target)", dimensions); 1493 return GL_TRUE; 1494 } 1495 if (border != 0) { 1496 if (!isProxy) { 1497 _mesa_error(ctx, GL_INVALID_OPERATION, 1498 "glTexImage%dD(border!=0)", dimensions); 1499 } 1500 return GL_TRUE; 1501 } 1502 } 1503 1504 /* additional checks for integer textures */ 1505 if (ctx->Extensions.EXT_texture_integer && 1506 (_mesa_is_integer_format(format) != 1507 _mesa_is_integer_format(internalFormat))) { 1508 if (!isProxy) { 1509 _mesa_error(ctx, GL_INVALID_OPERATION, 1510 "glTexImage%dD(integer/non-integer format mismatch)", 1511 dimensions); 1512 } 1513 return GL_TRUE; 1514 } 1515 1516 /* if we get here, the parameters are OK */ 1517 return GL_FALSE; 1518} 1519 1520 1521/** 1522 * Test glTexSubImage[123]D() parameters for errors. 1523 * 1524 * \param ctx GL context. 1525 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1526 * \param target texture target given by the user. 1527 * \param level image level given by the user. 1528 * \param xoffset sub-image x offset given by the user. 1529 * \param yoffset sub-image y offset given by the user. 1530 * \param zoffset sub-image z offset given by the user. 1531 * \param format pixel data format given by the user. 1532 * \param type pixel data type given by the user. 1533 * \param width image width given by the user. 1534 * \param height image height given by the user. 1535 * \param depth image depth given by the user. 1536 * 1537 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 1538 * 1539 * Verifies each of the parameters against the constants specified in 1540 * __struct gl_contextRec::Const and the supported extensions, and according 1541 * to the OpenGL specification. 1542 */ 1543static GLboolean 1544subtexture_error_check( struct gl_context *ctx, GLuint dimensions, 1545 GLenum target, GLint level, 1546 GLint xoffset, GLint yoffset, GLint zoffset, 1547 GLint width, GLint height, GLint depth, 1548 GLenum format, GLenum type ) 1549{ 1550 /* Check target */ 1551 if (dimensions == 1) { 1552 if (target != GL_TEXTURE_1D) { 1553 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" ); 1554 return GL_TRUE; 1555 } 1556 } 1557 else if (dimensions == 2) { 1558 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1559 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 1560 if (!ctx->Extensions.ARB_texture_cube_map) { 1561 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); 1562 return GL_TRUE; 1563 } 1564 } 1565 else if (target == GL_TEXTURE_RECTANGLE_NV) { 1566 if (!ctx->Extensions.NV_texture_rectangle) { 1567 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); 1568 return GL_TRUE; 1569 } 1570 } 1571 else if (target == GL_TEXTURE_1D_ARRAY_EXT) { 1572 if (!ctx->Extensions.MESA_texture_array) { 1573 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); 1574 return GL_TRUE; 1575 } 1576 } 1577 else if (target != GL_TEXTURE_2D) { 1578 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); 1579 return GL_TRUE; 1580 } 1581 } 1582 else if (dimensions == 3) { 1583 if (target == GL_TEXTURE_2D_ARRAY_EXT) { 1584 if (!ctx->Extensions.MESA_texture_array) { 1585 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" ); 1586 return GL_TRUE; 1587 } 1588 } 1589 else if (target != GL_TEXTURE_3D) { 1590 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" ); 1591 return GL_TRUE; 1592 } 1593 } 1594 else { 1595 _mesa_problem( ctx, "invalid dims in texture_error_check" ); 1596 return GL_TRUE; 1597 } 1598 1599 /* Basic level check */ 1600 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1601 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level); 1602 return GL_TRUE; 1603 } 1604 1605 if (width < 0) { 1606 _mesa_error(ctx, GL_INVALID_VALUE, 1607 "glTexSubImage%dD(width=%d)", dimensions, width); 1608 return GL_TRUE; 1609 } 1610 if (height < 0 && dimensions > 1) { 1611 _mesa_error(ctx, GL_INVALID_VALUE, 1612 "glTexSubImage%dD(height=%d)", dimensions, height); 1613 return GL_TRUE; 1614 } 1615 if (depth < 0 && dimensions > 2) { 1616 _mesa_error(ctx, GL_INVALID_VALUE, 1617 "glTexSubImage%dD(depth=%d)", dimensions, depth); 1618 return GL_TRUE; 1619 } 1620 1621 if (!_mesa_is_legal_format_and_type(ctx, format, type)) { 1622 /* As with the glTexImage2D check above, the error code here 1623 * depends on texture integer. 1624 */ 1625 GLenum error = _mesa_is_integer_format(format) 1626 ? GL_INVALID_OPERATION : GL_INVALID_ENUM; 1627 _mesa_error(ctx, error, 1628 "glTexSubImage%dD(incompatible format 0x%x, type 0x%x)", 1629 dimensions, format, type); 1630 return GL_TRUE; 1631 } 1632 1633 return GL_FALSE; 1634} 1635 1636 1637/** 1638 * Do second part of glTexSubImage which depends on the destination texture. 1639 * \return GL_TRUE if error recorded, GL_FALSE otherwise 1640 */ 1641static GLboolean 1642subtexture_error_check2( struct gl_context *ctx, GLuint dimensions, 1643 GLenum target, GLint level, 1644 GLint xoffset, GLint yoffset, GLint zoffset, 1645 GLint width, GLint height, GLint depth, 1646 GLenum format, GLenum type, 1647 const struct gl_texture_image *destTex ) 1648{ 1649 if (!destTex) { 1650 /* undefined image level */ 1651 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions); 1652 return GL_TRUE; 1653 } 1654 1655 if (xoffset < -((GLint)destTex->Border)) { 1656 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)", 1657 dimensions); 1658 return GL_TRUE; 1659 } 1660 if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) { 1661 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)", 1662 dimensions); 1663 return GL_TRUE; 1664 } 1665 if (dimensions > 1) { 1666 if (yoffset < -((GLint)destTex->Border)) { 1667 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)", 1668 dimensions); 1669 return GL_TRUE; 1670 } 1671 if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) { 1672 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)", 1673 dimensions); 1674 return GL_TRUE; 1675 } 1676 } 1677 if (dimensions > 2) { 1678 if (zoffset < -((GLint)destTex->Border)) { 1679 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)"); 1680 return GL_TRUE; 1681 } 1682 if (zoffset + depth > (GLint) (destTex->Depth + destTex->Border)) { 1683 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)"); 1684 return GL_TRUE; 1685 } 1686 } 1687 1688 if (_mesa_is_format_compressed(destTex->TexFormat)) { 1689 GLuint bw, bh; 1690 1691 if (!target_can_be_compressed(ctx, target)) { 1692 _mesa_error(ctx, GL_INVALID_ENUM, 1693 "glTexSubImage%dD(target=%s)", dimensions, 1694 _mesa_lookup_enum_by_nr(target)); 1695 return GL_TRUE; 1696 } 1697 1698 /* do tests which depend on compression block size */ 1699 _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh); 1700 1701 /* offset must be multiple of block size */ 1702 if ((xoffset % bw != 0) || (yoffset % bh != 0)) { 1703 _mesa_error(ctx, GL_INVALID_OPERATION, 1704 "glTexSubImage%dD(xoffset = %d, yoffset = %d)", 1705 dimensions, xoffset, yoffset); 1706 return GL_TRUE; 1707 } 1708 /* size must be multiple of bw by bh or equal to whole texture size */ 1709 if ((width % bw != 0) && (GLuint) width != destTex->Width) { 1710 _mesa_error(ctx, GL_INVALID_OPERATION, 1711 "glTexSubImage%dD(width = %d)", dimensions, width); 1712 return GL_TRUE; 1713 } 1714 if ((height % bh != 0) && (GLuint) height != destTex->Height) { 1715 _mesa_error(ctx, GL_INVALID_OPERATION, 1716 "glTexSubImage%dD(height = %d)", dimensions, height); 1717 return GL_TRUE; 1718 } 1719 } 1720 1721 return GL_FALSE; 1722} 1723 1724 1725/** 1726 * Test glCopyTexImage[12]D() parameters for errors. 1727 * 1728 * \param ctx GL context. 1729 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1730 * \param target texture target given by the user. 1731 * \param level image level given by the user. 1732 * \param internalFormat internal format given by the user. 1733 * \param width image width given by the user. 1734 * \param height image height given by the user. 1735 * \param border texture border. 1736 * 1737 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 1738 * 1739 * Verifies each of the parameters against the constants specified in 1740 * __struct gl_contextRec::Const and the supported extensions, and according 1741 * to the OpenGL specification. 1742 */ 1743static GLboolean 1744copytexture_error_check( struct gl_context *ctx, GLuint dimensions, 1745 GLenum target, GLint level, GLint internalFormat, 1746 GLint width, GLint height, GLint border ) 1747{ 1748 GLenum type; 1749 GLboolean sizeOK; 1750 GLint format; 1751 1752 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ 1753 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1754 _mesa_error(ctx, GL_INVALID_VALUE, 1755 "glCopyTexImage%dD(level=%d)", dimensions, level); 1756 return GL_TRUE; 1757 } 1758 1759 /* Check that the source buffer is complete */ 1760 if (ctx->ReadBuffer->Name) { 1761 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 1762 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 1763 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 1764 "glCopyTexImage%dD(invalid readbuffer)", dimensions); 1765 return GL_TRUE; 1766 } 1767 } 1768 1769 /* Check border */ 1770 if (border < 0 || border > 1 || 1771 ((target == GL_TEXTURE_RECTANGLE_NV || 1772 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 1773 return GL_TRUE; 1774 } 1775 1776 format = _mesa_base_tex_format(ctx, internalFormat); 1777 if (format < 0) { 1778 _mesa_error(ctx, GL_INVALID_VALUE, 1779 "glCopyTexImage%dD(internalFormat)", dimensions); 1780 return GL_TRUE; 1781 } 1782 1783 if (!_mesa_source_buffer_exists(ctx, format)) { 1784 _mesa_error(ctx, GL_INVALID_OPERATION, 1785 "glCopyTexImage%dD(missing readbuffer)", dimensions); 1786 return GL_TRUE; 1787 } 1788 1789 /* NOTE: the format and type aren't really significant for 1790 * TestProxyTexImage(). Only the internalformat really matters. 1791 */ 1792 type = GL_FLOAT; 1793 1794 /* Check target and call ctx->Driver.TestProxyTexImage() to check the 1795 * level, width, height and depth. 1796 */ 1797 if (dimensions == 1) { 1798 if (target == GL_TEXTURE_1D) { 1799 sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_1D, 1800 level, internalFormat, 1801 format, type, 1802 width, 1, 1, border); 1803 } 1804 else { 1805 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" ); 1806 return GL_TRUE; 1807 } 1808 } 1809 else if (dimensions == 2) { 1810 if (target == GL_TEXTURE_2D) { 1811 sizeOK = ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_2D, 1812 level, internalFormat, 1813 format, type, 1814 width, height, 1, border); 1815 } 1816 else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1817 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 1818 if (!ctx->Extensions.ARB_texture_cube_map) { 1819 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); 1820 return GL_TRUE; 1821 } 1822 sizeOK = (width == height) && 1823 ctx->Driver.TestProxyTexImage(ctx, GL_PROXY_TEXTURE_CUBE_MAP_ARB, 1824 level, internalFormat, format, type, 1825 width, height, 1, border); 1826 } 1827 else if (target == GL_TEXTURE_RECTANGLE_NV) { 1828 if (!ctx->Extensions.NV_texture_rectangle) { 1829 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); 1830 return GL_TRUE; 1831 } 1832 sizeOK = ctx->Driver.TestProxyTexImage(ctx, 1833 GL_PROXY_TEXTURE_RECTANGLE_NV, 1834 level, internalFormat, 1835 format, type, 1836 width, height, 1, border); 1837 } 1838 else if (target == GL_TEXTURE_1D_ARRAY_EXT) { 1839 if (!ctx->Extensions.MESA_texture_array) { 1840 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)"); 1841 return GL_TRUE; 1842 } 1843 sizeOK = ctx->Driver.TestProxyTexImage(ctx, 1844 GL_PROXY_TEXTURE_1D_ARRAY_EXT, 1845 level, internalFormat, 1846 format, type, 1847 width, height, 1, border); 1848 } 1849 else { 1850 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); 1851 return GL_TRUE; 1852 } 1853 } 1854 else { 1855 _mesa_problem(ctx, "invalid dimensions in copytexture_error_check"); 1856 return GL_TRUE; 1857 } 1858 1859 if (!sizeOK) { 1860 if (dimensions == 1) { 1861 _mesa_error(ctx, GL_INVALID_VALUE, 1862 "glCopyTexImage1D(width=%d)", width); 1863 } 1864 else { 1865 ASSERT(dimensions == 2); 1866 _mesa_error(ctx, GL_INVALID_VALUE, 1867 "glCopyTexImage2D(width=%d, height=%d)", width, height); 1868 } 1869 return GL_TRUE; 1870 } 1871 1872 if (_mesa_is_compressed_format(ctx, internalFormat)) { 1873 if (!target_can_be_compressed(ctx, target)) { 1874 _mesa_error(ctx, GL_INVALID_ENUM, 1875 "glCopyTexImage%dD(target)", dimensions); 1876 return GL_TRUE; 1877 } 1878 if (border != 0) { 1879 _mesa_error(ctx, GL_INVALID_OPERATION, 1880 "glCopyTexImage%dD(border!=0)", dimensions); 1881 return GL_TRUE; 1882 } 1883 } 1884 else if (_mesa_is_depth_format(internalFormat)) { 1885 /* make sure we have depth/stencil buffers */ 1886 if (!ctx->ReadBuffer->_DepthBuffer) { 1887 _mesa_error(ctx, GL_INVALID_OPERATION, 1888 "glCopyTexImage%dD(no depth)", dimensions); 1889 return GL_TRUE; 1890 } 1891 } 1892 else if (_mesa_is_depthstencil_format(internalFormat)) { 1893 /* make sure we have depth/stencil buffers */ 1894 if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) { 1895 _mesa_error(ctx, GL_INVALID_OPERATION, 1896 "glCopyTexImage%dD(no depth/stencil buffer)", dimensions); 1897 return GL_TRUE; 1898 } 1899 } 1900 1901 /* if we get here, the parameters are OK */ 1902 return GL_FALSE; 1903} 1904 1905 1906/** 1907 * Test glCopyTexSubImage[12]D() parameters for errors. 1908 * Note that this is the first part of error checking. 1909 * See also copytexsubimage_error_check2() below for the second part. 1910 * 1911 * \param ctx GL context. 1912 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1913 * \param target texture target given by the user. 1914 * \param level image level given by the user. 1915 * 1916 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 1917 */ 1918static GLboolean 1919copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions, 1920 GLenum target, GLint level) 1921{ 1922 /* Check that the source buffer is complete */ 1923 if (ctx->ReadBuffer->Name) { 1924 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 1925 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 1926 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 1927 "glCopyTexImage%dD(invalid readbuffer)", dimensions); 1928 return GL_TRUE; 1929 } 1930 } 1931 1932 /* Check target */ 1933 if (dimensions == 1) { 1934 if (target != GL_TEXTURE_1D) { 1935 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" ); 1936 return GL_TRUE; 1937 } 1938 } 1939 else if (dimensions == 2) { 1940 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1941 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 1942 if (!ctx->Extensions.ARB_texture_cube_map) { 1943 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); 1944 return GL_TRUE; 1945 } 1946 } 1947 else if (target == GL_TEXTURE_RECTANGLE_NV) { 1948 if (!ctx->Extensions.NV_texture_rectangle) { 1949 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); 1950 return GL_TRUE; 1951 } 1952 } 1953 else if (target == GL_TEXTURE_1D_ARRAY_EXT) { 1954 if (!ctx->Extensions.MESA_texture_array) { 1955 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); 1956 return GL_TRUE; 1957 } 1958 } 1959 else if (target != GL_TEXTURE_2D) { 1960 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); 1961 return GL_TRUE; 1962 } 1963 } 1964 else if (dimensions == 3) { 1965 if (((target != GL_TEXTURE_2D_ARRAY_EXT) || 1966 (!ctx->Extensions.MESA_texture_array)) 1967 && (target != GL_TEXTURE_3D)) { 1968 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" ); 1969 return GL_TRUE; 1970 } 1971 } 1972 1973 /* Check level */ 1974 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1975 _mesa_error(ctx, GL_INVALID_VALUE, 1976 "glCopyTexSubImage%dD(level=%d)", dimensions, level); 1977 return GL_TRUE; 1978 } 1979 1980 return GL_FALSE; 1981} 1982 1983 1984/** 1985 * Second part of error checking for glCopyTexSubImage[12]D(). 1986 * \param xoffset sub-image x offset given by the user. 1987 * \param yoffset sub-image y offset given by the user. 1988 * \param zoffset sub-image z offset given by the user. 1989 * \param width image width given by the user. 1990 * \param height image height given by the user. 1991 */ 1992static GLboolean 1993copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions, 1994 GLenum target, GLint level, 1995 GLint xoffset, GLint yoffset, GLint zoffset, 1996 GLsizei width, GLsizei height, 1997 const struct gl_texture_image *teximage ) 1998{ 1999 /* check that dest tex image exists */ 2000 if (!teximage) { 2001 _mesa_error(ctx, GL_INVALID_OPERATION, 2002 "glCopyTexSubImage%dD(undefined texture level: %d)", 2003 dimensions, level); 2004 return GL_TRUE; 2005 } 2006 2007 /* Check size */ 2008 if (width < 0) { 2009 _mesa_error(ctx, GL_INVALID_VALUE, 2010 "glCopyTexSubImage%dD(width=%d)", dimensions, width); 2011 return GL_TRUE; 2012 } 2013 if (dimensions > 1 && height < 0) { 2014 _mesa_error(ctx, GL_INVALID_VALUE, 2015 "glCopyTexSubImage%dD(height=%d)", dimensions, height); 2016 return GL_TRUE; 2017 } 2018 2019 /* check x/y offsets */ 2020 if (xoffset < -((GLint)teximage->Border)) { 2021 _mesa_error(ctx, GL_INVALID_VALUE, 2022 "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset); 2023 return GL_TRUE; 2024 } 2025 if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) { 2026 _mesa_error(ctx, GL_INVALID_VALUE, 2027 "glCopyTexSubImage%dD(xoffset+width)", dimensions); 2028 return GL_TRUE; 2029 } 2030 if (dimensions > 1) { 2031 if (yoffset < -((GLint)teximage->Border)) { 2032 _mesa_error(ctx, GL_INVALID_VALUE, 2033 "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset); 2034 return GL_TRUE; 2035 } 2036 /* NOTE: we're adding the border here, not subtracting! */ 2037 if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) { 2038 _mesa_error(ctx, GL_INVALID_VALUE, 2039 "glCopyTexSubImage%dD(yoffset+height)", dimensions); 2040 return GL_TRUE; 2041 } 2042 } 2043 2044 /* check z offset */ 2045 if (dimensions > 2) { 2046 if (zoffset < -((GLint)teximage->Border)) { 2047 _mesa_error(ctx, GL_INVALID_VALUE, 2048 "glCopyTexSubImage%dD(zoffset)", dimensions); 2049 return GL_TRUE; 2050 } 2051 if (zoffset > (GLint) (teximage->Depth + teximage->Border)) { 2052 _mesa_error(ctx, GL_INVALID_VALUE, 2053 "glCopyTexSubImage%dD(zoffset+depth)", dimensions); 2054 return GL_TRUE; 2055 } 2056 } 2057 2058 if (_mesa_is_format_compressed(teximage->TexFormat)) { 2059 if (!target_can_be_compressed(ctx, target)) { 2060 _mesa_error(ctx, GL_INVALID_ENUM, 2061 "glCopyTexSubImage%dD(target)", dimensions); 2062 return GL_TRUE; 2063 } 2064 /* offset must be multiple of 4 */ 2065 if ((xoffset & 3) || (yoffset & 3)) { 2066 _mesa_error(ctx, GL_INVALID_VALUE, 2067 "glCopyTexSubImage%dD(xoffset or yoffset)", dimensions); 2068 return GL_TRUE; 2069 } 2070 /* size must be multiple of 4 */ 2071 if ((width & 3) != 0 && (GLuint) width != teximage->Width) { 2072 _mesa_error(ctx, GL_INVALID_VALUE, 2073 "glCopyTexSubImage%dD(width)", dimensions); 2074 return GL_TRUE; 2075 } 2076 if ((height & 3) != 0 && (GLuint) height != teximage->Height) { 2077 _mesa_error(ctx, GL_INVALID_VALUE, 2078 "glCopyTexSubImage%dD(height)", dimensions); 2079 return GL_TRUE; 2080 } 2081 } 2082 2083 if (teximage->InternalFormat == GL_YCBCR_MESA) { 2084 _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D"); 2085 return GL_TRUE; 2086 } 2087 2088 if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) { 2089 _mesa_error(ctx, GL_INVALID_OPERATION, 2090 "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)", 2091 dimensions, teximage->_BaseFormat); 2092 return GL_TRUE; 2093 } 2094 2095 if (teximage->_BaseFormat == GL_DEPTH_COMPONENT) { 2096 if (!ctx->ReadBuffer->_DepthBuffer) { 2097 _mesa_error(ctx, GL_INVALID_OPERATION, 2098 "glCopyTexSubImage%dD(no depth buffer)", 2099 dimensions); 2100 return GL_TRUE; 2101 } 2102 } 2103 else if (teximage->_BaseFormat == GL_DEPTH_STENCIL_EXT) { 2104 if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) { 2105 _mesa_error(ctx, GL_INVALID_OPERATION, 2106 "glCopyTexSubImage%dD(no depth/stencil buffer)", 2107 dimensions); 2108 return GL_TRUE; 2109 } 2110 } 2111 2112 /* If copying into an integer texture, the source buffer must also be 2113 * integer-valued. 2114 */ 2115 if (_mesa_is_format_integer_color(teximage->TexFormat)) { 2116 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 2117 if (!_mesa_is_format_integer_color(rb->Format)) { 2118 _mesa_error(ctx, GL_INVALID_OPERATION, 2119 "glCopyTexSubImage%dD(source buffer is not integer format)", 2120 dimensions); 2121 return GL_TRUE; 2122 } 2123 } 2124 2125 /* if we get here, the parameters are OK */ 2126 return GL_FALSE; 2127} 2128 2129 2130/** Callback info for walking over FBO hash table */ 2131struct cb_info 2132{ 2133 struct gl_context *ctx; 2134 struct gl_texture_object *texObj; 2135 GLuint level, face; 2136}; 2137 2138 2139/** 2140 * Check render to texture callback. Called from _mesa_HashWalk(). 2141 */ 2142static void 2143check_rtt_cb(GLuint key, void *data, void *userData) 2144{ 2145 struct gl_framebuffer *fb = (struct gl_framebuffer *) data; 2146 const struct cb_info *info = (struct cb_info *) userData; 2147 struct gl_context *ctx = info->ctx; 2148 const struct gl_texture_object *texObj = info->texObj; 2149 const GLuint level = info->level, face = info->face; 2150 2151 /* If this is a user-created FBO */ 2152 if (fb->Name) { 2153 GLuint i; 2154 /* check if any of the FBO's attachments point to 'texObj' */ 2155 for (i = 0; i < BUFFER_COUNT; i++) { 2156 struct gl_renderbuffer_attachment *att = fb->Attachment + i; 2157 if (att->Type == GL_TEXTURE && 2158 att->Texture == texObj && 2159 att->TextureLevel == level && 2160 att->CubeMapFace == face) { 2161 ASSERT(att->Texture->Image[att->CubeMapFace][att->TextureLevel]); 2162 /* Tell driver about the new renderbuffer texture */ 2163 ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att); 2164 /* Mark fb status as indeterminate to force re-validation */ 2165 fb->_Status = 0; 2166 } 2167 } 2168 } 2169} 2170 2171 2172/** 2173 * When a texture image is specified we have to check if it's bound to 2174 * any framebuffer objects (render to texture) in order to detect changes 2175 * in size or format since that effects FBO completeness. 2176 * Any FBOs rendering into the texture must be re-validated. 2177 */ 2178static void 2179update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj, 2180 GLuint face, GLuint level) 2181{ 2182 /* Only check this texture if it's been marked as RenderToTexture */ 2183 if (texObj->_RenderToTexture) { 2184 struct cb_info info; 2185 info.ctx = ctx; 2186 info.texObj = texObj; 2187 info.level = level; 2188 info.face = face; 2189 _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info); 2190 } 2191} 2192 2193 2194/** 2195 * If the texture object's GenerateMipmap flag is set and we've 2196 * changed the texture base level image, regenerate the rest of the 2197 * mipmap levels now. 2198 */ 2199static INLINE void 2200check_gen_mipmap(struct gl_context *ctx, GLenum target, 2201 struct gl_texture_object *texObj, GLint level) 2202{ 2203 ASSERT(target != GL_TEXTURE_CUBE_MAP); 2204 if (texObj->GenerateMipmap && 2205 level == texObj->BaseLevel && 2206 level < texObj->MaxLevel) { 2207 ASSERT(ctx->Driver.GenerateMipmap); 2208 ctx->Driver.GenerateMipmap(ctx, target, texObj); 2209 } 2210} 2211 2212 2213/** Debug helper: override the user-requested internal format */ 2214static GLenum 2215override_internal_format(GLenum internalFormat, GLint width, GLint height) 2216{ 2217#if 0 2218 if (internalFormat == GL_RGBA16F_ARB || 2219 internalFormat == GL_RGBA32F_ARB) { 2220 printf("Convert rgba float tex to int %d x %d\n", width, height); 2221 return GL_RGBA; 2222 } 2223 else if (internalFormat == GL_RGB16F_ARB || 2224 internalFormat == GL_RGB32F_ARB) { 2225 printf("Convert rgb float tex to int %d x %d\n", width, height); 2226 return GL_RGB; 2227 } 2228 else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB || 2229 internalFormat == GL_LUMINANCE_ALPHA32F_ARB) { 2230 printf("Convert luminance float tex to int %d x %d\n", width, height); 2231 return GL_LUMINANCE_ALPHA; 2232 } 2233 else if (internalFormat == GL_LUMINANCE16F_ARB || 2234 internalFormat == GL_LUMINANCE32F_ARB) { 2235 printf("Convert luminance float tex to int %d x %d\n", width, height); 2236 return GL_LUMINANCE; 2237 } 2238 else if (internalFormat == GL_ALPHA16F_ARB || 2239 internalFormat == GL_ALPHA32F_ARB) { 2240 printf("Convert luminance float tex to int %d x %d\n", width, height); 2241 return GL_ALPHA; 2242 } 2243 /* 2244 else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) { 2245 internalFormat = GL_RGBA; 2246 } 2247 */ 2248 else { 2249 return internalFormat; 2250 } 2251#else 2252 return internalFormat; 2253#endif 2254} 2255 2256 2257/** 2258 * Choose the actual hardware format for a texture image. 2259 * Try to use the same format as the previous image level when possible. 2260 * Otherwise, ask the driver for the best format. 2261 * It's important to try to choose a consistant format for all levels 2262 * for efficient texture memory layout/allocation. In particular, this 2263 * comes up during automatic mipmap generation. 2264 */ 2265void 2266_mesa_choose_texture_format(struct gl_context *ctx, 2267 struct gl_texture_object *texObj, 2268 struct gl_texture_image *texImage, 2269 GLenum target, GLint level, 2270 GLenum internalFormat, GLenum format, GLenum type) 2271{ 2272 /* see if we've already chosen a format for the previous level */ 2273 if (level > 0) { 2274 struct gl_texture_image *prevImage = 2275 _mesa_select_tex_image(ctx, texObj, target, level - 1); 2276 /* See if the prev level is defined and has an internal format which 2277 * matches the new internal format. 2278 */ 2279 if (prevImage && 2280 prevImage->Width > 0 && 2281 prevImage->InternalFormat == internalFormat) { 2282 /* use the same format */ 2283 texImage->TexFormat = prevImage->TexFormat; 2284 ASSERT(texImage->TexFormat != MESA_FORMAT_NONE); 2285 return; 2286 } 2287 } 2288 2289 /* choose format from scratch */ 2290 texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, 2291 format, type); 2292 ASSERT(texImage->TexFormat != MESA_FORMAT_NONE); 2293} 2294 2295 2296 2297/* 2298 * Called from the API. Note that width includes the border. 2299 */ 2300void GLAPIENTRY 2301_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, 2302 GLsizei width, GLint border, GLenum format, 2303 GLenum type, const GLvoid *pixels ) 2304{ 2305 GET_CURRENT_CONTEXT(ctx); 2306 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2307 2308 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2309 _mesa_debug(ctx, "glTexImage1D %s %d %s %d %d %s %s %p\n", 2310 _mesa_lookup_enum_by_nr(target), level, 2311 _mesa_lookup_enum_by_nr(internalFormat), width, border, 2312 _mesa_lookup_enum_by_nr(format), 2313 _mesa_lookup_enum_by_nr(type), pixels); 2314 2315 internalFormat = override_internal_format(internalFormat, width, 1); 2316 2317 if (target == GL_TEXTURE_1D) { 2318 /* non-proxy target */ 2319 struct gl_texture_object *texObj; 2320 struct gl_texture_image *texImage; 2321 const GLuint face = _mesa_tex_target_to_face(target); 2322 2323 if (texture_error_check(ctx, target, level, internalFormat, 2324 format, type, 1, width, 1, 1, border)) { 2325 return; /* error was recorded */ 2326 } 2327 2328 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2329 _mesa_update_state(ctx); 2330 2331 texObj = _mesa_get_current_tex_object(ctx, target); 2332 _mesa_lock_texture(ctx, texObj); 2333 { 2334 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2335 if (!texImage) { 2336 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); 2337 } 2338 else { 2339 if (texImage->Data) { 2340 ctx->Driver.FreeTexImageData( ctx, texImage ); 2341 } 2342 2343 ASSERT(texImage->Data == NULL); 2344 2345 clear_teximage_fields(texImage); /* not really needed, but helpful */ 2346 _mesa_init_teximage_fields(ctx, target, texImage, 2347 width, 1, 1, 2348 border, internalFormat); 2349 2350 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2351 internalFormat, format, type); 2352 2353 /* Give the texture to the driver. <pixels> may be null. */ 2354 ASSERT(ctx->Driver.TexImage1D); 2355 ctx->Driver.TexImage1D(ctx, target, level, internalFormat, 2356 width, border, format, type, pixels, 2357 &ctx->Unpack, texObj, texImage); 2358 2359 _mesa_set_fetch_functions(texImage, 1); 2360 2361 check_gen_mipmap(ctx, target, texObj, level); 2362 2363 update_fbo_texture(ctx, texObj, face, level); 2364 2365 /* state update */ 2366 texObj->_Complete = GL_FALSE; 2367 ctx->NewState |= _NEW_TEXTURE; 2368 } 2369 } 2370 _mesa_unlock_texture(ctx, texObj); 2371 } 2372 else if (target == GL_PROXY_TEXTURE_1D) { 2373 /* Proxy texture: check for errors and update proxy state */ 2374 struct gl_texture_image *texImage; 2375 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 2376 if (texture_error_check(ctx, target, level, internalFormat, 2377 format, type, 1, width, 1, 1, border)) { 2378 /* when error, clear all proxy texture image parameters */ 2379 if (texImage) 2380 clear_teximage_fields(texImage); 2381 } 2382 else { 2383 /* no error, set the tex image parameters */ 2384 struct gl_texture_object *texObj = 2385 _mesa_get_current_tex_object(ctx, target); 2386 ASSERT(texImage); 2387 _mesa_init_teximage_fields(ctx, target, texImage, 2388 width, 1, 1, 2389 border, internalFormat); 2390 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2391 internalFormat, format, type); 2392 } 2393 } 2394 else { 2395 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); 2396 return; 2397 } 2398} 2399 2400 2401void GLAPIENTRY 2402_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 2403 GLsizei width, GLsizei height, GLint border, 2404 GLenum format, GLenum type, 2405 const GLvoid *pixels ) 2406{ 2407 GET_CURRENT_CONTEXT(ctx); 2408 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2409 2410 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2411 _mesa_debug(ctx, "glTexImage2D %s %d %s %d %d %d %s %s %p\n", 2412 _mesa_lookup_enum_by_nr(target), level, 2413 _mesa_lookup_enum_by_nr(internalFormat), width, height, 2414 border, _mesa_lookup_enum_by_nr(format), 2415 _mesa_lookup_enum_by_nr(type), pixels); 2416 2417 internalFormat = override_internal_format(internalFormat, width, height); 2418 2419 if (target == GL_TEXTURE_2D || 2420 (ctx->Extensions.ARB_texture_cube_map && 2421 target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 2422 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) || 2423 (ctx->Extensions.NV_texture_rectangle && 2424 target == GL_TEXTURE_RECTANGLE_NV) || 2425 (ctx->Extensions.MESA_texture_array && 2426 target == GL_TEXTURE_1D_ARRAY_EXT)) { 2427 /* non-proxy target */ 2428 struct gl_texture_object *texObj; 2429 struct gl_texture_image *texImage; 2430 const GLuint face = _mesa_tex_target_to_face(target); 2431 2432 if (texture_error_check(ctx, target, level, internalFormat, 2433 format, type, 2, width, height, 1, border)) { 2434 return; /* error was recorded */ 2435 } 2436 2437 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2438 _mesa_update_state(ctx); 2439 2440 texObj = _mesa_get_current_tex_object(ctx, target); 2441 _mesa_lock_texture(ctx, texObj); 2442 { 2443 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2444 if (!texImage) { 2445 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); 2446 } 2447 else { 2448 if (texImage->Data) { 2449 ctx->Driver.FreeTexImageData( ctx, texImage ); 2450 } 2451 2452 ASSERT(texImage->Data == NULL); 2453 clear_teximage_fields(texImage); /* not really needed, but helpful */ 2454 _mesa_init_teximage_fields(ctx, target, texImage, 2455 width, height, 1, 2456 border, internalFormat); 2457 2458 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2459 internalFormat, format, type); 2460 2461 /* Give the texture to the driver. <pixels> may be null. */ 2462 ASSERT(ctx->Driver.TexImage2D); 2463 ctx->Driver.TexImage2D(ctx, target, level, internalFormat, 2464 width, height, border, format, type, 2465 pixels, &ctx->Unpack, texObj, texImage); 2466 2467 _mesa_set_fetch_functions(texImage, 2); 2468 2469 check_gen_mipmap(ctx, target, texObj, level); 2470 2471 update_fbo_texture(ctx, texObj, face, level); 2472 2473 /* state update */ 2474 texObj->_Complete = GL_FALSE; 2475 ctx->NewState |= _NEW_TEXTURE; 2476 } 2477 } 2478 _mesa_unlock_texture(ctx, texObj); 2479 } 2480 else if (target == GL_PROXY_TEXTURE_2D || 2481 (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && 2482 ctx->Extensions.ARB_texture_cube_map) || 2483 (target == GL_PROXY_TEXTURE_RECTANGLE_NV && 2484 ctx->Extensions.NV_texture_rectangle) || 2485 (ctx->Extensions.MESA_texture_array && 2486 target == GL_PROXY_TEXTURE_1D_ARRAY_EXT)) { 2487 /* Proxy texture: check for errors and update proxy state */ 2488 struct gl_texture_image *texImage; 2489 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 2490 if (texture_error_check(ctx, target, level, internalFormat, 2491 format, type, 2, width, height, 1, border)) { 2492 /* when error, clear all proxy texture image parameters */ 2493 if (texImage) 2494 clear_teximage_fields(texImage); 2495 } 2496 else { 2497 /* no error, set the tex image parameters */ 2498 struct gl_texture_object *texObj = 2499 _mesa_get_current_tex_object(ctx, target); 2500 _mesa_init_teximage_fields(ctx, target, texImage, 2501 width, height, 1, 2502 border, internalFormat); 2503 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2504 internalFormat, format, type); 2505 } 2506 } 2507 else { 2508 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" ); 2509 return; 2510 } 2511} 2512 2513 2514/* 2515 * Called by the API or display list executor. 2516 * Note that width and height include the border. 2517 */ 2518void GLAPIENTRY 2519_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, 2520 GLsizei width, GLsizei height, GLsizei depth, 2521 GLint border, GLenum format, GLenum type, 2522 const GLvoid *pixels ) 2523{ 2524 GET_CURRENT_CONTEXT(ctx); 2525 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2526 2527 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2528 _mesa_debug(ctx, "glTexImage3D %s %d %s %d %d %d %d %s %s %p\n", 2529 _mesa_lookup_enum_by_nr(target), level, 2530 _mesa_lookup_enum_by_nr(internalFormat), width, height, 2531 depth, border, _mesa_lookup_enum_by_nr(format), 2532 _mesa_lookup_enum_by_nr(type), pixels); 2533 2534 internalFormat = override_internal_format(internalFormat, width, height); 2535 2536 if (target == GL_TEXTURE_3D || 2537 (ctx->Extensions.MESA_texture_array && 2538 target == GL_TEXTURE_2D_ARRAY_EXT)) { 2539 /* non-proxy target */ 2540 struct gl_texture_object *texObj; 2541 struct gl_texture_image *texImage; 2542 const GLuint face = _mesa_tex_target_to_face(target); 2543 2544 if (texture_error_check(ctx, target, level, (GLint) internalFormat, 2545 format, type, 3, width, height, depth, border)) { 2546 return; /* error was recorded */ 2547 } 2548 2549 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2550 _mesa_update_state(ctx); 2551 2552 texObj = _mesa_get_current_tex_object(ctx, target); 2553 _mesa_lock_texture(ctx, texObj); 2554 { 2555 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2556 if (!texImage) { 2557 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); 2558 } 2559 else { 2560 if (texImage->Data) { 2561 ctx->Driver.FreeTexImageData( ctx, texImage ); 2562 } 2563 2564 ASSERT(texImage->Data == NULL); 2565 clear_teximage_fields(texImage); /* not really needed, but helpful */ 2566 _mesa_init_teximage_fields(ctx, target, texImage, 2567 width, height, depth, 2568 border, internalFormat); 2569 2570 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2571 internalFormat, format, type); 2572 2573 /* Give the texture to the driver. <pixels> may be null. */ 2574 ASSERT(ctx->Driver.TexImage3D); 2575 ctx->Driver.TexImage3D(ctx, target, level, internalFormat, 2576 width, height, depth, border, format, type, 2577 pixels, &ctx->Unpack, texObj, texImage); 2578 2579 _mesa_set_fetch_functions(texImage, 3); 2580 2581 check_gen_mipmap(ctx, target, texObj, level); 2582 2583 update_fbo_texture(ctx, texObj, face, level); 2584 2585 /* state update */ 2586 texObj->_Complete = GL_FALSE; 2587 ctx->NewState |= _NEW_TEXTURE; 2588 } 2589 } 2590 _mesa_unlock_texture(ctx, texObj); 2591 } 2592 else if (target == GL_PROXY_TEXTURE_3D || 2593 (ctx->Extensions.MESA_texture_array && 2594 target == GL_PROXY_TEXTURE_2D_ARRAY_EXT)) { 2595 /* Proxy texture: check for errors and update proxy state */ 2596 struct gl_texture_image *texImage; 2597 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 2598 if (texture_error_check(ctx, target, level, internalFormat, 2599 format, type, 3, width, height, depth, border)) { 2600 /* when error, clear all proxy texture image parameters */ 2601 if (texImage) 2602 clear_teximage_fields(texImage); 2603 } 2604 else { 2605 /* no error, set the tex image parameters */ 2606 struct gl_texture_object *texObj = 2607 _mesa_get_current_tex_object(ctx, target); 2608 _mesa_init_teximage_fields(ctx, target, texImage, width, height, 2609 depth, border, internalFormat); 2610 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2611 internalFormat, format, type); 2612 } 2613 } 2614 else { 2615 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); 2616 return; 2617 } 2618} 2619 2620 2621void GLAPIENTRY 2622_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, 2623 GLsizei width, GLsizei height, GLsizei depth, 2624 GLint border, GLenum format, GLenum type, 2625 const GLvoid *pixels ) 2626{ 2627 _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height, 2628 depth, border, format, type, pixels); 2629} 2630 2631 2632#if FEATURE_OES_EGL_image 2633void GLAPIENTRY 2634_mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) 2635{ 2636 struct gl_texture_object *texObj; 2637 struct gl_texture_image *texImage; 2638 GET_CURRENT_CONTEXT(ctx); 2639 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2640 2641 if (!ctx->Extensions.OES_EGL_image) { 2642 _mesa_error(ctx, GL_INVALID_OPERATION, 2643 "glEGLImageTargetTexture2DOES(unsupported)"); 2644 return; 2645 } 2646 2647 if (target != GL_TEXTURE_2D) { 2648 _mesa_error(ctx, GL_INVALID_ENUM, 2649 "glEGLImageTargetTexture2D(target=%d)", target); 2650 return; 2651 } 2652 2653 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2654 _mesa_update_state(ctx); 2655 2656 texObj = _mesa_get_current_tex_object(ctx, target); 2657 _mesa_lock_texture(ctx, texObj); 2658 2659 texImage = _mesa_get_tex_image(ctx, texObj, target, 0); 2660 if (!texImage) { 2661 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEGLImageTargetTexture2D"); 2662 } else { 2663 if (texImage->Data) 2664 ctx->Driver.FreeTexImageData( ctx, texImage ); 2665 2666 ASSERT(texImage->Data == NULL); 2667 ctx->Driver.EGLImageTargetTexture2D(ctx, target, 2668 texObj, texImage, image); 2669 2670 /* state update */ 2671 texObj->_Complete = GL_FALSE; 2672 ctx->NewState |= _NEW_TEXTURE; 2673 } 2674 _mesa_unlock_texture(ctx, texObj); 2675 2676} 2677#endif 2678 2679 2680void GLAPIENTRY 2681_mesa_TexSubImage1D( GLenum target, GLint level, 2682 GLint xoffset, GLsizei width, 2683 GLenum format, GLenum type, 2684 const GLvoid *pixels ) 2685{ 2686 struct gl_texture_object *texObj; 2687 struct gl_texture_image *texImage; 2688 GET_CURRENT_CONTEXT(ctx); 2689 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2690 2691 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2692 _mesa_debug(ctx, "glTexSubImage1D %s %d %d %d %s %s %p\n", 2693 _mesa_lookup_enum_by_nr(target), level, 2694 xoffset, width, _mesa_lookup_enum_by_nr(format), 2695 _mesa_lookup_enum_by_nr(type), pixels); 2696 2697 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2698 _mesa_update_state(ctx); 2699 2700 if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, 2701 width, 1, 1, format, type)) { 2702 return; /* error was detected */ 2703 } 2704 2705 2706 texObj = _mesa_get_current_tex_object(ctx, target); 2707 assert(texObj); 2708 2709 _mesa_lock_texture(ctx, texObj); 2710 { 2711 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 2712 2713 if (subtexture_error_check2(ctx, 1, target, level, xoffset, 0, 0, 2714 width, 1, 1, format, type, texImage)) { 2715 /* error was recorded */ 2716 } 2717 else if (width > 0) { 2718 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 2719 xoffset += texImage->Border; 2720 2721 ASSERT(ctx->Driver.TexSubImage1D); 2722 ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width, 2723 format, type, pixels, &ctx->Unpack, 2724 texObj, texImage); 2725 2726 check_gen_mipmap(ctx, target, texObj, level); 2727 2728 ctx->NewState |= _NEW_TEXTURE; 2729 } 2730 } 2731 _mesa_unlock_texture(ctx, texObj); 2732} 2733 2734 2735void GLAPIENTRY 2736_mesa_TexSubImage2D( GLenum target, GLint level, 2737 GLint xoffset, GLint yoffset, 2738 GLsizei width, GLsizei height, 2739 GLenum format, GLenum type, 2740 const GLvoid *pixels ) 2741{ 2742 struct gl_texture_object *texObj; 2743 struct gl_texture_image *texImage; 2744 GET_CURRENT_CONTEXT(ctx); 2745 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2746 2747 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2748 _mesa_debug(ctx, "glTexSubImage2D %s %d %d %d %d %d %s %s %p\n", 2749 _mesa_lookup_enum_by_nr(target), level, 2750 xoffset, yoffset, width, height, 2751 _mesa_lookup_enum_by_nr(format), 2752 _mesa_lookup_enum_by_nr(type), pixels); 2753 2754 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2755 _mesa_update_state(ctx); 2756 2757 if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, 2758 width, height, 1, format, type)) { 2759 return; /* error was detected */ 2760 } 2761 2762 texObj = _mesa_get_current_tex_object(ctx, target); 2763 2764 _mesa_lock_texture(ctx, texObj); 2765 { 2766 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 2767 2768 if (subtexture_error_check2(ctx, 2, target, level, xoffset, yoffset, 0, 2769 width, height, 1, format, type, texImage)) { 2770 /* error was recorded */ 2771 } 2772 else if (width > 0 && height >= 0) { 2773 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 2774 xoffset += texImage->Border; 2775 yoffset += texImage->Border; 2776 2777 ASSERT(ctx->Driver.TexSubImage2D); 2778 ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset, 2779 width, height, format, type, pixels, 2780 &ctx->Unpack, texObj, texImage); 2781 2782 check_gen_mipmap(ctx, target, texObj, level); 2783 2784 ctx->NewState |= _NEW_TEXTURE; 2785 } 2786 } 2787 _mesa_unlock_texture(ctx, texObj); 2788} 2789 2790 2791 2792void GLAPIENTRY 2793_mesa_TexSubImage3D( GLenum target, GLint level, 2794 GLint xoffset, GLint yoffset, GLint zoffset, 2795 GLsizei width, GLsizei height, GLsizei depth, 2796 GLenum format, GLenum type, 2797 const GLvoid *pixels ) 2798{ 2799 struct gl_texture_object *texObj; 2800 struct gl_texture_image *texImage; 2801 GET_CURRENT_CONTEXT(ctx); 2802 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2803 2804 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2805 _mesa_debug(ctx, "glTexSubImage3D %s %d %d %d %d %d %d %d %s %s %p\n", 2806 _mesa_lookup_enum_by_nr(target), level, 2807 xoffset, yoffset, zoffset, width, height, depth, 2808 _mesa_lookup_enum_by_nr(format), 2809 _mesa_lookup_enum_by_nr(type), pixels); 2810 2811 if (ctx->NewState & _MESA_NEW_TRANSFER_STATE) 2812 _mesa_update_state(ctx); 2813 2814 if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, 2815 width, height, depth, format, type)) { 2816 return; /* error was detected */ 2817 } 2818 2819 texObj = _mesa_get_current_tex_object(ctx, target); 2820 2821 _mesa_lock_texture(ctx, texObj); 2822 { 2823 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 2824 2825 if (subtexture_error_check2(ctx, 3, target, level, 2826 xoffset, yoffset, zoffset, 2827 width, height, depth, 2828 format, type, texImage)) { 2829 /* error was recorded */ 2830 } 2831 else if (width > 0 && height > 0 && height > 0) { 2832 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 2833 xoffset += texImage->Border; 2834 yoffset += texImage->Border; 2835 zoffset += texImage->Border; 2836 2837 ASSERT(ctx->Driver.TexSubImage3D); 2838 ctx->Driver.TexSubImage3D(ctx, target, level, 2839 xoffset, yoffset, zoffset, 2840 width, height, depth, 2841 format, type, pixels, 2842 &ctx->Unpack, texObj, texImage ); 2843 2844 check_gen_mipmap(ctx, target, texObj, level); 2845 2846 ctx->NewState |= _NEW_TEXTURE; 2847 } 2848 } 2849 _mesa_unlock_texture(ctx, texObj); 2850} 2851 2852 2853 2854void GLAPIENTRY 2855_mesa_CopyTexImage1D( GLenum target, GLint level, 2856 GLenum internalFormat, 2857 GLint x, GLint y, 2858 GLsizei width, GLint border ) 2859{ 2860 struct gl_texture_object *texObj; 2861 struct gl_texture_image *texImage; 2862 const GLuint face = _mesa_tex_target_to_face(target); 2863 GET_CURRENT_CONTEXT(ctx); 2864 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2865 2866 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2867 _mesa_debug(ctx, "glCopyTexImage1D %s %d %s %d %d %d %d\n", 2868 _mesa_lookup_enum_by_nr(target), level, 2869 _mesa_lookup_enum_by_nr(internalFormat), 2870 x, y, width, border); 2871 2872 if (ctx->NewState & NEW_COPY_TEX_STATE) 2873 _mesa_update_state(ctx); 2874 2875 if (copytexture_error_check(ctx, 1, target, level, internalFormat, 2876 width, 1, border)) 2877 return; 2878 2879 texObj = _mesa_get_current_tex_object(ctx, target); 2880 2881 _mesa_lock_texture(ctx, texObj); 2882 { 2883 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2884 if (!texImage) { 2885 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); 2886 } 2887 else { 2888 if (texImage->Data) { 2889 ctx->Driver.FreeTexImageData( ctx, texImage ); 2890 } 2891 2892 ASSERT(texImage->Data == NULL); 2893 2894 clear_teximage_fields(texImage); /* not really needed, but helpful */ 2895 _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, 2896 border, internalFormat); 2897 2898 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2899 internalFormat, GL_NONE, GL_NONE); 2900 2901 ASSERT(ctx->Driver.CopyTexImage1D); 2902 ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat, 2903 x, y, width, border); 2904 2905 _mesa_set_fetch_functions(texImage, 1); 2906 2907 check_gen_mipmap(ctx, target, texObj, level); 2908 2909 update_fbo_texture(ctx, texObj, face, level); 2910 2911 /* state update */ 2912 texObj->_Complete = GL_FALSE; 2913 ctx->NewState |= _NEW_TEXTURE; 2914 } 2915 } 2916 _mesa_unlock_texture(ctx, texObj); 2917} 2918 2919 2920 2921void GLAPIENTRY 2922_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, 2923 GLint x, GLint y, GLsizei width, GLsizei height, 2924 GLint border ) 2925{ 2926 struct gl_texture_object *texObj; 2927 struct gl_texture_image *texImage; 2928 const GLuint face = _mesa_tex_target_to_face(target); 2929 GET_CURRENT_CONTEXT(ctx); 2930 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2931 2932 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2933 _mesa_debug(ctx, "glCopyTexImage2D %s %d %s %d %d %d %d %d\n", 2934 _mesa_lookup_enum_by_nr(target), level, 2935 _mesa_lookup_enum_by_nr(internalFormat), 2936 x, y, width, height, border); 2937 2938 if (ctx->NewState & NEW_COPY_TEX_STATE) 2939 _mesa_update_state(ctx); 2940 2941 if (copytexture_error_check(ctx, 2, target, level, internalFormat, 2942 width, height, border)) 2943 return; 2944 2945 texObj = _mesa_get_current_tex_object(ctx, target); 2946 2947 _mesa_lock_texture(ctx, texObj); 2948 { 2949 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2950 2951 if (!texImage) { 2952 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); 2953 } 2954 else { 2955 if (texImage->Data) { 2956 ctx->Driver.FreeTexImageData( ctx, texImage ); 2957 } 2958 2959 ASSERT(texImage->Data == NULL); 2960 2961 clear_teximage_fields(texImage); /* not really needed, but helpful */ 2962 _mesa_init_teximage_fields(ctx, target, texImage, 2963 width, height, 1, 2964 border, internalFormat); 2965 2966 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 2967 internalFormat, GL_NONE, GL_NONE); 2968 2969 ASSERT(ctx->Driver.CopyTexImage2D); 2970 ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat, 2971 x, y, width, height, border); 2972 2973 _mesa_set_fetch_functions(texImage, 2); 2974 2975 check_gen_mipmap(ctx, target, texObj, level); 2976 2977 update_fbo_texture(ctx, texObj, face, level); 2978 2979 /* state update */ 2980 texObj->_Complete = GL_FALSE; 2981 ctx->NewState |= _NEW_TEXTURE; 2982 } 2983 } 2984 _mesa_unlock_texture(ctx, texObj); 2985} 2986 2987 2988void GLAPIENTRY 2989_mesa_CopyTexSubImage1D( GLenum target, GLint level, 2990 GLint xoffset, GLint x, GLint y, GLsizei width ) 2991{ 2992 struct gl_texture_object *texObj; 2993 struct gl_texture_image *texImage; 2994 GLint yoffset = 0; 2995 GLsizei height = 1; 2996 2997 GET_CURRENT_CONTEXT(ctx); 2998 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2999 3000 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3001 _mesa_debug(ctx, "glCopyTexSubImage1D %s %d %d %d %d %d\n", 3002 _mesa_lookup_enum_by_nr(target), 3003 level, xoffset, x, y, width); 3004 3005 if (ctx->NewState & NEW_COPY_TEX_STATE) 3006 _mesa_update_state(ctx); 3007 3008 if (copytexsubimage_error_check1(ctx, 1, target, level)) 3009 return; 3010 3011 texObj = _mesa_get_current_tex_object(ctx, target); 3012 3013 _mesa_lock_texture(ctx, texObj); 3014 { 3015 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3016 3017 if (copytexsubimage_error_check2(ctx, 1, target, level, 3018 xoffset, 0, 0, width, 1, texImage)) { 3019 /* error was recorded */ 3020 } 3021 else { 3022 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 3023 xoffset += texImage->Border; 3024 3025 if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, 3026 &width, &height)) { 3027 ASSERT(ctx->Driver.CopyTexSubImage1D); 3028 ctx->Driver.CopyTexSubImage1D(ctx, target, level, 3029 xoffset, x, y, width); 3030 3031 check_gen_mipmap(ctx, target, texObj, level); 3032 3033 ctx->NewState |= _NEW_TEXTURE; 3034 } 3035 } 3036 } 3037 _mesa_unlock_texture(ctx, texObj); 3038} 3039 3040 3041 3042void GLAPIENTRY 3043_mesa_CopyTexSubImage2D( GLenum target, GLint level, 3044 GLint xoffset, GLint yoffset, 3045 GLint x, GLint y, GLsizei width, GLsizei height ) 3046{ 3047 struct gl_texture_object *texObj; 3048 struct gl_texture_image *texImage; 3049 GET_CURRENT_CONTEXT(ctx); 3050 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3051 3052 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3053 _mesa_debug(ctx, "glCopyTexSubImage2D %s %d %d %d %d %d %d %d\n", 3054 _mesa_lookup_enum_by_nr(target), 3055 level, xoffset, yoffset, x, y, width, height); 3056 3057 if (ctx->NewState & NEW_COPY_TEX_STATE) 3058 _mesa_update_state(ctx); 3059 3060 if (copytexsubimage_error_check1(ctx, 2, target, level)) 3061 return; 3062 3063 texObj = _mesa_get_current_tex_object(ctx, target); 3064 3065 _mesa_lock_texture(ctx, texObj); 3066 { 3067 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3068 3069 if (copytexsubimage_error_check2(ctx, 2, target, level, 3070 xoffset, yoffset, 0, 3071 width, height, texImage)) { 3072 /* error was recorded */ 3073 } 3074 else { 3075 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 3076 xoffset += texImage->Border; 3077 yoffset += texImage->Border; 3078 3079 if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, 3080 &width, &height)) { 3081 ASSERT(ctx->Driver.CopyTexSubImage2D); 3082 ctx->Driver.CopyTexSubImage2D(ctx, target, level, xoffset, yoffset, 3083 x, y, width, height); 3084 3085 check_gen_mipmap(ctx, target, texObj, level); 3086 3087 ctx->NewState |= _NEW_TEXTURE; 3088 } 3089 } 3090 } 3091 _mesa_unlock_texture(ctx, texObj); 3092} 3093 3094 3095 3096void GLAPIENTRY 3097_mesa_CopyTexSubImage3D( GLenum target, GLint level, 3098 GLint xoffset, GLint yoffset, GLint zoffset, 3099 GLint x, GLint y, GLsizei width, GLsizei height ) 3100{ 3101 struct gl_texture_object *texObj; 3102 struct gl_texture_image *texImage; 3103 GET_CURRENT_CONTEXT(ctx); 3104 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3105 3106 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3107 _mesa_debug(ctx, "glCopyTexSubImage3D %s %d %d %d %d %d %d %d %d\n", 3108 _mesa_lookup_enum_by_nr(target), 3109 level, xoffset, yoffset, zoffset, x, y, width, height); 3110 3111 if (ctx->NewState & NEW_COPY_TEX_STATE) 3112 _mesa_update_state(ctx); 3113 3114 if (copytexsubimage_error_check1(ctx, 3, target, level)) 3115 return; 3116 3117 texObj = _mesa_get_current_tex_object(ctx, target); 3118 3119 _mesa_lock_texture(ctx, texObj); 3120 { 3121 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3122 3123 if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset, 3124 zoffset, width, height, texImage)) { 3125 /* error was recored */ 3126 } 3127 else { 3128 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 3129 xoffset += texImage->Border; 3130 yoffset += texImage->Border; 3131 zoffset += texImage->Border; 3132 3133 if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, 3134 &width, &height)) { 3135 ASSERT(ctx->Driver.CopyTexSubImage3D); 3136 ctx->Driver.CopyTexSubImage3D(ctx, target, level, 3137 xoffset, yoffset, zoffset, 3138 x, y, width, height); 3139 3140 check_gen_mipmap(ctx, target, texObj, level); 3141 3142 ctx->NewState |= _NEW_TEXTURE; 3143 } 3144 } 3145 } 3146 _mesa_unlock_texture(ctx, texObj); 3147} 3148 3149 3150 3151 3152/**********************************************************************/ 3153/****** Compressed Textures ******/ 3154/**********************************************************************/ 3155 3156 3157/** 3158 * Return expected size of a compressed texture. 3159 */ 3160static GLuint 3161compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth, 3162 GLenum glformat) 3163{ 3164 gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 3165 return _mesa_format_image_size(mesaFormat, width, height, depth); 3166} 3167 3168 3169/* 3170 * Return compressed texture block size, in pixels. 3171 */ 3172static void 3173get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh) 3174{ 3175 gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 3176 _mesa_get_format_block_size(mesaFormat, bw, bh); 3177} 3178 3179 3180/** 3181 * Error checking for glCompressedTexImage[123]D(). 3182 * \return error code or GL_NO_ERROR. 3183 */ 3184static GLenum 3185compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, 3186 GLenum target, GLint level, 3187 GLenum internalFormat, GLsizei width, 3188 GLsizei height, GLsizei depth, GLint border, 3189 GLsizei imageSize) 3190{ 3191 GLint expectedSize, maxLevels = 0, maxTextureSize; 3192 3193 if (dimensions == 1) { 3194 /* 1D compressed textures not allowed */ 3195 return GL_INVALID_ENUM; 3196 } 3197 else if (dimensions == 2) { 3198 if (target == GL_PROXY_TEXTURE_2D) { 3199 maxLevels = ctx->Const.MaxTextureLevels; 3200 } 3201 else if (target == GL_TEXTURE_2D) { 3202 maxLevels = ctx->Const.MaxTextureLevels; 3203 } 3204 else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { 3205 if (!ctx->Extensions.ARB_texture_cube_map) 3206 return GL_INVALID_ENUM; /*target*/ 3207 maxLevels = ctx->Const.MaxCubeTextureLevels; 3208 } 3209 else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 3210 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 3211 if (!ctx->Extensions.ARB_texture_cube_map) 3212 return GL_INVALID_ENUM; /*target*/ 3213 maxLevels = ctx->Const.MaxCubeTextureLevels; 3214 } 3215 else { 3216 return GL_INVALID_ENUM; /*target*/ 3217 } 3218 } 3219 else if (dimensions == 3) { 3220 /* 3D compressed textures not allowed */ 3221 return GL_INVALID_ENUM; 3222 } 3223 else { 3224 assert(0); 3225 return GL_INVALID_ENUM; 3226 } 3227 3228 maxTextureSize = 1 << (maxLevels - 1); 3229 3230 /* This will detect any invalid internalFormat value */ 3231 if (!_mesa_is_compressed_format(ctx, internalFormat)) 3232 return GL_INVALID_ENUM; 3233 3234 /* This should really never fail */ 3235 if (_mesa_base_tex_format(ctx, internalFormat) < 0) 3236 return GL_INVALID_ENUM; 3237 3238 if (border != 0) 3239 return GL_INVALID_VALUE; 3240 3241 /* 3242 * XXX We should probably use the proxy texture error check function here. 3243 */ 3244 if (width < 1 || width > maxTextureSize || 3245 (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(width))) 3246 return GL_INVALID_VALUE; 3247 3248 if ((height < 1 || height > maxTextureSize || 3249 (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(height))) 3250 && dimensions > 1) 3251 return GL_INVALID_VALUE; 3252 3253 if ((depth < 1 || depth > maxTextureSize || 3254 (!ctx->Extensions.ARB_texture_non_power_of_two && !_mesa_is_pow_two(depth))) 3255 && dimensions > 2) 3256 return GL_INVALID_VALUE; 3257 3258 /* For cube map, width must equal height */ 3259 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 3260 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB && width != height) 3261 return GL_INVALID_VALUE; 3262 3263 if (level < 0 || level >= maxLevels) 3264 return GL_INVALID_VALUE; 3265 3266 expectedSize = compressed_tex_size(width, height, depth, internalFormat); 3267 if (expectedSize != imageSize) 3268 return GL_INVALID_VALUE; 3269 3270#if FEATURE_EXT_texture_sRGB 3271 if ((internalFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT || 3272 internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT || 3273 internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT || 3274 internalFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) 3275 && border != 0) { 3276 return GL_INVALID_OPERATION; 3277 } 3278#endif 3279 3280 return GL_NO_ERROR; 3281} 3282 3283 3284/** 3285 * Error checking for glCompressedTexSubImage[123]D(). 3286 * \warning There are some bad assumptions here about the size of compressed 3287 * texture tiles (multiple of 4) used to test the validity of the 3288 * offset and size parameters. 3289 * \return error code or GL_NO_ERROR. 3290 */ 3291static GLenum 3292compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions, 3293 GLenum target, GLint level, 3294 GLint xoffset, GLint yoffset, GLint zoffset, 3295 GLsizei width, GLsizei height, GLsizei depth, 3296 GLenum format, GLsizei imageSize) 3297{ 3298 GLint expectedSize, maxLevels = 0, maxTextureSize; 3299 GLuint bw, bh; 3300 (void) zoffset; 3301 3302 if (dimensions == 1) { 3303 /* 1D compressed textures not allowed */ 3304 return GL_INVALID_ENUM; 3305 } 3306 else if (dimensions == 2) { 3307 if (target == GL_PROXY_TEXTURE_2D) { 3308 maxLevels = ctx->Const.MaxTextureLevels; 3309 } 3310 else if (target == GL_TEXTURE_2D) { 3311 maxLevels = ctx->Const.MaxTextureLevels; 3312 } 3313 else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { 3314 if (!ctx->Extensions.ARB_texture_cube_map) 3315 return GL_INVALID_ENUM; /*target*/ 3316 maxLevels = ctx->Const.MaxCubeTextureLevels; 3317 } 3318 else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 3319 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 3320 if (!ctx->Extensions.ARB_texture_cube_map) 3321 return GL_INVALID_ENUM; /*target*/ 3322 maxLevels = ctx->Const.MaxCubeTextureLevels; 3323 } 3324 else { 3325 return GL_INVALID_ENUM; /*target*/ 3326 } 3327 } 3328 else if (dimensions == 3) { 3329 /* 3D compressed textures not allowed */ 3330 return GL_INVALID_ENUM; 3331 } 3332 3333 maxTextureSize = 1 << (maxLevels - 1); 3334 3335 /* this will catch any invalid compressed format token */ 3336 if (!_mesa_is_compressed_format(ctx, format)) 3337 return GL_INVALID_ENUM; 3338 3339 if (width < 1 || width > maxTextureSize) 3340 return GL_INVALID_VALUE; 3341 3342 if ((height < 1 || height > maxTextureSize) 3343 && dimensions > 1) 3344 return GL_INVALID_VALUE; 3345 3346 if (level < 0 || level >= maxLevels) 3347 return GL_INVALID_VALUE; 3348 3349 /* 3350 * do checks which depend on compression block size 3351 */ 3352 get_compressed_block_size(format, &bw, &bh); 3353 3354 if ((xoffset % bw != 0) || (yoffset % bh != 0)) 3355 return GL_INVALID_VALUE; 3356 3357 if ((width % bw != 0) && width != 2 && width != 1) 3358 return GL_INVALID_VALUE; 3359 3360 if ((height % bh != 0) && height != 2 && height != 1) 3361 return GL_INVALID_VALUE; 3362 3363 expectedSize = compressed_tex_size(width, height, depth, format); 3364 if (expectedSize != imageSize) 3365 return GL_INVALID_VALUE; 3366 3367 return GL_NO_ERROR; 3368} 3369 3370 3371/** 3372 * Do second part of glCompressedTexSubImage error checking. 3373 * \return GL_TRUE if error found, GL_FALSE otherwise. 3374 */ 3375static GLboolean 3376compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims, 3377 GLsizei width, GLsizei height, 3378 GLsizei depth, GLenum format, 3379 struct gl_texture_image *texImage) 3380{ 3381 3382 if ((GLint) format != texImage->InternalFormat) { 3383 _mesa_error(ctx, GL_INVALID_OPERATION, 3384 "glCompressedTexSubImage%uD(format=0x%x)", dims, format); 3385 return GL_TRUE; 3386 } 3387 3388 if (((width == 1 || width == 2) && 3389 width != (GLsizei) texImage->Width) || 3390 (width > (GLsizei) texImage->Width)) { 3391 _mesa_error(ctx, GL_INVALID_VALUE, 3392 "glCompressedTexSubImage%uD(width=%d)", dims, width); 3393 return GL_TRUE; 3394 } 3395 3396 if (dims >= 2) { 3397 if (((height == 1 || height == 2) && 3398 height != (GLsizei) texImage->Height) || 3399 (height > (GLsizei) texImage->Height)) { 3400 _mesa_error(ctx, GL_INVALID_VALUE, 3401 "glCompressedTexSubImage%uD(height=%d)", dims, height); 3402 return GL_TRUE; 3403 } 3404 } 3405 3406 if (dims >= 3) { 3407 if (((depth == 1 || depth == 2) && 3408 depth != (GLsizei) texImage->Depth) || 3409 (depth > (GLsizei) texImage->Depth)) { 3410 _mesa_error(ctx, GL_INVALID_VALUE, 3411 "glCompressedTexSubImage%uD(depth=%d)", dims, depth); 3412 return GL_TRUE; 3413 } 3414 } 3415 3416 return GL_FALSE; 3417} 3418 3419 3420 3421void GLAPIENTRY 3422_mesa_CompressedTexImage1DARB(GLenum target, GLint level, 3423 GLenum internalFormat, GLsizei width, 3424 GLint border, GLsizei imageSize, 3425 const GLvoid *data) 3426{ 3427 GET_CURRENT_CONTEXT(ctx); 3428 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3429 3430 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3431 _mesa_debug(ctx, "glCompressedTexImage1DARB %s %d %s %d %d %d %p\n", 3432 _mesa_lookup_enum_by_nr(target), level, 3433 _mesa_lookup_enum_by_nr(internalFormat), 3434 width, border, imageSize, data); 3435 3436 if (target == GL_TEXTURE_1D) { 3437 /* non-proxy target */ 3438 struct gl_texture_object *texObj; 3439 struct gl_texture_image *texImage; 3440 GLenum error = compressed_texture_error_check(ctx, 1, target, level, 3441 internalFormat, width, 1, 1, border, imageSize); 3442 if (error) { 3443 _mesa_error(ctx, error, "glCompressedTexImage1D"); 3444 return; 3445 } 3446 3447 texObj = _mesa_get_current_tex_object(ctx, target); 3448 3449 _mesa_lock_texture(ctx, texObj); 3450 { 3451 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3452 if (!texImage) { 3453 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D"); 3454 } 3455 else { 3456 if (texImage->Data) { 3457 ctx->Driver.FreeTexImageData( ctx, texImage ); 3458 } 3459 ASSERT(texImage->Data == NULL); 3460 3461 _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, 3462 border, internalFormat); 3463 3464 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 3465 internalFormat, GL_NONE, GL_NONE); 3466 3467 ASSERT(ctx->Driver.CompressedTexImage1D); 3468 ctx->Driver.CompressedTexImage1D(ctx, target, level, 3469 internalFormat, width, border, 3470 imageSize, data, 3471 texObj, texImage); 3472 3473 _mesa_set_fetch_functions(texImage, 1); 3474 3475 check_gen_mipmap(ctx, target, texObj, level); 3476 3477 /* state update */ 3478 texObj->_Complete = GL_FALSE; 3479 ctx->NewState |= _NEW_TEXTURE; 3480 } 3481 } 3482 _mesa_unlock_texture(ctx, texObj); 3483 } 3484 else if (target == GL_PROXY_TEXTURE_1D) { 3485 /* Proxy texture: check for errors and update proxy state */ 3486 GLenum error = compressed_texture_error_check(ctx, 1, target, level, 3487 internalFormat, width, 1, 1, border, imageSize); 3488 if (!error) { 3489 ASSERT(ctx->Driver.TestProxyTexImage); 3490 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 3491 internalFormat, GL_NONE, GL_NONE, 3492 width, 1, 1, border); 3493 } 3494 if (error) { 3495 /* if error, clear all proxy texture image parameters */ 3496 struct gl_texture_image *texImage; 3497 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 3498 if (texImage) 3499 clear_teximage_fields(texImage); 3500 } 3501 else { 3502 /* store the teximage parameters */ 3503 struct gl_texture_object *texObj; 3504 struct gl_texture_image *texImage; 3505 3506 texObj = _mesa_get_current_tex_object(ctx, target); 3507 3508 _mesa_lock_texture(ctx, texObj); 3509 { 3510 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3511 _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, 3512 border, internalFormat); 3513 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 3514 internalFormat, GL_NONE, GL_NONE); 3515 } 3516 _mesa_unlock_texture(ctx, texObj); 3517 } 3518 } 3519 else { 3520 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1D(target)"); 3521 return; 3522 } 3523} 3524 3525void GLAPIENTRY 3526_mesa_CompressedTexImage2DARB(GLenum target, GLint level, 3527 GLenum internalFormat, GLsizei width, 3528 GLsizei height, GLint border, GLsizei imageSize, 3529 const GLvoid *data) 3530{ 3531 GET_CURRENT_CONTEXT(ctx); 3532 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3533 3534 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3535 _mesa_debug(ctx, "glCompressedTexImage2DARB %s %d %s %d %d %d %d %p\n", 3536 _mesa_lookup_enum_by_nr(target), level, 3537 _mesa_lookup_enum_by_nr(internalFormat), 3538 width, height, border, imageSize, data); 3539 3540#if FEATURE_ES 3541 switch (internalFormat) { 3542 case GL_PALETTE4_RGB8_OES: 3543 case GL_PALETTE4_RGBA8_OES: 3544 case GL_PALETTE4_R5_G6_B5_OES: 3545 case GL_PALETTE4_RGBA4_OES: 3546 case GL_PALETTE4_RGB5_A1_OES: 3547 case GL_PALETTE8_RGB8_OES: 3548 case GL_PALETTE8_RGBA8_OES: 3549 case GL_PALETTE8_R5_G6_B5_OES: 3550 case GL_PALETTE8_RGBA4_OES: 3551 case GL_PALETTE8_RGB5_A1_OES: 3552 _mesa_cpal_compressed_teximage2d(target, level, internalFormat, 3553 width, height, imageSize, data); 3554 return; 3555 } 3556#endif 3557 3558 if (target == GL_TEXTURE_2D || 3559 (ctx->Extensions.ARB_texture_cube_map && 3560 target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 3561 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { 3562 /* non-proxy target */ 3563 struct gl_texture_object *texObj; 3564 struct gl_texture_image *texImage; 3565 3566 GLenum error = compressed_texture_error_check(ctx, 2, target, level, 3567 internalFormat, width, height, 1, border, imageSize); 3568 if (error) { 3569 _mesa_error(ctx, error, "glCompressedTexImage2D"); 3570 return; 3571 } 3572 3573 texObj = _mesa_get_current_tex_object(ctx, target); 3574 3575 _mesa_lock_texture(ctx, texObj); 3576 { 3577 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3578 if (!texImage) { 3579 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); 3580 } 3581 else { 3582 if (texImage->Data) { 3583 ctx->Driver.FreeTexImageData( ctx, texImage ); 3584 } 3585 ASSERT(texImage->Data == NULL); 3586 3587 _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, 3588 border, internalFormat); 3589 3590 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 3591 internalFormat, GL_NONE, GL_NONE); 3592 3593 ASSERT(ctx->Driver.CompressedTexImage2D); 3594 ctx->Driver.CompressedTexImage2D(ctx, target, level, 3595 internalFormat, width, height, 3596 border, imageSize, data, 3597 texObj, texImage); 3598 3599 _mesa_set_fetch_functions(texImage, 2); 3600 3601 check_gen_mipmap(ctx, target, texObj, level); 3602 3603 /* state update */ 3604 texObj->_Complete = GL_FALSE; 3605 ctx->NewState |= _NEW_TEXTURE; 3606 } 3607 } 3608 _mesa_unlock_texture(ctx, texObj); 3609 } 3610 else if (target == GL_PROXY_TEXTURE_2D || 3611 (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && 3612 ctx->Extensions.ARB_texture_cube_map)) { 3613 /* Proxy texture: check for errors and update proxy state */ 3614 GLenum error = compressed_texture_error_check(ctx, 2, target, level, 3615 internalFormat, width, height, 1, border, imageSize); 3616 if (!error) { 3617 ASSERT(ctx->Driver.TestProxyTexImage); 3618 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 3619 internalFormat, GL_NONE, GL_NONE, 3620 width, height, 1, border); 3621 } 3622 if (error) { 3623 /* if error, clear all proxy texture image parameters */ 3624 struct gl_texture_image *texImage; 3625 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 3626 if (texImage) 3627 clear_teximage_fields(texImage); 3628 } 3629 else { 3630 /* store the teximage parameters */ 3631 struct gl_texture_object *texObj; 3632 struct gl_texture_image *texImage; 3633 3634 texObj = _mesa_get_current_tex_object(ctx, target); 3635 3636 _mesa_lock_texture(ctx, texObj); 3637 { 3638 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3639 _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, 3640 border, internalFormat); 3641 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 3642 internalFormat, GL_NONE, GL_NONE); 3643 } 3644 _mesa_unlock_texture(ctx, texObj); 3645 } 3646 } 3647 else { 3648 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(target)"); 3649 return; 3650 } 3651} 3652 3653 3654void GLAPIENTRY 3655_mesa_CompressedTexImage3DARB(GLenum target, GLint level, 3656 GLenum internalFormat, GLsizei width, 3657 GLsizei height, GLsizei depth, GLint border, 3658 GLsizei imageSize, const GLvoid *data) 3659{ 3660 GET_CURRENT_CONTEXT(ctx); 3661 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3662 3663 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3664 _mesa_debug(ctx, "glCompressedTexImage3DARB %s %d %s %d %d %d %d %d %p\n", 3665 _mesa_lookup_enum_by_nr(target), level, 3666 _mesa_lookup_enum_by_nr(internalFormat), 3667 width, height, depth, border, imageSize, data); 3668 3669 if (target == GL_TEXTURE_3D) { 3670 /* non-proxy target */ 3671 struct gl_texture_object *texObj; 3672 struct gl_texture_image *texImage; 3673 GLenum error = compressed_texture_error_check(ctx, 3, target, level, 3674 internalFormat, width, height, depth, border, imageSize); 3675 if (error) { 3676 _mesa_error(ctx, error, "glCompressedTexImage3D"); 3677 return; 3678 } 3679 3680 texObj = _mesa_get_current_tex_object(ctx, target); 3681 3682 _mesa_lock_texture(ctx, texObj); 3683 { 3684 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3685 if (!texImage) { 3686 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D"); 3687 } 3688 else { 3689 if (texImage->Data) { 3690 ctx->Driver.FreeTexImageData( ctx, texImage ); 3691 } 3692 ASSERT(texImage->Data == NULL); 3693 3694 _mesa_init_teximage_fields(ctx, target, texImage, 3695 width, height, depth, 3696 border, internalFormat); 3697 3698 /* Choose actual texture format */ 3699 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 3700 internalFormat, GL_NONE, GL_NONE); 3701 3702 ASSERT(ctx->Driver.CompressedTexImage3D); 3703 ctx->Driver.CompressedTexImage3D(ctx, target, level, 3704 internalFormat, 3705 width, height, depth, 3706 border, imageSize, data, 3707 texObj, texImage); 3708 3709 _mesa_set_fetch_functions(texImage, 3); 3710 3711 check_gen_mipmap(ctx, target, texObj, level); 3712 3713 /* state update */ 3714 texObj->_Complete = GL_FALSE; 3715 ctx->NewState |= _NEW_TEXTURE; 3716 } 3717 } 3718 _mesa_unlock_texture(ctx, texObj); 3719 } 3720 else if (target == GL_PROXY_TEXTURE_3D) { 3721 /* Proxy texture: check for errors and update proxy state */ 3722 GLenum error = compressed_texture_error_check(ctx, 3, target, level, 3723 internalFormat, width, height, depth, border, imageSize); 3724 if (!error) { 3725 ASSERT(ctx->Driver.TestProxyTexImage); 3726 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 3727 internalFormat, GL_NONE, GL_NONE, 3728 width, height, depth, border); 3729 } 3730 if (error) { 3731 /* if error, clear all proxy texture image parameters */ 3732 struct gl_texture_image *texImage; 3733 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 3734 if (texImage) 3735 clear_teximage_fields(texImage); 3736 } 3737 else { 3738 /* store the teximage parameters */ 3739 struct gl_texture_object *texObj; 3740 struct gl_texture_image *texImage; 3741 3742 texObj = _mesa_get_current_tex_object(ctx, target); 3743 3744 _mesa_lock_texture(ctx, texObj); 3745 { 3746 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3747 _mesa_init_teximage_fields(ctx, target, texImage, width, height, 3748 depth, border, internalFormat); 3749 _mesa_choose_texture_format(ctx, texObj, texImage, target, level, 3750 internalFormat, GL_NONE, GL_NONE); 3751 } 3752 _mesa_unlock_texture(ctx, texObj); 3753 } 3754 } 3755 else { 3756 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3D(target)"); 3757 return; 3758 } 3759} 3760 3761 3762/** 3763 * Common helper for glCompressedTexSubImage1/2/3D(). 3764 */ 3765static void 3766compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, 3767 GLint xoffset, GLint yoffset, GLint zoffset, 3768 GLsizei width, GLsizei height, GLsizei depth, 3769 GLenum format, GLsizei imageSize, const GLvoid *data) 3770{ 3771 struct gl_texture_object *texObj; 3772 struct gl_texture_image *texImage; 3773 GLenum error; 3774 GET_CURRENT_CONTEXT(ctx); 3775 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3776 3777 error = compressed_subtexture_error_check(ctx, dims, target, level, 3778 xoffset, 0, 0, /* pos */ 3779 width, height, depth, /* size */ 3780 format, imageSize); 3781 if (error) { 3782 _mesa_error(ctx, error, "glCompressedTexSubImage%uD", dims); 3783 return; 3784 } 3785 3786 texObj = _mesa_get_current_tex_object(ctx, target); 3787 3788 _mesa_lock_texture(ctx, texObj); 3789 { 3790 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3791 assert(texImage); 3792 3793 if (compressed_subtexture_error_check2(ctx, dims, width, height, depth, 3794 format, texImage)) { 3795 /* error was recorded */ 3796 } 3797 else if (width > 0 && height > 0 && depth > 0) { 3798 switch (dims) { 3799 case 1: 3800 if (ctx->Driver.CompressedTexSubImage1D) { 3801 ctx->Driver.CompressedTexSubImage1D(ctx, target, level, 3802 xoffset, width, 3803 format, imageSize, data, 3804 texObj, texImage); 3805 } 3806 break; 3807 case 2: 3808 if (ctx->Driver.CompressedTexSubImage2D) { 3809 ctx->Driver.CompressedTexSubImage2D(ctx, target, level, 3810 xoffset, yoffset, 3811 width, height, 3812 format, imageSize, data, 3813 texObj, texImage); 3814 } 3815 break; 3816 case 3: 3817 if (ctx->Driver.CompressedTexSubImage3D) { 3818 ctx->Driver.CompressedTexSubImage3D(ctx, target, level, 3819 xoffset, yoffset, zoffset, 3820 width, height, depth, 3821 format, imageSize, data, 3822 texObj, texImage); 3823 } 3824 break; 3825 default: 3826 ; 3827 } 3828 3829 check_gen_mipmap(ctx, target, texObj, level); 3830 3831 ctx->NewState |= _NEW_TEXTURE; 3832 } 3833 } 3834 _mesa_unlock_texture(ctx, texObj); 3835} 3836 3837 3838void GLAPIENTRY 3839_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, 3840 GLsizei width, GLenum format, 3841 GLsizei imageSize, const GLvoid *data) 3842{ 3843 compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1, 3844 format, imageSize, data); 3845} 3846 3847 3848void GLAPIENTRY 3849_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, 3850 GLint yoffset, GLsizei width, GLsizei height, 3851 GLenum format, GLsizei imageSize, 3852 const GLvoid *data) 3853{ 3854 compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0, 3855 width, height, 1, format, imageSize, data); 3856} 3857 3858 3859void GLAPIENTRY 3860_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, 3861 GLint yoffset, GLint zoffset, GLsizei width, 3862 GLsizei height, GLsizei depth, GLenum format, 3863 GLsizei imageSize, const GLvoid *data) 3864{ 3865 compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset, 3866 width, height, depth, format, imageSize, data); 3867} 3868