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