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