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