teximage.c revision 6950a4faf650fe119ee97aa18b006eed099038be
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 * Install gl_texture_image in a gl_texture_object according to the target 545 * 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 */ 552static void 553set_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 free(texImage); 608} 609 610 611/** 612 * Test if a target is a proxy target. 613 * 614 * \param target texture target. 615 * 616 * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise. 617 */ 618GLboolean 619_mesa_is_proxy_texture(GLenum target) 620{ 621 /* 622 * NUM_TEXTURE_TARGETS should match number of terms below, except there's no 623 * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES. 624 */ 625 assert(NUM_TEXTURE_TARGETS == 7 + 2); 626 627 return (target == GL_PROXY_TEXTURE_1D || 628 target == GL_PROXY_TEXTURE_2D || 629 target == GL_PROXY_TEXTURE_3D || 630 target == GL_PROXY_TEXTURE_CUBE_MAP_ARB || 631 target == GL_PROXY_TEXTURE_RECTANGLE_NV || 632 target == GL_PROXY_TEXTURE_1D_ARRAY_EXT || 633 target == GL_PROXY_TEXTURE_2D_ARRAY_EXT); 634} 635 636 637/** 638 * Return the proxy target which corresponds to the given texture target 639 */ 640static GLenum 641get_proxy_target(GLenum target) 642{ 643 switch (target) { 644 case GL_TEXTURE_1D: 645 case GL_PROXY_TEXTURE_1D: 646 return GL_PROXY_TEXTURE_1D; 647 case GL_TEXTURE_2D: 648 case GL_PROXY_TEXTURE_2D: 649 return GL_PROXY_TEXTURE_2D; 650 case GL_TEXTURE_3D: 651 case GL_PROXY_TEXTURE_3D: 652 return GL_PROXY_TEXTURE_3D; 653 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 654 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 655 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 656 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 657 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 658 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 659 case GL_TEXTURE_CUBE_MAP_ARB: 660 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 661 return GL_PROXY_TEXTURE_CUBE_MAP_ARB; 662 case GL_TEXTURE_RECTANGLE_NV: 663 case GL_PROXY_TEXTURE_RECTANGLE_NV: 664 return GL_PROXY_TEXTURE_RECTANGLE_NV; 665 case GL_TEXTURE_1D_ARRAY_EXT: 666 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 667 return GL_PROXY_TEXTURE_1D_ARRAY_EXT; 668 case GL_TEXTURE_2D_ARRAY_EXT: 669 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 670 return GL_PROXY_TEXTURE_2D_ARRAY_EXT; 671 default: 672 _mesa_problem(NULL, "unexpected target in get_proxy_target()"); 673 return 0; 674 } 675} 676 677 678/** 679 * Get the texture object that corresponds to the target of the given 680 * texture unit. The target should have already been checked for validity. 681 * 682 * \param ctx GL context. 683 * \param texUnit texture unit. 684 * \param target texture target. 685 * 686 * \return pointer to the texture object on success, or NULL on failure. 687 */ 688struct gl_texture_object * 689_mesa_select_tex_object(struct gl_context *ctx, 690 const struct gl_texture_unit *texUnit, 691 GLenum target) 692{ 693 const GLboolean arrayTex = (ctx->Extensions.MESA_texture_array || 694 ctx->Extensions.EXT_texture_array); 695 696 switch (target) { 697 case GL_TEXTURE_1D: 698 return texUnit->CurrentTex[TEXTURE_1D_INDEX]; 699 case GL_PROXY_TEXTURE_1D: 700 return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX]; 701 case GL_TEXTURE_2D: 702 return texUnit->CurrentTex[TEXTURE_2D_INDEX]; 703 case GL_PROXY_TEXTURE_2D: 704 return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX]; 705 case GL_TEXTURE_3D: 706 return texUnit->CurrentTex[TEXTURE_3D_INDEX]; 707 case GL_PROXY_TEXTURE_3D: 708 return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; 709 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 710 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 711 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 712 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 713 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 714 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 715 case GL_TEXTURE_CUBE_MAP_ARB: 716 return ctx->Extensions.ARB_texture_cube_map 717 ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL; 718 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 719 return ctx->Extensions.ARB_texture_cube_map 720 ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; 721 case GL_TEXTURE_RECTANGLE_NV: 722 return ctx->Extensions.NV_texture_rectangle 723 ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL; 724 case GL_PROXY_TEXTURE_RECTANGLE_NV: 725 return ctx->Extensions.NV_texture_rectangle 726 ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL; 727 case GL_TEXTURE_1D_ARRAY_EXT: 728 return arrayTex ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL; 729 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 730 return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL; 731 case GL_TEXTURE_2D_ARRAY_EXT: 732 return arrayTex ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL; 733 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 734 return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL; 735 case GL_TEXTURE_BUFFER: 736 return ctx->Extensions.ARB_texture_buffer_object 737 ? texUnit->CurrentTex[TEXTURE_BUFFER_INDEX] : NULL; 738 case GL_TEXTURE_EXTERNAL_OES: 739 return ctx->Extensions.OES_EGL_image_external 740 ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL; 741 default: 742 _mesa_problem(NULL, "bad target in _mesa_select_tex_object()"); 743 return NULL; 744 } 745} 746 747 748/** 749 * Return pointer to texture object for given target on current texture unit. 750 */ 751struct gl_texture_object * 752_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) 753{ 754 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); 755 return _mesa_select_tex_object(ctx, texUnit, target); 756} 757 758 759/** 760 * Get a texture image pointer from a texture object, given a texture 761 * target and mipmap level. The target and level parameters should 762 * have already been error-checked. 763 * 764 * \param ctx GL context. 765 * \param texObj texture unit. 766 * \param target texture target. 767 * \param level image level. 768 * 769 * \return pointer to the texture image structure, or NULL on failure. 770 */ 771struct gl_texture_image * 772_mesa_select_tex_image(struct gl_context *ctx, 773 const struct gl_texture_object *texObj, 774 GLenum target, GLint level) 775{ 776 const GLuint face = _mesa_tex_target_to_face(target); 777 778 ASSERT(texObj); 779 ASSERT(level >= 0); 780 ASSERT(level < MAX_TEXTURE_LEVELS); 781 782 return texObj->Image[face][level]; 783} 784 785 786/** 787 * Like _mesa_select_tex_image() but if the image doesn't exist, allocate 788 * it and install it. Only return NULL if passed a bad parameter or run 789 * out of memory. 790 */ 791struct gl_texture_image * 792_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, 793 GLenum target, GLint level) 794{ 795 struct gl_texture_image *texImage; 796 797 if (!texObj) 798 return NULL; 799 800 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 801 if (!texImage) { 802 texImage = ctx->Driver.NewTextureImage(ctx); 803 if (!texImage) { 804 _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation"); 805 return NULL; 806 } 807 808 set_tex_image(texObj, target, level, texImage); 809 } 810 811 return texImage; 812} 813 814 815/** 816 * Return pointer to the specified proxy texture image. 817 * Note that proxy textures are per-context, not per-texture unit. 818 * \return pointer to texture image or NULL if invalid target, invalid 819 * level, or out of memory. 820 */ 821struct gl_texture_image * 822_mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level) 823{ 824 struct gl_texture_image *texImage; 825 GLuint texIndex; 826 827 if (level < 0 ) 828 return NULL; 829 830 switch (target) { 831 case GL_PROXY_TEXTURE_1D: 832 if (level >= ctx->Const.MaxTextureLevels) 833 return NULL; 834 texIndex = TEXTURE_1D_INDEX; 835 break; 836 case GL_PROXY_TEXTURE_2D: 837 if (level >= ctx->Const.MaxTextureLevels) 838 return NULL; 839 texIndex = TEXTURE_2D_INDEX; 840 break; 841 case GL_PROXY_TEXTURE_3D: 842 if (level >= ctx->Const.Max3DTextureLevels) 843 return NULL; 844 texIndex = TEXTURE_3D_INDEX; 845 break; 846 case GL_PROXY_TEXTURE_CUBE_MAP: 847 if (level >= ctx->Const.MaxCubeTextureLevels) 848 return NULL; 849 texIndex = TEXTURE_CUBE_INDEX; 850 break; 851 case GL_PROXY_TEXTURE_RECTANGLE_NV: 852 if (level > 0) 853 return NULL; 854 texIndex = TEXTURE_RECT_INDEX; 855 break; 856 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 857 if (level >= ctx->Const.MaxTextureLevels) 858 return NULL; 859 texIndex = TEXTURE_1D_ARRAY_INDEX; 860 break; 861 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 862 if (level >= ctx->Const.MaxTextureLevels) 863 return NULL; 864 texIndex = TEXTURE_2D_ARRAY_INDEX; 865 break; 866 default: 867 return NULL; 868 } 869 870 texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level]; 871 if (!texImage) { 872 texImage = ctx->Driver.NewTextureImage(ctx); 873 if (!texImage) { 874 _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); 875 return NULL; 876 } 877 ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage; 878 /* Set the 'back' pointer */ 879 texImage->TexObject = ctx->Texture.ProxyTex[texIndex]; 880 } 881 return texImage; 882} 883 884 885/** 886 * Get the maximum number of allowed mipmap levels. 887 * 888 * \param ctx GL context. 889 * \param target texture target. 890 * 891 * \return the maximum number of allowed mipmap levels for the given 892 * texture target, or zero if passed a bad target. 893 * 894 * \sa gl_constants. 895 */ 896GLint 897_mesa_max_texture_levels(struct gl_context *ctx, GLenum target) 898{ 899 switch (target) { 900 case GL_TEXTURE_1D: 901 case GL_PROXY_TEXTURE_1D: 902 case GL_TEXTURE_2D: 903 case GL_PROXY_TEXTURE_2D: 904 return ctx->Const.MaxTextureLevels; 905 case GL_TEXTURE_3D: 906 case GL_PROXY_TEXTURE_3D: 907 return ctx->Const.Max3DTextureLevels; 908 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 909 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 910 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 911 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 912 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 913 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 914 case GL_TEXTURE_CUBE_MAP_ARB: 915 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 916 return ctx->Extensions.ARB_texture_cube_map 917 ? ctx->Const.MaxCubeTextureLevels : 0; 918 case GL_TEXTURE_RECTANGLE_NV: 919 case GL_PROXY_TEXTURE_RECTANGLE_NV: 920 return ctx->Extensions.NV_texture_rectangle ? 1 : 0; 921 case GL_TEXTURE_1D_ARRAY_EXT: 922 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 923 case GL_TEXTURE_2D_ARRAY_EXT: 924 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 925 return (ctx->Extensions.MESA_texture_array || 926 ctx->Extensions.EXT_texture_array) 927 ? ctx->Const.MaxTextureLevels : 0; 928 case GL_TEXTURE_BUFFER: 929 case GL_TEXTURE_EXTERNAL_OES: 930 /* fall-through */ 931 default: 932 return 0; /* bad target */ 933 } 934} 935 936 937/** 938 * Return number of dimensions per mipmap level for the given texture target. 939 */ 940GLint 941_mesa_get_texture_dimensions(GLenum target) 942{ 943 switch (target) { 944 case GL_TEXTURE_1D: 945 case GL_PROXY_TEXTURE_1D: 946 return 1; 947 case GL_TEXTURE_2D: 948 case GL_TEXTURE_RECTANGLE: 949 case GL_TEXTURE_CUBE_MAP: 950 case GL_PROXY_TEXTURE_2D: 951 case GL_PROXY_TEXTURE_RECTANGLE: 952 case GL_PROXY_TEXTURE_CUBE_MAP: 953 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 954 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 955 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 956 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 957 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 958 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 959 case GL_TEXTURE_1D_ARRAY: 960 case GL_PROXY_TEXTURE_1D_ARRAY: 961 case GL_TEXTURE_EXTERNAL_OES: 962 return 2; 963 case GL_TEXTURE_3D: 964 case GL_PROXY_TEXTURE_3D: 965 case GL_TEXTURE_2D_ARRAY: 966 case GL_PROXY_TEXTURE_2D_ARRAY: 967 return 3; 968 case GL_TEXTURE_BUFFER: 969 /* fall-through */ 970 default: 971 _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()", 972 target); 973 return 2; 974 } 975} 976 977 978 979 980#if 000 /* not used anymore */ 981/* 982 * glTexImage[123]D can accept a NULL image pointer. In this case we 983 * create a texture image with unspecified image contents per the OpenGL 984 * spec. 985 */ 986static GLubyte * 987make_null_texture(GLint width, GLint height, GLint depth, GLenum format) 988{ 989 const GLint components = _mesa_components_in_format(format); 990 const GLint numPixels = width * height * depth; 991 GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte)); 992 993#ifdef DEBUG 994 /* 995 * Let's see if anyone finds this. If glTexImage2D() is called with 996 * a NULL image pointer then load the texture image with something 997 * interesting instead of leaving it indeterminate. 998 */ 999 if (data) { 1000 static const char message[8][32] = { 1001 " X X XXXXX XXX X ", 1002 " XX XX X X X X X ", 1003 " X X X X X X X ", 1004 " X X XXXX XXX XXXXX ", 1005 " X X X X X X ", 1006 " X X X X X X X ", 1007 " X X XXXXX XXX X X ", 1008 " " 1009 }; 1010 1011 GLubyte *imgPtr = data; 1012 GLint h, i, j, k; 1013 for (h = 0; h < depth; h++) { 1014 for (i = 0; i < height; i++) { 1015 GLint srcRow = 7 - (i % 8); 1016 for (j = 0; j < width; j++) { 1017 GLint srcCol = j % 32; 1018 GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70; 1019 for (k = 0; k < components; k++) { 1020 *imgPtr++ = texel; 1021 } 1022 } 1023 } 1024 } 1025 } 1026#endif 1027 1028 return data; 1029} 1030#endif 1031 1032 1033 1034/** 1035 * Set the size and format-related fields of a gl_texture_image struct 1036 * to zero. This is used when a proxy texture test fails. 1037 */ 1038static void 1039clear_teximage_fields(struct gl_texture_image *img) 1040{ 1041 ASSERT(img); 1042 img->_BaseFormat = 0; 1043 img->InternalFormat = 0; 1044 img->Border = 0; 1045 img->Width = 0; 1046 img->Height = 0; 1047 img->Depth = 0; 1048 img->Width2 = 0; 1049 img->Height2 = 0; 1050 img->Depth2 = 0; 1051 img->WidthLog2 = 0; 1052 img->HeightLog2 = 0; 1053 img->DepthLog2 = 0; 1054 img->TexFormat = MESA_FORMAT_NONE; 1055} 1056 1057 1058/** 1059 * Initialize basic fields of the gl_texture_image struct. 1060 * 1061 * \param ctx GL context. 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, 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, array and cube textures supported, not 3D 1640 * Cubemaps are only supported for GL version > 3.0 or with EXT_gpu_shader4 */ 1641 if (target != GL_TEXTURE_1D && 1642 target != GL_PROXY_TEXTURE_1D && 1643 target != GL_TEXTURE_2D && 1644 target != GL_PROXY_TEXTURE_2D && 1645 target != GL_TEXTURE_1D_ARRAY && 1646 target != GL_PROXY_TEXTURE_1D_ARRAY && 1647 target != GL_TEXTURE_2D_ARRAY && 1648 target != GL_PROXY_TEXTURE_2D_ARRAY && 1649 target != GL_TEXTURE_RECTANGLE_ARB && 1650 target != GL_PROXY_TEXTURE_RECTANGLE_ARB && 1651 !((_mesa_is_cube_face(target) || target == GL_PROXY_TEXTURE_CUBE_MAP) && 1652 (ctx->VersionMajor >= 3 || ctx->Extensions.EXT_gpu_shader4))) { 1653 if (!isProxy) 1654 _mesa_error(ctx, GL_INVALID_ENUM, 1655 "glTexImage(target/internalFormat)"); 1656 return GL_TRUE; 1657 } 1658 } 1659 1660 /* additional checks for compressed textures */ 1661 if (_mesa_is_compressed_format(ctx, internalFormat)) { 1662 if (!target_can_be_compressed(ctx, target, internalFormat)) { 1663 if (!isProxy) 1664 _mesa_error(ctx, GL_INVALID_ENUM, 1665 "glTexImage%dD(target)", dimensions); 1666 return GL_TRUE; 1667 } 1668 if (compressedteximage_only_format(ctx, internalFormat)) { 1669 _mesa_error(ctx, GL_INVALID_OPERATION, 1670 "glTexImage%dD(no compression for format)", dimensions); 1671 return GL_TRUE; 1672 } 1673 if (border != 0) { 1674 if (!isProxy) { 1675 _mesa_error(ctx, GL_INVALID_OPERATION, 1676 "glTexImage%dD(border!=0)", dimensions); 1677 } 1678 return GL_TRUE; 1679 } 1680 } 1681 1682 /* additional checks for integer textures */ 1683 if (ctx->Extensions.EXT_texture_integer && 1684 (_mesa_is_integer_format(format) != 1685 _mesa_is_integer_format(internalFormat))) { 1686 if (!isProxy) { 1687 _mesa_error(ctx, GL_INVALID_OPERATION, 1688 "glTexImage%dD(integer/non-integer format mismatch)", 1689 dimensions); 1690 } 1691 return GL_TRUE; 1692 } 1693 1694 if (!mutable_tex_object(ctx, target)) { 1695 _mesa_error(ctx, GL_INVALID_OPERATION, 1696 "glTexImage%dD(immutable texture)", dimensions); 1697 return GL_TRUE; 1698 } 1699 1700 /* if we get here, the parameters are OK */ 1701 return GL_FALSE; 1702} 1703 1704 1705/** 1706 * Test glTexSubImage[123]D() parameters for errors. 1707 * 1708 * \param ctx GL context. 1709 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1710 * \param target texture target given by the user. 1711 * \param level image level given by the user. 1712 * \param xoffset sub-image x offset given by the user. 1713 * \param yoffset sub-image y offset given by the user. 1714 * \param zoffset sub-image z offset given by the user. 1715 * \param format pixel data format given by the user. 1716 * \param type pixel data type given by the user. 1717 * \param width image width given by the user. 1718 * \param height image height given by the user. 1719 * \param depth image depth given by the user. 1720 * 1721 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 1722 * 1723 * Verifies each of the parameters against the constants specified in 1724 * __struct gl_contextRec::Const and the supported extensions, and according 1725 * to the OpenGL specification. 1726 */ 1727static GLboolean 1728subtexture_error_check( struct gl_context *ctx, GLuint dimensions, 1729 GLenum target, GLint level, 1730 GLint xoffset, GLint yoffset, GLint zoffset, 1731 GLint width, GLint height, GLint depth, 1732 GLenum format, GLenum type ) 1733{ 1734 /* Basic level check */ 1735 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1736 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level); 1737 return GL_TRUE; 1738 } 1739 1740 /* Check for negative sizes */ 1741 if (width < 0) { 1742 _mesa_error(ctx, GL_INVALID_VALUE, 1743 "glTexSubImage%dD(width=%d)", dimensions, width); 1744 return GL_TRUE; 1745 } 1746 if (height < 0 && dimensions > 1) { 1747 _mesa_error(ctx, GL_INVALID_VALUE, 1748 "glTexSubImage%dD(height=%d)", dimensions, height); 1749 return GL_TRUE; 1750 } 1751 if (depth < 0 && dimensions > 2) { 1752 _mesa_error(ctx, GL_INVALID_VALUE, 1753 "glTexSubImage%dD(depth=%d)", dimensions, depth); 1754 return GL_TRUE; 1755 } 1756 1757 if (!_mesa_is_legal_format_and_type(ctx, format, type)) { 1758 /* As with the glTexImage2D check above, the error code here 1759 * depends on texture integer. 1760 */ 1761 GLenum error = _mesa_is_integer_format(format) 1762 ? GL_INVALID_OPERATION : GL_INVALID_ENUM; 1763 _mesa_error(ctx, error, 1764 "glTexSubImage%dD(incompatible format 0x%x, type 0x%x)", 1765 dimensions, format, type); 1766 return GL_TRUE; 1767 } 1768 1769 return GL_FALSE; 1770} 1771 1772 1773/** 1774 * Do second part of glTexSubImage which depends on the destination texture. 1775 * \return GL_TRUE if error recorded, GL_FALSE otherwise 1776 */ 1777static GLboolean 1778subtexture_error_check2( struct gl_context *ctx, GLuint dimensions, 1779 GLenum target, GLint level, 1780 GLint xoffset, GLint yoffset, GLint zoffset, 1781 GLint width, GLint height, GLint depth, 1782 GLenum format, GLenum type, 1783 const struct gl_texture_image *destTex ) 1784{ 1785 if (!destTex) { 1786 /* undefined image level */ 1787 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions); 1788 return GL_TRUE; 1789 } 1790 1791 if (xoffset < -((GLint)destTex->Border)) { 1792 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)", 1793 dimensions); 1794 return GL_TRUE; 1795 } 1796 if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) { 1797 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)", 1798 dimensions); 1799 return GL_TRUE; 1800 } 1801 if (dimensions > 1) { 1802 if (yoffset < -((GLint)destTex->Border)) { 1803 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)", 1804 dimensions); 1805 return GL_TRUE; 1806 } 1807 if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) { 1808 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)", 1809 dimensions); 1810 return GL_TRUE; 1811 } 1812 } 1813 if (dimensions > 2) { 1814 if (zoffset < -((GLint)destTex->Border)) { 1815 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)"); 1816 return GL_TRUE; 1817 } 1818 if (zoffset + depth > (GLint) (destTex->Depth + destTex->Border)) { 1819 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)"); 1820 return GL_TRUE; 1821 } 1822 } 1823 1824 if (_mesa_is_format_compressed(destTex->TexFormat)) { 1825 GLuint bw, bh; 1826 1827 if (compressedteximage_only_format(ctx, destTex->InternalFormat)) { 1828 _mesa_error(ctx, GL_INVALID_OPERATION, 1829 "glTexSubImage%dD(no compression for format)", dimensions); 1830 return GL_TRUE; 1831 } 1832 1833 /* do tests which depend on compression block size */ 1834 _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh); 1835 1836 /* offset must be multiple of block size */ 1837 if ((xoffset % bw != 0) || (yoffset % bh != 0)) { 1838 _mesa_error(ctx, GL_INVALID_OPERATION, 1839 "glTexSubImage%dD(xoffset = %d, yoffset = %d)", 1840 dimensions, xoffset, yoffset); 1841 return GL_TRUE; 1842 } 1843 /* size must be multiple of bw by bh or equal to whole texture size */ 1844 if ((width % bw != 0) && (GLuint) width != destTex->Width) { 1845 _mesa_error(ctx, GL_INVALID_OPERATION, 1846 "glTexSubImage%dD(width = %d)", dimensions, width); 1847 return GL_TRUE; 1848 } 1849 if ((height % bh != 0) && (GLuint) height != destTex->Height) { 1850 _mesa_error(ctx, GL_INVALID_OPERATION, 1851 "glTexSubImage%dD(height = %d)", dimensions, height); 1852 return GL_TRUE; 1853 } 1854 } 1855 1856 return GL_FALSE; 1857} 1858 1859 1860/** 1861 * Test glCopyTexImage[12]D() parameters for errors. 1862 * 1863 * \param ctx GL context. 1864 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1865 * \param target texture target given by the user. 1866 * \param level image level given by the user. 1867 * \param internalFormat internal format given by the user. 1868 * \param width image width given by the user. 1869 * \param height image height given by the user. 1870 * \param border texture border. 1871 * 1872 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 1873 * 1874 * Verifies each of the parameters against the constants specified in 1875 * __struct gl_contextRec::Const and the supported extensions, and according 1876 * to the OpenGL specification. 1877 */ 1878static GLboolean 1879copytexture_error_check( struct gl_context *ctx, GLuint dimensions, 1880 GLenum target, GLint level, GLint internalFormat, 1881 GLint width, GLint height, GLint border ) 1882{ 1883 const GLenum proxyTarget = get_proxy_target(target); 1884 const GLenum type = GL_FLOAT; 1885 GLboolean sizeOK; 1886 GLint baseFormat; 1887 1888 /* check target */ 1889 if (!legal_texsubimage_target(ctx, dimensions, target)) { 1890 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)", 1891 dimensions, _mesa_lookup_enum_by_nr(target)); 1892 return GL_TRUE; 1893 } 1894 1895 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */ 1896 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 1897 _mesa_error(ctx, GL_INVALID_VALUE, 1898 "glCopyTexImage%dD(level=%d)", dimensions, level); 1899 return GL_TRUE; 1900 } 1901 1902 /* Check that the source buffer is complete */ 1903 if (_mesa_is_user_fbo(ctx->ReadBuffer)) { 1904 if (ctx->ReadBuffer->_Status == 0) { 1905 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 1906 } 1907 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 1908 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 1909 "glCopyTexImage%dD(invalid readbuffer)", dimensions); 1910 return GL_TRUE; 1911 } 1912 1913 if (ctx->ReadBuffer->Visual.samples > 0) { 1914 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION, 1915 "glCopyTexImage%dD(multisample FBO)", 1916 dimensions); 1917 return GL_TRUE; 1918 } 1919 } 1920 1921 /* Check border */ 1922 if (border < 0 || border > 1 || 1923 ((target == GL_TEXTURE_RECTANGLE_NV || 1924 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) { 1925 return GL_TRUE; 1926 } 1927 1928 baseFormat = _mesa_base_tex_format(ctx, internalFormat); 1929 if (baseFormat < 0) { 1930 _mesa_error(ctx, GL_INVALID_VALUE, 1931 "glCopyTexImage%dD(internalFormat)", dimensions); 1932 return GL_TRUE; 1933 } 1934 1935 if (!_mesa_source_buffer_exists(ctx, baseFormat)) { 1936 _mesa_error(ctx, GL_INVALID_OPERATION, 1937 "glCopyTexImage%dD(missing readbuffer)", dimensions); 1938 return GL_TRUE; 1939 } 1940 1941 /* Do size, level checking */ 1942 sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) 1943 ? (width == height) : 1; 1944 1945 sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level, 1946 internalFormat, baseFormat, 1947 type, width, height, 1948 1, border); 1949 1950 if (!sizeOK) { 1951 if (dimensions == 1) { 1952 _mesa_error(ctx, GL_INVALID_VALUE, 1953 "glCopyTexImage1D(width=%d)", width); 1954 } 1955 else { 1956 ASSERT(dimensions == 2); 1957 _mesa_error(ctx, GL_INVALID_VALUE, 1958 "glCopyTexImage2D(width=%d, height=%d)", width, height); 1959 } 1960 return GL_TRUE; 1961 } 1962 1963 if (_mesa_is_compressed_format(ctx, internalFormat)) { 1964 if (!target_can_be_compressed(ctx, target, internalFormat)) { 1965 _mesa_error(ctx, GL_INVALID_ENUM, 1966 "glCopyTexImage%dD(target)", dimensions); 1967 return GL_TRUE; 1968 } 1969 if (compressedteximage_only_format(ctx, internalFormat)) { 1970 _mesa_error(ctx, GL_INVALID_OPERATION, 1971 "glCopyTexImage%dD(no compression for format)", dimensions); 1972 return GL_TRUE; 1973 } 1974 if (border != 0) { 1975 _mesa_error(ctx, GL_INVALID_OPERATION, 1976 "glCopyTexImage%dD(border!=0)", dimensions); 1977 return GL_TRUE; 1978 } 1979 } 1980 1981 if (!mutable_tex_object(ctx, target)) { 1982 _mesa_error(ctx, GL_INVALID_OPERATION, 1983 "glCopyTexImage%dD(immutable texture)", dimensions); 1984 return GL_TRUE; 1985 } 1986 1987 /* if we get here, the parameters are OK */ 1988 return GL_FALSE; 1989} 1990 1991 1992/** 1993 * Test glCopyTexSubImage[12]D() parameters for errors. 1994 * Note that this is the first part of error checking. 1995 * See also copytexsubimage_error_check2() below for the second part. 1996 * 1997 * \param ctx GL context. 1998 * \param dimensions texture image dimensions (must be 1, 2 or 3). 1999 * \param target texture target given by the user. 2000 * \param level image level given by the user. 2001 * 2002 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors. 2003 */ 2004static GLboolean 2005copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions, 2006 GLenum target, GLint level) 2007{ 2008 /* Check that the source buffer is complete */ 2009 if (_mesa_is_user_fbo(ctx->ReadBuffer)) { 2010 if (ctx->ReadBuffer->_Status == 0) { 2011 _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer); 2012 } 2013 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 2014 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 2015 "glCopyTexImage%dD(invalid readbuffer)", dimensions); 2016 return GL_TRUE; 2017 } 2018 2019 if (ctx->ReadBuffer->Visual.samples > 0) { 2020 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION, 2021 "glCopyTexSubImage%dD(multisample FBO)", 2022 dimensions); 2023 return GL_TRUE; 2024 } 2025 } 2026 2027 /* check target (proxies not allowed) */ 2028 if (!legal_texsubimage_target(ctx, dimensions, target)) { 2029 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)", 2030 dimensions, _mesa_lookup_enum_by_nr(target)); 2031 return GL_TRUE; 2032 } 2033 2034 /* Check level */ 2035 if (level < 0 || level >= MAX_TEXTURE_LEVELS) { 2036 _mesa_error(ctx, GL_INVALID_VALUE, 2037 "glCopyTexSubImage%dD(level=%d)", dimensions, level); 2038 return GL_TRUE; 2039 } 2040 2041 return GL_FALSE; 2042} 2043 2044 2045/** 2046 * Second part of error checking for glCopyTexSubImage[12]D(). 2047 * \param xoffset sub-image x offset given by the user. 2048 * \param yoffset sub-image y offset given by the user. 2049 * \param zoffset sub-image z offset given by the user. 2050 * \param width image width given by the user. 2051 * \param height image height given by the user. 2052 */ 2053static GLboolean 2054copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions, 2055 GLenum target, GLint level, 2056 GLint xoffset, GLint yoffset, GLint zoffset, 2057 GLsizei width, GLsizei height, 2058 const struct gl_texture_image *teximage ) 2059{ 2060 /* check that dest tex image exists */ 2061 if (!teximage) { 2062 _mesa_error(ctx, GL_INVALID_OPERATION, 2063 "glCopyTexSubImage%dD(undefined texture level: %d)", 2064 dimensions, level); 2065 return GL_TRUE; 2066 } 2067 2068 /* Check size */ 2069 if (width < 0) { 2070 _mesa_error(ctx, GL_INVALID_VALUE, 2071 "glCopyTexSubImage%dD(width=%d)", dimensions, width); 2072 return GL_TRUE; 2073 } 2074 if (dimensions > 1 && height < 0) { 2075 _mesa_error(ctx, GL_INVALID_VALUE, 2076 "glCopyTexSubImage%dD(height=%d)", dimensions, height); 2077 return GL_TRUE; 2078 } 2079 2080 /* check x/y offsets */ 2081 if (xoffset < -((GLint)teximage->Border)) { 2082 _mesa_error(ctx, GL_INVALID_VALUE, 2083 "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset); 2084 return GL_TRUE; 2085 } 2086 if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) { 2087 _mesa_error(ctx, GL_INVALID_VALUE, 2088 "glCopyTexSubImage%dD(xoffset+width)", dimensions); 2089 return GL_TRUE; 2090 } 2091 if (dimensions > 1) { 2092 if (yoffset < -((GLint)teximage->Border)) { 2093 _mesa_error(ctx, GL_INVALID_VALUE, 2094 "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset); 2095 return GL_TRUE; 2096 } 2097 /* NOTE: we're adding the border here, not subtracting! */ 2098 if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) { 2099 _mesa_error(ctx, GL_INVALID_VALUE, 2100 "glCopyTexSubImage%dD(yoffset+height)", dimensions); 2101 return GL_TRUE; 2102 } 2103 } 2104 2105 /* check z offset */ 2106 if (dimensions > 2) { 2107 if (zoffset < -((GLint)teximage->Border)) { 2108 _mesa_error(ctx, GL_INVALID_VALUE, 2109 "glCopyTexSubImage%dD(zoffset)", dimensions); 2110 return GL_TRUE; 2111 } 2112 if (zoffset > (GLint) (teximage->Depth + teximage->Border)) { 2113 _mesa_error(ctx, GL_INVALID_VALUE, 2114 "glCopyTexSubImage%dD(zoffset+depth)", dimensions); 2115 return GL_TRUE; 2116 } 2117 } 2118 2119 if (_mesa_is_format_compressed(teximage->TexFormat)) { 2120 if (compressedteximage_only_format(ctx, teximage->InternalFormat)) { 2121 _mesa_error(ctx, GL_INVALID_OPERATION, 2122 "glCopyTexSubImage%dD(no compression for format)", dimensions); 2123 return GL_TRUE; 2124 } 2125 /* offset must be multiple of 4 */ 2126 if ((xoffset & 3) || (yoffset & 3)) { 2127 _mesa_error(ctx, GL_INVALID_VALUE, 2128 "glCopyTexSubImage%dD(xoffset or yoffset)", dimensions); 2129 return GL_TRUE; 2130 } 2131 /* size must be multiple of 4 */ 2132 if ((width & 3) != 0 && (GLuint) width != teximage->Width) { 2133 _mesa_error(ctx, GL_INVALID_VALUE, 2134 "glCopyTexSubImage%dD(width)", dimensions); 2135 return GL_TRUE; 2136 } 2137 if ((height & 3) != 0 && (GLuint) height != teximage->Height) { 2138 _mesa_error(ctx, GL_INVALID_VALUE, 2139 "glCopyTexSubImage%dD(height)", dimensions); 2140 return GL_TRUE; 2141 } 2142 } 2143 2144 if (teximage->InternalFormat == GL_YCBCR_MESA) { 2145 _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D"); 2146 return GL_TRUE; 2147 } 2148 2149 if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) { 2150 _mesa_error(ctx, GL_INVALID_OPERATION, 2151 "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)", 2152 dimensions, teximage->_BaseFormat); 2153 return GL_TRUE; 2154 } 2155 2156 /* If copying into an integer texture, the source buffer must also be 2157 * integer-valued. 2158 */ 2159 if (_mesa_is_format_integer_color(teximage->TexFormat)) { 2160 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; 2161 if (!_mesa_is_format_integer_color(rb->Format)) { 2162 _mesa_error(ctx, GL_INVALID_OPERATION, 2163 "glCopyTexSubImage%dD(source buffer is not integer format)", 2164 dimensions); 2165 return GL_TRUE; 2166 } 2167 } 2168 2169 /* if we get here, the parameters are OK */ 2170 return GL_FALSE; 2171} 2172 2173 2174/** Callback info for walking over FBO hash table */ 2175struct cb_info 2176{ 2177 struct gl_context *ctx; 2178 struct gl_texture_object *texObj; 2179 GLuint level, face; 2180}; 2181 2182 2183/** 2184 * Check render to texture callback. Called from _mesa_HashWalk(). 2185 */ 2186static void 2187check_rtt_cb(GLuint key, void *data, void *userData) 2188{ 2189 struct gl_framebuffer *fb = (struct gl_framebuffer *) data; 2190 const struct cb_info *info = (struct cb_info *) userData; 2191 struct gl_context *ctx = info->ctx; 2192 const struct gl_texture_object *texObj = info->texObj; 2193 const GLuint level = info->level, face = info->face; 2194 2195 /* If this is a user-created FBO */ 2196 if (_mesa_is_user_fbo(fb)) { 2197 GLuint i; 2198 /* check if any of the FBO's attachments point to 'texObj' */ 2199 for (i = 0; i < BUFFER_COUNT; i++) { 2200 struct gl_renderbuffer_attachment *att = fb->Attachment + i; 2201 if (att->Type == GL_TEXTURE && 2202 att->Texture == texObj && 2203 att->TextureLevel == level && 2204 att->CubeMapFace == face) { 2205 ASSERT(_mesa_get_attachment_teximage(att)); 2206 /* Tell driver about the new renderbuffer texture */ 2207 ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att); 2208 /* Mark fb status as indeterminate to force re-validation */ 2209 fb->_Status = 0; 2210 } 2211 } 2212 } 2213} 2214 2215 2216/** 2217 * When a texture image is specified we have to check if it's bound to 2218 * any framebuffer objects (render to texture) in order to detect changes 2219 * in size or format since that effects FBO completeness. 2220 * Any FBOs rendering into the texture must be re-validated. 2221 */ 2222void 2223_mesa_update_fbo_texture(struct gl_context *ctx, 2224 struct gl_texture_object *texObj, 2225 GLuint face, GLuint level) 2226{ 2227 /* Only check this texture if it's been marked as RenderToTexture */ 2228 if (texObj->_RenderToTexture) { 2229 struct cb_info info; 2230 info.ctx = ctx; 2231 info.texObj = texObj; 2232 info.level = level; 2233 info.face = face; 2234 _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info); 2235 } 2236} 2237 2238 2239/** 2240 * If the texture object's GenerateMipmap flag is set and we've 2241 * changed the texture base level image, regenerate the rest of the 2242 * mipmap levels now. 2243 */ 2244static inline void 2245check_gen_mipmap(struct gl_context *ctx, GLenum target, 2246 struct gl_texture_object *texObj, GLint level) 2247{ 2248 ASSERT(target != GL_TEXTURE_CUBE_MAP); 2249 if (texObj->GenerateMipmap && 2250 level == texObj->BaseLevel && 2251 level < texObj->MaxLevel) { 2252 ASSERT(ctx->Driver.GenerateMipmap); 2253 ctx->Driver.GenerateMipmap(ctx, target, texObj); 2254 } 2255} 2256 2257 2258/** Debug helper: override the user-requested internal format */ 2259static GLenum 2260override_internal_format(GLenum internalFormat, GLint width, GLint height) 2261{ 2262#if 0 2263 if (internalFormat == GL_RGBA16F_ARB || 2264 internalFormat == GL_RGBA32F_ARB) { 2265 printf("Convert rgba float tex to int %d x %d\n", width, height); 2266 return GL_RGBA; 2267 } 2268 else if (internalFormat == GL_RGB16F_ARB || 2269 internalFormat == GL_RGB32F_ARB) { 2270 printf("Convert rgb float tex to int %d x %d\n", width, height); 2271 return GL_RGB; 2272 } 2273 else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB || 2274 internalFormat == GL_LUMINANCE_ALPHA32F_ARB) { 2275 printf("Convert luminance float tex to int %d x %d\n", width, height); 2276 return GL_LUMINANCE_ALPHA; 2277 } 2278 else if (internalFormat == GL_LUMINANCE16F_ARB || 2279 internalFormat == GL_LUMINANCE32F_ARB) { 2280 printf("Convert luminance float tex to int %d x %d\n", width, height); 2281 return GL_LUMINANCE; 2282 } 2283 else if (internalFormat == GL_ALPHA16F_ARB || 2284 internalFormat == GL_ALPHA32F_ARB) { 2285 printf("Convert luminance float tex to int %d x %d\n", width, height); 2286 return GL_ALPHA; 2287 } 2288 /* 2289 else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) { 2290 internalFormat = GL_RGBA; 2291 } 2292 */ 2293 else { 2294 return internalFormat; 2295 } 2296#else 2297 return internalFormat; 2298#endif 2299} 2300 2301 2302/** 2303 * Choose the actual hardware format for a texture image. 2304 * Try to use the same format as the previous image level when possible. 2305 * Otherwise, ask the driver for the best format. 2306 * It's important to try to choose a consistant format for all levels 2307 * for efficient texture memory layout/allocation. In particular, this 2308 * comes up during automatic mipmap generation. 2309 */ 2310gl_format 2311_mesa_choose_texture_format(struct gl_context *ctx, 2312 struct gl_texture_object *texObj, 2313 GLenum target, GLint level, 2314 GLenum internalFormat, GLenum format, GLenum type) 2315{ 2316 gl_format f; 2317 2318 /* see if we've already chosen a format for the previous level */ 2319 if (level > 0) { 2320 struct gl_texture_image *prevImage = 2321 _mesa_select_tex_image(ctx, texObj, target, level - 1); 2322 /* See if the prev level is defined and has an internal format which 2323 * matches the new internal format. 2324 */ 2325 if (prevImage && 2326 prevImage->Width > 0 && 2327 prevImage->InternalFormat == internalFormat) { 2328 /* use the same format */ 2329 ASSERT(prevImage->TexFormat != MESA_FORMAT_NONE); 2330 return prevImage->TexFormat; 2331 } 2332 } 2333 2334 /* choose format from scratch */ 2335 f = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type); 2336 ASSERT(f != MESA_FORMAT_NONE); 2337 return f; 2338} 2339 2340/** 2341 * Adjust pixel unpack params and image dimensions to strip off the 2342 * texture border. 2343 * 2344 * Gallium and intel don't support texture borders. They've seldem been used 2345 * and seldom been implemented correctly anyway. 2346 * 2347 * \param unpackNew returns the new pixel unpack parameters 2348 */ 2349static void 2350strip_texture_border(GLint *border, 2351 GLint *width, GLint *height, GLint *depth, 2352 const struct gl_pixelstore_attrib *unpack, 2353 struct gl_pixelstore_attrib *unpackNew) 2354{ 2355 assert(*border > 0); /* sanity check */ 2356 2357 *unpackNew = *unpack; 2358 2359 if (unpackNew->RowLength == 0) 2360 unpackNew->RowLength = *width; 2361 2362 if (depth && unpackNew->ImageHeight == 0) 2363 unpackNew->ImageHeight = *height; 2364 2365 unpackNew->SkipPixels += *border; 2366 if (height) 2367 unpackNew->SkipRows += *border; 2368 if (depth) 2369 unpackNew->SkipImages += *border; 2370 2371 assert(*width >= 3); 2372 *width = *width - 2 * *border; 2373 if (height && *height >= 3) 2374 *height = *height - 2 * *border; 2375 if (depth && *depth >= 3) 2376 *depth = *depth - 2 * *border; 2377 *border = 0; 2378} 2379 2380/** 2381 * Common code to implement all the glTexImage1D/2D/3D functions. 2382 */ 2383static void 2384teximage(struct gl_context *ctx, GLuint dims, 2385 GLenum target, GLint level, GLint internalFormat, 2386 GLsizei width, GLsizei height, GLsizei depth, 2387 GLint border, GLenum format, GLenum type, 2388 const GLvoid *pixels) 2389{ 2390 GLboolean error; 2391 struct gl_pixelstore_attrib unpack_no_border; 2392 const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; 2393 2394 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2395 2396 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2397 _mesa_debug(ctx, "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n", 2398 dims, 2399 _mesa_lookup_enum_by_nr(target), level, 2400 _mesa_lookup_enum_by_nr(internalFormat), 2401 width, height, depth, border, 2402 _mesa_lookup_enum_by_nr(format), 2403 _mesa_lookup_enum_by_nr(type), pixels); 2404 2405 internalFormat = override_internal_format(internalFormat, width, height); 2406 2407 /* target error checking */ 2408 if (!legal_teximage_target(ctx, dims, target)) { 2409 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uD(target=%s)", 2410 dims, _mesa_lookup_enum_by_nr(target)); 2411 return; 2412 } 2413 2414 /* general error checking */ 2415 error = texture_error_check(ctx, dims, target, level, internalFormat, 2416 format, type, width, height, depth, border); 2417 2418 if (_mesa_is_proxy_texture(target)) { 2419 /* Proxy texture: just clear or set state depending on error checking */ 2420 struct gl_texture_image *texImage = 2421 _mesa_get_proxy_tex_image(ctx, target, level); 2422 2423 if (error) { 2424 /* when error, clear all proxy texture image parameters */ 2425 if (texImage) 2426 clear_teximage_fields(texImage); 2427 } 2428 else { 2429 /* no error, set the tex image parameters */ 2430 struct gl_texture_object *texObj = 2431 _mesa_get_current_tex_object(ctx, target); 2432 gl_format texFormat = _mesa_choose_texture_format(ctx, texObj, 2433 target, level, 2434 internalFormat, 2435 format, type); 2436 2437 if (legal_texture_size(ctx, texFormat, width, height, depth)) { 2438 _mesa_init_teximage_fields(ctx, texImage, width, height, 2439 depth, border, internalFormat, 2440 texFormat); 2441 } 2442 else if (texImage) { 2443 clear_teximage_fields(texImage); 2444 } 2445 } 2446 } 2447 else { 2448 /* non-proxy target */ 2449 const GLuint face = _mesa_tex_target_to_face(target); 2450 struct gl_texture_object *texObj; 2451 struct gl_texture_image *texImage; 2452 2453 if (error) { 2454 return; /* error was recorded */ 2455 } 2456 2457 /* Allow a hardware driver to just strip out the border, to provide 2458 * reliable but slightly incorrect hardware rendering instead of 2459 * rarely-tested software fallback rendering. 2460 */ 2461 if (border && ctx->Const.StripTextureBorder) { 2462 strip_texture_border(&border, &width, &height, &depth, unpack, 2463 &unpack_no_border); 2464 unpack = &unpack_no_border; 2465 } 2466 2467 if (ctx->NewState & _NEW_PIXEL) 2468 _mesa_update_state(ctx); 2469 2470 texObj = _mesa_get_current_tex_object(ctx, target); 2471 2472 _mesa_lock_texture(ctx, texObj); 2473 { 2474 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2475 2476 if (!texImage) { 2477 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); 2478 } 2479 else { 2480 gl_format texFormat; 2481 2482 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 2483 2484 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 2485 internalFormat, format, 2486 type); 2487 2488 if (legal_texture_size(ctx, texFormat, width, height, depth)) { 2489 _mesa_init_teximage_fields(ctx, texImage, 2490 width, height, depth, 2491 border, internalFormat, texFormat); 2492 2493 /* Give the texture to the driver. <pixels> may be null. */ 2494 ASSERT(ctx->Driver.TexImage3D); 2495 switch (dims) { 2496 case 1: 2497 ctx->Driver.TexImage1D(ctx, texImage, internalFormat, 2498 width, border, format, 2499 type, pixels, unpack); 2500 break; 2501 case 2: 2502 ctx->Driver.TexImage2D(ctx, texImage, internalFormat, 2503 width, height, border, format, 2504 type, pixels, unpack); 2505 break; 2506 case 3: 2507 ctx->Driver.TexImage3D(ctx, texImage, internalFormat, 2508 width, height, depth, border, format, 2509 type, pixels, unpack); 2510 break; 2511 default: 2512 _mesa_problem(ctx, "invalid dims=%u in teximage()", dims); 2513 } 2514 2515 check_gen_mipmap(ctx, target, texObj, level); 2516 2517 _mesa_update_fbo_texture(ctx, texObj, face, level); 2518 2519 /* state update */ 2520 texObj->_Complete = GL_FALSE; 2521 ctx->NewState |= _NEW_TEXTURE; 2522 } 2523 else { 2524 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); 2525 } 2526 } 2527 } 2528 _mesa_unlock_texture(ctx, texObj); 2529 } 2530} 2531 2532 2533/* 2534 * Called from the API. Note that width includes the border. 2535 */ 2536void GLAPIENTRY 2537_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, 2538 GLsizei width, GLint border, GLenum format, 2539 GLenum type, const GLvoid *pixels ) 2540{ 2541 GET_CURRENT_CONTEXT(ctx); 2542 teximage(ctx, 1, target, level, internalFormat, width, 1, 1, 2543 border, format, type, pixels); 2544} 2545 2546 2547void GLAPIENTRY 2548_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 2549 GLsizei width, GLsizei height, GLint border, 2550 GLenum format, GLenum type, 2551 const GLvoid *pixels ) 2552{ 2553 GET_CURRENT_CONTEXT(ctx); 2554 teximage(ctx, 2, target, level, internalFormat, width, height, 1, 2555 border, format, type, pixels); 2556} 2557 2558 2559/* 2560 * Called by the API or display list executor. 2561 * Note that width and height include the border. 2562 */ 2563void GLAPIENTRY 2564_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, 2565 GLsizei width, GLsizei height, GLsizei depth, 2566 GLint border, GLenum format, GLenum type, 2567 const GLvoid *pixels ) 2568{ 2569 GET_CURRENT_CONTEXT(ctx); 2570 teximage(ctx, 3, target, level, internalFormat, width, height, depth, 2571 border, format, type, pixels); 2572} 2573 2574 2575void GLAPIENTRY 2576_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, 2577 GLsizei width, GLsizei height, GLsizei depth, 2578 GLint border, GLenum format, GLenum type, 2579 const GLvoid *pixels ) 2580{ 2581 _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height, 2582 depth, border, format, type, pixels); 2583} 2584 2585 2586#if FEATURE_OES_EGL_image 2587void GLAPIENTRY 2588_mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image) 2589{ 2590 struct gl_texture_object *texObj; 2591 struct gl_texture_image *texImage; 2592 GET_CURRENT_CONTEXT(ctx); 2593 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2594 2595 if ((target == GL_TEXTURE_2D && 2596 !ctx->Extensions.OES_EGL_image) || 2597 (target == GL_TEXTURE_EXTERNAL_OES && 2598 !ctx->Extensions.OES_EGL_image_external)) { 2599 _mesa_error(ctx, GL_INVALID_ENUM, 2600 "glEGLImageTargetTexture2D(target=%d)", target); 2601 return; 2602 } 2603 2604 if (ctx->NewState & _NEW_PIXEL) 2605 _mesa_update_state(ctx); 2606 2607 texObj = _mesa_get_current_tex_object(ctx, target); 2608 _mesa_lock_texture(ctx, texObj); 2609 2610 texImage = _mesa_get_tex_image(ctx, texObj, target, 0); 2611 if (!texImage) { 2612 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEGLImageTargetTexture2D"); 2613 } else { 2614 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 2615 2616 ctx->Driver.EGLImageTargetTexture2D(ctx, target, 2617 texObj, texImage, image); 2618 2619 /* state update */ 2620 texObj->_Complete = GL_FALSE; 2621 ctx->NewState |= _NEW_TEXTURE; 2622 } 2623 _mesa_unlock_texture(ctx, texObj); 2624 2625} 2626#endif 2627 2628 2629 2630/** 2631 * Implement all the glTexSubImage1/2/3D() functions. 2632 */ 2633static void 2634texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, 2635 GLint xoffset, GLint yoffset, GLint zoffset, 2636 GLsizei width, GLsizei height, GLsizei depth, 2637 GLenum format, GLenum type, const GLvoid *pixels ) 2638{ 2639 struct gl_texture_object *texObj; 2640 struct gl_texture_image *texImage; 2641 2642 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2643 2644 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2645 _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n", 2646 dims, 2647 _mesa_lookup_enum_by_nr(target), level, 2648 xoffset, yoffset, zoffset, width, height, depth, 2649 _mesa_lookup_enum_by_nr(format), 2650 _mesa_lookup_enum_by_nr(type), pixels); 2651 2652 /* check target (proxies not allowed) */ 2653 if (!legal_texsubimage_target(ctx, dims, target)) { 2654 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)", 2655 dims, _mesa_lookup_enum_by_nr(target)); 2656 return; 2657 } 2658 2659 if (ctx->NewState & _NEW_PIXEL) 2660 _mesa_update_state(ctx); 2661 2662 if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset, 2663 width, height, depth, format, type)) { 2664 return; /* error was detected */ 2665 } 2666 2667 texObj = _mesa_get_current_tex_object(ctx, target); 2668 2669 _mesa_lock_texture(ctx, texObj); 2670 { 2671 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 2672 2673 if (subtexture_error_check2(ctx, dims, target, level, 2674 xoffset, yoffset, zoffset, 2675 width, height, depth, 2676 format, type, texImage)) { 2677 /* error was recorded */ 2678 } 2679 else if (width > 0 && height > 0 && depth > 0) { 2680 /* If we have a border, offset=-1 is legal. Bias by border width. */ 2681 switch (dims) { 2682 case 3: 2683 zoffset += texImage->Border; 2684 /* fall-through */ 2685 case 2: 2686 yoffset += texImage->Border; 2687 /* fall-through */ 2688 case 1: 2689 xoffset += texImage->Border; 2690 } 2691 2692 switch (dims) { 2693 case 1: 2694 ctx->Driver.TexSubImage1D(ctx, texImage, 2695 xoffset, width, 2696 format, type, pixels, &ctx->Unpack); 2697 break; 2698 case 2: 2699 ctx->Driver.TexSubImage2D(ctx, texImage, 2700 xoffset, yoffset, width, height, 2701 format, type, pixels, &ctx->Unpack); 2702 break; 2703 case 3: 2704 ctx->Driver.TexSubImage3D(ctx, texImage, 2705 xoffset, yoffset, zoffset, 2706 width, height, depth, 2707 format, type, pixels, &ctx->Unpack); 2708 break; 2709 default: 2710 _mesa_problem(ctx, "unexpected dims in subteximage()"); 2711 } 2712 2713 check_gen_mipmap(ctx, target, texObj, level); 2714 2715 ctx->NewState |= _NEW_TEXTURE; 2716 } 2717 } 2718 _mesa_unlock_texture(ctx, texObj); 2719} 2720 2721 2722void GLAPIENTRY 2723_mesa_TexSubImage1D( GLenum target, GLint level, 2724 GLint xoffset, GLsizei width, 2725 GLenum format, GLenum type, 2726 const GLvoid *pixels ) 2727{ 2728 GET_CURRENT_CONTEXT(ctx); 2729 texsubimage(ctx, 1, target, level, 2730 xoffset, 0, 0, 2731 width, 1, 1, 2732 format, type, pixels); 2733} 2734 2735 2736void GLAPIENTRY 2737_mesa_TexSubImage2D( GLenum target, GLint level, 2738 GLint xoffset, GLint yoffset, 2739 GLsizei width, GLsizei height, 2740 GLenum format, GLenum type, 2741 const GLvoid *pixels ) 2742{ 2743 GET_CURRENT_CONTEXT(ctx); 2744 texsubimage(ctx, 2, target, level, 2745 xoffset, yoffset, 0, 2746 width, height, 1, 2747 format, type, pixels); 2748} 2749 2750 2751 2752void GLAPIENTRY 2753_mesa_TexSubImage3D( GLenum target, GLint level, 2754 GLint xoffset, GLint yoffset, GLint zoffset, 2755 GLsizei width, GLsizei height, GLsizei depth, 2756 GLenum format, GLenum type, 2757 const GLvoid *pixels ) 2758{ 2759 GET_CURRENT_CONTEXT(ctx); 2760 texsubimage(ctx, 3, target, level, 2761 xoffset, yoffset, zoffset, 2762 width, height, depth, 2763 format, type, pixels); 2764} 2765 2766 2767 2768/** 2769 * For glCopyTexSubImage, return the source renderbuffer to copy texel data 2770 * from. This depends on whether the texture contains color or depth values. 2771 */ 2772static struct gl_renderbuffer * 2773get_copy_tex_image_source(struct gl_context *ctx, gl_format texFormat) 2774{ 2775 if (_mesa_get_format_bits(texFormat, GL_DEPTH_BITS) > 0) { 2776 /* reading from depth/stencil buffer */ 2777 return ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 2778 } 2779 else { 2780 /* copying from color buffer */ 2781 return ctx->ReadBuffer->_ColorReadBuffer; 2782 } 2783} 2784 2785 2786 2787/** 2788 * Implement the glCopyTexImage1/2D() functions. 2789 */ 2790static void 2791copyteximage(struct gl_context *ctx, GLuint dims, 2792 GLenum target, GLint level, GLenum internalFormat, 2793 GLint x, GLint y, GLsizei width, GLsizei height, GLint border ) 2794{ 2795 struct gl_texture_object *texObj; 2796 struct gl_texture_image *texImage; 2797 const GLuint face = _mesa_tex_target_to_face(target); 2798 2799 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2800 2801 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2802 _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n", 2803 dims, 2804 _mesa_lookup_enum_by_nr(target), level, 2805 _mesa_lookup_enum_by_nr(internalFormat), 2806 x, y, width, height, border); 2807 2808 if (ctx->NewState & NEW_COPY_TEX_STATE) 2809 _mesa_update_state(ctx); 2810 2811 if (copytexture_error_check(ctx, dims, target, level, internalFormat, 2812 width, height, border)) 2813 return; 2814 2815 texObj = _mesa_get_current_tex_object(ctx, target); 2816 2817 if (border && ctx->Const.StripTextureBorder) { 2818 x += border; 2819 width -= border * 2; 2820 if (dims == 2) { 2821 y += border; 2822 height -= border * 2; 2823 } 2824 border = 0; 2825 } 2826 2827 _mesa_lock_texture(ctx, texObj); 2828 { 2829 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 2830 2831 if (!texImage) { 2832 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); 2833 } 2834 else { 2835 /* choose actual hw format */ 2836 gl_format texFormat = _mesa_choose_texture_format(ctx, texObj, 2837 target, level, 2838 internalFormat, 2839 GL_NONE, GL_NONE); 2840 2841 if (legal_texture_size(ctx, texFormat, width, height, 1)) { 2842 GLint srcX = x, srcY = y, dstX = 0, dstY = 0; 2843 2844 /* Free old texture image */ 2845 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 2846 2847 _mesa_init_teximage_fields(ctx, texImage, width, height, 1, 2848 border, internalFormat, texFormat); 2849 2850 /* Allocate texture memory (no pixel data yet) */ 2851 if (dims == 1) { 2852 ctx->Driver.TexImage1D(ctx, texImage, internalFormat, 2853 width, border, GL_NONE, GL_NONE, NULL, 2854 &ctx->Unpack); 2855 } 2856 else { 2857 ctx->Driver.TexImage2D(ctx, texImage, internalFormat, 2858 width, height, border, GL_NONE, GL_NONE, 2859 NULL, &ctx->Unpack); 2860 } 2861 2862 if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY, 2863 &width, &height)) { 2864 struct gl_renderbuffer *srcRb = 2865 get_copy_tex_image_source(ctx, texImage->TexFormat); 2866 2867 if (dims == 1) 2868 ctx->Driver.CopyTexSubImage1D(ctx, texImage, dstX, 2869 srcRb, srcX, srcY, width); 2870 2871 else 2872 ctx->Driver.CopyTexSubImage2D(ctx, texImage, dstX, dstY, 2873 srcRb, srcX, srcY, width, height); 2874 } 2875 2876 check_gen_mipmap(ctx, target, texObj, level); 2877 2878 _mesa_update_fbo_texture(ctx, texObj, face, level); 2879 2880 /* state update */ 2881 texObj->_Complete = GL_FALSE; 2882 ctx->NewState |= _NEW_TEXTURE; 2883 } 2884 else { 2885 /* probably too large of image */ 2886 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims); 2887 } 2888 } 2889 } 2890 _mesa_unlock_texture(ctx, texObj); 2891} 2892 2893 2894 2895void GLAPIENTRY 2896_mesa_CopyTexImage1D( GLenum target, GLint level, 2897 GLenum internalFormat, 2898 GLint x, GLint y, 2899 GLsizei width, GLint border ) 2900{ 2901 GET_CURRENT_CONTEXT(ctx); 2902 copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border); 2903} 2904 2905 2906 2907void GLAPIENTRY 2908_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, 2909 GLint x, GLint y, GLsizei width, GLsizei height, 2910 GLint border ) 2911{ 2912 GET_CURRENT_CONTEXT(ctx); 2913 copyteximage(ctx, 2, target, level, internalFormat, 2914 x, y, width, height, border); 2915} 2916 2917 2918 2919/** 2920 * Implementation for glCopyTexSubImage1/2/3D() functions. 2921 */ 2922static void 2923copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, 2924 GLint xoffset, GLint yoffset, GLint zoffset, 2925 GLint x, GLint y, GLsizei width, GLsizei height) 2926{ 2927 struct gl_texture_object *texObj; 2928 struct gl_texture_image *texImage; 2929 2930 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2931 2932 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 2933 _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n", 2934 dims, 2935 _mesa_lookup_enum_by_nr(target), 2936 level, xoffset, yoffset, zoffset, x, y, width, height); 2937 2938 if (ctx->NewState & NEW_COPY_TEX_STATE) 2939 _mesa_update_state(ctx); 2940 2941 if (copytexsubimage_error_check1(ctx, dims, target, level)) 2942 return; 2943 2944 texObj = _mesa_get_current_tex_object(ctx, target); 2945 2946 _mesa_lock_texture(ctx, texObj); 2947 { 2948 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 2949 2950 if (copytexsubimage_error_check2(ctx, dims, target, level, xoffset, yoffset, 2951 zoffset, width, height, texImage)) { 2952 /* error was recored */ 2953 } 2954 else { 2955 /* If we have a border, offset=-1 is legal. Bias by border width. */ 2956 switch (dims) { 2957 case 3: 2958 zoffset += texImage->Border; 2959 /* fall-through */ 2960 case 2: 2961 yoffset += texImage->Border; 2962 /* fall-through */ 2963 case 1: 2964 xoffset += texImage->Border; 2965 } 2966 2967 if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y, 2968 &width, &height)) { 2969 struct gl_renderbuffer *srcRb = 2970 get_copy_tex_image_source(ctx, texImage->TexFormat); 2971 2972 switch (dims) { 2973 case 1: 2974 ctx->Driver.CopyTexSubImage1D(ctx, texImage, xoffset, 2975 srcRb, x, y, width); 2976 break; 2977 case 2: 2978 ctx->Driver.CopyTexSubImage2D(ctx, texImage, xoffset, yoffset, 2979 srcRb, x, y, width, height); 2980 break; 2981 case 3: 2982 ctx->Driver.CopyTexSubImage3D(ctx, texImage, 2983 xoffset, yoffset, zoffset, 2984 srcRb, x, y, width, height); 2985 break; 2986 default: 2987 _mesa_problem(ctx, "bad dims in copytexsubimage()"); 2988 } 2989 2990 check_gen_mipmap(ctx, target, texObj, level); 2991 2992 ctx->NewState |= _NEW_TEXTURE; 2993 } 2994 } 2995 } 2996 _mesa_unlock_texture(ctx, texObj); 2997} 2998 2999 3000void GLAPIENTRY 3001_mesa_CopyTexSubImage1D( GLenum target, GLint level, 3002 GLint xoffset, GLint x, GLint y, GLsizei width ) 3003{ 3004 GET_CURRENT_CONTEXT(ctx); 3005 copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1); 3006} 3007 3008 3009 3010void GLAPIENTRY 3011_mesa_CopyTexSubImage2D( GLenum target, GLint level, 3012 GLint xoffset, GLint yoffset, 3013 GLint x, GLint y, GLsizei width, GLsizei height ) 3014{ 3015 GET_CURRENT_CONTEXT(ctx); 3016 copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y, 3017 width, height); 3018} 3019 3020 3021 3022void GLAPIENTRY 3023_mesa_CopyTexSubImage3D( GLenum target, GLint level, 3024 GLint xoffset, GLint yoffset, GLint zoffset, 3025 GLint x, GLint y, GLsizei width, GLsizei height ) 3026{ 3027 GET_CURRENT_CONTEXT(ctx); 3028 copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, 3029 x, y, width, height); 3030} 3031 3032 3033 3034 3035/**********************************************************************/ 3036/****** Compressed Textures ******/ 3037/**********************************************************************/ 3038 3039 3040/** 3041 * Return expected size of a compressed texture. 3042 */ 3043static GLuint 3044compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth, 3045 GLenum glformat) 3046{ 3047 gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 3048 return _mesa_format_image_size(mesaFormat, width, height, depth); 3049} 3050 3051 3052/* 3053 * Return compressed texture block size, in pixels. 3054 */ 3055static void 3056get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh) 3057{ 3058 gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat); 3059 _mesa_get_format_block_size(mesaFormat, bw, bh); 3060} 3061 3062 3063/** 3064 * Error checking for glCompressedTexImage[123]D(). 3065 * \param reason returns reason for error, if any 3066 * \return error code or GL_NO_ERROR. 3067 */ 3068static GLenum 3069compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, 3070 GLenum target, GLint level, 3071 GLenum internalFormat, GLsizei width, 3072 GLsizei height, GLsizei depth, GLint border, 3073 GLsizei imageSize, char **reason) 3074{ 3075 const GLenum proxyTarget = get_proxy_target(target); 3076 const GLint maxLevels = _mesa_max_texture_levels(ctx, target); 3077 GLint expectedSize; 3078 GLenum choose_format; 3079 GLenum choose_type; 3080 GLenum proxy_format; 3081 3082 *reason = ""; /* no error */ 3083 3084 if (!target_can_be_compressed(ctx, target, internalFormat)) { 3085 *reason = "target"; 3086 return GL_INVALID_ENUM; 3087 } 3088 3089 /* This will detect any invalid internalFormat value */ 3090 if (!_mesa_is_compressed_format(ctx, internalFormat)) { 3091 *reason = "internalFormat"; 3092 return GL_INVALID_ENUM; 3093 } 3094 3095 switch (internalFormat) { 3096#if FEATURE_ES 3097 case GL_PALETTE4_RGB8_OES: 3098 case GL_PALETTE4_RGBA8_OES: 3099 case GL_PALETTE4_R5_G6_B5_OES: 3100 case GL_PALETTE4_RGBA4_OES: 3101 case GL_PALETTE4_RGB5_A1_OES: 3102 case GL_PALETTE8_RGB8_OES: 3103 case GL_PALETTE8_RGBA8_OES: 3104 case GL_PALETTE8_R5_G6_B5_OES: 3105 case GL_PALETTE8_RGBA4_OES: 3106 case GL_PALETTE8_RGB5_A1_OES: 3107 _mesa_cpal_compressed_format_type(internalFormat, &choose_format, 3108 &choose_type); 3109 proxy_format = choose_format; 3110 3111 /* check level */ 3112 if (level > 0 || level < -maxLevels) { 3113 *reason = "level"; 3114 return GL_INVALID_VALUE; 3115 } 3116 3117 if (dimensions != 2) { 3118 *reason = "compressed paletted textures must be 2D"; 3119 return GL_INVALID_OPERATION; 3120 } 3121 3122 /* Figure out the expected texture size (in bytes). This will be 3123 * checked against the actual size later. 3124 */ 3125 expectedSize = _mesa_cpal_compressed_size(level, internalFormat, 3126 width, height); 3127 3128 /* This is for the benefit of the TestProxyTexImage below. It expects 3129 * level to be non-negative. OES_compressed_paletted_texture uses a 3130 * weird mechanism where the level specified to glCompressedTexImage2D 3131 * is -(n-1) number of levels in the texture, and the data specifies the 3132 * complete mipmap stack. This is done to ensure the palette is the 3133 * same for all levels. 3134 */ 3135 level = -level; 3136 break; 3137#endif 3138 3139 default: 3140 choose_format = GL_NONE; 3141 choose_type = GL_NONE; 3142 proxy_format = internalFormat; 3143 3144 /* check level */ 3145 if (level < 0 || level >= maxLevels) { 3146 *reason = "level"; 3147 return GL_INVALID_VALUE; 3148 } 3149 3150 /* Figure out the expected texture size (in bytes). This will be 3151 * checked against the actual size later. 3152 */ 3153 expectedSize = compressed_tex_size(width, height, depth, internalFormat); 3154 break; 3155 } 3156 3157 /* This should really never fail */ 3158 if (_mesa_base_tex_format(ctx, internalFormat) < 0) { 3159 *reason = "internalFormat"; 3160 return GL_INVALID_ENUM; 3161 } 3162 3163 /* No compressed formats support borders at this time */ 3164 if (border != 0) { 3165 *reason = "border != 0"; 3166 return GL_INVALID_VALUE; 3167 } 3168 3169 /* For cube map, width must equal height */ 3170 if (_mesa_is_cube_face(target) && width != height) { 3171 *reason = "width != height"; 3172 return GL_INVALID_VALUE; 3173 } 3174 3175 /* check image size against compression block size */ 3176 { 3177 gl_format texFormat = 3178 ctx->Driver.ChooseTextureFormat(ctx, proxy_format, 3179 choose_format, choose_type); 3180 GLuint bw, bh; 3181 3182 _mesa_get_format_block_size(texFormat, &bw, &bh); 3183 if ((width > bw && width % bw > 0) || 3184 (height > bh && height % bh > 0)) { 3185 /* 3186 * Per GL_ARB_texture_compression: GL_INVALID_OPERATION is 3187 * generated [...] if any parameter combinations are not 3188 * supported by the specific compressed internal format. 3189 */ 3190 *reason = "invalid width or height for compression format"; 3191 return GL_INVALID_OPERATION; 3192 } 3193 } 3194 3195 /* check image sizes */ 3196 if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level, 3197 proxy_format, choose_format, 3198 choose_type, 3199 width, height, depth, border)) { 3200 /* See error comment above */ 3201 *reason = "invalid width, height or format"; 3202 return GL_INVALID_OPERATION; 3203 } 3204 3205 /* check image size in bytes */ 3206 if (expectedSize != imageSize) { 3207 /* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...] 3208 * if <imageSize> is not consistent with the format, dimensions, and 3209 * contents of the specified image. 3210 */ 3211 *reason = "imageSize inconsistant with width/height/format"; 3212 return GL_INVALID_VALUE; 3213 } 3214 3215 if (!mutable_tex_object(ctx, target)) { 3216 *reason = "immutable texture"; 3217 return GL_INVALID_OPERATION; 3218 } 3219 3220 return GL_NO_ERROR; 3221} 3222 3223 3224/** 3225 * Error checking for glCompressedTexSubImage[123]D(). 3226 * \warning There are some bad assumptions here about the size of compressed 3227 * texture tiles (multiple of 4) used to test the validity of the 3228 * offset and size parameters. 3229 * \return error code or GL_NO_ERROR. 3230 */ 3231static GLenum 3232compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions, 3233 GLenum target, GLint level, 3234 GLint xoffset, GLint yoffset, GLint zoffset, 3235 GLsizei width, GLsizei height, GLsizei depth, 3236 GLenum format, GLsizei imageSize) 3237{ 3238 GLint expectedSize, maxLevels = 0, maxTextureSize; 3239 GLuint bw, bh; 3240 (void) zoffset; 3241 3242 if (dimensions == 1) { 3243 /* 1D compressed textures not allowed */ 3244 return GL_INVALID_ENUM; 3245 } 3246 else if (dimensions == 2) { 3247 if (target == GL_PROXY_TEXTURE_2D) { 3248 maxLevels = ctx->Const.MaxTextureLevels; 3249 } 3250 else if (target == GL_TEXTURE_2D) { 3251 maxLevels = ctx->Const.MaxTextureLevels; 3252 } 3253 else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { 3254 if (!ctx->Extensions.ARB_texture_cube_map) 3255 return GL_INVALID_ENUM; /*target*/ 3256 maxLevels = ctx->Const.MaxCubeTextureLevels; 3257 } 3258 else if (_mesa_is_cube_face(target)) { 3259 if (!ctx->Extensions.ARB_texture_cube_map) 3260 return GL_INVALID_ENUM; /*target*/ 3261 maxLevels = ctx->Const.MaxCubeTextureLevels; 3262 } 3263 else { 3264 return GL_INVALID_ENUM; /*target*/ 3265 } 3266 } 3267 else if (dimensions == 3) { 3268 /* 3D compressed textures not allowed */ 3269 return GL_INVALID_ENUM; 3270 } 3271 3272 maxTextureSize = 1 << (maxLevels - 1); 3273 3274 /* this will catch any invalid compressed format token */ 3275 if (!_mesa_is_compressed_format(ctx, format)) 3276 return GL_INVALID_ENUM; 3277 3278 if (width < 1 || width > maxTextureSize) 3279 return GL_INVALID_VALUE; 3280 3281 if ((height < 1 || height > maxTextureSize) 3282 && dimensions > 1) 3283 return GL_INVALID_VALUE; 3284 3285 if (level < 0 || level >= maxLevels) 3286 return GL_INVALID_VALUE; 3287 3288 /* 3289 * do checks which depend on compression block size 3290 */ 3291 get_compressed_block_size(format, &bw, &bh); 3292 3293 if ((xoffset % bw != 0) || (yoffset % bh != 0)) 3294 return GL_INVALID_VALUE; 3295 3296 if ((width % bw != 0) && width != 2 && width != 1) 3297 return GL_INVALID_VALUE; 3298 3299 if ((height % bh != 0) && height != 2 && height != 1) 3300 return GL_INVALID_VALUE; 3301 3302 expectedSize = compressed_tex_size(width, height, depth, format); 3303 if (expectedSize != imageSize) 3304 return GL_INVALID_VALUE; 3305 3306 return GL_NO_ERROR; 3307} 3308 3309 3310/** 3311 * Do second part of glCompressedTexSubImage error checking. 3312 * \return GL_TRUE if error found, GL_FALSE otherwise. 3313 */ 3314static GLboolean 3315compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims, 3316 GLsizei width, GLsizei height, 3317 GLsizei depth, GLenum format, 3318 struct gl_texture_image *texImage) 3319{ 3320 3321 if ((GLint) format != texImage->InternalFormat) { 3322 _mesa_error(ctx, GL_INVALID_OPERATION, 3323 "glCompressedTexSubImage%uD(format=0x%x)", dims, format); 3324 return GL_TRUE; 3325 } 3326 3327 if (compressedteximage_only_format(ctx, format)) { 3328 _mesa_error(ctx, GL_INVALID_OPERATION, 3329 "glCompressedTexSubImage%uD(format=0x%x cannot be updated)" 3330 , dims, format); 3331 return GL_TRUE; 3332 } 3333 3334 if (((width == 1 || width == 2) && 3335 width != (GLsizei) texImage->Width) || 3336 (width > (GLsizei) texImage->Width)) { 3337 _mesa_error(ctx, GL_INVALID_VALUE, 3338 "glCompressedTexSubImage%uD(width=%d)", dims, width); 3339 return GL_TRUE; 3340 } 3341 3342 if (dims >= 2) { 3343 if (((height == 1 || height == 2) && 3344 height != (GLsizei) texImage->Height) || 3345 (height > (GLsizei) texImage->Height)) { 3346 _mesa_error(ctx, GL_INVALID_VALUE, 3347 "glCompressedTexSubImage%uD(height=%d)", dims, height); 3348 return GL_TRUE; 3349 } 3350 } 3351 3352 if (dims >= 3) { 3353 if (((depth == 1 || depth == 2) && 3354 depth != (GLsizei) texImage->Depth) || 3355 (depth > (GLsizei) texImage->Depth)) { 3356 _mesa_error(ctx, GL_INVALID_VALUE, 3357 "glCompressedTexSubImage%uD(depth=%d)", dims, depth); 3358 return GL_TRUE; 3359 } 3360 } 3361 3362 return GL_FALSE; 3363} 3364 3365 3366/** 3367 * Implementation of the glCompressedTexImage1/2/3D() functions. 3368 */ 3369static void 3370compressedteximage(struct gl_context *ctx, GLuint dims, 3371 GLenum target, GLint level, 3372 GLenum internalFormat, GLsizei width, 3373 GLsizei height, GLsizei depth, GLint border, 3374 GLsizei imageSize, const GLvoid *data) 3375{ 3376 GLenum error; 3377 char *reason = ""; 3378 3379 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3380 3381 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) 3382 _mesa_debug(ctx, 3383 "glCompressedTexImage%uDARB %s %d %s %d %d %d %d %d %p\n", 3384 dims, 3385 _mesa_lookup_enum_by_nr(target), level, 3386 _mesa_lookup_enum_by_nr(internalFormat), 3387 width, height, depth, border, imageSize, data); 3388 3389 /* check target */ 3390 if (!legal_teximage_target(ctx, dims, target)) { 3391 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(target=%s)", 3392 dims, _mesa_lookup_enum_by_nr(target)); 3393 return; 3394 } 3395 3396 error = compressed_texture_error_check(ctx, dims, target, level, 3397 internalFormat, width, height, depth, 3398 border, imageSize, &reason); 3399 3400#if FEATURE_ES 3401 /* XXX this is kind of a hack */ 3402 if (!error && dims == 2) { 3403 switch (internalFormat) { 3404 case GL_PALETTE4_RGB8_OES: 3405 case GL_PALETTE4_RGBA8_OES: 3406 case GL_PALETTE4_R5_G6_B5_OES: 3407 case GL_PALETTE4_RGBA4_OES: 3408 case GL_PALETTE4_RGB5_A1_OES: 3409 case GL_PALETTE8_RGB8_OES: 3410 case GL_PALETTE8_RGBA8_OES: 3411 case GL_PALETTE8_R5_G6_B5_OES: 3412 case GL_PALETTE8_RGBA4_OES: 3413 case GL_PALETTE8_RGB5_A1_OES: 3414 _mesa_cpal_compressed_teximage2d(target, level, internalFormat, 3415 width, height, imageSize, data); 3416 return; 3417 } 3418 } 3419#endif 3420 3421 if (_mesa_is_proxy_texture(target)) { 3422 /* Proxy texture: just check for errors and update proxy state */ 3423 struct gl_texture_image *texImage; 3424 3425 if (!error) { 3426 struct gl_texture_object *texObj = 3427 _mesa_get_current_tex_object(ctx, target); 3428 gl_format texFormat = 3429 _mesa_choose_texture_format(ctx, texObj, target, level, 3430 internalFormat, GL_NONE, GL_NONE); 3431 if (!legal_texture_size(ctx, texFormat, width, height, depth)) { 3432 error = GL_OUT_OF_MEMORY; 3433 } 3434 } 3435 3436 texImage = _mesa_get_proxy_tex_image(ctx, target, level); 3437 if (texImage) { 3438 if (error) { 3439 /* if error, clear all proxy texture image parameters */ 3440 clear_teximage_fields(texImage); 3441 } 3442 else { 3443 /* no error: store the teximage parameters */ 3444 _mesa_init_teximage_fields(ctx, texImage, width, height, 3445 depth, border, internalFormat, 3446 MESA_FORMAT_NONE); 3447 } 3448 } 3449 } 3450 else { 3451 /* non-proxy target */ 3452 struct gl_texture_object *texObj; 3453 struct gl_texture_image *texImage; 3454 3455 if (error) { 3456 _mesa_error(ctx, error, "glCompressedTexImage%uD(%s)", dims, reason); 3457 return; 3458 } 3459 3460 texObj = _mesa_get_current_tex_object(ctx, target); 3461 3462 _mesa_lock_texture(ctx, texObj); 3463 { 3464 texImage = _mesa_get_tex_image(ctx, texObj, target, level); 3465 if (!texImage) { 3466 _mesa_error(ctx, GL_OUT_OF_MEMORY, 3467 "glCompressedTexImage%uD", dims); 3468 } 3469 else { 3470 gl_format texFormat; 3471 3472 ctx->Driver.FreeTextureImageBuffer(ctx, texImage); 3473 3474 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, 3475 internalFormat, GL_NONE, 3476 GL_NONE); 3477 3478 if (legal_texture_size(ctx, texFormat, width, height, depth)) { 3479 _mesa_init_teximage_fields(ctx, texImage, 3480 width, height, depth, 3481 border, internalFormat, texFormat); 3482 3483 switch (dims) { 3484 case 1: 3485 ASSERT(ctx->Driver.CompressedTexImage1D); 3486 ctx->Driver.CompressedTexImage1D(ctx, texImage, 3487 internalFormat, 3488 width, 3489 border, imageSize, data); 3490 break; 3491 case 2: 3492 ASSERT(ctx->Driver.CompressedTexImage2D); 3493 ctx->Driver.CompressedTexImage2D(ctx, texImage, 3494 internalFormat, 3495 width, height, 3496 border, imageSize, data); 3497 break; 3498 case 3: 3499 ASSERT(ctx->Driver.CompressedTexImage3D); 3500 ctx->Driver.CompressedTexImage3D(ctx, texImage, 3501 internalFormat, 3502 width, height, depth, 3503 border, imageSize, data); 3504 break; 3505 default: 3506 _mesa_problem(ctx, "bad dims in compressedteximage"); 3507 } 3508 3509 check_gen_mipmap(ctx, target, texObj, level); 3510 3511 /* state update */ 3512 texObj->_Complete = GL_FALSE; 3513 ctx->NewState |= _NEW_TEXTURE; 3514 } 3515 else { 3516 _mesa_error(ctx, GL_OUT_OF_MEMORY, 3517 "glCompressedTexImage%uD", dims); 3518 } 3519 } 3520 } 3521 _mesa_unlock_texture(ctx, texObj); 3522 } 3523} 3524 3525 3526void GLAPIENTRY 3527_mesa_CompressedTexImage1DARB(GLenum target, GLint level, 3528 GLenum internalFormat, GLsizei width, 3529 GLint border, GLsizei imageSize, 3530 const GLvoid *data) 3531{ 3532 GET_CURRENT_CONTEXT(ctx); 3533 compressedteximage(ctx, 1, target, level, internalFormat, 3534 width, 1, 1, border, imageSize, data); 3535} 3536 3537 3538void GLAPIENTRY 3539_mesa_CompressedTexImage2DARB(GLenum target, GLint level, 3540 GLenum internalFormat, GLsizei width, 3541 GLsizei height, GLint border, GLsizei imageSize, 3542 const GLvoid *data) 3543{ 3544 GET_CURRENT_CONTEXT(ctx); 3545 compressedteximage(ctx, 2, target, level, internalFormat, 3546 width, height, 1, border, imageSize, data); 3547} 3548 3549 3550void GLAPIENTRY 3551_mesa_CompressedTexImage3DARB(GLenum target, GLint level, 3552 GLenum internalFormat, GLsizei width, 3553 GLsizei height, GLsizei depth, GLint border, 3554 GLsizei imageSize, const GLvoid *data) 3555{ 3556 GET_CURRENT_CONTEXT(ctx); 3557 compressedteximage(ctx, 3, target, level, internalFormat, 3558 width, height, depth, border, imageSize, data); 3559} 3560 3561 3562/** 3563 * Common helper for glCompressedTexSubImage1/2/3D(). 3564 */ 3565static void 3566compressed_tex_sub_image(GLuint dims, GLenum target, GLint level, 3567 GLint xoffset, GLint yoffset, GLint zoffset, 3568 GLsizei width, GLsizei height, GLsizei depth, 3569 GLenum format, GLsizei imageSize, const GLvoid *data) 3570{ 3571 struct gl_texture_object *texObj; 3572 struct gl_texture_image *texImage; 3573 GLenum error; 3574 GET_CURRENT_CONTEXT(ctx); 3575 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3576 3577 error = compressed_subtexture_error_check(ctx, dims, target, level, 3578 xoffset, 0, 0, /* pos */ 3579 width, height, depth, /* size */ 3580 format, imageSize); 3581 if (error) { 3582 _mesa_error(ctx, error, "glCompressedTexSubImage%uD", dims); 3583 return; 3584 } 3585 3586 texObj = _mesa_get_current_tex_object(ctx, target); 3587 3588 _mesa_lock_texture(ctx, texObj); 3589 { 3590 texImage = _mesa_select_tex_image(ctx, texObj, target, level); 3591 assert(texImage); 3592 3593 if (compressed_subtexture_error_check2(ctx, dims, width, height, depth, 3594 format, texImage)) { 3595 /* error was recorded */ 3596 } 3597 else if (width > 0 && height > 0 && depth > 0) { 3598 switch (dims) { 3599 case 1: 3600 if (ctx->Driver.CompressedTexSubImage1D) { 3601 ctx->Driver.CompressedTexSubImage1D(ctx, texImage, 3602 xoffset, width, 3603 format, imageSize, data); 3604 } 3605 break; 3606 case 2: 3607 if (ctx->Driver.CompressedTexSubImage2D) { 3608 ctx->Driver.CompressedTexSubImage2D(ctx, texImage, 3609 xoffset, yoffset, 3610 width, height, 3611 format, imageSize, data); 3612 } 3613 break; 3614 case 3: 3615 if (ctx->Driver.CompressedTexSubImage3D) { 3616 ctx->Driver.CompressedTexSubImage3D(ctx, texImage, 3617 xoffset, yoffset, zoffset, 3618 width, height, depth, 3619 format, imageSize, data); 3620 } 3621 break; 3622 default: 3623 ; 3624 } 3625 3626 check_gen_mipmap(ctx, target, texObj, level); 3627 3628 ctx->NewState |= _NEW_TEXTURE; 3629 } 3630 } 3631 _mesa_unlock_texture(ctx, texObj); 3632} 3633 3634 3635void GLAPIENTRY 3636_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, 3637 GLsizei width, GLenum format, 3638 GLsizei imageSize, const GLvoid *data) 3639{ 3640 compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1, 3641 format, imageSize, data); 3642} 3643 3644 3645void GLAPIENTRY 3646_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, 3647 GLint yoffset, GLsizei width, GLsizei height, 3648 GLenum format, GLsizei imageSize, 3649 const GLvoid *data) 3650{ 3651 compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0, 3652 width, height, 1, format, imageSize, data); 3653} 3654 3655 3656void GLAPIENTRY 3657_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, 3658 GLint yoffset, GLint zoffset, GLsizei width, 3659 GLsizei height, GLsizei depth, GLenum format, 3660 GLsizei imageSize, const GLvoid *data) 3661{ 3662 compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset, 3663 width, height, depth, format, imageSize, data); 3664} 3665 3666 3667/** 3668 * Helper for glTexBuffer(). Check if internalFormat is legal. If so, 3669 * return the basic data type and number of components for the format. 3670 * \param return GL_TRUE if internalFormat is legal, GL_FALSE otherwise 3671 */ 3672static GLboolean 3673get_sized_format_info(const struct gl_context *ctx, GLenum internalFormat, 3674 GLenum *datatype, GLuint *components) 3675{ 3676 switch (internalFormat) { 3677 case GL_ALPHA8: 3678 *datatype = GL_UNSIGNED_BYTE; 3679 *components = 1; 3680 break; 3681 case GL_ALPHA16: 3682 *datatype = GL_UNSIGNED_SHORT; 3683 *components = 1; 3684 break; 3685 case GL_ALPHA16F_ARB: 3686 *datatype = GL_HALF_FLOAT; 3687 *components = 1; 3688 break; 3689 case GL_ALPHA32F_ARB: 3690 *datatype = GL_FLOAT; 3691 *components = 1; 3692 break; 3693 case GL_ALPHA8I_EXT: 3694 *datatype = GL_BYTE; 3695 *components = 1; 3696 break; 3697 case GL_ALPHA16I_EXT: 3698 *datatype = GL_SHORT; 3699 *components = 1; 3700 break; 3701 case GL_ALPHA32I_EXT: 3702 *datatype = GL_INT; 3703 *components = 1; 3704 break; 3705 case GL_ALPHA8UI_EXT: 3706 *datatype = GL_UNSIGNED_BYTE; 3707 *components = 1; 3708 break; 3709 case GL_ALPHA16UI_EXT: 3710 *datatype = GL_UNSIGNED_SHORT; 3711 *components = 1; 3712 break; 3713 case GL_ALPHA32UI_EXT: 3714 *datatype = GL_UNSIGNED_INT; 3715 *components = 1; 3716 break; 3717 case GL_LUMINANCE8: 3718 *datatype = GL_UNSIGNED_BYTE; 3719 *components = 1; 3720 break; 3721 case GL_LUMINANCE16: 3722 *datatype = GL_UNSIGNED_SHORT; 3723 *components = 1; 3724 break; 3725 case GL_LUMINANCE16F_ARB: 3726 *datatype = GL_HALF_FLOAT; 3727 *components = 1; 3728 break; 3729 case GL_LUMINANCE32F_ARB: 3730 *datatype = GL_FLOAT; 3731 *components = 1; 3732 break; 3733 case GL_LUMINANCE8I_EXT: 3734 *datatype = GL_BYTE; 3735 *components = 1; 3736 break; 3737 case GL_LUMINANCE16I_EXT: 3738 *datatype = GL_SHORT; 3739 *components = 1; 3740 break; 3741 case GL_LUMINANCE32I_EXT: 3742 *datatype = GL_INT; 3743 *components = 1; 3744 break; 3745 case GL_LUMINANCE8UI_EXT: 3746 *datatype = GL_UNSIGNED_BYTE; 3747 *components = 1; 3748 break; 3749 case GL_LUMINANCE16UI_EXT: 3750 *datatype = GL_UNSIGNED_SHORT; 3751 *components = 1; 3752 break; 3753 case GL_LUMINANCE32UI_EXT: 3754 *datatype = GL_UNSIGNED_INT; 3755 *components = 1; 3756 break; 3757 case GL_LUMINANCE8_ALPHA8: 3758 *datatype = GL_UNSIGNED_BYTE; 3759 *components = 2; 3760 break; 3761 case GL_LUMINANCE16_ALPHA16: 3762 *datatype = GL_UNSIGNED_SHORT; 3763 *components = 2; 3764 break; 3765 case GL_LUMINANCE_ALPHA16F_ARB: 3766 *datatype = GL_HALF_FLOAT; 3767 *components = 2; 3768 break; 3769 case GL_LUMINANCE_ALPHA32F_ARB: 3770 *datatype = GL_FLOAT; 3771 *components = 2; 3772 break; 3773 case GL_LUMINANCE_ALPHA8I_EXT: 3774 *datatype = GL_BYTE; 3775 *components = 2; 3776 break; 3777 case GL_LUMINANCE_ALPHA16I_EXT: 3778 *datatype = GL_SHORT; 3779 *components = 2; 3780 break; 3781 case GL_LUMINANCE_ALPHA32I_EXT: 3782 *datatype = GL_INT; 3783 *components = 2; 3784 break; 3785 case GL_LUMINANCE_ALPHA8UI_EXT: 3786 *datatype = GL_UNSIGNED_BYTE; 3787 *components = 2; 3788 break; 3789 case GL_LUMINANCE_ALPHA16UI_EXT: 3790 *datatype = GL_UNSIGNED_SHORT; 3791 *components = 2; 3792 break; 3793 case GL_LUMINANCE_ALPHA32UI_EXT: 3794 *datatype = GL_UNSIGNED_INT; 3795 *components = 2; 3796 break; 3797 case GL_INTENSITY8: 3798 *datatype = GL_UNSIGNED_BYTE; 3799 *components = 1; 3800 break; 3801 case GL_INTENSITY16: 3802 *datatype = GL_UNSIGNED_SHORT; 3803 *components = 1; 3804 break; 3805 case GL_INTENSITY16F_ARB: 3806 *datatype = GL_HALF_FLOAT; 3807 *components = 1; 3808 break; 3809 case GL_INTENSITY32F_ARB: 3810 *datatype = GL_FLOAT; 3811 *components = 1; 3812 break; 3813 case GL_INTENSITY8I_EXT: 3814 *datatype = GL_BYTE; 3815 *components = 1; 3816 break; 3817 case GL_INTENSITY16I_EXT: 3818 *datatype = GL_SHORT; 3819 *components = 1; 3820 break; 3821 case GL_INTENSITY32I_EXT: 3822 *datatype = GL_INT; 3823 *components = 1; 3824 break; 3825 case GL_INTENSITY8UI_EXT: 3826 *datatype = GL_UNSIGNED_BYTE; 3827 *components = 1; 3828 break; 3829 case GL_INTENSITY16UI_EXT: 3830 *datatype = GL_UNSIGNED_SHORT; 3831 *components = 1; 3832 break; 3833 case GL_INTENSITY32UI_EXT: 3834 *datatype = GL_UNSIGNED_INT; 3835 *components = 1; 3836 break; 3837 case GL_RGBA8: 3838 *datatype = GL_UNSIGNED_BYTE; 3839 *components = 4; 3840 break; 3841 case GL_RGBA16: 3842 *datatype = GL_UNSIGNED_SHORT; 3843 *components = 4; 3844 break; 3845 case GL_RGBA16F_ARB: 3846 *datatype = GL_HALF_FLOAT; 3847 *components = 4; 3848 break; 3849 case GL_RGBA32F_ARB: 3850 *datatype = GL_FLOAT; 3851 *components = 4; 3852 break; 3853 case GL_RGBA8I_EXT: 3854 *datatype = GL_BYTE; 3855 *components = 4; 3856 break; 3857 case GL_RGBA16I_EXT: 3858 *datatype = GL_SHORT; 3859 *components = 4; 3860 break; 3861 case GL_RGBA32I_EXT: 3862 *datatype = GL_INT; 3863 *components = 4; 3864 break; 3865 case GL_RGBA8UI_EXT: 3866 *datatype = GL_UNSIGNED_BYTE; 3867 *components = 4; 3868 break; 3869 case GL_RGBA16UI_EXT: 3870 *datatype = GL_UNSIGNED_SHORT; 3871 *components = 4; 3872 break; 3873 case GL_RGBA32UI_EXT: 3874 *datatype = GL_UNSIGNED_INT; 3875 *components = 4; 3876 break; 3877 default: 3878 return GL_FALSE; 3879 } 3880 3881 if (*datatype == GL_FLOAT && !ctx->Extensions.ARB_texture_float) 3882 return GL_FALSE; 3883 3884 if (*datatype == GL_HALF_FLOAT && !ctx->Extensions.ARB_half_float_pixel) 3885 return GL_FALSE; 3886 3887 return GL_TRUE; 3888} 3889 3890 3891/** GL_ARB_texture_buffer_object */ 3892void GLAPIENTRY 3893_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer) 3894{ 3895 struct gl_texture_object *texObj; 3896 struct gl_buffer_object *bufObj; 3897 GLenum dataType; 3898 GLuint comps; 3899 3900 GET_CURRENT_CONTEXT(ctx); 3901 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 3902 3903 if (!ctx->Extensions.ARB_texture_buffer_object) { 3904 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer"); 3905 return; 3906 } 3907 3908 if (target != GL_TEXTURE_BUFFER_ARB) { 3909 _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)"); 3910 return; 3911 } 3912 3913 if (!get_sized_format_info(ctx, internalFormat, &dataType, &comps)) { 3914 _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(internalFormat 0x%x)", 3915 internalFormat); 3916 return; 3917 } 3918 3919 bufObj = _mesa_lookup_bufferobj(ctx, buffer); 3920 if (buffer && !bufObj) { 3921 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer(buffer %u)", buffer); 3922 return; 3923 } 3924 3925 texObj = _mesa_get_current_tex_object(ctx, target); 3926 3927 _mesa_lock_texture(ctx, texObj); 3928 { 3929 _mesa_reference_buffer_object(ctx, &texObj->BufferObject, bufObj); 3930 texObj->BufferObjectFormat = internalFormat; 3931 } 3932 _mesa_unlock_texture(ctx, texObj); 3933} 3934