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