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