teximage.c revision 3b4fbbc129c711a5aec8d653d5c6eb2e195f947c
1/* $Id: teximage.c,v 1.111 2002/07/09 01:22:50 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 4.1 6 * 7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 28#ifdef PC_HEADER 29#include "all.h" 30#else 31#include "glheader.h" 32#include "context.h" 33#include "convolve.h" 34#include "image.h" 35#include "macros.h" 36#include "mem.h" 37#include "mmath.h" 38#include "state.h" 39#include "texformat.h" 40#include "teximage.h" 41#include "texstate.h" 42#include "texstore.h" 43#include "mtypes.h" 44#endif 45 46 47/* 48 * NOTES: 49 * 50 * Mesa's native texture datatype is GLchan. Native formats are 51 * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA, 52 * and GL_COLOR_INDEX. 53 * Device drivers are free to implement any internal format they want. 54 */ 55 56 57#if 0 58static void PrintTexture(GLcontext *ctx, const struct gl_texture_image *img) 59{ 60#if CHAN_TYPE == GL_FLOAT 61 _mesa_problem(NULL, "PrintTexture doesn't support float channels"); 62#else 63 GLuint i, j, c; 64 const GLchan *data = (const GLchan *) img->Data; 65 66 if (!data) { 67 _mesa_printf(ctx, "No texture data\n"); 68 return; 69 } 70 71 switch (img->Format) { 72 case GL_ALPHA: 73 case GL_LUMINANCE: 74 case GL_INTENSITY: 75 case GL_COLOR_INDEX: 76 c = 1; 77 break; 78 case GL_LUMINANCE_ALPHA: 79 c = 2; 80 break; 81 case GL_RGB: 82 c = 3; 83 break; 84 case GL_RGBA: 85 c = 4; 86 break; 87 default: 88 _mesa_problem(NULL, "error in PrintTexture\n"); 89 return; 90 } 91 92 for (i = 0; i < img->Height; i++) { 93 for (j = 0; j < img->Width; j++) { 94 if (c==1) 95 _mesa_printf(ctx, "%02x ", data[0]); 96 else if (c==2) 97 _mesa_printf(ctx, "%02x%02x ", data[0], data[1]); 98 else if (c==3) 99 _mesa_printf(ctx, "%02x%02x%02x ", data[0], data[1], data[2]); 100 else if (c==4) 101 _mesa_printf(ctx, "%02x%02x%02x%02x ", data[0], data[1], data[2], data[3]); 102 data += c; 103 } 104 _mesa_printf(ctx, "\n"); 105 } 106#endif 107} 108#endif 109 110 111 112/* 113 * Compute log base 2 of n. 114 * If n isn't an exact power of two return -1. 115 * If n < 0 return -1. 116 */ 117static int 118logbase2( int n ) 119{ 120 GLint i = 1; 121 GLint log2 = 0; 122 123 if (n < 0) { 124 return -1; 125 } 126 127 while ( n > i ) { 128 i *= 2; 129 log2++; 130 } 131 if (i != n) { 132 return -1; 133 } 134 else { 135 return log2; 136 } 137} 138 139 140 141/* 142 * Given an internal texture format enum or 1, 2, 3, 4 return the 143 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE, 144 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. 145 * Return -1 if invalid enum. 146 */ 147GLint 148_mesa_base_tex_format( GLcontext *ctx, GLint format ) 149{ 150 /* 151 * Ask the driver for the base format, if it doesn't 152 * know, it will return -1; 153 */ 154 if (ctx->Driver.BaseCompressedTexFormat) { 155 GLint ifmt = (*ctx->Driver.BaseCompressedTexFormat)(ctx, format); 156 if (ifmt >= 0) { 157 return ifmt; 158 } 159 } 160 switch (format) { 161 case GL_ALPHA: 162 case GL_ALPHA4: 163 case GL_ALPHA8: 164 case GL_ALPHA12: 165 case GL_ALPHA16: 166 return GL_ALPHA; 167 case 1: 168 case GL_LUMINANCE: 169 case GL_LUMINANCE4: 170 case GL_LUMINANCE8: 171 case GL_LUMINANCE12: 172 case GL_LUMINANCE16: 173 return GL_LUMINANCE; 174 case 2: 175 case GL_LUMINANCE_ALPHA: 176 case GL_LUMINANCE4_ALPHA4: 177 case GL_LUMINANCE6_ALPHA2: 178 case GL_LUMINANCE8_ALPHA8: 179 case GL_LUMINANCE12_ALPHA4: 180 case GL_LUMINANCE12_ALPHA12: 181 case GL_LUMINANCE16_ALPHA16: 182 return GL_LUMINANCE_ALPHA; 183 case GL_INTENSITY: 184 case GL_INTENSITY4: 185 case GL_INTENSITY8: 186 case GL_INTENSITY12: 187 case GL_INTENSITY16: 188 return GL_INTENSITY; 189 case 3: 190 case GL_RGB: 191 case GL_R3_G3_B2: 192 case GL_RGB4: 193 case GL_RGB5: 194 case GL_RGB8: 195 case GL_RGB10: 196 case GL_RGB12: 197 case GL_RGB16: 198 return GL_RGB; 199 case 4: 200 case GL_RGBA: 201 case GL_RGBA2: 202 case GL_RGBA4: 203 case GL_RGB5_A1: 204 case GL_RGBA8: 205 case GL_RGB10_A2: 206 case GL_RGBA12: 207 case GL_RGBA16: 208 return GL_RGBA; 209 case GL_COLOR_INDEX: 210 case GL_COLOR_INDEX1_EXT: 211 case GL_COLOR_INDEX2_EXT: 212 case GL_COLOR_INDEX4_EXT: 213 case GL_COLOR_INDEX8_EXT: 214 case GL_COLOR_INDEX12_EXT: 215 case GL_COLOR_INDEX16_EXT: 216 return GL_COLOR_INDEX; 217 case GL_DEPTH_COMPONENT: 218 case GL_DEPTH_COMPONENT16_SGIX: 219 case GL_DEPTH_COMPONENT24_SGIX: 220 case GL_DEPTH_COMPONENT32_SGIX: 221 if (ctx->Extensions.SGIX_depth_texture) 222 return GL_DEPTH_COMPONENT; 223 else 224 return -1; 225 default: 226 return -1; /* error */ 227 } 228} 229 230 231/* 232 * Test if the given image format is a color/rgba format. That is, 233 * not color index, depth, stencil, etc. 234 */ 235static GLboolean 236is_color_format(GLenum format) 237{ 238 switch (format) { 239 case GL_ALPHA: 240 case GL_ALPHA4: 241 case GL_ALPHA8: 242 case GL_ALPHA12: 243 case GL_ALPHA16: 244 case 1: 245 case GL_LUMINANCE: 246 case GL_LUMINANCE4: 247 case GL_LUMINANCE8: 248 case GL_LUMINANCE12: 249 case GL_LUMINANCE16: 250 case 2: 251 case GL_LUMINANCE_ALPHA: 252 case GL_LUMINANCE4_ALPHA4: 253 case GL_LUMINANCE6_ALPHA2: 254 case GL_LUMINANCE8_ALPHA8: 255 case GL_LUMINANCE12_ALPHA4: 256 case GL_LUMINANCE12_ALPHA12: 257 case GL_LUMINANCE16_ALPHA16: 258 case GL_INTENSITY: 259 case GL_INTENSITY4: 260 case GL_INTENSITY8: 261 case GL_INTENSITY12: 262 case GL_INTENSITY16: 263 case 3: 264 case GL_RGB: 265 case GL_R3_G3_B2: 266 case GL_RGB4: 267 case GL_RGB5: 268 case GL_RGB8: 269 case GL_RGB10: 270 case GL_RGB12: 271 case GL_RGB16: 272 case 4: 273 case GL_RGBA: 274 case GL_RGBA2: 275 case GL_RGBA4: 276 case GL_RGB5_A1: 277 case GL_RGBA8: 278 case GL_RGB10_A2: 279 case GL_RGBA12: 280 case GL_RGBA16: 281 return GL_TRUE; 282 default: 283 return GL_FALSE; 284 } 285} 286 287 288static GLboolean 289is_index_format(GLenum format) 290{ 291 switch (format) { 292 case GL_COLOR_INDEX: 293 case GL_COLOR_INDEX1_EXT: 294 case GL_COLOR_INDEX2_EXT: 295 case GL_COLOR_INDEX4_EXT: 296 case GL_COLOR_INDEX8_EXT: 297 case GL_COLOR_INDEX12_EXT: 298 case GL_COLOR_INDEX16_EXT: 299 return GL_TRUE; 300 default: 301 return GL_FALSE; 302 } 303} 304 305 306/* 307 * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE 308 * otherwise. 309 */ 310static GLboolean 311is_compressed_format(GLcontext *ctx, GLenum internalFormat) 312{ 313 if (ctx->Driver.BaseCompressedTexFormat) { 314 GLint b = (*ctx->Driver.BaseCompressedTexFormat)(ctx, internalFormat); 315 if (b > 0) 316 return GL_TRUE; 317 else 318 return GL_FALSE; 319 } 320 return GL_FALSE; 321} 322 323 324 325/* 326 * Store a gl_texture_image pointer in a gl_texture_object structure 327 * according to the target and level parameters. 328 * This was basically prompted by the introduction of cube maps. 329 */ 330void 331_mesa_set_tex_image(struct gl_texture_object *tObj, 332 GLenum target, GLint level, 333 struct gl_texture_image *texImage) 334{ 335 ASSERT(tObj); 336 ASSERT(texImage); 337 switch (target) { 338 case GL_TEXTURE_1D: 339 case GL_TEXTURE_2D: 340 case GL_TEXTURE_3D: 341 tObj->Image[level] = texImage; 342 return; 343 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 344 tObj->Image[level] = texImage; 345 return; 346 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 347 tObj->NegX[level] = texImage; 348 return; 349 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 350 tObj->PosY[level] = texImage; 351 return; 352 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 353 tObj->NegY[level] = texImage; 354 return; 355 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 356 tObj->PosZ[level] = texImage; 357 return; 358 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 359 tObj->NegZ[level] = texImage; 360 return; 361 case GL_TEXTURE_RECTANGLE_NV: 362 ASSERT(level == 0); 363 tObj->Image[level] = texImage; 364 return; 365 default: 366 _mesa_problem(NULL, "bad target in _mesa_set_tex_image()"); 367 return; 368 } 369} 370 371 372 373/* 374 * Return new gl_texture_image struct with all fields initialized to zero. 375 */ 376struct gl_texture_image * 377_mesa_alloc_texture_image( void ) 378{ 379 return CALLOC_STRUCT(gl_texture_image); 380} 381 382 383 384void 385_mesa_free_texture_image( struct gl_texture_image *teximage ) 386{ 387 if (teximage->Data) { 388 MESA_PBUFFER_FREE( teximage->Data ); 389 teximage->Data = NULL; 390 } 391 FREE( teximage ); 392} 393 394 395/* 396 * Return GL_TRUE if the target is a proxy target. 397 */ 398static GLboolean 399is_proxy_target(GLenum target) 400{ 401 return (target == GL_PROXY_TEXTURE_1D || 402 target == GL_PROXY_TEXTURE_2D || 403 target == GL_PROXY_TEXTURE_3D || 404 target == GL_PROXY_TEXTURE_CUBE_MAP_ARB); 405} 406 407 408/* 409 * Given a texture unit and a texture target, return the corresponding 410 * texture object. 411 */ 412struct gl_texture_object * 413_mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, 414 GLenum target) 415{ 416 switch (target) { 417 case GL_TEXTURE_1D: 418 return texUnit->Current1D; 419 case GL_PROXY_TEXTURE_1D: 420 return ctx->Texture.Proxy1D; 421 case GL_TEXTURE_2D: 422 return texUnit->Current2D; 423 case GL_PROXY_TEXTURE_2D: 424 return ctx->Texture.Proxy2D; 425 case GL_TEXTURE_3D: 426 return texUnit->Current3D; 427 case GL_PROXY_TEXTURE_3D: 428 return ctx->Texture.Proxy3D; 429 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 430 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 431 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 432 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 433 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 434 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 435 case GL_TEXTURE_CUBE_MAP_ARB: 436 return ctx->Extensions.ARB_texture_cube_map 437 ? texUnit->CurrentCubeMap : NULL; 438 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 439 return ctx->Extensions.ARB_texture_cube_map 440 ? ctx->Texture.ProxyCubeMap : NULL; 441 case GL_TEXTURE_RECTANGLE_NV: 442 return ctx->Extensions.NV_texture_rectangle 443 ? texUnit->CurrentRect : NULL; 444 case GL_PROXY_TEXTURE_RECTANGLE_NV: 445 return ctx->Extensions.NV_texture_rectangle 446 ? ctx->Texture.ProxyRect : NULL; 447 default: 448 _mesa_problem(NULL, "bad target in _mesa_select_tex_object()"); 449 return NULL; 450 } 451} 452 453 454/* 455 * Return the texture image struct which corresponds to target and level 456 * for the given texture unit. 457 */ 458struct gl_texture_image * 459_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, 460 GLenum target, GLint level) 461{ 462 ASSERT(texUnit); 463 ASSERT(level < MAX_TEXTURE_LEVELS); 464 switch (target) { 465 case GL_TEXTURE_1D: 466 return texUnit->Current1D->Image[level]; 467 case GL_PROXY_TEXTURE_1D: 468 return ctx->Texture.Proxy1D->Image[level]; 469 case GL_TEXTURE_2D: 470 return texUnit->Current2D->Image[level]; 471 case GL_PROXY_TEXTURE_2D: 472 return ctx->Texture.Proxy2D->Image[level]; 473 case GL_TEXTURE_3D: 474 return texUnit->Current3D->Image[level]; 475 case GL_PROXY_TEXTURE_3D: 476 return ctx->Texture.Proxy3D->Image[level]; 477 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 478 if (ctx->Extensions.ARB_texture_cube_map) 479 return texUnit->CurrentCubeMap->Image[level]; 480 else 481 return NULL; 482 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 483 if (ctx->Extensions.ARB_texture_cube_map) 484 return texUnit->CurrentCubeMap->NegX[level]; 485 else 486 return NULL; 487 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 488 if (ctx->Extensions.ARB_texture_cube_map) 489 return texUnit->CurrentCubeMap->PosY[level]; 490 else 491 return NULL; 492 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 493 if (ctx->Extensions.ARB_texture_cube_map) 494 return texUnit->CurrentCubeMap->NegY[level]; 495 else 496 return NULL; 497 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 498 if (ctx->Extensions.ARB_texture_cube_map) 499 return texUnit->CurrentCubeMap->PosZ[level]; 500 else 501 return NULL; 502 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 503 if (ctx->Extensions.ARB_texture_cube_map) 504 return texUnit->CurrentCubeMap->NegZ[level]; 505 else 506 return NULL; 507 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 508 if (ctx->Extensions.ARB_texture_cube_map) 509 return ctx->Texture.ProxyCubeMap->Image[level]; 510 else 511 return NULL; 512 case GL_TEXTURE_RECTANGLE_NV: 513 if (ctx->Extensions.NV_texture_rectangle) { 514 ASSERT(level == 0); 515 return texUnit->CurrentRect->Image[level]; 516 } 517 else { 518 return NULL; 519 } 520 case GL_PROXY_TEXTURE_RECTANGLE_NV: 521 if (ctx->Extensions.NV_texture_rectangle) { 522 ASSERT(level == 0); 523 return ctx->Texture.ProxyRect->Image[level]; 524 } 525 else { 526 return NULL; 527 } 528 default: 529 _mesa_problem(ctx, "bad target in _mesa_select_tex_image()"); 530 return NULL; 531 } 532} 533 534 535 536#if 000 /* not used anymore */ 537/* 538 * glTexImage[123]D can accept a NULL image pointer. In this case we 539 * create a texture image with unspecified image contents per the OpenGL 540 * spec. 541 */ 542static GLubyte * 543make_null_texture(GLint width, GLint height, GLint depth, GLenum format) 544{ 545 const GLint components = _mesa_components_in_format(format); 546 const GLint numPixels = width * height * depth; 547 GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte)); 548 549#ifdef DEBUG 550 /* 551 * Let's see if anyone finds this. If glTexImage2D() is called with 552 * a NULL image pointer then load the texture image with something 553 * interesting instead of leaving it indeterminate. 554 */ 555 if (data) { 556 static const char message[8][32] = { 557 " X X XXXXX XXX X ", 558 " XX XX X X X X X ", 559 " X X X X X X X ", 560 " X X XXXX XXX XXXXX ", 561 " X X X X X X ", 562 " X X X X X X X ", 563 " X X XXXXX XXX X X ", 564 " " 565 }; 566 567 GLubyte *imgPtr = data; 568 GLint h, i, j, k; 569 for (h = 0; h < depth; h++) { 570 for (i = 0; i < height; i++) { 571 GLint srcRow = 7 - (i % 8); 572 for (j = 0; j < width; j++) { 573 GLint srcCol = j % 32; 574 GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70; 575 for (k = 0; k < components; k++) { 576 *imgPtr++ = texel; 577 } 578 } 579 } 580 } 581 } 582#endif 583 584 return data; 585} 586#endif 587 588 589 590/* 591 * Reset the fields of a gl_texture_image struct to zero. 592 * This is called when a proxy texture test fails, we set all the 593 * image members (except DriverData) to zero. 594 * It's also used in glTexImage[123]D as a safeguard to be sure all 595 * required fields get initialized properly by the Driver.TexImage[123]D 596 * functions. 597 */ 598static void 599clear_teximage_fields(struct gl_texture_image *img) 600{ 601 ASSERT(img); 602 img->Format = 0; 603 img->IntFormat = 0; 604 img->Border = 0; 605 img->Width = 0; 606 img->Height = 0; 607 img->Depth = 0; 608 img->Width2 = 0; 609 img->Height2 = 0; 610 img->Depth2 = 0; 611 img->WidthLog2 = 0; 612 img->HeightLog2 = 0; 613 img->DepthLog2 = 0; 614 img->Data = NULL; 615 img->TexFormat = &_mesa_null_texformat; 616 img->FetchTexel = NULL; 617 img->IsCompressed = 0; 618 img->CompressedSize = 0; 619} 620 621 622/* 623 * Initialize basic fields of the gl_texture_image struct. 624 */ 625void 626_mesa_init_teximage_fields(GLcontext *ctx, GLenum target, 627 struct gl_texture_image *img, 628 GLsizei width, GLsizei height, GLsizei depth, 629 GLint border, GLenum internalFormat) 630{ 631 ASSERT(img); 632 img->Format = _mesa_base_tex_format( ctx, internalFormat ); 633 ASSERT(img->Format > 0); 634 img->IntFormat = internalFormat; 635 img->Border = border; 636 img->Width = width; 637 img->Height = height; 638 img->Depth = depth; 639 img->WidthLog2 = logbase2(width - 2 * border); 640 if (height == 1) /* 1-D texture */ 641 img->HeightLog2 = 0; 642 else 643 img->HeightLog2 = logbase2(height - 2 * border); 644 if (depth == 1) /* 2-D texture */ 645 img->DepthLog2 = 0; 646 else 647 img->DepthLog2 = logbase2(depth - 2 * border); 648 img->Width2 = 1 << img->WidthLog2; 649 img->Height2 = 1 << img->HeightLog2; 650 img->Depth2 = 1 << img->DepthLog2; 651 img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); 652 img->IsCompressed = is_compressed_format(ctx, internalFormat); 653 /* Compute Width/Height/DepthScale for mipmap lod computation */ 654 if (target == GL_TEXTURE_RECTANGLE_NV) { 655 /* scale = 1.0 since texture coords directly map to texels */ 656 img->WidthScale = 1.0; 657 img->HeightScale = 1.0; 658 img->DepthScale = 1.0; 659 } 660 else { 661 img->WidthScale = (GLfloat) img->Width; 662 img->HeightScale = (GLfloat) img->Height; 663 img->DepthScale = (GLfloat) img->Depth; 664 } 665} 666 667 668 669/* 670 * Test glTexImage[123]D() parameters for errors. 671 * Input: 672 * dimensions - must be 1 or 2 or 3 673 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors 674 */ 675static GLboolean 676texture_error_check( GLcontext *ctx, GLenum target, 677 GLint level, GLint internalFormat, 678 GLenum format, GLenum type, 679 GLuint dimensions, 680 GLint width, GLint height, 681 GLint depth, GLint border ) 682{ 683 GLboolean isProxy; 684 GLint iformat; 685 GLint maxLevels = 0, maxTextureSize; 686 687 if (dimensions == 1) { 688 if (target == GL_PROXY_TEXTURE_1D) { 689 isProxy = GL_TRUE; 690 } 691 else if (target == GL_TEXTURE_1D) { 692 isProxy = GL_FALSE; 693 } 694 else { 695 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); 696 return GL_TRUE; 697 } 698 maxLevels = ctx->Const.MaxTextureLevels; 699 } 700 else if (dimensions == 2) { 701 if (target == GL_PROXY_TEXTURE_2D) { 702 isProxy = GL_TRUE; 703 maxLevels = ctx->Const.MaxTextureLevels; 704 } 705 else if (target == GL_TEXTURE_2D) { 706 isProxy = GL_FALSE; 707 maxLevels = ctx->Const.MaxTextureLevels; 708 } 709 else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { 710 if (!ctx->Extensions.ARB_texture_cube_map) { 711 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); 712 return GL_TRUE; 713 } 714 isProxy = GL_TRUE; 715 maxLevels = ctx->Const.MaxCubeTextureLevels; 716 } 717 else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 718 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 719 if (!ctx->Extensions.ARB_texture_cube_map) { 720 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); 721 return GL_TRUE; 722 } 723 isProxy = GL_FALSE; 724 maxLevels = ctx->Const.MaxCubeTextureLevels; 725 } 726 else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV) { 727 if (!ctx->Extensions.NV_texture_rectangle) { 728 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); 729 return GL_TRUE; 730 } 731 isProxy = GL_TRUE; 732 maxLevels = 1; 733 } 734 else if (target == GL_TEXTURE_RECTANGLE_NV) { 735 if (!ctx->Extensions.NV_texture_rectangle) { 736 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); 737 return GL_TRUE; 738 } 739 isProxy = GL_FALSE; 740 maxLevels = 1; 741 } 742 else { 743 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage2D(target)"); 744 return GL_TRUE; 745 } 746 } 747 else if (dimensions == 3) { 748 if (target == GL_PROXY_TEXTURE_3D) { 749 isProxy = GL_TRUE; 750 } 751 else if (target == GL_TEXTURE_3D) { 752 isProxy = GL_FALSE; 753 } 754 else { 755 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); 756 return GL_TRUE; 757 } 758 maxLevels = ctx->Const.Max3DTextureLevels; 759 } 760 else { 761 _mesa_problem( ctx, "bad dims in texture_error_check" ); 762 return GL_TRUE; 763 } 764 765 ASSERT(maxLevels > 0); 766 maxTextureSize = 1 << (maxLevels - 1); 767 768 /* Border */ 769 if (border != 0 && border != 1) { 770 if (!isProxy) { 771 _mesa_error(ctx, GL_INVALID_VALUE, 772 "glTexImage%dD(border=%d)", dimensions, border); 773 } 774 return GL_TRUE; 775 } 776 if ((target == GL_TEXTURE_RECTANGLE_NV || 777 target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0) { 778 return GL_TRUE; 779 } 780 781 /* Width */ 782 if (target == GL_TEXTURE_RECTANGLE_NV || 783 target == GL_PROXY_TEXTURE_RECTANGLE_NV) { 784 if (width < 1 || width > ctx->Const.MaxTextureRectSize) { 785 if (!isProxy) { 786 _mesa_error(ctx, GL_INVALID_VALUE, 787 "glTexImage%dD(width=%d)", dimensions, width); 788 } 789 return GL_TRUE; 790 } 791 } 792 else if (width < 2 * border || width > 2 + maxTextureSize 793 || logbase2( width - 2 * border ) < 0) { 794 if (!isProxy) { 795 _mesa_error(ctx, GL_INVALID_VALUE, 796 "glTexImage%dD(width=%d)", dimensions, width); 797 } 798 return GL_TRUE; 799 } 800 801 /* Height */ 802 if (target == GL_TEXTURE_RECTANGLE_NV || 803 target == GL_PROXY_TEXTURE_RECTANGLE_NV) { 804 if (height < 1 || height > ctx->Const.MaxTextureRectSize) { 805 if (!isProxy) { 806 _mesa_error(ctx, GL_INVALID_VALUE, 807 "glTexImage%dD(height=%d)", dimensions, height); 808 } 809 return GL_TRUE; 810 } 811 } 812 else if (dimensions >= 2) { 813 if (height < 2 * border || height > 2 + maxTextureSize 814 || logbase2( height - 2 * border ) < 0) { 815 if (!isProxy) { 816 _mesa_error(ctx, GL_INVALID_VALUE, 817 "glTexImage%dD(height=%d)", dimensions, height); 818 } 819 return GL_TRUE; 820 } 821 } 822 823 /* For cube map, width must equal height */ 824 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 825 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 826 if (width != height) { 827 if (!isProxy) { 828 _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage2D(width != height)"); 829 } 830 return GL_TRUE; 831 } 832 } 833 834 /* Depth */ 835 if (dimensions >= 3) { 836 if (depth < 2 * border || depth > 2 + maxTextureSize 837 || logbase2( depth - 2 * border ) < 0) { 838 if (!isProxy) { 839 _mesa_error( ctx, GL_INVALID_VALUE, 840 "glTexImage3D(depth=%d)", depth ); 841 } 842 return GL_TRUE; 843 } 844 } 845 846 /* Level */ 847 if (target == GL_TEXTURE_RECTANGLE_NV || 848 target == GL_PROXY_TEXTURE_RECTANGLE_NV) { 849 if (level != 0) { 850 if (!isProxy) { 851 _mesa_error(ctx, GL_INVALID_VALUE, 852 "glTexImage2D(level=%d)", level); 853 } 854 return GL_TRUE; 855 } 856 } 857 else if (level < 0 || level >= maxLevels) { 858 if (!isProxy) { 859 _mesa_error(ctx, GL_INVALID_VALUE, 860 "glTexImage%dD(level=%d)", dimensions, level); 861 } 862 return GL_TRUE; 863 } 864 865 /* For cube map, width must equal height */ 866 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 867 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 868 if (width != height) { 869 _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage2D(width != height)"); 870 return GL_TRUE; 871 } 872 } 873 874 iformat = _mesa_base_tex_format( ctx, internalFormat ); 875 if (iformat < 0) { 876 if (!isProxy) { 877 _mesa_error(ctx, GL_INVALID_VALUE, 878 "glTexImage%dD(internalFormat=0x%x)", 879 dimensions, internalFormat); 880 } 881 return GL_TRUE; 882 } 883 884 ASSERT(iformat > 0); 885 886 if (!is_compressed_format( ctx, internalFormat ) && 887 !_mesa_is_legal_format_and_type( format, type )) { 888 /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there 889 * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4. 890 */ 891 if (!isProxy) { 892 _mesa_error(ctx, GL_INVALID_OPERATION, 893 "glTexImage%dD(format or type)", dimensions); 894 } 895 return GL_TRUE; 896 } 897 898 /* if we get here, the parameters are OK */ 899 return GL_FALSE; 900} 901 902 903 904/* 905 * Test glTexSubImage[123]D() parameters for errors. 906 * Input: 907 * dimensions - must be 1 or 2 or 3 908 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors 909 */ 910static GLboolean 911subtexture_error_check( GLcontext *ctx, GLuint dimensions, 912 GLenum target, GLint level, 913 GLint xoffset, GLint yoffset, GLint zoffset, 914 GLint width, GLint height, GLint depth, 915 GLenum format, GLenum type ) 916{ 917 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 918 struct gl_texture_image *destTex; 919 GLint maxLevels = 0; 920 GLboolean compressed; 921 922 if (dimensions == 1) { 923 if (target != GL_TEXTURE_1D) { 924 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" ); 925 return GL_TRUE; 926 } 927 maxLevels = ctx->Const.MaxTextureLevels; 928 } 929 else if (dimensions == 2) { 930 if (ctx->Extensions.ARB_texture_cube_map) { 931 if ((target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || 932 target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) && 933 target != GL_TEXTURE_2D) { 934 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); 935 return GL_TRUE; 936 } 937 } 938 else if (target != GL_TEXTURE_2D) { 939 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); 940 return GL_TRUE; 941 } 942 if (target == GL_PROXY_TEXTURE_2D && target == GL_TEXTURE_2D) 943 maxLevels = ctx->Const.MaxTextureLevels; 944 else 945 maxLevels = ctx->Const.MaxCubeTextureLevels; 946 } 947 else if (dimensions == 3) { 948 if (target != GL_TEXTURE_3D) { 949 _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" ); 950 return GL_TRUE; 951 } 952 maxLevels = ctx->Const.Max3DTextureLevels; 953 } 954 else { 955 _mesa_problem( ctx, "bad dims in texture_error_check" ); 956 return GL_TRUE; 957 } 958 959 ASSERT(maxLevels > 0); 960 961 if (level < 0 || level >= maxLevels) { 962 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level); 963 return GL_TRUE; 964 } 965 966 if (width < 0) { 967 _mesa_error(ctx, GL_INVALID_VALUE, 968 "glTexSubImage%dD(width=%d)", dimensions, width); 969 return GL_TRUE; 970 } 971 if (height < 0 && dimensions > 1) { 972 _mesa_error(ctx, GL_INVALID_VALUE, 973 "glTexSubImage%dD(height=%d)", dimensions, height); 974 return GL_TRUE; 975 } 976 if (depth < 0 && dimensions > 2) { 977 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(depth=%d)", dimensions, depth); 978 return GL_TRUE; 979 } 980 981 destTex = _mesa_select_tex_image(ctx, texUnit, target, level); 982 983 if (!destTex) { 984 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage2D"); 985 return GL_TRUE; 986 } 987 988 if (xoffset < -((GLint)destTex->Border)) { 989 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset)"); 990 return GL_TRUE; 991 } 992 if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) { 993 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset+width)"); 994 return GL_TRUE; 995 } 996 if (dimensions > 1) { 997 if (yoffset < -((GLint)destTex->Border)) { 998 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset)"); 999 return GL_TRUE; 1000 } 1001 if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) { 1002 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset+height)"); 1003 return GL_TRUE; 1004 } 1005 } 1006 if (dimensions > 2) { 1007 if (zoffset < -((GLint)destTex->Border)) { 1008 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)"); 1009 return GL_TRUE; 1010 } 1011 if (zoffset + depth > (GLint) (destTex->Depth + destTex->Border)) { 1012 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)"); 1013 return GL_TRUE; 1014 } 1015 } 1016 1017 compressed = is_compressed_format(ctx, destTex->IntFormat); 1018 1019 if (!compressed && !_mesa_is_legal_format_and_type(format, type)) { 1020 _mesa_error(ctx, GL_INVALID_ENUM, 1021 "glTexSubImage%dD(format or type)", dimensions); 1022 return GL_TRUE; 1023 } 1024 1025 if (compressed) { 1026 if (xoffset != -((GLint)destTex->Border)) { 1027 _mesa_error(ctx, GL_INVALID_OPERATION, 1028 "glTexSubImage1/2/3D(xoffset != -border"); 1029 return GL_TRUE; 1030 } 1031 if (dimensions > 1 && yoffset != -((GLint)destTex->Border)) { 1032 _mesa_error(ctx, GL_INVALID_OPERATION, 1033 "glTexSubImage2/3D(yoffset != -border"); 1034 return GL_TRUE; 1035 } 1036 if (dimensions > 2 && zoffset != -((GLint)destTex->Border)) { 1037 _mesa_error(ctx, GL_INVALID_OPERATION, 1038 "glTexSubImage3D(zoffset != -border"); 1039 return GL_TRUE; 1040 } 1041 } 1042 1043 return GL_FALSE; 1044} 1045 1046 1047/* 1048 * Test glCopyTexImage[12]D() parameters for errors. 1049 * Input: dimensions - must be 1 or 2 or 3 1050 * Return: GL_TRUE = an error was detected, GL_FALSE = no errors 1051 */ 1052static GLboolean 1053copytexture_error_check( GLcontext *ctx, GLuint dimensions, 1054 GLenum target, GLint level, GLint internalFormat, 1055 GLint width, GLint height, GLint border ) 1056{ 1057 GLint iformat; 1058 GLint maxLevels = 0, maxTextureSize; 1059 1060 if (dimensions == 1) { 1061 if (target != GL_TEXTURE_1D) { 1062 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" ); 1063 return GL_TRUE; 1064 } 1065 maxLevels = ctx->Const.MaxTextureLevels; 1066 } 1067 else if (dimensions == 2) { 1068 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1069 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 1070 if (!ctx->Extensions.ARB_texture_cube_map) { 1071 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); 1072 return GL_TRUE; 1073 } 1074 } 1075 else if (target == GL_TEXTURE_RECTANGLE_NV) { 1076 if (!ctx->Extensions.NV_texture_rectangle) { 1077 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); 1078 return GL_TRUE; 1079 } 1080 } 1081 else if (target != GL_TEXTURE_2D) { 1082 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); 1083 return GL_TRUE; 1084 } 1085 if (target == GL_TEXTURE_2D) 1086 maxLevels = ctx->Const.MaxTextureLevels; 1087 else if (target == GL_TEXTURE_RECTANGLE_NV) 1088 maxLevels = 1; 1089 else 1090 maxLevels = ctx->Const.MaxCubeTextureLevels; 1091 } 1092 1093 ASSERT(maxLevels > 0); 1094 maxTextureSize = 1 << (maxLevels - 1); 1095 1096 /* Border */ 1097 if (border != 0 && border != 1) { 1098 _mesa_error(ctx, GL_INVALID_VALUE, 1099 "glCopyTexImage%dD(border)", dimensions); 1100 return GL_TRUE; 1101 } 1102 1103 /* Width */ 1104 if (width < 2 * border || width > 2 + maxTextureSize 1105 || logbase2( width - 2 * border ) < 0) { 1106 _mesa_error(ctx, GL_INVALID_VALUE, 1107 "glCopyTexImage%dD(width=%d)", dimensions, width); 1108 return GL_TRUE; 1109 } 1110 1111 /* Height */ 1112 if (dimensions >= 2) { 1113 if (height < 2 * border || height > 2 + maxTextureSize 1114 || logbase2( height - 2 * border ) < 0) { 1115 _mesa_error(ctx, GL_INVALID_VALUE, 1116 "glCopyTexImage%dD(height=%d)", dimensions, height); 1117 return GL_TRUE; 1118 } 1119 } 1120 1121 /* For cube map, width must equal height */ 1122 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1123 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { 1124 if (width != height) { 1125 _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexImage2D(width != height)"); 1126 return GL_TRUE; 1127 } 1128 } 1129 1130 /* Level */ 1131 if (level < 0 || level >= maxLevels) { 1132 _mesa_error(ctx, GL_INVALID_VALUE, 1133 "glCopyTexImage%dD(level=%d)", dimensions, level); 1134 return GL_TRUE; 1135 } 1136 1137 iformat = _mesa_base_tex_format(ctx, internalFormat); 1138 if (iformat < 0) { 1139 _mesa_error(ctx, GL_INVALID_VALUE, 1140 "glCopyTexImage%dD(internalFormat)", dimensions); 1141 return GL_TRUE; 1142 } 1143 1144 /* if we get here, the parameters are OK */ 1145 return GL_FALSE; 1146} 1147 1148 1149static GLboolean 1150copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, 1151 GLenum target, GLint level, 1152 GLint xoffset, GLint yoffset, GLint zoffset, 1153 GLsizei width, GLsizei height ) 1154{ 1155 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1156 struct gl_texture_image *teximage; 1157 GLint maxLevels = 0; 1158 GLboolean compressed; 1159 1160 if (dimensions == 1) { 1161 if (target != GL_TEXTURE_1D) { 1162 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" ); 1163 return GL_TRUE; 1164 } 1165 maxLevels = ctx->Const.MaxTextureLevels; 1166 } 1167 else if (dimensions == 2) { 1168 if (ctx->Extensions.ARB_texture_cube_map) { 1169 if ((target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || 1170 target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) && 1171 target != GL_TEXTURE_2D) { 1172 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); 1173 return GL_TRUE; 1174 } 1175 } 1176 else if (target != GL_TEXTURE_2D) { 1177 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); 1178 return GL_TRUE; 1179 } 1180 if (target == GL_PROXY_TEXTURE_2D && target == GL_TEXTURE_2D) 1181 maxLevels = ctx->Const.MaxTextureLevels; 1182 else 1183 maxLevels = ctx->Const.MaxCubeTextureLevels; 1184 } 1185 else if (dimensions == 3) { 1186 if (target != GL_TEXTURE_3D) { 1187 _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" ); 1188 return GL_TRUE; 1189 } 1190 maxLevels = ctx->Const.Max3DTextureLevels; 1191 } 1192 1193 ASSERT(maxLevels > 0); 1194 1195 if (level < 0 || level >= maxLevels) { 1196 _mesa_error(ctx, GL_INVALID_VALUE, 1197 "glCopyTexSubImage%dD(level=%d)", dimensions, level); 1198 return GL_TRUE; 1199 } 1200 1201 if (width < 0) { 1202 _mesa_error(ctx, GL_INVALID_VALUE, 1203 "glCopyTexSubImage%dD(width=%d)", dimensions, width); 1204 return GL_TRUE; 1205 } 1206 if (dimensions > 1 && height < 0) { 1207 _mesa_error(ctx, GL_INVALID_VALUE, 1208 "glCopyTexSubImage%dD(height=%d)", dimensions, height); 1209 return GL_TRUE; 1210 } 1211 1212 teximage = _mesa_select_tex_image(ctx, texUnit, target, level); 1213 if (!teximage) { 1214 _mesa_error(ctx, GL_INVALID_OPERATION, 1215 "glCopyTexSubImage%dD(undefined texture)", dimensions); 1216 return GL_TRUE; 1217 } 1218 1219 if (xoffset < -((GLint)teximage->Border)) { 1220 _mesa_error(ctx, GL_INVALID_VALUE, 1221 "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset); 1222 return GL_TRUE; 1223 } 1224 if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) { 1225 _mesa_error(ctx, GL_INVALID_VALUE, 1226 "glCopyTexSubImage%dD(xoffset+width)", dimensions); 1227 return GL_TRUE; 1228 } 1229 if (dimensions > 1) { 1230 if (yoffset < -((GLint)teximage->Border)) { 1231 _mesa_error(ctx, GL_INVALID_VALUE, 1232 "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset); 1233 return GL_TRUE; 1234 } 1235 /* NOTE: we're adding the border here, not subtracting! */ 1236 if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) { 1237 _mesa_error(ctx, GL_INVALID_VALUE, 1238 "glCopyTexSubImage%dD(yoffset+height)", dimensions); 1239 return GL_TRUE; 1240 } 1241 } 1242 1243 if (dimensions > 2) { 1244 if (zoffset < -((GLint)teximage->Border)) { 1245 _mesa_error(ctx, GL_INVALID_VALUE, 1246 "glCopyTexSubImage%dD(zoffset)", dimensions); 1247 return GL_TRUE; 1248 } 1249 if (zoffset > (GLint) (teximage->Depth + teximage->Border)) { 1250 _mesa_error(ctx, GL_INVALID_VALUE, 1251 "glCopyTexSubImage%dD(zoffset+depth)", dimensions); 1252 return GL_TRUE; 1253 } 1254 } 1255 1256 compressed = is_compressed_format(ctx, teximage->IntFormat); 1257 if (compressed) { 1258 if (xoffset != -((GLint)teximage->Border)) { 1259 _mesa_error(ctx, GL_INVALID_OPERATION, 1260 "glCopyTexSubImage1/2/3D(xoffset != -border"); 1261 return GL_TRUE; 1262 } 1263 if (dimensions > 1 && yoffset != -((GLint)teximage->Border)) { 1264 _mesa_error(ctx, GL_INVALID_OPERATION, 1265 "glCopyTexSubImage2/3D(yoffset != -border"); 1266 return GL_TRUE; 1267 } 1268 if (dimensions > 2 && zoffset != -((GLint)teximage->Border)) { 1269 _mesa_error(ctx, GL_INVALID_OPERATION, 1270 "glCopyTexSubImage3D(zoffset != -border"); 1271 return GL_TRUE; 1272 } 1273 } 1274 1275 /* if we get here, the parameters are OK */ 1276 return GL_FALSE; 1277} 1278 1279 1280 1281void 1282_mesa_GetTexImage( GLenum target, GLint level, GLenum format, 1283 GLenum type, GLvoid *pixels ) 1284{ 1285 const struct gl_texture_unit *texUnit; 1286 const struct gl_texture_object *texObj; 1287 struct gl_texture_image *texImage; 1288 GLint maxLevels = 0; 1289 GET_CURRENT_CONTEXT(ctx); 1290 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1291 1292 texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]); 1293 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1294 if (!texObj || is_proxy_target(target)) { 1295 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)"); 1296 return; 1297 } 1298 1299 if (target == GL_TEXTURE_1D || target == GL_TEXTURE_2D) { 1300 maxLevels = ctx->Const.MaxTextureLevels; 1301 } 1302 else if (target == GL_TEXTURE_3D) { 1303 maxLevels = ctx->Const.Max3DTextureLevels; 1304 } 1305 else if (target == GL_TEXTURE_RECTANGLE_NV) { 1306 maxLevels = 1; 1307 } 1308 else { 1309 maxLevels = ctx->Const.MaxCubeTextureLevels; 1310 } 1311 1312 ASSERT(maxLevels > 0); 1313 1314 if (level < 0 || level >= maxLevels) { 1315 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" ); 1316 return; 1317 } 1318 1319 if (_mesa_sizeof_packed_type(type) <= 0) { 1320 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" ); 1321 return; 1322 } 1323 1324 if (_mesa_components_in_format(format) <= 0 || 1325 format == GL_STENCIL_INDEX) { 1326 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" ); 1327 return; 1328 } 1329 1330 if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) { 1331 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); 1332 } 1333 1334 if (!ctx->Extensions.SGIX_depth_texture && format == GL_DEPTH_COMPONENT) { 1335 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); 1336 } 1337 1338 /* XXX what if format/type doesn't match texture format/type? */ 1339 1340 if (!pixels) 1341 return; 1342 1343 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1344 if (!texImage) { 1345 /* invalid mipmap level, not an error */ 1346 return; 1347 } 1348 1349 if (!texImage->Data) { 1350 /* no image data, not an error */ 1351 return; 1352 } 1353 1354 { 1355 const GLint width = texImage->Width; 1356 const GLint height = texImage->Height; 1357 const GLint depth = texImage->Depth; 1358 GLint img, row; 1359 for (img = 0; img < depth; img++) { 1360 for (row = 0; row < height; row++) { 1361 /* compute destination address in client memory */ 1362 GLvoid *dest = _mesa_image_address( &ctx->Unpack, pixels, 1363 width, height, format, type, 1364 img, row, 0); 1365 assert(dest); 1366 1367 if (format == GL_COLOR_INDEX) { 1368 GLuint indexRow[MAX_WIDTH]; 1369 GLint col; 1370 for (col = 0; col < width; col++) { 1371 (*texImage->FetchTexel)(texImage, col, row, img, 1372 (GLvoid *) &indexRow[col]); 1373 } 1374 _mesa_pack_index_span(ctx, width, type, dest, 1375 indexRow, &ctx->Pack, 1376 0 /* no image transfer */); 1377 } 1378 else if (format == GL_DEPTH_COMPONENT) { 1379 GLfloat depthRow[MAX_WIDTH]; 1380 GLint col; 1381 for (col = 0; col < width; col++) { 1382 (*texImage->FetchTexel)(texImage, col, row, img, 1383 (GLvoid *) &depthRow[col]); 1384 } 1385 _mesa_pack_depth_span(ctx, width, dest, type, 1386 depthRow, &ctx->Pack); 1387 } 1388 else { 1389 /* general case: convert row to RGBA format */ 1390 GLchan rgba[MAX_WIDTH][4]; 1391 GLint col; 1392 for (col = 0; col < width; col++) { 1393 (*texImage->FetchTexel)(texImage, col, row, img, 1394 (GLvoid *) rgba[col]); 1395 } 1396 _mesa_pack_rgba_span(ctx, width, (const GLchan (*)[4])rgba, 1397 format, type, dest, &ctx->Pack, 1398 0 /* no image transfer */); 1399 } /* format */ 1400 } /* row */ 1401 } /* img */ 1402 } 1403} 1404 1405 1406 1407/* 1408 * Called from the API. Note that width includes the border. 1409 */ 1410void 1411_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, 1412 GLsizei width, GLint border, GLenum format, 1413 GLenum type, const GLvoid *pixels ) 1414{ 1415 GLsizei postConvWidth = width; 1416 GET_CURRENT_CONTEXT(ctx); 1417 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1418 1419 if (is_color_format(internalFormat)) { 1420 _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); 1421 } 1422 1423 if (target == GL_TEXTURE_1D) { 1424 struct gl_texture_unit *texUnit; 1425 struct gl_texture_object *texObj; 1426 struct gl_texture_image *texImage; 1427 1428 if (texture_error_check(ctx, target, level, internalFormat, 1429 format, type, 1, postConvWidth, 1, 1, border)) { 1430 return; /* error was recorded */ 1431 } 1432 1433 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1434 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1435 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1436 1437 if (!texImage) { 1438 texImage = _mesa_alloc_texture_image(); 1439 texObj->Image[level] = texImage; 1440 if (!texImage) { 1441 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); 1442 return; 1443 } 1444 } 1445 else if (texImage->Data) { 1446 /* free the old texture data */ 1447 MESA_PBUFFER_FREE(texImage->Data); 1448 texImage->Data = NULL; 1449 } 1450 clear_teximage_fields(texImage); /* not really needed, but helpful */ 1451 _mesa_init_teximage_fields(ctx, target, texImage, 1452 postConvWidth, 1, 1, 1453 border, internalFormat); 1454 1455 if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) 1456 _mesa_update_state(ctx); 1457 1458 ASSERT(ctx->Driver.TexImage1D); 1459 1460#if 0 /* don't make default teximage anymore */ 1461 if (pixels) { 1462 (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, 1463 width, border, format, type, pixels, 1464 &ctx->Unpack, texObj, texImage); 1465 } 1466 else { 1467 GLubyte *dummy = make_null_texture(width, 1, 1, format); 1468 if (dummy) { 1469 (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, 1470 width, border, 1471 format, GL_UNSIGNED_BYTE, dummy, 1472 &_mesa_native_packing, texObj, texImage); 1473 FREE(dummy); 1474 } 1475 } 1476#else 1477 /* <pixels> may be null! */ 1478 (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, 1479 width, border, format, type, pixels, 1480 &ctx->Unpack, texObj, texImage); 1481#endif 1482 1483 ASSERT(texImage->TexFormat); 1484 if (!texImage->FetchTexel) { 1485 /* If driver didn't explicitly set this, use the default */ 1486 texImage->FetchTexel = texImage->TexFormat->FetchTexel1D; 1487 } 1488 ASSERT(texImage->FetchTexel); 1489 1490 if (texImage->IsCompressed) { 1491 ASSERT(texImage->CompressedSize > 0); 1492 } 1493 1494 /* state update */ 1495 texObj->Complete = GL_FALSE; 1496 ctx->NewState |= _NEW_TEXTURE; 1497 } 1498 else if (target == GL_PROXY_TEXTURE_1D) { 1499 /* Proxy texture: check for errors and update proxy state */ 1500 GLenum error = texture_error_check(ctx, target, level, internalFormat, 1501 format, type, 1, 1502 postConvWidth, 1, 1, border); 1503 if (!error) { 1504 struct gl_texture_unit *texUnit; 1505 struct gl_texture_image *texImage; 1506 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1507 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1508 _mesa_init_teximage_fields(ctx, target, texImage, 1509 postConvWidth, 1, 1, 1510 border, internalFormat); 1511 ASSERT(ctx->Driver.TestProxyTexImage); 1512 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 1513 internalFormat, format, type, 1514 postConvWidth, 1, 1, border); 1515 } 1516 if (error) { 1517 /* if error, clear all proxy texture image parameters */ 1518 if (level >= 0 && level < ctx->Const.MaxTextureLevels) { 1519 clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]); 1520 } 1521 } 1522 } 1523 else { 1524 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); 1525 return; 1526 } 1527} 1528 1529 1530void 1531_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, 1532 GLsizei width, GLsizei height, GLint border, 1533 GLenum format, GLenum type, 1534 const GLvoid *pixels ) 1535{ 1536 GLsizei postConvWidth = width, postConvHeight = height; 1537 GET_CURRENT_CONTEXT(ctx); 1538 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1539 1540 if (is_color_format(internalFormat)) { 1541 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, 1542 &postConvHeight); 1543 } 1544 1545 if (target == GL_TEXTURE_2D || 1546 (ctx->Extensions.ARB_texture_cube_map && 1547 target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 1548 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) || 1549 (ctx->Extensions.NV_texture_rectangle && 1550 target == GL_TEXTURE_RECTANGLE_NV)) { 1551 /* non-proxy target */ 1552 struct gl_texture_unit *texUnit; 1553 struct gl_texture_object *texObj; 1554 struct gl_texture_image *texImage; 1555 1556 if (texture_error_check(ctx, target, level, internalFormat, 1557 format, type, 2, postConvWidth, postConvHeight, 1558 1, border)) { 1559 return; /* error was recorded */ 1560 } 1561 1562 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1563 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1564 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1565 1566 if (!texImage) { 1567 texImage = _mesa_alloc_texture_image(); 1568 _mesa_set_tex_image(texObj, target, level, texImage); 1569 if (!texImage) { 1570 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); 1571 return; 1572 } 1573 } 1574 else if (texImage->Data) { 1575 /* free the old texture data */ 1576 MESA_PBUFFER_FREE(texImage->Data); 1577 texImage->Data = NULL; 1578 } 1579 clear_teximage_fields(texImage); /* not really needed, but helpful */ 1580 _mesa_init_teximage_fields(ctx, target, texImage, 1581 postConvWidth, postConvHeight, 1, 1582 border, internalFormat); 1583 1584 if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) 1585 _mesa_update_state(ctx); 1586 1587 ASSERT(ctx->Driver.TexImage2D); 1588 1589#if 0 /* don't make default teximage anymore */ 1590 if (pixels) { 1591 (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, 1592 width, height, border, format, type, pixels, 1593 &ctx->Unpack, texObj, texImage); 1594 } 1595 else { 1596 GLubyte *dummy = make_null_texture(width, height, 1, format); 1597 if (dummy) { 1598 (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, 1599 width, height, border, 1600 format, GL_UNSIGNED_BYTE, dummy, 1601 &_mesa_native_packing, texObj, texImage); 1602 FREE(dummy); 1603 } 1604 } 1605#else 1606 /* <pixels> may be null! */ 1607 (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, 1608 width, height, border, format, type, pixels, 1609 &ctx->Unpack, texObj, texImage); 1610#endif 1611 1612 ASSERT(texImage->TexFormat); 1613 if (!texImage->FetchTexel) { 1614 /* If driver didn't explicitly set this, use the default */ 1615 texImage->FetchTexel = texImage->TexFormat->FetchTexel2D; 1616 } 1617 ASSERT(texImage->FetchTexel); 1618 1619 if (texImage->IsCompressed) { 1620 ASSERT(texImage->CompressedSize > 0); 1621 } 1622 1623 /* state update */ 1624 texObj->Complete = GL_FALSE; 1625 ctx->NewState |= _NEW_TEXTURE; 1626 } 1627 else if (target == GL_PROXY_TEXTURE_2D || 1628 (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB && 1629 ctx->Extensions.ARB_texture_cube_map) || 1630 (target == GL_PROXY_TEXTURE_RECTANGLE_NV && 1631 ctx->Extensions.NV_texture_rectangle)) { 1632 /* Proxy texture: check for errors and update proxy state */ 1633 GLenum error = texture_error_check(ctx, target, level, internalFormat, 1634 format, type, 2, 1635 postConvWidth, postConvHeight, 1, border); 1636 if (!error) { 1637 struct gl_texture_unit *texUnit; 1638 struct gl_texture_image *texImage; 1639 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1640 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1641 _mesa_init_teximage_fields(ctx, target, texImage, 1642 postConvWidth, postConvHeight, 1, 1643 border, internalFormat); 1644 ASSERT(ctx->Driver.TestProxyTexImage); 1645 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 1646 internalFormat, format, type, 1647 postConvWidth, postConvHeight, 1, border); 1648 } 1649 if (error) { 1650 /* if error, clear all proxy texture image parameters */ 1651 const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ? 1652 ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels; 1653 if (level >= 0 && level < maxLevels) { 1654 clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]); 1655 } 1656 } 1657 } 1658 else { 1659 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" ); 1660 return; 1661 } 1662} 1663 1664 1665/* 1666 * Called by the API or display list executor. 1667 * Note that width and height include the border. 1668 */ 1669void 1670_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat, 1671 GLsizei width, GLsizei height, GLsizei depth, 1672 GLint border, GLenum format, GLenum type, 1673 const GLvoid *pixels ) 1674{ 1675 GET_CURRENT_CONTEXT(ctx); 1676 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1677 1678 if (target == GL_TEXTURE_3D) { 1679 struct gl_texture_unit *texUnit; 1680 struct gl_texture_object *texObj; 1681 struct gl_texture_image *texImage; 1682 1683 if (texture_error_check(ctx, target, level, (GLint) internalFormat, 1684 format, type, 3, width, height, depth, border)) { 1685 return; /* error was recorded */ 1686 } 1687 1688 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1689 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1690 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1691 1692 if (!texImage) { 1693 texImage = _mesa_alloc_texture_image(); 1694 texObj->Image[level] = texImage; 1695 if (!texImage) { 1696 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); 1697 return; 1698 } 1699 } 1700 else if (texImage->Data) { 1701 MESA_PBUFFER_FREE(texImage->Data); 1702 texImage->Data = NULL; 1703 } 1704 clear_teximage_fields(texImage); /* not really needed, but helpful */ 1705 _mesa_init_teximage_fields(ctx, target, texImage, 1706 width, height, depth, 1707 border, internalFormat); 1708 1709 if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) 1710 _mesa_update_state(ctx); 1711 1712 ASSERT(ctx->Driver.TexImage3D); 1713 1714#if 0 /* don't make default teximage anymore */ 1715 if (pixels) { 1716 (*ctx->Driver.TexImage3D)(ctx, target, level, (GLint) internalFormat, 1717 width, height, depth, border, 1718 format, type, pixels, 1719 &ctx->Unpack, texObj, texImage); 1720 } 1721 else { 1722 GLubyte *dummy = make_null_texture(width, height, depth, format); 1723 if (dummy) { 1724 (*ctx->Driver.TexImage3D)(ctx, target, level, 1725 (GLint) internalFormat, 1726 width, height, depth, border, 1727 format, GL_UNSIGNED_BYTE, dummy, 1728 &_mesa_native_packing, texObj, texImage); 1729 FREE(dummy); 1730 } 1731 } 1732#else 1733 /* <pixels> may be null! */ 1734 (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat, 1735 width, height, depth, border, format, type, 1736 pixels, &ctx->Unpack, texObj, texImage); 1737#endif 1738 1739 ASSERT(texImage->TexFormat); 1740 if (!texImage->FetchTexel) { 1741 /* If driver didn't explicitly set this, use the default */ 1742 texImage->FetchTexel = texImage->TexFormat->FetchTexel3D; 1743 } 1744 ASSERT(texImage->FetchTexel); 1745 1746 if (texImage->IsCompressed) { 1747 ASSERT(texImage->CompressedSize > 0); 1748 } 1749 1750 /* state update */ 1751 texObj->Complete = GL_FALSE; 1752 ctx->NewState |= _NEW_TEXTURE; 1753 } 1754 else if (target == GL_PROXY_TEXTURE_3D) { 1755 /* Proxy texture: check for errors and update proxy state */ 1756 GLenum error = texture_error_check(ctx, target, level, internalFormat, 1757 format, type, 3, width, height, depth, border); 1758 if (!error) { 1759 struct gl_texture_unit *texUnit; 1760 struct gl_texture_image *texImage; 1761 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1762 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1763 _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, 1764 border, internalFormat); 1765 ASSERT(ctx->Driver.TestProxyTexImage); 1766 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 1767 internalFormat, format, type, 1768 width, height, depth, border); 1769 } 1770 if (error) { 1771 /* if error, clear all proxy texture image parameters */ 1772 if (level >= 0 && level < ctx->Const.Max3DTextureLevels) { 1773 clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]); 1774 } 1775 } 1776 } 1777 else { 1778 _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); 1779 return; 1780 } 1781} 1782 1783 1784void 1785_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, 1786 GLsizei width, GLsizei height, GLsizei depth, 1787 GLint border, GLenum format, GLenum type, 1788 const GLvoid *pixels ) 1789{ 1790 _mesa_TexImage3D(target, level, internalFormat, width, height, 1791 depth, border, format, type, pixels); 1792} 1793 1794 1795 1796void 1797_mesa_TexSubImage1D( GLenum target, GLint level, 1798 GLint xoffset, GLsizei width, 1799 GLenum format, GLenum type, 1800 const GLvoid *pixels ) 1801{ 1802 GLsizei postConvWidth = width; 1803 struct gl_texture_unit *texUnit; 1804 struct gl_texture_object *texObj; 1805 struct gl_texture_image *texImage; 1806 GET_CURRENT_CONTEXT(ctx); 1807 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1808 1809 if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) 1810 _mesa_update_state(ctx); 1811 1812 /* XXX should test internal format */ 1813 if (is_color_format(format)) { 1814 _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); 1815 } 1816 1817 if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, 1818 postConvWidth, 1, 1, format, type)) { 1819 return; /* error was detected */ 1820 } 1821 1822 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1823 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1824 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1825 assert(texImage); 1826 1827 if (width == 0 || !pixels) 1828 return; /* no-op, not an error */ 1829 1830 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 1831 xoffset += texImage->Border; 1832 1833 ASSERT(ctx->Driver.TexSubImage1D); 1834 (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, 1835 format, type, pixels, &ctx->Unpack, 1836 texObj, texImage); 1837 ctx->NewState |= _NEW_TEXTURE; 1838} 1839 1840 1841void 1842_mesa_TexSubImage2D( GLenum target, GLint level, 1843 GLint xoffset, GLint yoffset, 1844 GLsizei width, GLsizei height, 1845 GLenum format, GLenum type, 1846 const GLvoid *pixels ) 1847{ 1848 GLsizei postConvWidth = width, postConvHeight = height; 1849 struct gl_texture_unit *texUnit; 1850 struct gl_texture_object *texObj; 1851 struct gl_texture_image *texImage; 1852 GET_CURRENT_CONTEXT(ctx); 1853 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1854 1855 if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) 1856 _mesa_update_state(ctx); 1857 1858 /* XXX should test internal format */ 1859 if (is_color_format(format)) { 1860 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, 1861 &postConvHeight); 1862 } 1863 1864 if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, 1865 postConvWidth, postConvHeight, 1, format, type)) { 1866 return; /* error was detected */ 1867 } 1868 1869 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1870 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1871 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1872 assert(texImage); 1873 1874 if (width == 0 || height == 0 || !pixels) 1875 return; /* no-op, not an error */ 1876 1877 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 1878 xoffset += texImage->Border; 1879 yoffset += texImage->Border; 1880 1881 ASSERT(ctx->Driver.TexSubImage2D); 1882 (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset, 1883 width, height, format, type, pixels, 1884 &ctx->Unpack, texObj, texImage); 1885 ctx->NewState |= _NEW_TEXTURE; 1886} 1887 1888 1889 1890void 1891_mesa_TexSubImage3D( GLenum target, GLint level, 1892 GLint xoffset, GLint yoffset, GLint zoffset, 1893 GLsizei width, GLsizei height, GLsizei depth, 1894 GLenum format, GLenum type, 1895 const GLvoid *pixels ) 1896{ 1897 struct gl_texture_unit *texUnit; 1898 struct gl_texture_object *texObj; 1899 struct gl_texture_image *texImage; 1900 GET_CURRENT_CONTEXT(ctx); 1901 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1902 1903 if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) 1904 _mesa_update_state(ctx); 1905 1906 if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, 1907 width, height, depth, format, type)) { 1908 return; /* error was detected */ 1909 } 1910 1911 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1912 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1913 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1914 assert(texImage); 1915 1916 if (width == 0 || height == 0 || height == 0 || !pixels) 1917 return; /* no-op, not an error */ 1918 1919 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 1920 xoffset += texImage->Border; 1921 yoffset += texImage->Border; 1922 zoffset += texImage->Border; 1923 1924 ASSERT(ctx->Driver.TexSubImage3D); 1925 (*ctx->Driver.TexSubImage3D)(ctx, target, level, 1926 xoffset, yoffset, zoffset, 1927 width, height, depth, 1928 format, type, pixels, 1929 &ctx->Unpack, texObj, texImage ); 1930 ctx->NewState |= _NEW_TEXTURE; 1931} 1932 1933 1934 1935void 1936_mesa_CopyTexImage1D( GLenum target, GLint level, 1937 GLenum internalFormat, 1938 GLint x, GLint y, 1939 GLsizei width, GLint border ) 1940{ 1941 struct gl_texture_unit *texUnit; 1942 struct gl_texture_object *texObj; 1943 struct gl_texture_image *texImage; 1944 GLsizei postConvWidth = width; 1945 GET_CURRENT_CONTEXT(ctx); 1946 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1947 1948 if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) 1949 _mesa_update_state(ctx); 1950 1951 if (is_color_format(internalFormat)) { 1952 _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); 1953 } 1954 1955 if (copytexture_error_check(ctx, 1, target, level, internalFormat, 1956 postConvWidth, 1, border)) 1957 return; 1958 1959 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 1960 texObj = _mesa_select_tex_object(ctx, texUnit, target); 1961 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 1962 if (!texImage) { 1963 texImage = _mesa_alloc_texture_image(); 1964 _mesa_set_tex_image(texObj, target, level, texImage); 1965 if (!texImage) { 1966 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); 1967 return; 1968 } 1969 } 1970 else if (texImage->Data) { 1971 /* free the old texture data */ 1972 MESA_PBUFFER_FREE(texImage->Data); 1973 texImage->Data = NULL; 1974 } 1975 1976 clear_teximage_fields(texImage); /* not really needed, but helpful */ 1977 _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1, 1978 border, internalFormat); 1979 1980 1981 ASSERT(ctx->Driver.CopyTexImage1D); 1982 (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat, 1983 x, y, width, border); 1984 1985 ASSERT(texImage->TexFormat); 1986 if (!texImage->FetchTexel) { 1987 /* If driver didn't explicitly set this, use the default */ 1988 texImage->FetchTexel = texImage->TexFormat->FetchTexel1D; 1989 } 1990 ASSERT(texImage->FetchTexel); 1991 1992 /* state update */ 1993 texObj->Complete = GL_FALSE; 1994 ctx->NewState |= _NEW_TEXTURE; 1995} 1996 1997 1998 1999void 2000_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, 2001 GLint x, GLint y, GLsizei width, GLsizei height, 2002 GLint border ) 2003{ 2004 struct gl_texture_unit *texUnit; 2005 struct gl_texture_object *texObj; 2006 struct gl_texture_image *texImage; 2007 GLsizei postConvWidth = width, postConvHeight = height; 2008 GET_CURRENT_CONTEXT(ctx); 2009 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2010 2011 if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) 2012 _mesa_update_state(ctx); 2013 2014 if (is_color_format(internalFormat)) { 2015 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, 2016 &postConvHeight); 2017 } 2018 2019 if (copytexture_error_check(ctx, 2, target, level, internalFormat, 2020 postConvWidth, postConvHeight, border)) 2021 return; 2022 2023 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2024 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2025 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2026 if (!texImage) { 2027 texImage = _mesa_alloc_texture_image(); 2028 _mesa_set_tex_image(texObj, target, level, texImage); 2029 if (!texImage) { 2030 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); 2031 return; 2032 } 2033 } 2034 else if (texImage->Data) { 2035 /* free the old texture data */ 2036 MESA_PBUFFER_FREE(texImage->Data); 2037 texImage->Data = NULL; 2038 } 2039 2040 clear_teximage_fields(texImage); /* not really needed, but helpful */ 2041 _mesa_init_teximage_fields(ctx, target, texImage, 2042 postConvWidth, postConvHeight, 1, 2043 border, internalFormat); 2044 2045 ASSERT(ctx->Driver.CopyTexImage2D); 2046 (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat, 2047 x, y, width, height, border); 2048 2049 ASSERT(texImage->TexFormat); 2050 if (!texImage->FetchTexel) { 2051 /* If driver didn't explicitly set this, use the default */ 2052 texImage->FetchTexel = texImage->TexFormat->FetchTexel2D; 2053 } 2054 ASSERT(texImage->FetchTexel); 2055 2056 /* state update */ 2057 texObj->Complete = GL_FALSE; 2058 ctx->NewState |= _NEW_TEXTURE; 2059} 2060 2061 2062 2063void 2064_mesa_CopyTexSubImage1D( GLenum target, GLint level, 2065 GLint xoffset, GLint x, GLint y, GLsizei width ) 2066{ 2067 struct gl_texture_unit *texUnit; 2068 struct gl_texture_object *texObj; 2069 struct gl_texture_image *texImage; 2070 GLsizei postConvWidth = width; 2071 GET_CURRENT_CONTEXT(ctx); 2072 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2073 2074 if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) 2075 _mesa_update_state(ctx); 2076 2077 /* XXX should test internal format */ 2078 _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); 2079 2080 if (copytexsubimage_error_check(ctx, 1, target, level, 2081 xoffset, 0, 0, postConvWidth, 1)) 2082 return; 2083 2084 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2085 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2086 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2087 2088 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 2089 xoffset += texImage->Border; 2090 2091 ASSERT(ctx->Driver.CopyTexSubImage1D); 2092 (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width); 2093 ctx->NewState |= _NEW_TEXTURE; 2094} 2095 2096 2097 2098void 2099_mesa_CopyTexSubImage2D( GLenum target, GLint level, 2100 GLint xoffset, GLint yoffset, 2101 GLint x, GLint y, GLsizei width, GLsizei height ) 2102{ 2103 struct gl_texture_unit *texUnit; 2104 struct gl_texture_object *texObj; 2105 struct gl_texture_image *texImage; 2106 GLsizei postConvWidth = width, postConvHeight = height; 2107 GET_CURRENT_CONTEXT(ctx); 2108 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2109 2110 if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) 2111 _mesa_update_state(ctx); 2112 2113 /* XXX should test internal format */ 2114 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); 2115 2116 if (copytexsubimage_error_check(ctx, 2, target, level, xoffset, yoffset, 0, 2117 postConvWidth, postConvHeight)) 2118 return; 2119 2120 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2121 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2122 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2123 2124 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 2125 xoffset += texImage->Border; 2126 yoffset += texImage->Border; 2127 2128 ASSERT(ctx->Driver.CopyTexSubImage2D); 2129 (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level, 2130 xoffset, yoffset, x, y, width, height); 2131 ctx->NewState |= _NEW_TEXTURE; 2132} 2133 2134 2135 2136void 2137_mesa_CopyTexSubImage3D( GLenum target, GLint level, 2138 GLint xoffset, GLint yoffset, GLint zoffset, 2139 GLint x, GLint y, GLsizei width, GLsizei height ) 2140{ 2141 struct gl_texture_unit *texUnit; 2142 struct gl_texture_object *texObj; 2143 struct gl_texture_image *texImage; 2144 GLsizei postConvWidth = width, postConvHeight = height; 2145 GET_CURRENT_CONTEXT(ctx); 2146 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2147 2148 if (ctx->NewState & _IMAGE_NEW_TRANSFER_STATE) 2149 _mesa_update_state(ctx); 2150 2151 /* XXX should test internal format */ 2152 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); 2153 2154 if (copytexsubimage_error_check(ctx, 3, target, level, xoffset, yoffset, 2155 zoffset, postConvWidth, postConvHeight)) 2156 return; 2157 2158 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2159 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2160 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2161 2162 /* If we have a border, xoffset=-1 is legal. Bias by border width */ 2163 xoffset += texImage->Border; 2164 yoffset += texImage->Border; 2165 zoffset += texImage->Border; 2166 2167 ASSERT(ctx->Driver.CopyTexSubImage3D); 2168 (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level, 2169 xoffset, yoffset, zoffset, 2170 x, y, width, height); 2171 ctx->NewState |= _NEW_TEXTURE; 2172} 2173 2174 2175 2176void 2177_mesa_CompressedTexImage1DARB(GLenum target, GLint level, 2178 GLenum internalFormat, GLsizei width, 2179 GLint border, GLsizei imageSize, 2180 const GLvoid *data) 2181{ 2182 GET_CURRENT_CONTEXT(ctx); 2183 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2184 2185 switch (internalFormat) { 2186 case GL_COMPRESSED_ALPHA_ARB: 2187 case GL_COMPRESSED_LUMINANCE_ARB: 2188 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: 2189 case GL_COMPRESSED_INTENSITY_ARB: 2190 case GL_COMPRESSED_RGB_ARB: 2191 case GL_COMPRESSED_RGBA_ARB: 2192 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB"); 2193 return; 2194 default: 2195 /* silence compiler warning */ 2196 ; 2197 } 2198 2199 if (target == GL_TEXTURE_1D) { 2200 struct gl_texture_unit *texUnit; 2201 struct gl_texture_object *texObj; 2202 struct gl_texture_image *texImage; 2203 2204 if (texture_error_check(ctx, target, level, internalFormat, 2205 GL_NONE, GL_NONE, 1, width, 1, 1, border)) { 2206 return; /* error in texture image was detected */ 2207 } 2208 2209 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2210 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2211 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2212 2213 if (!texImage) { 2214 texImage = _mesa_alloc_texture_image(); 2215 texObj->Image[level] = texImage; 2216 if (!texImage) { 2217 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1DARB"); 2218 return; 2219 } 2220 } 2221 else if (texImage->Data) { 2222 MESA_PBUFFER_FREE(texImage->Data); 2223 texImage->Data = NULL; 2224 } 2225 2226 _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, 2227 border, internalFormat); 2228 2229 if (ctx->Extensions.ARB_texture_compression) { 2230 ASSERT(ctx->Driver.CompressedTexImage1D); 2231 (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, 2232 internalFormat, width, border, 2233 imageSize, data, 2234 texObj, texImage); 2235 ASSERT(texImage->CompressedSize > 0); /* sanity */ 2236 } 2237 2238 /* state update */ 2239 texObj->Complete = GL_FALSE; 2240 ctx->NewState |= _NEW_TEXTURE; 2241 } 2242 else if (target == GL_PROXY_TEXTURE_1D) { 2243 /* Proxy texture: check for errors and update proxy state */ 2244 GLenum error = texture_error_check(ctx, target, level, internalFormat, 2245 GL_NONE, GL_NONE, 1, width, 1, 1, border); 2246 if (!error) { 2247 struct gl_texture_unit *texUnit; 2248 struct gl_texture_image *texImage; 2249 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2250 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2251 _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1, 2252 border, internalFormat); 2253 ASSERT(ctx->Driver.TestProxyTexImage); 2254 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 2255 internalFormat, GL_NONE, GL_NONE, 2256 width, 1, 1, border); 2257 } 2258 if (error) { 2259 /* if error, clear all proxy texture image parameters */ 2260 if (level >= 0 && level < ctx->Const.MaxTextureLevels) { 2261 clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]); 2262 } 2263 } 2264 } 2265 else { 2266 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB(target)"); 2267 return; 2268 } 2269} 2270 2271 2272void 2273_mesa_CompressedTexImage2DARB(GLenum target, GLint level, 2274 GLenum internalFormat, GLsizei width, 2275 GLsizei height, GLint border, GLsizei imageSize, 2276 const GLvoid *data) 2277{ 2278 GET_CURRENT_CONTEXT(ctx); 2279 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2280 2281 switch (internalFormat) { 2282 case GL_COMPRESSED_ALPHA_ARB: 2283 case GL_COMPRESSED_LUMINANCE_ARB: 2284 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: 2285 case GL_COMPRESSED_INTENSITY_ARB: 2286 case GL_COMPRESSED_RGB_ARB: 2287 case GL_COMPRESSED_RGBA_ARB: 2288 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB"); 2289 return; 2290 default: 2291 /* silence compiler warning */ 2292 ; 2293 } 2294 2295 if (target == GL_TEXTURE_2D || 2296 (ctx->Extensions.ARB_texture_cube_map && 2297 target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && 2298 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) || 2299 (ctx->Extensions.NV_texture_rectangle && 2300 target == GL_TEXTURE_RECTANGLE_NV)) { 2301 struct gl_texture_unit *texUnit; 2302 struct gl_texture_object *texObj; 2303 struct gl_texture_image *texImage; 2304 2305 if (texture_error_check(ctx, target, level, internalFormat, 2306 GL_NONE, GL_NONE, 1, width, height, 1, border)) { 2307 return; /* error in texture image was detected */ 2308 } 2309 2310 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2311 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2312 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2313 2314 if (!texImage) { 2315 texImage = _mesa_alloc_texture_image(); 2316 texObj->Image[level] = texImage; 2317 if (!texImage) { 2318 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB"); 2319 return; 2320 } 2321 } 2322 else if (texImage->Data) { 2323 MESA_PBUFFER_FREE(texImage->Data); 2324 texImage->Data = NULL; 2325 } 2326 2327 _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, 2328 border, internalFormat); 2329 2330 if (ctx->Extensions.ARB_texture_compression) { 2331 ASSERT(ctx->Driver.CompressedTexImage2D); 2332 (*ctx->Driver.CompressedTexImage2D)(ctx, target, level, 2333 internalFormat, width, height, 2334 border, imageSize, data, 2335 texObj, texImage); 2336 ASSERT(texImage->CompressedSize > 0); /* sanity */ 2337 } 2338 2339 /* state update */ 2340 texObj->Complete = GL_FALSE; 2341 ctx->NewState |= _NEW_TEXTURE; 2342 } 2343 else if (target == GL_PROXY_TEXTURE_2D) { 2344 /* Proxy texture: check for errors and update proxy state */ 2345 GLenum error = texture_error_check(ctx, target, level, internalFormat, 2346 GL_NONE, GL_NONE, 2, width, height, 1, border); 2347 if (!error) { 2348 struct gl_texture_unit *texUnit; 2349 struct gl_texture_image *texImage; 2350 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2351 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2352 _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1, 2353 border, internalFormat); 2354 ASSERT(ctx->Driver.TestProxyTexImage); 2355 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 2356 internalFormat, GL_NONE, GL_NONE, 2357 width, height, 1, border); 2358 } 2359 if (error) { 2360 /* if error, clear all proxy texture image parameters */ 2361 const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ? 2362 ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels; 2363 if (level >= 0 && level < maxLevels) { 2364 clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]); 2365 } 2366 } 2367 } 2368 else { 2369 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB(target)"); 2370 return; 2371 } 2372} 2373 2374 2375void 2376_mesa_CompressedTexImage3DARB(GLenum target, GLint level, 2377 GLenum internalFormat, GLsizei width, 2378 GLsizei height, GLsizei depth, GLint border, 2379 GLsizei imageSize, const GLvoid *data) 2380{ 2381 GET_CURRENT_CONTEXT(ctx); 2382 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2383 2384 switch (internalFormat) { 2385 case GL_COMPRESSED_ALPHA_ARB: 2386 case GL_COMPRESSED_LUMINANCE_ARB: 2387 case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: 2388 case GL_COMPRESSED_INTENSITY_ARB: 2389 case GL_COMPRESSED_RGB_ARB: 2390 case GL_COMPRESSED_RGBA_ARB: 2391 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB"); 2392 return; 2393 default: 2394 /* silence compiler warning */ 2395 ; 2396 } 2397 2398 if (target == GL_TEXTURE_3D) { 2399 struct gl_texture_unit *texUnit; 2400 struct gl_texture_object *texObj; 2401 struct gl_texture_image *texImage; 2402 2403 if (texture_error_check(ctx, target, level, internalFormat, 2404 GL_NONE, GL_NONE, 1, width, height, depth, border)) { 2405 return; /* error in texture image was detected */ 2406 } 2407 2408 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2409 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2410 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2411 2412 if (!texImage) { 2413 texImage = _mesa_alloc_texture_image(); 2414 texObj->Image[level] = texImage; 2415 if (!texImage) { 2416 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3DARB"); 2417 return; 2418 } 2419 } 2420 else if (texImage->Data) { 2421 MESA_PBUFFER_FREE(texImage->Data); 2422 texImage->Data = NULL; 2423 } 2424 2425 _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth, 2426 border, internalFormat); 2427 2428 if (ctx->Extensions.ARB_texture_compression) { 2429 ASSERT(ctx->Driver.CompressedTexImage3D); 2430 (*ctx->Driver.CompressedTexImage3D)(ctx, target, level, 2431 internalFormat, 2432 width, height, depth, 2433 border, imageSize, data, 2434 texObj, texImage); 2435 ASSERT(texImage->CompressedSize > 0); /* sanity */ 2436 } 2437 2438 /* state update */ 2439 texObj->Complete = GL_FALSE; 2440 ctx->NewState |= _NEW_TEXTURE; 2441 } 2442 else if (target == GL_PROXY_TEXTURE_3D) { 2443 /* Proxy texture: check for errors and update proxy state */ 2444 GLenum error = texture_error_check(ctx, target, level, internalFormat, 2445 GL_NONE, GL_NONE, 1, width, height, depth, border); 2446 if (!error) { 2447 struct gl_texture_unit *texUnit; 2448 struct gl_texture_image *texImage; 2449 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2450 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2451 _mesa_init_teximage_fields(ctx, target, texImage, 2452 width, height, depth, 2453 border, internalFormat); 2454 ASSERT(ctx->Driver.TestProxyTexImage); 2455 error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, 2456 internalFormat, GL_NONE, GL_NONE, 2457 width, height, depth, border); 2458 } 2459 if (error) { 2460 /* if error, clear all proxy texture image parameters */ 2461 if (level >= 0 && level < ctx->Const.Max3DTextureLevels) { 2462 clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]); 2463 } 2464 } 2465 } 2466 else { 2467 _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB(target)"); 2468 return; 2469 } 2470} 2471 2472 2473void 2474_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, 2475 GLsizei width, GLenum format, 2476 GLsizei imageSize, const GLvoid *data) 2477{ 2478 struct gl_texture_unit *texUnit; 2479 struct gl_texture_object *texObj; 2480 struct gl_texture_image *texImage; 2481 GET_CURRENT_CONTEXT(ctx); 2482 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2483 2484 if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, 2485 width, 1, 1, format, GL_NONE)) { 2486 return; /* error was detected */ 2487 } 2488 2489 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2490 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2491 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2492 assert(texImage); 2493 2494 if (width == 0 || !data) 2495 return; /* no-op, not an error */ 2496 2497 if (ctx->Driver.CompressedTexSubImage1D) { 2498 (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level, 2499 xoffset, width, 2500 format, imageSize, data, 2501 texObj, texImage); 2502 } 2503 ctx->NewState |= _NEW_TEXTURE; 2504} 2505 2506 2507void 2508_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, 2509 GLint yoffset, GLsizei width, GLsizei height, 2510 GLenum format, GLsizei imageSize, 2511 const GLvoid *data) 2512{ 2513 struct gl_texture_unit *texUnit; 2514 struct gl_texture_object *texObj; 2515 struct gl_texture_image *texImage; 2516 GET_CURRENT_CONTEXT(ctx); 2517 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2518 2519 if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, 2520 width, height, 1, format, GL_NONE)) { 2521 return; /* error was detected */ 2522 } 2523 2524 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2525 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2526 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2527 assert(texImage); 2528 2529 if (width == 0 || height == 0 || !data) 2530 return; /* no-op, not an error */ 2531 2532 if (ctx->Driver.CompressedTexSubImage2D) { 2533 (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level, 2534 xoffset, yoffset, width, height, 2535 format, imageSize, data, 2536 texObj, texImage); 2537 } 2538 ctx->NewState |= _NEW_TEXTURE; 2539} 2540 2541 2542void 2543_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, 2544 GLint yoffset, GLint zoffset, GLsizei width, 2545 GLsizei height, GLsizei depth, GLenum format, 2546 GLsizei imageSize, const GLvoid *data) 2547{ 2548 struct gl_texture_unit *texUnit; 2549 struct gl_texture_object *texObj; 2550 struct gl_texture_image *texImage; 2551 GET_CURRENT_CONTEXT(ctx); 2552 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2553 2554 if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, 2555 width, height, depth, format, GL_NONE)) { 2556 return; /* error was detected */ 2557 } 2558 2559 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2560 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2561 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2562 assert(texImage); 2563 2564 if (width == 0 || height == 0 || depth == 0 || !data) 2565 return; /* no-op, not an error */ 2566 2567 if (ctx->Driver.CompressedTexSubImage3D) { 2568 (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level, 2569 xoffset, yoffset, zoffset, 2570 width, height, depth, 2571 format, imageSize, data, 2572 texObj, texImage); 2573 } 2574 ctx->NewState |= _NEW_TEXTURE; 2575} 2576 2577 2578void 2579_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) 2580{ 2581 const struct gl_texture_unit *texUnit; 2582 const struct gl_texture_object *texObj; 2583 struct gl_texture_image *texImage; 2584 GLint maxLevels; 2585 GET_CURRENT_CONTEXT(ctx); 2586 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 2587 2588 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; 2589 texObj = _mesa_select_tex_object(ctx, texUnit, target); 2590 if (!texObj) { 2591 _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB"); 2592 return; 2593 } 2594 2595 if (target == GL_TEXTURE_1D || target == GL_TEXTURE_2D) { 2596 maxLevels = ctx->Const.MaxTextureLevels; 2597 } 2598 else if (target == GL_TEXTURE_3D) { 2599 maxLevels = ctx->Const.Max3DTextureLevels; 2600 } 2601 else { 2602 maxLevels = ctx->Const.MaxCubeTextureLevels; 2603 } 2604 2605 ASSERT(maxLevels > 0); 2606 2607 if (level < 0 || level >= maxLevels) { 2608 _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)"); 2609 return; 2610 } 2611 2612 if (is_proxy_target(target)) { 2613 _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)"); 2614 return; 2615 } 2616 2617 texImage = _mesa_select_tex_image(ctx, texUnit, target, level); 2618 if (!texImage) { 2619 /* probably invalid mipmap level */ 2620 _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)"); 2621 return; 2622 } 2623 2624 if (!texImage->IsCompressed) { 2625 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImageARB"); 2626 return; 2627 } 2628 2629 if (!img) 2630 return; 2631 2632 if (ctx->Extensions.ARB_texture_compression) { 2633 ASSERT(ctx->Driver.GetCompressedTexImage); 2634 (*ctx->Driver.GetCompressedTexImage)(ctx, target, level, img, texObj, 2635 texImage); 2636 } 2637} 2638