1 /* 2 * Mesa 3-D graphics library 3 * Version: 7.5 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * Copyright (c) 2008-2009 VMware, Inc. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 /* 27 * Authors: 28 * Brian Paul 29 */ 30 31 /** 32 * The GL texture image functions in teximage.c basically just do 33 * error checking and data structure allocation. They in turn call 34 * device driver functions which actually copy/convert/store the user's 35 * texture image data. 36 * 37 * However, most device drivers will be able to use the fallback functions 38 * in this file. That is, most drivers will have the following bit of 39 * code: 40 * ctx->Driver.TexImage = _mesa_store_teximage; 41 * ctx->Driver.TexSubImage = _mesa_store_texsubimage; 42 * etc... 43 * 44 * Texture image processing is actually kind of complicated. We have to do: 45 * Format/type conversions 46 * pixel unpacking 47 * pixel transfer (scale, bais, lookup, etc) 48 * 49 * These functions can handle most everything, including processing full 50 * images and sub-images. 51 */ 52 53 54 #include "glheader.h" 55 #include "bufferobj.h" 56 #include "colormac.h" 57 #include "format_pack.h" 58 #include "image.h" 59 #include "macros.h" 60 #include "mipmap.h" 61 #include "mfeatures.h" 62 #include "mtypes.h" 63 #include "pack.h" 64 #include "pbo.h" 65 #include "imports.h" 66 #include "texcompress.h" 67 #include "texcompress_fxt1.h" 68 #include "texcompress_rgtc.h" 69 #include "texcompress_s3tc.h" 70 #include "texcompress_etc.h" 71 #include "teximage.h" 72 #include "texstore.h" 73 #include "enums.h" 74 #include "glformats.h" 75 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h" 76 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h" 77 78 79 enum { 80 ZERO = 4, 81 ONE = 5 82 }; 83 84 85 /** 86 * Texture image storage function. 87 */ 88 typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS); 89 90 91 /** 92 * Return GL_TRUE if the given image format is one that be converted 93 * to another format by swizzling. 94 */ 95 static GLboolean 96 can_swizzle(GLenum logicalBaseFormat) 97 { 98 switch (logicalBaseFormat) { 99 case GL_RGBA: 100 case GL_RGB: 101 case GL_LUMINANCE_ALPHA: 102 case GL_INTENSITY: 103 case GL_ALPHA: 104 case GL_LUMINANCE: 105 case GL_RED: 106 case GL_GREEN: 107 case GL_BLUE: 108 case GL_BGR: 109 case GL_BGRA: 110 case GL_ABGR_EXT: 111 case GL_RG: 112 return GL_TRUE; 113 default: 114 return GL_FALSE; 115 } 116 } 117 118 119 120 enum { 121 IDX_LUMINANCE = 0, 122 IDX_ALPHA, 123 IDX_INTENSITY, 124 IDX_LUMINANCE_ALPHA, 125 IDX_RGB, 126 IDX_RGBA, 127 IDX_RED, 128 IDX_GREEN, 129 IDX_BLUE, 130 IDX_BGR, 131 IDX_BGRA, 132 IDX_ABGR, 133 IDX_RG, 134 MAX_IDX 135 }; 136 137 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO) 138 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO) 139 #define MAP3(x,y,z) MAP4(x, y, z, ZERO) 140 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE } 141 142 143 static const struct { 144 GLubyte format_idx; 145 GLubyte to_rgba[6]; 146 GLubyte from_rgba[6]; 147 } mappings[MAX_IDX] = 148 { 149 { 150 IDX_LUMINANCE, 151 MAP4(0,0,0,ONE), 152 MAP1(0) 153 }, 154 155 { 156 IDX_ALPHA, 157 MAP4(ZERO, ZERO, ZERO, 0), 158 MAP1(3) 159 }, 160 161 { 162 IDX_INTENSITY, 163 MAP4(0, 0, 0, 0), 164 MAP1(0), 165 }, 166 167 { 168 IDX_LUMINANCE_ALPHA, 169 MAP4(0,0,0,1), 170 MAP2(0,3) 171 }, 172 173 { 174 IDX_RGB, 175 MAP4(0,1,2,ONE), 176 MAP3(0,1,2) 177 }, 178 179 { 180 IDX_RGBA, 181 MAP4(0,1,2,3), 182 MAP4(0,1,2,3), 183 }, 184 185 { 186 IDX_RED, 187 MAP4(0, ZERO, ZERO, ONE), 188 MAP1(0), 189 }, 190 191 { 192 IDX_GREEN, 193 MAP4(ZERO, 0, ZERO, ONE), 194 MAP1(1), 195 }, 196 197 { 198 IDX_BLUE, 199 MAP4(ZERO, ZERO, 0, ONE), 200 MAP1(2), 201 }, 202 203 { 204 IDX_BGR, 205 MAP4(2,1,0,ONE), 206 MAP3(2,1,0) 207 }, 208 209 { 210 IDX_BGRA, 211 MAP4(2,1,0,3), 212 MAP4(2,1,0,3) 213 }, 214 215 { 216 IDX_ABGR, 217 MAP4(3,2,1,0), 218 MAP4(3,2,1,0) 219 }, 220 221 { 222 IDX_RG, 223 MAP4(0, 1, ZERO, ONE), 224 MAP2(0, 1) 225 }, 226 }; 227 228 229 230 /** 231 * Convert a GL image format enum to an IDX_* value (see above). 232 */ 233 static int 234 get_map_idx(GLenum value) 235 { 236 switch (value) { 237 case GL_LUMINANCE: return IDX_LUMINANCE; 238 case GL_ALPHA: return IDX_ALPHA; 239 case GL_INTENSITY: return IDX_INTENSITY; 240 case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA; 241 case GL_RGB: return IDX_RGB; 242 case GL_RGBA: return IDX_RGBA; 243 case GL_RED: return IDX_RED; 244 case GL_GREEN: return IDX_GREEN; 245 case GL_BLUE: return IDX_BLUE; 246 case GL_BGR: return IDX_BGR; 247 case GL_BGRA: return IDX_BGRA; 248 case GL_ABGR_EXT: return IDX_ABGR; 249 case GL_RG: return IDX_RG; 250 default: 251 _mesa_problem(NULL, "Unexpected inFormat"); 252 return 0; 253 } 254 } 255 256 257 /** 258 * When promoting texture formats (see below) we need to compute the 259 * mapping of dest components back to source components. 260 * This function does that. 261 * \param inFormat the incoming format of the texture 262 * \param outFormat the final texture format 263 * \return map[6] a full 6-component map 264 */ 265 static void 266 compute_component_mapping(GLenum inFormat, GLenum outFormat, 267 GLubyte *map) 268 { 269 const int inFmt = get_map_idx(inFormat); 270 const int outFmt = get_map_idx(outFormat); 271 const GLubyte *in2rgba = mappings[inFmt].to_rgba; 272 const GLubyte *rgba2out = mappings[outFmt].from_rgba; 273 int i; 274 275 for (i = 0; i < 4; i++) 276 map[i] = in2rgba[rgba2out[i]]; 277 278 map[ZERO] = ZERO; 279 map[ONE] = ONE; 280 281 #if 0 282 printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n", 283 inFormat, _mesa_lookup_enum_by_nr(inFormat), 284 outFormat, _mesa_lookup_enum_by_nr(outFormat), 285 map[0], 286 map[1], 287 map[2], 288 map[3], 289 map[4], 290 map[5]); 291 #endif 292 } 293 294 295 /** 296 * Make a temporary (color) texture image with GLfloat components. 297 * Apply all needed pixel unpacking and pixel transfer operations. 298 * Note that there are both logicalBaseFormat and textureBaseFormat parameters. 299 * Suppose the user specifies GL_LUMINANCE as the internal texture format 300 * but the graphics hardware doesn't support luminance textures. So, we might 301 * use an RGB hardware format instead. 302 * If logicalBaseFormat != textureBaseFormat we have some extra work to do. 303 * 304 * \param ctx the rendering context 305 * \param dims image dimensions: 1, 2 or 3 306 * \param logicalBaseFormat basic texture derived from the user's 307 * internal texture format value 308 * \param textureBaseFormat the actual basic format of the texture 309 * \param srcWidth source image width 310 * \param srcHeight source image height 311 * \param srcDepth source image depth 312 * \param srcFormat source image format 313 * \param srcType source image type 314 * \param srcAddr source image address 315 * \param srcPacking source image pixel packing 316 * \return resulting image with format = textureBaseFormat and type = GLfloat. 317 */ 318 GLfloat * 319 _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims, 320 GLenum logicalBaseFormat, 321 GLenum textureBaseFormat, 322 GLint srcWidth, GLint srcHeight, GLint srcDepth, 323 GLenum srcFormat, GLenum srcType, 324 const GLvoid *srcAddr, 325 const struct gl_pixelstore_attrib *srcPacking, 326 GLbitfield transferOps) 327 { 328 GLfloat *tempImage; 329 const GLint components = _mesa_components_in_format(logicalBaseFormat); 330 const GLint srcStride = 331 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 332 GLfloat *dst; 333 GLint img, row; 334 335 ASSERT(dims >= 1 && dims <= 3); 336 337 ASSERT(logicalBaseFormat == GL_RGBA || 338 logicalBaseFormat == GL_RGB || 339 logicalBaseFormat == GL_RG || 340 logicalBaseFormat == GL_RED || 341 logicalBaseFormat == GL_LUMINANCE_ALPHA || 342 logicalBaseFormat == GL_LUMINANCE || 343 logicalBaseFormat == GL_ALPHA || 344 logicalBaseFormat == GL_INTENSITY || 345 logicalBaseFormat == GL_DEPTH_COMPONENT); 346 347 ASSERT(textureBaseFormat == GL_RGBA || 348 textureBaseFormat == GL_RGB || 349 textureBaseFormat == GL_RG || 350 textureBaseFormat == GL_RED || 351 textureBaseFormat == GL_LUMINANCE_ALPHA || 352 textureBaseFormat == GL_LUMINANCE || 353 textureBaseFormat == GL_ALPHA || 354 textureBaseFormat == GL_INTENSITY || 355 textureBaseFormat == GL_DEPTH_COMPONENT); 356 357 tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth 358 * components * sizeof(GLfloat)); 359 if (!tempImage) 360 return NULL; 361 362 dst = tempImage; 363 for (img = 0; img < srcDepth; img++) { 364 const GLubyte *src 365 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, 366 srcWidth, srcHeight, 367 srcFormat, srcType, 368 img, 0, 0); 369 for (row = 0; row < srcHeight; row++) { 370 _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat, 371 dst, srcFormat, srcType, src, 372 srcPacking, transferOps); 373 dst += srcWidth * components; 374 src += srcStride; 375 } 376 } 377 378 if (logicalBaseFormat != textureBaseFormat) { 379 /* more work */ 380 GLint texComponents = _mesa_components_in_format(textureBaseFormat); 381 GLint logComponents = _mesa_components_in_format(logicalBaseFormat); 382 GLfloat *newImage; 383 GLint i, n; 384 GLubyte map[6]; 385 386 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ 387 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || 388 textureBaseFormat == GL_LUMINANCE_ALPHA); 389 390 /* The actual texture format should have at least as many components 391 * as the logical texture format. 392 */ 393 ASSERT(texComponents >= logComponents); 394 395 newImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth 396 * texComponents * sizeof(GLfloat)); 397 if (!newImage) { 398 free(tempImage); 399 return NULL; 400 } 401 402 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); 403 404 n = srcWidth * srcHeight * srcDepth; 405 for (i = 0; i < n; i++) { 406 GLint k; 407 for (k = 0; k < texComponents; k++) { 408 GLint j = map[k]; 409 if (j == ZERO) 410 newImage[i * texComponents + k] = 0.0F; 411 else if (j == ONE) 412 newImage[i * texComponents + k] = 1.0F; 413 else 414 newImage[i * texComponents + k] = tempImage[i * logComponents + j]; 415 } 416 } 417 418 free(tempImage); 419 tempImage = newImage; 420 } 421 422 return tempImage; 423 } 424 425 426 /** 427 * Make temporary image with uint pixel values. Used for unsigned 428 * integer-valued textures. 429 */ 430 static GLuint * 431 make_temp_uint_image(struct gl_context *ctx, GLuint dims, 432 GLenum logicalBaseFormat, 433 GLenum textureBaseFormat, 434 GLint srcWidth, GLint srcHeight, GLint srcDepth, 435 GLenum srcFormat, GLenum srcType, 436 const GLvoid *srcAddr, 437 const struct gl_pixelstore_attrib *srcPacking) 438 { 439 GLuint *tempImage; 440 const GLint components = _mesa_components_in_format(logicalBaseFormat); 441 const GLint srcStride = 442 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 443 GLuint *dst; 444 GLint img, row; 445 446 ASSERT(dims >= 1 && dims <= 3); 447 448 ASSERT(logicalBaseFormat == GL_RGBA || 449 logicalBaseFormat == GL_RGB || 450 logicalBaseFormat == GL_RG || 451 logicalBaseFormat == GL_RED || 452 logicalBaseFormat == GL_LUMINANCE_ALPHA || 453 logicalBaseFormat == GL_LUMINANCE || 454 logicalBaseFormat == GL_INTENSITY || 455 logicalBaseFormat == GL_ALPHA); 456 457 ASSERT(textureBaseFormat == GL_RGBA || 458 textureBaseFormat == GL_RGB || 459 textureBaseFormat == GL_RG || 460 textureBaseFormat == GL_RED || 461 textureBaseFormat == GL_LUMINANCE_ALPHA || 462 textureBaseFormat == GL_LUMINANCE || 463 textureBaseFormat == GL_INTENSITY || 464 textureBaseFormat == GL_ALPHA); 465 466 tempImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth 467 * components * sizeof(GLuint)); 468 if (!tempImage) 469 return NULL; 470 471 dst = tempImage; 472 for (img = 0; img < srcDepth; img++) { 473 const GLubyte *src 474 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, 475 srcWidth, srcHeight, 476 srcFormat, srcType, 477 img, 0, 0); 478 for (row = 0; row < srcHeight; row++) { 479 _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat, 480 dst, srcFormat, srcType, src, 481 srcPacking); 482 dst += srcWidth * components; 483 src += srcStride; 484 } 485 } 486 487 if (logicalBaseFormat != textureBaseFormat) { 488 /* more work */ 489 GLint texComponents = _mesa_components_in_format(textureBaseFormat); 490 GLint logComponents = _mesa_components_in_format(logicalBaseFormat); 491 GLuint *newImage; 492 GLint i, n; 493 GLubyte map[6]; 494 495 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ 496 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || 497 textureBaseFormat == GL_LUMINANCE_ALPHA); 498 499 /* The actual texture format should have at least as many components 500 * as the logical texture format. 501 */ 502 ASSERT(texComponents >= logComponents); 503 504 newImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth 505 * texComponents * sizeof(GLuint)); 506 if (!newImage) { 507 free(tempImage); 508 return NULL; 509 } 510 511 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); 512 513 n = srcWidth * srcHeight * srcDepth; 514 for (i = 0; i < n; i++) { 515 GLint k; 516 for (k = 0; k < texComponents; k++) { 517 GLint j = map[k]; 518 if (j == ZERO) 519 newImage[i * texComponents + k] = 0; 520 else if (j == ONE) 521 newImage[i * texComponents + k] = 1; 522 else 523 newImage[i * texComponents + k] = tempImage[i * logComponents + j]; 524 } 525 } 526 527 free(tempImage); 528 tempImage = newImage; 529 } 530 531 return tempImage; 532 } 533 534 535 536 /** 537 * Make a temporary (color) texture image with GLubyte components. 538 * Apply all needed pixel unpacking and pixel transfer operations. 539 * Note that there are both logicalBaseFormat and textureBaseFormat parameters. 540 * Suppose the user specifies GL_LUMINANCE as the internal texture format 541 * but the graphics hardware doesn't support luminance textures. So, we might 542 * use an RGB hardware format instead. 543 * If logicalBaseFormat != textureBaseFormat we have some extra work to do. 544 * 545 * \param ctx the rendering context 546 * \param dims image dimensions: 1, 2 or 3 547 * \param logicalBaseFormat basic texture derived from the user's 548 * internal texture format value 549 * \param textureBaseFormat the actual basic format of the texture 550 * \param srcWidth source image width 551 * \param srcHeight source image height 552 * \param srcDepth source image depth 553 * \param srcFormat source image format 554 * \param srcType source image type 555 * \param srcAddr source image address 556 * \param srcPacking source image pixel packing 557 * \return resulting image with format = textureBaseFormat and type = GLubyte. 558 */ 559 GLubyte * 560 _mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims, 561 GLenum logicalBaseFormat, 562 GLenum textureBaseFormat, 563 GLint srcWidth, GLint srcHeight, GLint srcDepth, 564 GLenum srcFormat, GLenum srcType, 565 const GLvoid *srcAddr, 566 const struct gl_pixelstore_attrib *srcPacking) 567 { 568 GLuint transferOps = ctx->_ImageTransferState; 569 const GLint components = _mesa_components_in_format(logicalBaseFormat); 570 GLint img, row; 571 GLubyte *tempImage, *dst; 572 573 ASSERT(dims >= 1 && dims <= 3); 574 575 ASSERT(logicalBaseFormat == GL_RGBA || 576 logicalBaseFormat == GL_RGB || 577 logicalBaseFormat == GL_RG || 578 logicalBaseFormat == GL_RED || 579 logicalBaseFormat == GL_LUMINANCE_ALPHA || 580 logicalBaseFormat == GL_LUMINANCE || 581 logicalBaseFormat == GL_ALPHA || 582 logicalBaseFormat == GL_INTENSITY); 583 584 ASSERT(textureBaseFormat == GL_RGBA || 585 textureBaseFormat == GL_RGB || 586 textureBaseFormat == GL_RG || 587 textureBaseFormat == GL_RED || 588 textureBaseFormat == GL_LUMINANCE_ALPHA || 589 textureBaseFormat == GL_LUMINANCE || 590 textureBaseFormat == GL_ALPHA || 591 textureBaseFormat == GL_INTENSITY); 592 593 /* unpack and transfer the source image */ 594 tempImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth 595 * components * sizeof(GLubyte)); 596 if (!tempImage) { 597 return NULL; 598 } 599 600 dst = tempImage; 601 for (img = 0; img < srcDepth; img++) { 602 const GLint srcStride = 603 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 604 const GLubyte *src = 605 (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, 606 srcWidth, srcHeight, 607 srcFormat, srcType, 608 img, 0, 0); 609 for (row = 0; row < srcHeight; row++) { 610 _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst, 611 srcFormat, srcType, src, srcPacking, 612 transferOps); 613 dst += srcWidth * components; 614 src += srcStride; 615 } 616 } 617 618 if (logicalBaseFormat != textureBaseFormat) { 619 /* one more conversion step */ 620 GLint texComponents = _mesa_components_in_format(textureBaseFormat); 621 GLint logComponents = _mesa_components_in_format(logicalBaseFormat); 622 GLubyte *newImage; 623 GLint i, n; 624 GLubyte map[6]; 625 626 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ 627 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || 628 textureBaseFormat == GL_LUMINANCE_ALPHA); 629 630 /* The actual texture format should have at least as many components 631 * as the logical texture format. 632 */ 633 ASSERT(texComponents >= logComponents); 634 635 newImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth 636 * texComponents * sizeof(GLubyte)); 637 if (!newImage) { 638 free(tempImage); 639 return NULL; 640 } 641 642 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); 643 644 n = srcWidth * srcHeight * srcDepth; 645 for (i = 0; i < n; i++) { 646 GLint k; 647 for (k = 0; k < texComponents; k++) { 648 GLint j = map[k]; 649 if (j == ZERO) 650 newImage[i * texComponents + k] = 0; 651 else if (j == ONE) 652 newImage[i * texComponents + k] = 255; 653 else 654 newImage[i * texComponents + k] = tempImage[i * logComponents + j]; 655 } 656 } 657 658 free(tempImage); 659 tempImage = newImage; 660 } 661 662 return tempImage; 663 } 664 665 666 /** 667 * Copy GLubyte pixels from <src> to <dst> with swizzling. 668 * \param dst destination pixels 669 * \param dstComponents number of color components in destination pixels 670 * \param src source pixels 671 * \param srcComponents number of color components in source pixels 672 * \param map the swizzle mapping. map[X] says where to find the X component 673 * in the source image's pixels. For example, if the source image 674 * is GL_BGRA and X = red, map[0] yields 2. 675 * \param count number of pixels to copy/swizzle. 676 */ 677 static void 678 swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src, 679 GLuint srcComponents, const GLubyte *map, GLuint count) 680 { 681 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \ 682 do { \ 683 GLuint i; \ 684 for (i = 0; i < count; i++) { \ 685 GLuint j; \ 686 if (srcComps == 4) { \ 687 COPY_4UBV(tmp, src); \ 688 } \ 689 else { \ 690 for (j = 0; j < srcComps; j++) { \ 691 tmp[j] = src[j]; \ 692 } \ 693 } \ 694 src += srcComps; \ 695 for (j = 0; j < dstComps; j++) { \ 696 dst[j] = tmp[map[j]]; \ 697 } \ 698 dst += dstComps; \ 699 } \ 700 } while (0) 701 702 GLubyte tmp[6]; 703 704 tmp[ZERO] = 0x0; 705 tmp[ONE] = 0xff; 706 707 ASSERT(srcComponents <= 4); 708 ASSERT(dstComponents <= 4); 709 710 switch (dstComponents) { 711 case 4: 712 switch (srcComponents) { 713 case 4: 714 SWZ_CPY(dst, src, count, 4, 4); 715 break; 716 case 3: 717 SWZ_CPY(dst, src, count, 4, 3); 718 break; 719 case 2: 720 SWZ_CPY(dst, src, count, 4, 2); 721 break; 722 case 1: 723 SWZ_CPY(dst, src, count, 4, 1); 724 break; 725 default: 726 ; 727 } 728 break; 729 case 3: 730 switch (srcComponents) { 731 case 4: 732 SWZ_CPY(dst, src, count, 3, 4); 733 break; 734 case 3: 735 SWZ_CPY(dst, src, count, 3, 3); 736 break; 737 case 2: 738 SWZ_CPY(dst, src, count, 3, 2); 739 break; 740 case 1: 741 SWZ_CPY(dst, src, count, 3, 1); 742 break; 743 default: 744 ; 745 } 746 break; 747 case 2: 748 switch (srcComponents) { 749 case 4: 750 SWZ_CPY(dst, src, count, 2, 4); 751 break; 752 case 3: 753 SWZ_CPY(dst, src, count, 2, 3); 754 break; 755 case 2: 756 SWZ_CPY(dst, src, count, 2, 2); 757 break; 758 case 1: 759 SWZ_CPY(dst, src, count, 2, 1); 760 break; 761 default: 762 ; 763 } 764 break; 765 case 1: 766 switch (srcComponents) { 767 case 4: 768 SWZ_CPY(dst, src, count, 1, 4); 769 break; 770 case 3: 771 SWZ_CPY(dst, src, count, 1, 3); 772 break; 773 case 2: 774 SWZ_CPY(dst, src, count, 1, 2); 775 break; 776 case 1: 777 SWZ_CPY(dst, src, count, 1, 1); 778 break; 779 default: 780 ; 781 } 782 break; 783 default: 784 ; 785 } 786 #undef SWZ_CPY 787 } 788 789 790 791 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE }; 792 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE }; 793 794 795 /** 796 * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a 797 * mapping array depending on endianness. 798 */ 799 static const GLubyte * 800 type_mapping( GLenum srcType ) 801 { 802 switch (srcType) { 803 case GL_BYTE: 804 case GL_UNSIGNED_BYTE: 805 return map_identity; 806 case GL_UNSIGNED_INT_8_8_8_8: 807 return _mesa_little_endian() ? map_3210 : map_identity; 808 case GL_UNSIGNED_INT_8_8_8_8_REV: 809 return _mesa_little_endian() ? map_identity : map_3210; 810 default: 811 return NULL; 812 } 813 } 814 815 816 /** 817 * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a 818 * mapping array depending on pixelstore byte swapping state. 819 */ 820 static const GLubyte * 821 byteswap_mapping( GLboolean swapBytes, 822 GLenum srcType ) 823 { 824 if (!swapBytes) 825 return map_identity; 826 827 switch (srcType) { 828 case GL_BYTE: 829 case GL_UNSIGNED_BYTE: 830 return map_identity; 831 case GL_UNSIGNED_INT_8_8_8_8: 832 case GL_UNSIGNED_INT_8_8_8_8_REV: 833 return map_3210; 834 default: 835 return NULL; 836 } 837 } 838 839 840 841 /** 842 * Transfer a GLubyte texture image with component swizzling. 843 */ 844 static void 845 _mesa_swizzle_ubyte_image(struct gl_context *ctx, 846 GLuint dimensions, 847 GLenum srcFormat, 848 GLenum srcType, 849 850 GLenum baseInternalFormat, 851 852 const GLubyte *rgba2dst, 853 GLuint dstComponents, 854 855 GLint dstRowStride, 856 GLubyte **dstSlices, 857 858 GLint srcWidth, GLint srcHeight, GLint srcDepth, 859 const GLvoid *srcAddr, 860 const struct gl_pixelstore_attrib *srcPacking ) 861 { 862 GLint srcComponents = _mesa_components_in_format(srcFormat); 863 const GLubyte *srctype2ubyte, *swap; 864 GLubyte map[4], src2base[6], base2rgba[6]; 865 GLint i; 866 const GLint srcRowStride = 867 _mesa_image_row_stride(srcPacking, srcWidth, 868 srcFormat, GL_UNSIGNED_BYTE); 869 const GLint srcImageStride 870 = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat, 871 GL_UNSIGNED_BYTE); 872 const GLubyte *srcImage 873 = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr, 874 srcWidth, srcHeight, srcFormat, 875 GL_UNSIGNED_BYTE, 0, 0, 0); 876 877 (void) ctx; 878 879 /* Translate from src->baseInternal->GL_RGBA->dst. This will 880 * correctly deal with RGBA->RGB->RGBA conversions where the final 881 * A value must be 0xff regardless of the incoming alpha values. 882 */ 883 compute_component_mapping(srcFormat, baseInternalFormat, src2base); 884 compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba); 885 swap = byteswap_mapping(srcPacking->SwapBytes, srcType); 886 srctype2ubyte = type_mapping(srcType); 887 888 889 for (i = 0; i < 4; i++) 890 map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]]; 891 892 /* printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */ 893 894 if (srcComponents == dstComponents && 895 srcRowStride == dstRowStride && 896 srcRowStride == srcWidth * srcComponents && 897 dimensions < 3) { 898 /* 1 and 2D images only */ 899 GLubyte *dstImage = dstSlices[0]; 900 swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map, 901 srcWidth * srcHeight); 902 } 903 else { 904 GLint img, row; 905 for (img = 0; img < srcDepth; img++) { 906 const GLubyte *srcRow = srcImage; 907 GLubyte *dstRow = dstSlices[img]; 908 for (row = 0; row < srcHeight; row++) { 909 swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth); 910 dstRow += dstRowStride; 911 srcRow += srcRowStride; 912 } 913 srcImage += srcImageStride; 914 } 915 } 916 } 917 918 919 /** 920 * Teximage storage routine for when a simple memcpy will do. 921 * No pixel transfer operations or special texel encodings allowed. 922 * 1D, 2D and 3D images supported. 923 */ 924 static void 925 memcpy_texture(struct gl_context *ctx, 926 GLuint dimensions, 927 gl_format dstFormat, 928 GLint dstRowStride, 929 GLubyte **dstSlices, 930 GLint srcWidth, GLint srcHeight, GLint srcDepth, 931 GLenum srcFormat, GLenum srcType, 932 const GLvoid *srcAddr, 933 const struct gl_pixelstore_attrib *srcPacking) 934 { 935 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, 936 srcFormat, srcType); 937 const GLint srcImageStride = _mesa_image_image_stride(srcPacking, 938 srcWidth, srcHeight, srcFormat, srcType); 939 const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions, 940 srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0); 941 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); 942 const GLint bytesPerRow = srcWidth * texelBytes; 943 944 if (dstRowStride == srcRowStride && 945 dstRowStride == bytesPerRow) { 946 /* memcpy image by image */ 947 GLint img; 948 for (img = 0; img < srcDepth; img++) { 949 GLubyte *dstImage = dstSlices[img]; 950 memcpy(dstImage, srcImage, bytesPerRow * srcHeight); 951 srcImage += srcImageStride; 952 } 953 } 954 else { 955 /* memcpy row by row */ 956 GLint img, row; 957 for (img = 0; img < srcDepth; img++) { 958 const GLubyte *srcRow = srcImage; 959 GLubyte *dstRow = dstSlices[img]; 960 for (row = 0; row < srcHeight; row++) { 961 memcpy(dstRow, srcRow, bytesPerRow); 962 dstRow += dstRowStride; 963 srcRow += srcRowStride; 964 } 965 srcImage += srcImageStride; 966 } 967 } 968 } 969 970 971 /** 972 * General-case function for storing a color texture images with 973 * components that can be represented with ubytes. Example destination 974 * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565. 975 */ 976 static GLboolean 977 store_ubyte_texture(TEXSTORE_PARAMS) 978 { 979 const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte); 980 GLubyte *tempImage, *src; 981 GLint img; 982 983 tempImage = _mesa_make_temp_ubyte_image(ctx, dims, 984 baseInternalFormat, 985 GL_RGBA, 986 srcWidth, srcHeight, srcDepth, 987 srcFormat, srcType, srcAddr, 988 srcPacking); 989 if (!tempImage) 990 return GL_FALSE; 991 992 src = tempImage; 993 for (img = 0; img < srcDepth; img++) { 994 _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight, 995 src, srcRowStride, 996 dstSlices[img], dstRowStride); 997 src += srcHeight * srcRowStride; 998 } 999 free(tempImage); 1000 1001 return GL_TRUE; 1002 } 1003 1004 1005 1006 1007 /** 1008 * Store a 32-bit integer or float depth component texture image. 1009 */ 1010 static GLboolean 1011 _mesa_texstore_z32(TEXSTORE_PARAMS) 1012 { 1013 const GLuint depthScale = 0xffffffff; 1014 GLenum dstType; 1015 (void) dims; 1016 ASSERT(dstFormat == MESA_FORMAT_Z32 || 1017 dstFormat == MESA_FORMAT_Z32_FLOAT); 1018 ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint)); 1019 1020 if (dstFormat == MESA_FORMAT_Z32) 1021 dstType = GL_UNSIGNED_INT; 1022 else 1023 dstType = GL_FLOAT; 1024 1025 if (ctx->Pixel.DepthScale == 1.0f && 1026 ctx->Pixel.DepthBias == 0.0f && 1027 !srcPacking->SwapBytes && 1028 baseInternalFormat == GL_DEPTH_COMPONENT && 1029 srcFormat == GL_DEPTH_COMPONENT && 1030 srcType == dstType) { 1031 /* simple memcpy path */ 1032 memcpy_texture(ctx, dims, 1033 dstFormat, 1034 dstRowStride, dstSlices, 1035 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1036 srcAddr, srcPacking); 1037 } 1038 else { 1039 /* general path */ 1040 GLint img, row; 1041 for (img = 0; img < srcDepth; img++) { 1042 GLubyte *dstRow = dstSlices[img]; 1043 for (row = 0; row < srcHeight; row++) { 1044 const GLvoid *src = _mesa_image_address(dims, srcPacking, 1045 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 1046 _mesa_unpack_depth_span(ctx, srcWidth, 1047 dstType, dstRow, 1048 depthScale, srcType, src, srcPacking); 1049 dstRow += dstRowStride; 1050 } 1051 } 1052 } 1053 return GL_TRUE; 1054 } 1055 1056 1057 /** 1058 * Store a 24-bit integer depth component texture image. 1059 */ 1060 static GLboolean 1061 _mesa_texstore_x8_z24(TEXSTORE_PARAMS) 1062 { 1063 const GLuint depthScale = 0xffffff; 1064 1065 (void) dims; 1066 ASSERT(dstFormat == MESA_FORMAT_X8_Z24); 1067 1068 { 1069 /* general path */ 1070 GLint img, row; 1071 for (img = 0; img < srcDepth; img++) { 1072 GLubyte *dstRow = dstSlices[img]; 1073 for (row = 0; row < srcHeight; row++) { 1074 const GLvoid *src = _mesa_image_address(dims, srcPacking, 1075 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 1076 _mesa_unpack_depth_span(ctx, srcWidth, 1077 GL_UNSIGNED_INT, (GLuint *) dstRow, 1078 depthScale, srcType, src, srcPacking); 1079 dstRow += dstRowStride; 1080 } 1081 } 1082 } 1083 return GL_TRUE; 1084 } 1085 1086 1087 /** 1088 * Store a 24-bit integer depth component texture image. 1089 */ 1090 static GLboolean 1091 _mesa_texstore_z24_x8(TEXSTORE_PARAMS) 1092 { 1093 const GLuint depthScale = 0xffffff; 1094 1095 (void) dims; 1096 ASSERT(dstFormat == MESA_FORMAT_Z24_X8); 1097 1098 { 1099 /* general path */ 1100 GLint img, row; 1101 for (img = 0; img < srcDepth; img++) { 1102 GLubyte *dstRow = dstSlices[img]; 1103 for (row = 0; row < srcHeight; row++) { 1104 const GLvoid *src = _mesa_image_address(dims, srcPacking, 1105 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 1106 GLuint *dst = (GLuint *) dstRow; 1107 GLint i; 1108 _mesa_unpack_depth_span(ctx, srcWidth, 1109 GL_UNSIGNED_INT, dst, 1110 depthScale, srcType, src, srcPacking); 1111 for (i = 0; i < srcWidth; i++) 1112 dst[i] <<= 8; 1113 dstRow += dstRowStride; 1114 } 1115 } 1116 } 1117 return GL_TRUE; 1118 } 1119 1120 1121 /** 1122 * Store a 16-bit integer depth component texture image. 1123 */ 1124 static GLboolean 1125 _mesa_texstore_z16(TEXSTORE_PARAMS) 1126 { 1127 const GLuint depthScale = 0xffff; 1128 (void) dims; 1129 ASSERT(dstFormat == MESA_FORMAT_Z16); 1130 ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort)); 1131 1132 if (ctx->Pixel.DepthScale == 1.0f && 1133 ctx->Pixel.DepthBias == 0.0f && 1134 !srcPacking->SwapBytes && 1135 baseInternalFormat == GL_DEPTH_COMPONENT && 1136 srcFormat == GL_DEPTH_COMPONENT && 1137 srcType == GL_UNSIGNED_SHORT) { 1138 /* simple memcpy path */ 1139 memcpy_texture(ctx, dims, 1140 dstFormat, 1141 dstRowStride, dstSlices, 1142 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1143 srcAddr, srcPacking); 1144 } 1145 else { 1146 /* general path */ 1147 GLint img, row; 1148 for (img = 0; img < srcDepth; img++) { 1149 GLubyte *dstRow = dstSlices[img]; 1150 for (row = 0; row < srcHeight; row++) { 1151 const GLvoid *src = _mesa_image_address(dims, srcPacking, 1152 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 1153 GLushort *dst16 = (GLushort *) dstRow; 1154 _mesa_unpack_depth_span(ctx, srcWidth, 1155 GL_UNSIGNED_SHORT, dst16, depthScale, 1156 srcType, src, srcPacking); 1157 dstRow += dstRowStride; 1158 } 1159 } 1160 } 1161 return GL_TRUE; 1162 } 1163 1164 1165 /** 1166 * Store an rgb565 or rgb565_rev texture image. 1167 */ 1168 static GLboolean 1169 _mesa_texstore_rgb565(TEXSTORE_PARAMS) 1170 { 1171 ASSERT(dstFormat == MESA_FORMAT_RGB565 || 1172 dstFormat == MESA_FORMAT_RGB565_REV); 1173 ASSERT(_mesa_get_format_bytes(dstFormat) == 2); 1174 1175 if (!ctx->_ImageTransferState && 1176 baseInternalFormat == GL_RGB && 1177 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 1178 srcPacking->SwapBytes)) { 1179 /* simple memcpy path */ 1180 memcpy_texture(ctx, dims, 1181 dstFormat, 1182 dstRowStride, dstSlices, 1183 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1184 srcAddr, srcPacking); 1185 } 1186 else if (!ctx->_ImageTransferState && 1187 !srcPacking->SwapBytes && 1188 baseInternalFormat == GL_RGB && 1189 srcFormat == GL_RGB && 1190 srcType == GL_UNSIGNED_BYTE && 1191 dims == 2) { 1192 /* do optimized tex store */ 1193 const GLint srcRowStride = 1194 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 1195 const GLubyte *src = (const GLubyte *) 1196 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, 1197 srcFormat, srcType, 0, 0, 0); 1198 GLubyte *dst = dstSlices[0]; 1199 GLint row, col; 1200 for (row = 0; row < srcHeight; row++) { 1201 const GLubyte *srcUB = (const GLubyte *) src; 1202 GLushort *dstUS = (GLushort *) dst; 1203 /* check for byteswapped format */ 1204 if (dstFormat == MESA_FORMAT_RGB565) { 1205 for (col = 0; col < srcWidth; col++) { 1206 dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] ); 1207 srcUB += 3; 1208 } 1209 } 1210 else { 1211 for (col = 0; col < srcWidth; col++) { 1212 dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] ); 1213 srcUB += 3; 1214 } 1215 } 1216 dst += dstRowStride; 1217 src += srcRowStride; 1218 } 1219 } 1220 else { 1221 return store_ubyte_texture(ctx, dims, baseInternalFormat, 1222 dstFormat, dstRowStride, dstSlices, 1223 srcWidth, srcHeight, srcDepth, 1224 srcFormat, srcType, srcAddr, srcPacking); 1225 } 1226 return GL_TRUE; 1227 } 1228 1229 1230 /** 1231 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV. 1232 */ 1233 static GLboolean 1234 _mesa_texstore_rgba8888(TEXSTORE_PARAMS) 1235 { 1236 const GLboolean littleEndian = _mesa_little_endian(); 1237 1238 ASSERT(dstFormat == MESA_FORMAT_RGBA8888 || 1239 dstFormat == MESA_FORMAT_RGBA8888_REV || 1240 dstFormat == MESA_FORMAT_RGBX8888 || 1241 dstFormat == MESA_FORMAT_RGBX8888_REV); 1242 ASSERT(_mesa_get_format_bytes(dstFormat) == 4); 1243 1244 if (!ctx->_ImageTransferState && 1245 baseInternalFormat == GL_RGBA && 1246 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 1247 srcPacking->SwapBytes)) { 1248 /* simple memcpy path */ 1249 memcpy_texture(ctx, dims, 1250 dstFormat, 1251 dstRowStride, dstSlices, 1252 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1253 srcAddr, srcPacking); 1254 } 1255 else if (!ctx->_ImageTransferState && 1256 (srcType == GL_UNSIGNED_BYTE || 1257 srcType == GL_UNSIGNED_INT_8_8_8_8 || 1258 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && 1259 can_swizzle(baseInternalFormat) && 1260 can_swizzle(srcFormat)) { 1261 1262 GLubyte dstmap[4]; 1263 1264 /* dstmap - how to swizzle from RGBA to dst format: 1265 */ 1266 if ((littleEndian && (dstFormat == MESA_FORMAT_RGBA8888 || 1267 dstFormat == MESA_FORMAT_RGBX8888)) || 1268 (!littleEndian && (dstFormat == MESA_FORMAT_RGBA8888_REV || 1269 dstFormat == MESA_FORMAT_RGBX8888_REV))) { 1270 dstmap[3] = 0; 1271 dstmap[2] = 1; 1272 dstmap[1] = 2; 1273 dstmap[0] = 3; 1274 } 1275 else { 1276 dstmap[3] = 3; 1277 dstmap[2] = 2; 1278 dstmap[1] = 1; 1279 dstmap[0] = 0; 1280 } 1281 1282 _mesa_swizzle_ubyte_image(ctx, dims, 1283 srcFormat, 1284 srcType, 1285 baseInternalFormat, 1286 dstmap, 4, 1287 dstRowStride, dstSlices, 1288 srcWidth, srcHeight, srcDepth, srcAddr, 1289 srcPacking); 1290 } 1291 else { 1292 return store_ubyte_texture(ctx, dims, baseInternalFormat, 1293 dstFormat, dstRowStride, dstSlices, 1294 srcWidth, srcHeight, srcDepth, 1295 srcFormat, srcType, srcAddr, srcPacking); 1296 } 1297 return GL_TRUE; 1298 } 1299 1300 1301 static GLboolean 1302 _mesa_texstore_argb8888(TEXSTORE_PARAMS) 1303 { 1304 const GLboolean littleEndian = _mesa_little_endian(); 1305 1306 ASSERT(dstFormat == MESA_FORMAT_ARGB8888 || 1307 dstFormat == MESA_FORMAT_ARGB8888_REV || 1308 dstFormat == MESA_FORMAT_XRGB8888 || 1309 dstFormat == MESA_FORMAT_XRGB8888_REV ); 1310 ASSERT(_mesa_get_format_bytes(dstFormat) == 4); 1311 1312 if (!ctx->_ImageTransferState && 1313 baseInternalFormat == GL_RGBA && 1314 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 1315 srcPacking->SwapBytes)) { 1316 /* simple memcpy path (big endian) */ 1317 memcpy_texture(ctx, dims, 1318 dstFormat, 1319 dstRowStride, dstSlices, 1320 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1321 srcAddr, srcPacking); 1322 } 1323 else if (!ctx->_ImageTransferState && 1324 !srcPacking->SwapBytes && 1325 (dstFormat == MESA_FORMAT_ARGB8888 || 1326 dstFormat == MESA_FORMAT_XRGB8888) && 1327 srcFormat == GL_RGB && 1328 (baseInternalFormat == GL_RGBA || 1329 baseInternalFormat == GL_RGB) && 1330 srcType == GL_UNSIGNED_BYTE) { 1331 int img, row, col; 1332 for (img = 0; img < srcDepth; img++) { 1333 const GLint srcRowStride = 1334 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 1335 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, 1336 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); 1337 GLubyte *dstRow = dstSlices[img]; 1338 for (row = 0; row < srcHeight; row++) { 1339 GLuint *d4 = (GLuint *) dstRow; 1340 for (col = 0; col < srcWidth; col++) { 1341 d4[col] = PACK_COLOR_8888(0xff, 1342 srcRow[col * 3 + RCOMP], 1343 srcRow[col * 3 + GCOMP], 1344 srcRow[col * 3 + BCOMP]); 1345 } 1346 dstRow += dstRowStride; 1347 srcRow += srcRowStride; 1348 } 1349 } 1350 } 1351 else if (!ctx->_ImageTransferState && 1352 !srcPacking->SwapBytes && 1353 dstFormat == MESA_FORMAT_ARGB8888 && 1354 srcFormat == GL_LUMINANCE_ALPHA && 1355 baseInternalFormat == GL_RGBA && 1356 srcType == GL_UNSIGNED_BYTE) { 1357 /* special case of storing LA -> ARGB8888 */ 1358 int img, row, col; 1359 const GLint srcRowStride = 1360 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 1361 for (img = 0; img < srcDepth; img++) { 1362 const GLubyte *srcRow = (const GLubyte *) 1363 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, 1364 srcHeight, srcFormat, srcType, img, 0, 0); 1365 GLubyte *dstRow = dstSlices[img]; 1366 for (row = 0; row < srcHeight; row++) { 1367 GLuint *d4 = (GLuint *) dstRow; 1368 for (col = 0; col < srcWidth; col++) { 1369 GLubyte l = srcRow[col * 2 + 0], a = srcRow[col * 2 + 1]; 1370 d4[col] = PACK_COLOR_8888(a, l, l, l); 1371 } 1372 dstRow += dstRowStride; 1373 srcRow += srcRowStride; 1374 } 1375 } 1376 } 1377 else if (!ctx->_ImageTransferState && 1378 !srcPacking->SwapBytes && 1379 dstFormat == MESA_FORMAT_ARGB8888 && 1380 srcFormat == GL_RGBA && 1381 baseInternalFormat == GL_RGBA && 1382 srcType == GL_UNSIGNED_BYTE) { 1383 /* same as above case, but src data has alpha too */ 1384 GLint img, row, col; 1385 /* For some reason, streaming copies to write-combined regions 1386 * are extremely sensitive to the characteristics of how the 1387 * source data is retrieved. By reordering the source reads to 1388 * be in-order, the speed of this operation increases by half. 1389 * Strangely the same isn't required for the RGB path, above. 1390 */ 1391 for (img = 0; img < srcDepth; img++) { 1392 const GLint srcRowStride = 1393 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 1394 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, 1395 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); 1396 GLubyte *dstRow = dstSlices[img]; 1397 for (row = 0; row < srcHeight; row++) { 1398 GLuint *d4 = (GLuint *) dstRow; 1399 for (col = 0; col < srcWidth; col++) { 1400 d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP], 1401 srcRow[col * 4 + RCOMP], 1402 srcRow[col * 4 + GCOMP], 1403 srcRow[col * 4 + BCOMP]); 1404 } 1405 dstRow += dstRowStride; 1406 srcRow += srcRowStride; 1407 } 1408 } 1409 } 1410 else if (!ctx->_ImageTransferState && 1411 (srcType == GL_UNSIGNED_BYTE || 1412 srcType == GL_UNSIGNED_INT_8_8_8_8 || 1413 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && 1414 can_swizzle(baseInternalFormat) && 1415 can_swizzle(srcFormat)) { 1416 1417 GLubyte dstmap[4]; 1418 1419 /* dstmap - how to swizzle from RGBA to dst format: 1420 */ 1421 if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) || 1422 (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) || 1423 (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) || 1424 (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) { 1425 dstmap[3] = 3; /* alpha */ 1426 dstmap[2] = 0; /* red */ 1427 dstmap[1] = 1; /* green */ 1428 dstmap[0] = 2; /* blue */ 1429 } 1430 else { 1431 assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) || 1432 (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) || 1433 (littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) || 1434 (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888)); 1435 dstmap[3] = 2; 1436 dstmap[2] = 1; 1437 dstmap[1] = 0; 1438 dstmap[0] = 3; 1439 } 1440 1441 _mesa_swizzle_ubyte_image(ctx, dims, 1442 srcFormat, 1443 srcType, 1444 baseInternalFormat, 1445 dstmap, 4, 1446 dstRowStride, 1447 dstSlices, 1448 srcWidth, srcHeight, srcDepth, srcAddr, 1449 srcPacking); 1450 } 1451 else { 1452 return store_ubyte_texture(ctx, dims, baseInternalFormat, 1453 dstFormat, dstRowStride, dstSlices, 1454 srcWidth, srcHeight, srcDepth, 1455 srcFormat, srcType, srcAddr, srcPacking); 1456 } 1457 return GL_TRUE; 1458 } 1459 1460 1461 static GLboolean 1462 _mesa_texstore_rgb888(TEXSTORE_PARAMS) 1463 { 1464 ASSERT(dstFormat == MESA_FORMAT_RGB888); 1465 ASSERT(_mesa_get_format_bytes(dstFormat) == 3); 1466 1467 if (!ctx->_ImageTransferState && 1468 baseInternalFormat == GL_RGB && 1469 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 1470 srcPacking->SwapBytes)) { 1471 /* simple memcpy path */ 1472 memcpy_texture(ctx, dims, 1473 dstFormat, 1474 dstRowStride, dstSlices, 1475 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1476 srcAddr, srcPacking); 1477 } 1478 else if (!ctx->_ImageTransferState && 1479 !srcPacking->SwapBytes && 1480 srcFormat == GL_RGBA && 1481 srcType == GL_UNSIGNED_BYTE) { 1482 /* extract RGB from RGBA */ 1483 GLint img, row, col; 1484 for (img = 0; img < srcDepth; img++) { 1485 const GLint srcRowStride = 1486 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 1487 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, 1488 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); 1489 GLubyte *dstRow = dstSlices[img]; 1490 for (row = 0; row < srcHeight; row++) { 1491 for (col = 0; col < srcWidth; col++) { 1492 dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP]; 1493 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP]; 1494 dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP]; 1495 } 1496 dstRow += dstRowStride; 1497 srcRow += srcRowStride; 1498 } 1499 } 1500 } 1501 else if (!ctx->_ImageTransferState && 1502 srcType == GL_UNSIGNED_BYTE && 1503 can_swizzle(baseInternalFormat) && 1504 can_swizzle(srcFormat)) { 1505 1506 GLubyte dstmap[4]; 1507 1508 /* dstmap - how to swizzle from RGBA to dst format: 1509 */ 1510 dstmap[0] = 2; 1511 dstmap[1] = 1; 1512 dstmap[2] = 0; 1513 dstmap[3] = ONE; /* ? */ 1514 1515 _mesa_swizzle_ubyte_image(ctx, dims, 1516 srcFormat, 1517 srcType, 1518 baseInternalFormat, 1519 dstmap, 3, 1520 dstRowStride, dstSlices, 1521 srcWidth, srcHeight, srcDepth, srcAddr, 1522 srcPacking); 1523 } 1524 else { 1525 return store_ubyte_texture(ctx, dims, baseInternalFormat, 1526 dstFormat, dstRowStride, dstSlices, 1527 srcWidth, srcHeight, srcDepth, 1528 srcFormat, srcType, srcAddr, srcPacking); 1529 } 1530 return GL_TRUE; 1531 } 1532 1533 1534 static GLboolean 1535 _mesa_texstore_bgr888(TEXSTORE_PARAMS) 1536 { 1537 ASSERT(dstFormat == MESA_FORMAT_BGR888); 1538 ASSERT(_mesa_get_format_bytes(dstFormat) == 3); 1539 1540 if (!ctx->_ImageTransferState && 1541 baseInternalFormat == GL_RGB && 1542 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 1543 srcPacking->SwapBytes)) { 1544 /* simple memcpy path */ 1545 memcpy_texture(ctx, dims, 1546 dstFormat, 1547 dstRowStride, dstSlices, 1548 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1549 srcAddr, srcPacking); 1550 } 1551 else if (!ctx->_ImageTransferState && 1552 !srcPacking->SwapBytes && 1553 srcFormat == GL_RGBA && 1554 srcType == GL_UNSIGNED_BYTE) { 1555 /* extract BGR from RGBA */ 1556 int img, row, col; 1557 for (img = 0; img < srcDepth; img++) { 1558 const GLint srcRowStride = 1559 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 1560 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, 1561 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); 1562 GLubyte *dstRow = dstSlices[img]; 1563 for (row = 0; row < srcHeight; row++) { 1564 for (col = 0; col < srcWidth; col++) { 1565 dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP]; 1566 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP]; 1567 dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP]; 1568 } 1569 dstRow += dstRowStride; 1570 srcRow += srcRowStride; 1571 } 1572 } 1573 } 1574 else if (!ctx->_ImageTransferState && 1575 srcType == GL_UNSIGNED_BYTE && 1576 can_swizzle(baseInternalFormat) && 1577 can_swizzle(srcFormat)) { 1578 1579 GLubyte dstmap[4]; 1580 1581 /* dstmap - how to swizzle from RGBA to dst format: 1582 */ 1583 dstmap[0] = 0; 1584 dstmap[1] = 1; 1585 dstmap[2] = 2; 1586 dstmap[3] = ONE; /* ? */ 1587 1588 _mesa_swizzle_ubyte_image(ctx, dims, 1589 srcFormat, 1590 srcType, 1591 baseInternalFormat, 1592 dstmap, 3, 1593 dstRowStride, dstSlices, 1594 srcWidth, srcHeight, srcDepth, srcAddr, 1595 srcPacking); 1596 } 1597 else { 1598 return store_ubyte_texture(ctx, dims, baseInternalFormat, 1599 dstFormat, dstRowStride, dstSlices, 1600 srcWidth, srcHeight, srcDepth, 1601 srcFormat, srcType, srcAddr, srcPacking); 1602 } 1603 return GL_TRUE; 1604 } 1605 1606 1607 static GLboolean 1608 _mesa_texstore_argb4444(TEXSTORE_PARAMS) 1609 { 1610 ASSERT(dstFormat == MESA_FORMAT_ARGB4444 || 1611 dstFormat == MESA_FORMAT_ARGB4444_REV); 1612 ASSERT(_mesa_get_format_bytes(dstFormat) == 2); 1613 1614 if (!ctx->_ImageTransferState && 1615 baseInternalFormat == GL_RGBA && 1616 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 1617 srcPacking->SwapBytes)) { 1618 /* simple memcpy path */ 1619 memcpy_texture(ctx, dims, 1620 dstFormat, 1621 dstRowStride, dstSlices, 1622 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1623 srcAddr, srcPacking); 1624 } 1625 else { 1626 return store_ubyte_texture(ctx, dims, baseInternalFormat, 1627 dstFormat, dstRowStride, dstSlices, 1628 srcWidth, srcHeight, srcDepth, 1629 srcFormat, srcType, srcAddr, srcPacking); 1630 } 1631 return GL_TRUE; 1632 } 1633 1634 static GLboolean 1635 _mesa_texstore_rgba5551(TEXSTORE_PARAMS) 1636 { 1637 ASSERT(dstFormat == MESA_FORMAT_RGBA5551); 1638 ASSERT(_mesa_get_format_bytes(dstFormat) == 2); 1639 1640 if (!ctx->_ImageTransferState && 1641 baseInternalFormat == GL_RGBA && 1642 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 1643 srcPacking->SwapBytes)) { 1644 /* simple memcpy path */ 1645 memcpy_texture(ctx, dims, 1646 dstFormat, 1647 dstRowStride, dstSlices, 1648 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1649 srcAddr, srcPacking); 1650 } 1651 else { 1652 return store_ubyte_texture(ctx, dims, baseInternalFormat, 1653 dstFormat, dstRowStride, dstSlices, 1654 srcWidth, srcHeight, srcDepth, 1655 srcFormat, srcType, srcAddr, srcPacking); 1656 } 1657 return GL_TRUE; 1658 } 1659 1660 static GLboolean 1661 _mesa_texstore_argb1555(TEXSTORE_PARAMS) 1662 { 1663 ASSERT(dstFormat == MESA_FORMAT_ARGB1555 || 1664 dstFormat == MESA_FORMAT_ARGB1555_REV); 1665 ASSERT(_mesa_get_format_bytes(dstFormat) == 2); 1666 1667 if (!ctx->_ImageTransferState && 1668 baseInternalFormat == GL_RGBA && 1669 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 1670 srcPacking->SwapBytes)) { 1671 /* simple memcpy path */ 1672 memcpy_texture(ctx, dims, 1673 dstFormat, 1674 dstRowStride, dstSlices, 1675 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1676 srcAddr, srcPacking); 1677 } 1678 else { 1679 return store_ubyte_texture(ctx, dims, baseInternalFormat, 1680 dstFormat, dstRowStride, dstSlices, 1681 srcWidth, srcHeight, srcDepth, 1682 srcFormat, srcType, srcAddr, srcPacking); 1683 } 1684 return GL_TRUE; 1685 } 1686 1687 1688 static GLboolean 1689 _mesa_texstore_argb2101010(TEXSTORE_PARAMS) 1690 { 1691 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 1692 1693 ASSERT(dstFormat == MESA_FORMAT_ARGB2101010); 1694 ASSERT(_mesa_get_format_bytes(dstFormat) == 4); 1695 1696 if (!ctx->_ImageTransferState && 1697 baseInternalFormat == GL_RGBA && 1698 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 1699 srcPacking->SwapBytes)) { 1700 /* simple memcpy path */ 1701 memcpy_texture(ctx, dims, 1702 dstFormat, 1703 dstRowStride, dstSlices, 1704 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1705 srcAddr, srcPacking); 1706 } 1707 else { 1708 /* general path */ 1709 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 1710 baseInternalFormat, 1711 baseFormat, 1712 srcWidth, srcHeight, srcDepth, 1713 srcFormat, srcType, srcAddr, 1714 srcPacking, 1715 ctx->_ImageTransferState); 1716 const GLfloat *src = tempImage; 1717 GLint img, row, col; 1718 if (!tempImage) 1719 return GL_FALSE; 1720 for (img = 0; img < srcDepth; img++) { 1721 GLubyte *dstRow = dstSlices[img]; 1722 if (baseInternalFormat == GL_RGBA) { 1723 for (row = 0; row < srcHeight; row++) { 1724 GLuint *dstUI = (GLuint *) dstRow; 1725 for (col = 0; col < srcWidth; col++) { 1726 GLushort a,r,g,b; 1727 1728 UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]); 1729 UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); 1730 UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); 1731 UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); 1732 dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b); 1733 src += 4; 1734 } 1735 dstRow += dstRowStride; 1736 } 1737 } else if (baseInternalFormat == GL_RGB) { 1738 for (row = 0; row < srcHeight; row++) { 1739 GLuint *dstUI = (GLuint *) dstRow; 1740 for (col = 0; col < srcWidth; col++) { 1741 GLushort r,g,b; 1742 1743 UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]); 1744 UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]); 1745 UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]); 1746 dstUI[col] = PACK_COLOR_2101010_US(0xffff, r, g, b); 1747 src += 4; 1748 } 1749 dstRow += dstRowStride; 1750 } 1751 } else { 1752 ASSERT(0); 1753 } 1754 } 1755 free((void *) tempImage); 1756 } 1757 return GL_TRUE; 1758 } 1759 1760 1761 /** 1762 * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats. 1763 */ 1764 static GLboolean 1765 _mesa_texstore_unorm44(TEXSTORE_PARAMS) 1766 { 1767 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 1768 1769 ASSERT(dstFormat == MESA_FORMAT_AL44); 1770 ASSERT(_mesa_get_format_bytes(dstFormat) == 1); 1771 1772 { 1773 /* general path */ 1774 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims, 1775 baseInternalFormat, 1776 baseFormat, 1777 srcWidth, srcHeight, srcDepth, 1778 srcFormat, srcType, srcAddr, 1779 srcPacking); 1780 const GLubyte *src = tempImage; 1781 GLint img, row, col; 1782 if (!tempImage) 1783 return GL_FALSE; 1784 for (img = 0; img < srcDepth; img++) { 1785 GLubyte *dstRow = dstSlices[img]; 1786 for (row = 0; row < srcHeight; row++) { 1787 GLubyte *dstUS = (GLubyte *) dstRow; 1788 for (col = 0; col < srcWidth; col++) { 1789 /* src[0] is luminance, src[1] is alpha */ 1790 dstUS[col] = PACK_COLOR_44( src[1], 1791 src[0] ); 1792 src += 2; 1793 } 1794 dstRow += dstRowStride; 1795 } 1796 } 1797 free((void *) tempImage); 1798 } 1799 return GL_TRUE; 1800 } 1801 1802 1803 /** 1804 * Do texstore for 2-channel, 8-bit/channel, unsigned normalized formats. 1805 */ 1806 static GLboolean 1807 _mesa_texstore_unorm88(TEXSTORE_PARAMS) 1808 { 1809 const GLboolean littleEndian = _mesa_little_endian(); 1810 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 1811 1812 ASSERT(dstFormat == MESA_FORMAT_AL88 || 1813 dstFormat == MESA_FORMAT_AL88_REV || 1814 dstFormat == MESA_FORMAT_GR88 || 1815 dstFormat == MESA_FORMAT_RG88); 1816 ASSERT(_mesa_get_format_bytes(dstFormat) == 2); 1817 1818 if (!ctx->_ImageTransferState && 1819 !srcPacking->SwapBytes && 1820 ((dstFormat == MESA_FORMAT_AL88 && 1821 baseInternalFormat == GL_LUMINANCE_ALPHA && 1822 srcFormat == GL_LUMINANCE_ALPHA) || 1823 (dstFormat == MESA_FORMAT_GR88 && 1824 baseInternalFormat == srcFormat)) && 1825 srcType == GL_UNSIGNED_BYTE && 1826 littleEndian) { 1827 /* simple memcpy path */ 1828 memcpy_texture(ctx, dims, 1829 dstFormat, 1830 dstRowStride, dstSlices, 1831 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1832 srcAddr, srcPacking); 1833 } 1834 else if (!ctx->_ImageTransferState && 1835 littleEndian && 1836 srcType == GL_UNSIGNED_BYTE && 1837 can_swizzle(baseInternalFormat) && 1838 can_swizzle(srcFormat)) { 1839 GLubyte dstmap[4]; 1840 1841 /* dstmap - how to swizzle from RGBA to dst format: 1842 */ 1843 if (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_AL88_REV) { 1844 if ((littleEndian && dstFormat == MESA_FORMAT_AL88) || 1845 (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) { 1846 dstmap[0] = 0; 1847 dstmap[1] = 3; 1848 } 1849 else { 1850 dstmap[0] = 3; 1851 dstmap[1] = 0; 1852 } 1853 } 1854 else { 1855 if ((littleEndian && dstFormat == MESA_FORMAT_GR88) || 1856 (!littleEndian && dstFormat == MESA_FORMAT_RG88)) { 1857 dstmap[0] = 0; 1858 dstmap[1] = 1; 1859 } 1860 else { 1861 dstmap[0] = 1; 1862 dstmap[1] = 0; 1863 } 1864 } 1865 dstmap[2] = ZERO; /* ? */ 1866 dstmap[3] = ONE; /* ? */ 1867 1868 _mesa_swizzle_ubyte_image(ctx, dims, 1869 srcFormat, 1870 srcType, 1871 baseInternalFormat, 1872 dstmap, 2, 1873 dstRowStride, dstSlices, 1874 srcWidth, srcHeight, srcDepth, srcAddr, 1875 srcPacking); 1876 } 1877 else { 1878 /* general path */ 1879 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims, 1880 baseInternalFormat, 1881 baseFormat, 1882 srcWidth, srcHeight, srcDepth, 1883 srcFormat, srcType, srcAddr, 1884 srcPacking); 1885 const GLubyte *src = tempImage; 1886 GLint img, row, col; 1887 if (!tempImage) 1888 return GL_FALSE; 1889 for (img = 0; img < srcDepth; img++) { 1890 GLubyte *dstRow = dstSlices[img]; 1891 for (row = 0; row < srcHeight; row++) { 1892 GLushort *dstUS = (GLushort *) dstRow; 1893 if (dstFormat == MESA_FORMAT_AL88 || 1894 dstFormat == MESA_FORMAT_GR88) { 1895 for (col = 0; col < srcWidth; col++) { 1896 /* src[0] is luminance (or R), src[1] is alpha (or G) */ 1897 dstUS[col] = PACK_COLOR_88( src[1], 1898 src[0] ); 1899 src += 2; 1900 } 1901 } 1902 else { 1903 for (col = 0; col < srcWidth; col++) { 1904 /* src[0] is luminance (or R), src[1] is alpha (or G) */ 1905 dstUS[col] = PACK_COLOR_88_REV( src[1], 1906 src[0] ); 1907 src += 2; 1908 } 1909 } 1910 dstRow += dstRowStride; 1911 } 1912 } 1913 free((void *) tempImage); 1914 } 1915 return GL_TRUE; 1916 } 1917 1918 1919 /** 1920 * Do texstore for 2-channel, 16-bit/channel, unsigned normalized formats. 1921 */ 1922 static GLboolean 1923 _mesa_texstore_unorm1616(TEXSTORE_PARAMS) 1924 { 1925 const GLboolean littleEndian = _mesa_little_endian(); 1926 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 1927 1928 ASSERT(dstFormat == MESA_FORMAT_AL1616 || 1929 dstFormat == MESA_FORMAT_AL1616_REV || 1930 dstFormat == MESA_FORMAT_RG1616 || 1931 dstFormat == MESA_FORMAT_RG1616_REV); 1932 ASSERT(_mesa_get_format_bytes(dstFormat) == 4); 1933 1934 if (!ctx->_ImageTransferState && 1935 !srcPacking->SwapBytes && 1936 ((dstFormat == MESA_FORMAT_AL1616 && 1937 baseInternalFormat == GL_LUMINANCE_ALPHA && 1938 srcFormat == GL_LUMINANCE_ALPHA) || 1939 (dstFormat == MESA_FORMAT_RG1616 && 1940 baseInternalFormat == srcFormat)) && 1941 srcType == GL_UNSIGNED_SHORT && 1942 littleEndian) { 1943 /* simple memcpy path */ 1944 memcpy_texture(ctx, dims, 1945 dstFormat, 1946 dstRowStride, dstSlices, 1947 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 1948 srcAddr, srcPacking); 1949 } 1950 else { 1951 /* general path */ 1952 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 1953 baseInternalFormat, 1954 baseFormat, 1955 srcWidth, srcHeight, srcDepth, 1956 srcFormat, srcType, srcAddr, 1957 srcPacking, 1958 ctx->_ImageTransferState); 1959 const GLfloat *src = tempImage; 1960 GLint img, row, col; 1961 if (!tempImage) 1962 return GL_FALSE; 1963 for (img = 0; img < srcDepth; img++) { 1964 GLubyte *dstRow = dstSlices[img]; 1965 for (row = 0; row < srcHeight; row++) { 1966 GLuint *dstUI = (GLuint *) dstRow; 1967 if (dstFormat == MESA_FORMAT_AL1616 || 1968 dstFormat == MESA_FORMAT_RG1616) { 1969 for (col = 0; col < srcWidth; col++) { 1970 GLushort l, a; 1971 1972 UNCLAMPED_FLOAT_TO_USHORT(l, src[0]); 1973 UNCLAMPED_FLOAT_TO_USHORT(a, src[1]); 1974 dstUI[col] = PACK_COLOR_1616(a, l); 1975 src += 2; 1976 } 1977 } 1978 else { 1979 for (col = 0; col < srcWidth; col++) { 1980 GLushort l, a; 1981 1982 UNCLAMPED_FLOAT_TO_USHORT(l, src[0]); 1983 UNCLAMPED_FLOAT_TO_USHORT(a, src[1]); 1984 dstUI[col] = PACK_COLOR_1616_REV(a, l); 1985 src += 2; 1986 } 1987 } 1988 dstRow += dstRowStride; 1989 } 1990 } 1991 free((void *) tempImage); 1992 } 1993 return GL_TRUE; 1994 } 1995 1996 1997 /* Texstore for R16, A16, L16, I16. */ 1998 static GLboolean 1999 _mesa_texstore_unorm16(TEXSTORE_PARAMS) 2000 { 2001 const GLboolean littleEndian = _mesa_little_endian(); 2002 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 2003 2004 ASSERT(dstFormat == MESA_FORMAT_R16 || 2005 dstFormat == MESA_FORMAT_A16 || 2006 dstFormat == MESA_FORMAT_L16 || 2007 dstFormat == MESA_FORMAT_I16); 2008 ASSERT(_mesa_get_format_bytes(dstFormat) == 2); 2009 2010 if (!ctx->_ImageTransferState && 2011 !srcPacking->SwapBytes && 2012 baseInternalFormat == srcFormat && 2013 srcType == GL_UNSIGNED_SHORT && 2014 littleEndian) { 2015 /* simple memcpy path */ 2016 memcpy_texture(ctx, dims, 2017 dstFormat, 2018 dstRowStride, dstSlices, 2019 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2020 srcAddr, srcPacking); 2021 } 2022 else { 2023 /* general path */ 2024 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 2025 baseInternalFormat, 2026 baseFormat, 2027 srcWidth, srcHeight, srcDepth, 2028 srcFormat, srcType, srcAddr, 2029 srcPacking, 2030 ctx->_ImageTransferState); 2031 const GLfloat *src = tempImage; 2032 GLint img, row, col; 2033 if (!tempImage) 2034 return GL_FALSE; 2035 for (img = 0; img < srcDepth; img++) { 2036 GLubyte *dstRow = dstSlices[img]; 2037 for (row = 0; row < srcHeight; row++) { 2038 GLushort *dstUS = (GLushort *) dstRow; 2039 for (col = 0; col < srcWidth; col++) { 2040 GLushort r; 2041 2042 UNCLAMPED_FLOAT_TO_USHORT(r, src[0]); 2043 dstUS[col] = r; 2044 src += 1; 2045 } 2046 dstRow += dstRowStride; 2047 } 2048 } 2049 free((void *) tempImage); 2050 } 2051 return GL_TRUE; 2052 } 2053 2054 2055 static GLboolean 2056 _mesa_texstore_rgba_16(TEXSTORE_PARAMS) 2057 { 2058 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 2059 2060 ASSERT(dstFormat == MESA_FORMAT_RGBA_16); 2061 ASSERT(_mesa_get_format_bytes(dstFormat) == 8); 2062 2063 if (!ctx->_ImageTransferState && 2064 !srcPacking->SwapBytes && 2065 baseInternalFormat == GL_RGBA && 2066 srcFormat == GL_RGBA && 2067 srcType == GL_UNSIGNED_SHORT) { 2068 /* simple memcpy path */ 2069 memcpy_texture(ctx, dims, 2070 dstFormat, 2071 dstRowStride, dstSlices, 2072 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2073 srcAddr, srcPacking); 2074 } 2075 else { 2076 /* general path */ 2077 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 2078 baseInternalFormat, 2079 baseFormat, 2080 srcWidth, srcHeight, srcDepth, 2081 srcFormat, srcType, srcAddr, 2082 srcPacking, 2083 ctx->_ImageTransferState); 2084 const GLfloat *src = tempImage; 2085 GLint img, row, col; 2086 if (!tempImage) 2087 return GL_FALSE; 2088 for (img = 0; img < srcDepth; img++) { 2089 GLubyte *dstRow = dstSlices[img]; 2090 for (row = 0; row < srcHeight; row++) { 2091 GLushort *dstUS = (GLushort *) dstRow; 2092 for (col = 0; col < srcWidth; col++) { 2093 GLushort r, g, b, a; 2094 2095 UNCLAMPED_FLOAT_TO_USHORT(r, src[0]); 2096 UNCLAMPED_FLOAT_TO_USHORT(g, src[1]); 2097 UNCLAMPED_FLOAT_TO_USHORT(b, src[2]); 2098 UNCLAMPED_FLOAT_TO_USHORT(a, src[3]); 2099 dstUS[col*4+0] = r; 2100 dstUS[col*4+1] = g; 2101 dstUS[col*4+2] = b; 2102 dstUS[col*4+3] = a; 2103 src += 4; 2104 } 2105 dstRow += dstRowStride; 2106 } 2107 } 2108 free((void *) tempImage); 2109 } 2110 return GL_TRUE; 2111 } 2112 2113 2114 static GLboolean 2115 _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS) 2116 { 2117 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 2118 2119 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGB_16 || 2120 dstFormat == MESA_FORMAT_SIGNED_RGBA_16); 2121 2122 if (!ctx->_ImageTransferState && 2123 !srcPacking->SwapBytes && 2124 baseInternalFormat == GL_RGBA && 2125 dstFormat == MESA_FORMAT_SIGNED_RGBA_16 && 2126 srcFormat == GL_RGBA && 2127 srcType == GL_SHORT) { 2128 /* simple memcpy path */ 2129 memcpy_texture(ctx, dims, 2130 dstFormat, 2131 dstRowStride, dstSlices, 2132 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2133 srcAddr, srcPacking); 2134 } 2135 else { 2136 /* general path */ 2137 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 2138 baseInternalFormat, 2139 baseFormat, 2140 srcWidth, srcHeight, srcDepth, 2141 srcFormat, srcType, srcAddr, 2142 srcPacking, 2143 ctx->_ImageTransferState); 2144 const GLfloat *src = tempImage; 2145 const GLuint comps = _mesa_get_format_bytes(dstFormat) / 2; 2146 GLint img, row, col; 2147 2148 if (!tempImage) 2149 return GL_FALSE; 2150 2151 /* Note: tempImage is always float[4] / RGBA. We convert to 1, 2, 2152 * 3 or 4 components/pixel here. 2153 */ 2154 for (img = 0; img < srcDepth; img++) { 2155 GLubyte *dstRow = dstSlices[img]; 2156 for (row = 0; row < srcHeight; row++) { 2157 GLshort *dstRowS = (GLshort *) dstRow; 2158 if (dstFormat == MESA_FORMAT_SIGNED_RGBA_16) { 2159 for (col = 0; col < srcWidth; col++) { 2160 GLuint c; 2161 for (c = 0; c < comps; c++) { 2162 GLshort p; 2163 UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 4 + c]); 2164 dstRowS[col * comps + c] = p; 2165 } 2166 } 2167 dstRow += dstRowStride; 2168 src += 4 * srcWidth; 2169 } else { 2170 for (col = 0; col < srcWidth; col++) { 2171 GLuint c; 2172 for (c = 0; c < comps; c++) { 2173 GLshort p; 2174 UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]); 2175 dstRowS[col * comps + c] = p; 2176 } 2177 } 2178 dstRow += dstRowStride; 2179 src += 3 * srcWidth; 2180 } 2181 } 2182 } 2183 free((void *) tempImage); 2184 } 2185 return GL_TRUE; 2186 } 2187 2188 2189 static GLboolean 2190 _mesa_texstore_rgb332(TEXSTORE_PARAMS) 2191 { 2192 ASSERT(dstFormat == MESA_FORMAT_RGB332); 2193 ASSERT(_mesa_get_format_bytes(dstFormat) == 1); 2194 2195 if (!ctx->_ImageTransferState && 2196 baseInternalFormat == GL_RGB && 2197 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 2198 srcPacking->SwapBytes)) { 2199 /* simple memcpy path */ 2200 memcpy_texture(ctx, dims, 2201 dstFormat, 2202 dstRowStride, dstSlices, 2203 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2204 srcAddr, srcPacking); 2205 } 2206 else { 2207 return store_ubyte_texture(ctx, dims, baseInternalFormat, 2208 dstFormat, dstRowStride, dstSlices, 2209 srcWidth, srcHeight, srcDepth, 2210 srcFormat, srcType, srcAddr, srcPacking); 2211 } 2212 return GL_TRUE; 2213 } 2214 2215 2216 /** 2217 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8. 2218 */ 2219 static GLboolean 2220 _mesa_texstore_unorm8(TEXSTORE_PARAMS) 2221 { 2222 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 2223 2224 ASSERT(dstFormat == MESA_FORMAT_A8 || 2225 dstFormat == MESA_FORMAT_L8 || 2226 dstFormat == MESA_FORMAT_I8 || 2227 dstFormat == MESA_FORMAT_R8); 2228 ASSERT(_mesa_get_format_bytes(dstFormat) == 1); 2229 2230 if (!ctx->_ImageTransferState && 2231 !srcPacking->SwapBytes && 2232 baseInternalFormat == srcFormat && 2233 srcType == GL_UNSIGNED_BYTE) { 2234 /* simple memcpy path */ 2235 memcpy_texture(ctx, dims, 2236 dstFormat, 2237 dstRowStride, dstSlices, 2238 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2239 srcAddr, srcPacking); 2240 } 2241 else if (!ctx->_ImageTransferState && 2242 srcType == GL_UNSIGNED_BYTE && 2243 can_swizzle(baseInternalFormat) && 2244 can_swizzle(srcFormat)) { 2245 GLubyte dstmap[4]; 2246 2247 /* dstmap - how to swizzle from RGBA to dst format: 2248 */ 2249 if (dstFormat == MESA_FORMAT_A8) { 2250 dstmap[0] = 3; 2251 } 2252 else { 2253 dstmap[0] = 0; 2254 } 2255 dstmap[1] = ZERO; /* ? */ 2256 dstmap[2] = ZERO; /* ? */ 2257 dstmap[3] = ONE; /* ? */ 2258 2259 _mesa_swizzle_ubyte_image(ctx, dims, 2260 srcFormat, 2261 srcType, 2262 baseInternalFormat, 2263 dstmap, 1, 2264 dstRowStride, dstSlices, 2265 srcWidth, srcHeight, srcDepth, srcAddr, 2266 srcPacking); 2267 } 2268 else { 2269 /* general path */ 2270 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims, 2271 baseInternalFormat, 2272 baseFormat, 2273 srcWidth, srcHeight, srcDepth, 2274 srcFormat, srcType, srcAddr, 2275 srcPacking); 2276 const GLubyte *src = tempImage; 2277 GLint img, row, col; 2278 if (!tempImage) 2279 return GL_FALSE; 2280 for (img = 0; img < srcDepth; img++) { 2281 GLubyte *dstRow = dstSlices[img]; 2282 for (row = 0; row < srcHeight; row++) { 2283 for (col = 0; col < srcWidth; col++) { 2284 dstRow[col] = src[col]; 2285 } 2286 dstRow += dstRowStride; 2287 src += srcWidth; 2288 } 2289 } 2290 free((void *) tempImage); 2291 } 2292 return GL_TRUE; 2293 } 2294 2295 2296 2297 /** 2298 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV. 2299 */ 2300 static GLboolean 2301 _mesa_texstore_ycbcr(TEXSTORE_PARAMS) 2302 { 2303 const GLboolean littleEndian = _mesa_little_endian(); 2304 2305 (void) ctx; (void) dims; (void) baseInternalFormat; 2306 2307 ASSERT((dstFormat == MESA_FORMAT_YCBCR) || 2308 (dstFormat == MESA_FORMAT_YCBCR_REV)); 2309 ASSERT(_mesa_get_format_bytes(dstFormat) == 2); 2310 ASSERT(ctx->Extensions.MESA_ycbcr_texture); 2311 ASSERT(srcFormat == GL_YCBCR_MESA); 2312 ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) || 2313 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA)); 2314 ASSERT(baseInternalFormat == GL_YCBCR_MESA); 2315 2316 /* always just memcpy since no pixel transfer ops apply */ 2317 memcpy_texture(ctx, dims, 2318 dstFormat, 2319 dstRowStride, dstSlices, 2320 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2321 srcAddr, srcPacking); 2322 2323 /* Check if we need byte swapping */ 2324 /* XXX the logic here _might_ be wrong */ 2325 if (srcPacking->SwapBytes ^ 2326 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^ 2327 (dstFormat == MESA_FORMAT_YCBCR_REV) ^ 2328 !littleEndian) { 2329 GLint img, row; 2330 for (img = 0; img < srcDepth; img++) { 2331 GLubyte *dstRow = dstSlices[img]; 2332 for (row = 0; row < srcHeight; row++) { 2333 _mesa_swap2((GLushort *) dstRow, srcWidth); 2334 dstRow += dstRowStride; 2335 } 2336 } 2337 } 2338 return GL_TRUE; 2339 } 2340 2341 static GLboolean 2342 _mesa_texstore_dudv8(TEXSTORE_PARAMS) 2343 { 2344 const GLboolean littleEndian = _mesa_little_endian(); 2345 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat); 2346 2347 ASSERT(dstFormat == MESA_FORMAT_DUDV8); 2348 ASSERT(texelBytes == 2); 2349 ASSERT(ctx->Extensions.ATI_envmap_bumpmap); 2350 ASSERT((srcFormat == GL_DU8DV8_ATI) || 2351 (srcFormat == GL_DUDV_ATI)); 2352 ASSERT(baseInternalFormat == GL_DUDV_ATI); 2353 2354 if (!srcPacking->SwapBytes && srcType == GL_BYTE && 2355 littleEndian) { 2356 /* simple memcpy path */ 2357 memcpy_texture(ctx, dims, 2358 dstFormat, 2359 dstRowStride, dstSlices, 2360 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2361 srcAddr, srcPacking); 2362 } 2363 else if (srcType == GL_BYTE) { 2364 GLubyte dstmap[4]; 2365 2366 /* dstmap - how to swizzle from RGBA to dst format: 2367 */ 2368 if (littleEndian) { 2369 dstmap[0] = 0; 2370 dstmap[1] = 3; 2371 } 2372 else { 2373 dstmap[0] = 3; 2374 dstmap[1] = 0; 2375 } 2376 dstmap[2] = ZERO; /* ? */ 2377 dstmap[3] = ONE; /* ? */ 2378 2379 _mesa_swizzle_ubyte_image(ctx, dims, 2380 GL_LUMINANCE_ALPHA, /* hack */ 2381 GL_UNSIGNED_BYTE, /* hack */ 2382 GL_LUMINANCE_ALPHA, /* hack */ 2383 dstmap, 2, 2384 dstRowStride, dstSlices, 2385 srcWidth, srcHeight, srcDepth, srcAddr, 2386 srcPacking); 2387 } 2388 else { 2389 /* general path - note this is defined for 2d textures only */ 2390 const GLint components = _mesa_components_in_format(baseInternalFormat); 2391 const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth, 2392 srcFormat, srcType); 2393 GLbyte *tempImage, *dst, *src; 2394 GLint row; 2395 2396 tempImage = (GLbyte *) malloc(srcWidth * srcHeight * srcDepth 2397 * components * sizeof(GLbyte)); 2398 if (!tempImage) 2399 return GL_FALSE; 2400 2401 src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr, 2402 srcWidth, srcHeight, 2403 srcFormat, srcType, 2404 0, 0, 0); 2405 2406 dst = tempImage; 2407 for (row = 0; row < srcHeight; row++) { 2408 _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat, 2409 dst, srcFormat, srcType, src, 2410 srcPacking, 0); 2411 dst += srcWidth * components; 2412 src += srcStride; 2413 } 2414 2415 src = tempImage; 2416 dst = (GLbyte *) dstSlices[0]; 2417 for (row = 0; row < srcHeight; row++) { 2418 memcpy(dst, src, srcWidth * texelBytes); 2419 dst += dstRowStride; 2420 src += srcWidth * texelBytes; 2421 } 2422 free((void *) tempImage); 2423 } 2424 return GL_TRUE; 2425 } 2426 2427 2428 /** 2429 * Store a texture in a signed normalized 8-bit format. 2430 */ 2431 static GLboolean 2432 _mesa_texstore_snorm8(TEXSTORE_PARAMS) 2433 { 2434 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 2435 2436 ASSERT(dstFormat == MESA_FORMAT_SIGNED_A8 || 2437 dstFormat == MESA_FORMAT_SIGNED_L8 || 2438 dstFormat == MESA_FORMAT_SIGNED_I8 || 2439 dstFormat == MESA_FORMAT_SIGNED_R8); 2440 ASSERT(_mesa_get_format_bytes(dstFormat) == 1); 2441 2442 if (!ctx->_ImageTransferState && 2443 !srcPacking->SwapBytes && 2444 baseInternalFormat == srcFormat && 2445 srcType == GL_BYTE) { 2446 /* simple memcpy path */ 2447 memcpy_texture(ctx, dims, 2448 dstFormat, 2449 dstRowStride, dstSlices, 2450 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2451 srcAddr, srcPacking); 2452 } 2453 else { 2454 /* general path */ 2455 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 2456 baseInternalFormat, 2457 baseFormat, 2458 srcWidth, srcHeight, srcDepth, 2459 srcFormat, srcType, srcAddr, 2460 srcPacking, 2461 ctx->_ImageTransferState); 2462 const GLfloat *src = tempImage; 2463 GLint img, row, col; 2464 if (!tempImage) 2465 return GL_FALSE; 2466 for (img = 0; img < srcDepth; img++) { 2467 GLbyte *dstRow = (GLbyte *) dstSlices[img]; 2468 for (row = 0; row < srcHeight; row++) { 2469 for (col = 0; col < srcWidth; col++) { 2470 dstRow[col] = FLOAT_TO_BYTE_TEX(src[col]); 2471 } 2472 dstRow += dstRowStride; 2473 src += srcWidth; 2474 } 2475 } 2476 free((void *) tempImage); 2477 } 2478 return GL_TRUE; 2479 } 2480 2481 2482 /** 2483 * Store a texture in a signed normalized two-channel 16-bit format. 2484 */ 2485 static GLboolean 2486 _mesa_texstore_snorm88(TEXSTORE_PARAMS) 2487 { 2488 const GLboolean littleEndian = _mesa_little_endian(); 2489 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 2490 2491 ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL88 || 2492 dstFormat == MESA_FORMAT_SIGNED_RG88_REV); 2493 ASSERT(_mesa_get_format_bytes(dstFormat) == 2); 2494 2495 if (!ctx->_ImageTransferState && 2496 !srcPacking->SwapBytes && 2497 baseInternalFormat == srcFormat && 2498 srcType == GL_BYTE && 2499 littleEndian) { 2500 /* simple memcpy path */ 2501 memcpy_texture(ctx, dims, 2502 dstFormat, 2503 dstRowStride, dstSlices, 2504 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2505 srcAddr, srcPacking); 2506 } 2507 else { 2508 /* general path */ 2509 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 2510 baseInternalFormat, 2511 baseFormat, 2512 srcWidth, srcHeight, srcDepth, 2513 srcFormat, srcType, srcAddr, 2514 srcPacking, 2515 ctx->_ImageTransferState); 2516 const GLfloat *src = tempImage; 2517 GLint img, row, col; 2518 if (!tempImage) 2519 return GL_FALSE; 2520 for (img = 0; img < srcDepth; img++) { 2521 GLbyte *dstRow = (GLbyte *) dstSlices[img]; 2522 for (row = 0; row < srcHeight; row++) { 2523 GLbyte *dst = dstRow; 2524 for (col = 0; col < srcWidth; col++) { 2525 dst[0] = FLOAT_TO_BYTE_TEX(src[0]); 2526 dst[1] = FLOAT_TO_BYTE_TEX(src[1]); 2527 src += 2; 2528 dst += 2; 2529 } 2530 dstRow += dstRowStride; 2531 } 2532 } 2533 free((void *) tempImage); 2534 } 2535 return GL_TRUE; 2536 } 2537 2538 /* Texstore for signed R16, A16, L16, I16. */ 2539 static GLboolean 2540 _mesa_texstore_snorm16(TEXSTORE_PARAMS) 2541 { 2542 const GLboolean littleEndian = _mesa_little_endian(); 2543 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 2544 2545 ASSERT(dstFormat == MESA_FORMAT_SIGNED_R16 || 2546 dstFormat == MESA_FORMAT_SIGNED_A16 || 2547 dstFormat == MESA_FORMAT_SIGNED_L16 || 2548 dstFormat == MESA_FORMAT_SIGNED_I16); 2549 ASSERT(_mesa_get_format_bytes(dstFormat) == 2); 2550 2551 if (!ctx->_ImageTransferState && 2552 !srcPacking->SwapBytes && 2553 baseInternalFormat == srcFormat && 2554 srcType == GL_SHORT && 2555 littleEndian) { 2556 /* simple memcpy path */ 2557 memcpy_texture(ctx, dims, 2558 dstFormat, 2559 dstRowStride, dstSlices, 2560 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2561 srcAddr, srcPacking); 2562 } 2563 else { 2564 /* general path */ 2565 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 2566 baseInternalFormat, 2567 baseFormat, 2568 srcWidth, srcHeight, srcDepth, 2569 srcFormat, srcType, srcAddr, 2570 srcPacking, 2571 ctx->_ImageTransferState); 2572 const GLfloat *src = tempImage; 2573 GLint img, row, col; 2574 if (!tempImage) 2575 return GL_FALSE; 2576 for (img = 0; img < srcDepth; img++) { 2577 GLubyte *dstRow = dstSlices[img]; 2578 for (row = 0; row < srcHeight; row++) { 2579 GLshort *dstUS = (GLshort *) dstRow; 2580 for (col = 0; col < srcWidth; col++) { 2581 GLushort r; 2582 2583 UNCLAMPED_FLOAT_TO_SHORT(r, src[0]); 2584 dstUS[col] = r; 2585 src += 1; 2586 } 2587 dstRow += dstRowStride; 2588 } 2589 } 2590 free((void *) tempImage); 2591 } 2592 return GL_TRUE; 2593 } 2594 2595 /** 2596 * Do texstore for 2-channel, 16-bit/channel, signed normalized formats. 2597 */ 2598 static GLboolean 2599 _mesa_texstore_snorm1616(TEXSTORE_PARAMS) 2600 { 2601 const GLboolean littleEndian = _mesa_little_endian(); 2602 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 2603 2604 ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL1616 || 2605 dstFormat == MESA_FORMAT_SIGNED_GR1616); 2606 ASSERT(_mesa_get_format_bytes(dstFormat) == 4); 2607 2608 if (!ctx->_ImageTransferState && 2609 !srcPacking->SwapBytes && 2610 baseInternalFormat == srcFormat && 2611 srcType == GL_SHORT && 2612 littleEndian) { 2613 /* simple memcpy path */ 2614 memcpy_texture(ctx, dims, 2615 dstFormat, 2616 dstRowStride, dstSlices, 2617 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2618 srcAddr, srcPacking); 2619 } 2620 else { 2621 /* general path */ 2622 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 2623 baseInternalFormat, 2624 baseFormat, 2625 srcWidth, srcHeight, srcDepth, 2626 srcFormat, srcType, srcAddr, 2627 srcPacking, 2628 ctx->_ImageTransferState); 2629 const GLfloat *src = tempImage; 2630 GLint img, row, col; 2631 if (!tempImage) 2632 return GL_FALSE; 2633 for (img = 0; img < srcDepth; img++) { 2634 GLubyte *dstRow = dstSlices[img]; 2635 for (row = 0; row < srcHeight; row++) { 2636 GLshort *dst = (GLshort *) dstRow; 2637 for (col = 0; col < srcWidth; col++) { 2638 GLushort l, a; 2639 2640 UNCLAMPED_FLOAT_TO_SHORT(l, src[0]); 2641 UNCLAMPED_FLOAT_TO_SHORT(a, src[1]); 2642 dst[0] = l; 2643 dst[1] = a; 2644 src += 2; 2645 dst += 2; 2646 } 2647 dstRow += dstRowStride; 2648 } 2649 } 2650 free((void *) tempImage); 2651 } 2652 return GL_TRUE; 2653 } 2654 2655 /** 2656 * Store a texture in MESA_FORMAT_SIGNED_RGBX8888. 2657 */ 2658 static GLboolean 2659 _mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS) 2660 { 2661 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 2662 2663 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBX8888); 2664 ASSERT(_mesa_get_format_bytes(dstFormat) == 4); 2665 2666 { 2667 /* general path */ 2668 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 2669 baseInternalFormat, 2670 baseFormat, 2671 srcWidth, srcHeight, srcDepth, 2672 srcFormat, srcType, srcAddr, 2673 srcPacking, 2674 ctx->_ImageTransferState); 2675 const GLfloat *srcRow = tempImage; 2676 GLint img, row, col; 2677 if (!tempImage) 2678 return GL_FALSE; 2679 for (img = 0; img < srcDepth; img++) { 2680 GLbyte *dstRow = (GLbyte *) dstSlices[img]; 2681 for (row = 0; row < srcHeight; row++) { 2682 GLbyte *dst = dstRow; 2683 for (col = 0; col < srcWidth; col++) { 2684 dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); 2685 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); 2686 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); 2687 dst[0] = 127; 2688 srcRow += 3; 2689 dst += 4; 2690 } 2691 dstRow += dstRowStride; 2692 } 2693 } 2694 free((void *) tempImage); 2695 } 2696 return GL_TRUE; 2697 } 2698 2699 2700 2701 /** 2702 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or 2703 * MESA_FORMAT_SIGNED_RGBA8888_REV 2704 */ 2705 static GLboolean 2706 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS) 2707 { 2708 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 2709 2710 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBA8888 || 2711 dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV); 2712 ASSERT(_mesa_get_format_bytes(dstFormat) == 4); 2713 2714 if (!ctx->_ImageTransferState && 2715 baseInternalFormat == GL_RGBA && 2716 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 2717 srcPacking->SwapBytes)) { 2718 /* simple memcpy path */ 2719 memcpy_texture(ctx, dims, 2720 dstFormat, 2721 dstRowStride, dstSlices, 2722 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2723 srcAddr, srcPacking); 2724 } 2725 else { 2726 /* general path */ 2727 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 2728 baseInternalFormat, 2729 baseFormat, 2730 srcWidth, srcHeight, srcDepth, 2731 srcFormat, srcType, srcAddr, 2732 srcPacking, 2733 ctx->_ImageTransferState); 2734 const GLfloat *srcRow = tempImage; 2735 GLint img, row, col; 2736 if (!tempImage) 2737 return GL_FALSE; 2738 for (img = 0; img < srcDepth; img++) { 2739 GLbyte *dstRow = (GLbyte *) dstSlices[img]; 2740 for (row = 0; row < srcHeight; row++) { 2741 GLbyte *dst = dstRow; 2742 if (dstFormat == MESA_FORMAT_SIGNED_RGBA8888) { 2743 for (col = 0; col < srcWidth; col++) { 2744 dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); 2745 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); 2746 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); 2747 dst[0] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]); 2748 srcRow += 4; 2749 dst += 4; 2750 } 2751 } 2752 else { 2753 for (col = 0; col < srcWidth; col++) { 2754 dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]); 2755 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]); 2756 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]); 2757 dst[3] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]); 2758 srcRow += 4; 2759 dst += 4; 2760 } 2761 } 2762 dstRow += dstRowStride; 2763 } 2764 } 2765 free((void *) tempImage); 2766 } 2767 return GL_TRUE; 2768 } 2769 2770 2771 /** 2772 * Store a combined depth/stencil texture image. 2773 */ 2774 static GLboolean 2775 _mesa_texstore_z24_s8(TEXSTORE_PARAMS) 2776 { 2777 const GLuint depthScale = 0xffffff; 2778 const GLint srcRowStride 2779 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 2780 GLint img, row; 2781 2782 ASSERT(dstFormat == MESA_FORMAT_Z24_S8); 2783 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || 2784 srcFormat == GL_DEPTH_COMPONENT || 2785 srcFormat == GL_STENCIL_INDEX); 2786 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT); 2787 2788 if (srcFormat == GL_DEPTH_STENCIL && ctx->Pixel.DepthScale == 1.0f && 2789 ctx->Pixel.DepthBias == 0.0f && 2790 !srcPacking->SwapBytes) { 2791 /* simple path */ 2792 memcpy_texture(ctx, dims, 2793 dstFormat, 2794 dstRowStride, dstSlices, 2795 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2796 srcAddr, srcPacking); 2797 } 2798 else if (srcFormat == GL_DEPTH_COMPONENT || 2799 srcFormat == GL_STENCIL_INDEX) { 2800 GLuint *depth = (GLuint *) malloc(srcWidth * sizeof(GLuint)); 2801 GLubyte *stencil = (GLubyte *) malloc(srcWidth * sizeof(GLubyte)); 2802 2803 if (!depth || !stencil) { 2804 free(depth); 2805 free(stencil); 2806 return GL_FALSE; 2807 } 2808 2809 /* In case we only upload depth we need to preserve the stencil */ 2810 for (img = 0; img < srcDepth; img++) { 2811 GLuint *dstRow = (GLuint *) dstSlices[img]; 2812 const GLubyte *src 2813 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, 2814 srcWidth, srcHeight, 2815 srcFormat, srcType, 2816 img, 0, 0); 2817 for (row = 0; row < srcHeight; row++) { 2818 GLint i; 2819 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE; 2820 2821 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */ 2822 keepstencil = GL_TRUE; 2823 } 2824 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */ 2825 keepdepth = GL_TRUE; 2826 } 2827 2828 if (keepdepth == GL_FALSE) 2829 /* the 24 depth bits will be in the low position: */ 2830 _mesa_unpack_depth_span(ctx, srcWidth, 2831 GL_UNSIGNED_INT, /* dst type */ 2832 keepstencil ? depth : dstRow, /* dst addr */ 2833 depthScale, 2834 srcType, src, srcPacking); 2835 2836 if (keepstencil == GL_FALSE) 2837 /* get the 8-bit stencil values */ 2838 _mesa_unpack_stencil_span(ctx, srcWidth, 2839 GL_UNSIGNED_BYTE, /* dst type */ 2840 stencil, /* dst addr */ 2841 srcType, src, srcPacking, 2842 ctx->_ImageTransferState); 2843 2844 for (i = 0; i < srcWidth; i++) { 2845 if (keepstencil) 2846 dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF); 2847 else 2848 dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF); 2849 } 2850 2851 src += srcRowStride; 2852 dstRow += dstRowStride / sizeof(GLuint); 2853 } 2854 } 2855 2856 free(depth); 2857 free(stencil); 2858 } 2859 return GL_TRUE; 2860 } 2861 2862 2863 /** 2864 * Store a combined depth/stencil texture image. 2865 */ 2866 static GLboolean 2867 _mesa_texstore_s8_z24(TEXSTORE_PARAMS) 2868 { 2869 const GLuint depthScale = 0xffffff; 2870 const GLint srcRowStride 2871 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 2872 GLint img, row; 2873 GLuint *depth; 2874 GLubyte *stencil; 2875 2876 ASSERT(dstFormat == MESA_FORMAT_S8_Z24); 2877 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || 2878 srcFormat == GL_DEPTH_COMPONENT || 2879 srcFormat == GL_STENCIL_INDEX); 2880 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || 2881 srcType == GL_UNSIGNED_INT_24_8_EXT); 2882 2883 depth = (GLuint *) malloc(srcWidth * sizeof(GLuint)); 2884 stencil = (GLubyte *) malloc(srcWidth * sizeof(GLubyte)); 2885 2886 if (!depth || !stencil) { 2887 free(depth); 2888 free(stencil); 2889 return GL_FALSE; 2890 } 2891 2892 for (img = 0; img < srcDepth; img++) { 2893 GLuint *dstRow = (GLuint *) dstSlices[img]; 2894 const GLubyte *src 2895 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, 2896 srcWidth, srcHeight, 2897 srcFormat, srcType, 2898 img, 0, 0); 2899 for (row = 0; row < srcHeight; row++) { 2900 GLint i; 2901 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE; 2902 2903 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */ 2904 keepstencil = GL_TRUE; 2905 } 2906 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */ 2907 keepdepth = GL_TRUE; 2908 } 2909 2910 if (keepdepth == GL_FALSE) 2911 /* the 24 depth bits will be in the low position: */ 2912 _mesa_unpack_depth_span(ctx, srcWidth, 2913 GL_UNSIGNED_INT, /* dst type */ 2914 keepstencil ? depth : dstRow, /* dst addr */ 2915 depthScale, 2916 srcType, src, srcPacking); 2917 2918 if (keepstencil == GL_FALSE) 2919 /* get the 8-bit stencil values */ 2920 _mesa_unpack_stencil_span(ctx, srcWidth, 2921 GL_UNSIGNED_BYTE, /* dst type */ 2922 stencil, /* dst addr */ 2923 srcType, src, srcPacking, 2924 ctx->_ImageTransferState); 2925 2926 /* merge stencil values into depth values */ 2927 for (i = 0; i < srcWidth; i++) { 2928 if (keepstencil) 2929 dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000); 2930 else 2931 dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24); 2932 2933 } 2934 src += srcRowStride; 2935 dstRow += dstRowStride / sizeof(GLuint); 2936 } 2937 } 2938 2939 free(depth); 2940 free(stencil); 2941 2942 return GL_TRUE; 2943 } 2944 2945 2946 /** 2947 * Store simple 8-bit/value stencil texture data. 2948 */ 2949 static GLboolean 2950 _mesa_texstore_s8(TEXSTORE_PARAMS) 2951 { 2952 ASSERT(dstFormat == MESA_FORMAT_S8); 2953 ASSERT(srcFormat == GL_STENCIL_INDEX); 2954 2955 if (!ctx->_ImageTransferState && 2956 !srcPacking->SwapBytes && 2957 baseInternalFormat == srcFormat && 2958 srcType == GL_UNSIGNED_BYTE) { 2959 /* simple memcpy path */ 2960 memcpy_texture(ctx, dims, 2961 dstFormat, 2962 dstRowStride, dstSlices, 2963 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 2964 srcAddr, srcPacking); 2965 } 2966 else { 2967 const GLint srcRowStride 2968 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); 2969 GLint img, row; 2970 GLubyte *stencil = (GLubyte *) malloc(srcWidth * sizeof(GLubyte)); 2971 2972 if (!stencil) 2973 return GL_FALSE; 2974 2975 for (img = 0; img < srcDepth; img++) { 2976 GLubyte *dstRow = dstSlices[img]; 2977 const GLubyte *src 2978 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, 2979 srcWidth, srcHeight, 2980 srcFormat, srcType, 2981 img, 0, 0); 2982 for (row = 0; row < srcHeight; row++) { 2983 GLint i; 2984 2985 /* get the 8-bit stencil values */ 2986 _mesa_unpack_stencil_span(ctx, srcWidth, 2987 GL_UNSIGNED_BYTE, /* dst type */ 2988 stencil, /* dst addr */ 2989 srcType, src, srcPacking, 2990 ctx->_ImageTransferState); 2991 /* merge stencil values into depth values */ 2992 for (i = 0; i < srcWidth; i++) 2993 dstRow[i] = stencil[i]; 2994 2995 src += srcRowStride; 2996 dstRow += dstRowStride / sizeof(GLubyte); 2997 } 2998 } 2999 3000 free(stencil); 3001 } 3002 3003 return GL_TRUE; 3004 } 3005 3006 3007 /** 3008 * Store an image in any of the formats: 3009 * _mesa_texformat_rgba_float32 3010 * _mesa_texformat_rgb_float32 3011 * _mesa_texformat_alpha_float32 3012 * _mesa_texformat_luminance_float32 3013 * _mesa_texformat_luminance_alpha_float32 3014 * _mesa_texformat_intensity_float32 3015 */ 3016 static GLboolean 3017 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS) 3018 { 3019 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3020 const GLint components = _mesa_components_in_format(baseFormat); 3021 3022 ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 || 3023 dstFormat == MESA_FORMAT_RGB_FLOAT32 || 3024 dstFormat == MESA_FORMAT_ALPHA_FLOAT32 || 3025 dstFormat == MESA_FORMAT_LUMINANCE_FLOAT32 || 3026 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 || 3027 dstFormat == MESA_FORMAT_INTENSITY_FLOAT32 || 3028 dstFormat == MESA_FORMAT_R_FLOAT32 || 3029 dstFormat == MESA_FORMAT_RG_FLOAT32); 3030 ASSERT(baseInternalFormat == GL_RGBA || 3031 baseInternalFormat == GL_RGB || 3032 baseInternalFormat == GL_ALPHA || 3033 baseInternalFormat == GL_LUMINANCE || 3034 baseInternalFormat == GL_LUMINANCE_ALPHA || 3035 baseInternalFormat == GL_INTENSITY || 3036 baseInternalFormat == GL_RED || 3037 baseInternalFormat == GL_RG); 3038 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLfloat)); 3039 3040 if (!ctx->_ImageTransferState && 3041 !srcPacking->SwapBytes && 3042 baseInternalFormat == srcFormat && 3043 baseInternalFormat == baseFormat && 3044 srcType == GL_FLOAT) { 3045 /* simple memcpy path */ 3046 memcpy_texture(ctx, dims, 3047 dstFormat, 3048 dstRowStride, dstSlices, 3049 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3050 srcAddr, srcPacking); 3051 } 3052 else { 3053 /* general path */ 3054 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 3055 baseInternalFormat, 3056 baseFormat, 3057 srcWidth, srcHeight, srcDepth, 3058 srcFormat, srcType, srcAddr, 3059 srcPacking, 3060 ctx->_ImageTransferState); 3061 const GLfloat *srcRow = tempImage; 3062 GLint bytesPerRow; 3063 GLint img, row; 3064 if (!tempImage) 3065 return GL_FALSE; 3066 bytesPerRow = srcWidth * components * sizeof(GLfloat); 3067 for (img = 0; img < srcDepth; img++) { 3068 GLubyte *dstRow = dstSlices[img]; 3069 for (row = 0; row < srcHeight; row++) { 3070 memcpy(dstRow, srcRow, bytesPerRow); 3071 dstRow += dstRowStride; 3072 srcRow += srcWidth * components; 3073 } 3074 } 3075 3076 free((void *) tempImage); 3077 } 3078 return GL_TRUE; 3079 } 3080 3081 3082 3083 /** 3084 * As above, but store 16-bit floats. 3085 */ 3086 static GLboolean 3087 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS) 3088 { 3089 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3090 const GLint components = _mesa_components_in_format(baseFormat); 3091 3092 ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 || 3093 dstFormat == MESA_FORMAT_RGB_FLOAT16 || 3094 dstFormat == MESA_FORMAT_ALPHA_FLOAT16 || 3095 dstFormat == MESA_FORMAT_LUMINANCE_FLOAT16 || 3096 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 || 3097 dstFormat == MESA_FORMAT_INTENSITY_FLOAT16 || 3098 dstFormat == MESA_FORMAT_R_FLOAT16 || 3099 dstFormat == MESA_FORMAT_RG_FLOAT16); 3100 ASSERT(baseInternalFormat == GL_RGBA || 3101 baseInternalFormat == GL_RGB || 3102 baseInternalFormat == GL_ALPHA || 3103 baseInternalFormat == GL_LUMINANCE || 3104 baseInternalFormat == GL_LUMINANCE_ALPHA || 3105 baseInternalFormat == GL_INTENSITY || 3106 baseInternalFormat == GL_RED || 3107 baseInternalFormat == GL_RG); 3108 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLhalfARB)); 3109 3110 if (!ctx->_ImageTransferState && 3111 !srcPacking->SwapBytes && 3112 baseInternalFormat == srcFormat && 3113 baseInternalFormat == baseFormat && 3114 srcType == GL_HALF_FLOAT_ARB) { 3115 /* simple memcpy path */ 3116 memcpy_texture(ctx, dims, 3117 dstFormat, 3118 dstRowStride, dstSlices, 3119 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3120 srcAddr, srcPacking); 3121 } 3122 else { 3123 /* general path */ 3124 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 3125 baseInternalFormat, 3126 baseFormat, 3127 srcWidth, srcHeight, srcDepth, 3128 srcFormat, srcType, srcAddr, 3129 srcPacking, 3130 ctx->_ImageTransferState); 3131 const GLfloat *src = tempImage; 3132 GLint img, row; 3133 if (!tempImage) 3134 return GL_FALSE; 3135 for (img = 0; img < srcDepth; img++) { 3136 GLubyte *dstRow = dstSlices[img]; 3137 for (row = 0; row < srcHeight; row++) { 3138 GLhalfARB *dstTexel = (GLhalfARB *) dstRow; 3139 GLint i; 3140 for (i = 0; i < srcWidth * components; i++) { 3141 dstTexel[i] = _mesa_float_to_half(src[i]); 3142 } 3143 dstRow += dstRowStride; 3144 src += srcWidth * components; 3145 } 3146 } 3147 3148 free((void *) tempImage); 3149 } 3150 return GL_TRUE; 3151 } 3152 3153 3154 /* non-normalized, signed int8 */ 3155 static GLboolean 3156 _mesa_texstore_rgba_int8(TEXSTORE_PARAMS) 3157 { 3158 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3159 const GLint components = _mesa_components_in_format(baseFormat); 3160 3161 ASSERT(dstFormat == MESA_FORMAT_R_INT8 || 3162 dstFormat == MESA_FORMAT_RG_INT8 || 3163 dstFormat == MESA_FORMAT_RGB_INT8 || 3164 dstFormat == MESA_FORMAT_RGBA_INT8 || 3165 dstFormat == MESA_FORMAT_ALPHA_INT8 || 3166 dstFormat == MESA_FORMAT_INTENSITY_INT8 || 3167 dstFormat == MESA_FORMAT_LUMINANCE_INT8 || 3168 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT8); 3169 ASSERT(baseInternalFormat == GL_RGBA || 3170 baseInternalFormat == GL_RGB || 3171 baseInternalFormat == GL_RG || 3172 baseInternalFormat == GL_RED || 3173 baseInternalFormat == GL_ALPHA || 3174 baseInternalFormat == GL_LUMINANCE || 3175 baseInternalFormat == GL_LUMINANCE_ALPHA || 3176 baseInternalFormat == GL_INTENSITY); 3177 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLbyte)); 3178 3179 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply 3180 * to integer formats. 3181 */ 3182 if (!srcPacking->SwapBytes && 3183 baseInternalFormat == srcFormat && 3184 srcType == GL_BYTE) { 3185 /* simple memcpy path */ 3186 memcpy_texture(ctx, dims, 3187 dstFormat, 3188 dstRowStride, dstSlices, 3189 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3190 srcAddr, srcPacking); 3191 } 3192 else { 3193 /* general path */ 3194 const GLuint *tempImage = make_temp_uint_image(ctx, dims, 3195 baseInternalFormat, 3196 baseFormat, 3197 srcWidth, srcHeight, srcDepth, 3198 srcFormat, srcType, 3199 srcAddr, 3200 srcPacking); 3201 const GLuint *src = tempImage; 3202 GLint img, row; 3203 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); 3204 if (!tempImage) 3205 return GL_FALSE; 3206 for (img = 0; img < srcDepth; img++) { 3207 GLubyte *dstRow = dstSlices[img]; 3208 for (row = 0; row < srcHeight; row++) { 3209 GLbyte *dstTexel = (GLbyte *) dstRow; 3210 GLint i; 3211 if (is_unsigned) { 3212 for (i = 0; i < srcWidth * components; i++) { 3213 dstTexel[i] = (GLbyte) MIN2(src[i], 0x7f); 3214 } 3215 } else { 3216 for (i = 0; i < srcWidth * components; i++) { 3217 dstTexel[i] = (GLbyte) CLAMP((GLint) src[i], -0x80, 0x7f); 3218 } 3219 } 3220 dstRow += dstRowStride; 3221 src += srcWidth * components; 3222 } 3223 } 3224 3225 free((void *) tempImage); 3226 } 3227 return GL_TRUE; 3228 } 3229 3230 3231 /* non-normalized, signed int16 */ 3232 static GLboolean 3233 _mesa_texstore_rgba_int16(TEXSTORE_PARAMS) 3234 { 3235 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3236 const GLint components = _mesa_components_in_format(baseFormat); 3237 3238 ASSERT(dstFormat == MESA_FORMAT_R_INT16 || 3239 dstFormat == MESA_FORMAT_RG_INT16 || 3240 dstFormat == MESA_FORMAT_RGB_INT16 || 3241 dstFormat == MESA_FORMAT_RGBA_INT16 || 3242 dstFormat == MESA_FORMAT_ALPHA_INT16 || 3243 dstFormat == MESA_FORMAT_LUMINANCE_INT16 || 3244 dstFormat == MESA_FORMAT_INTENSITY_INT16 || 3245 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16); 3246 ASSERT(baseInternalFormat == GL_RGBA || 3247 baseInternalFormat == GL_RGB || 3248 baseInternalFormat == GL_RG || 3249 baseInternalFormat == GL_RED || 3250 baseInternalFormat == GL_ALPHA || 3251 baseInternalFormat == GL_LUMINANCE || 3252 baseInternalFormat == GL_LUMINANCE_ALPHA || 3253 baseInternalFormat == GL_INTENSITY); 3254 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLshort)); 3255 3256 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply 3257 * to integer formats. 3258 */ 3259 if (!srcPacking->SwapBytes && 3260 baseInternalFormat == srcFormat && 3261 srcType == GL_SHORT) { 3262 /* simple memcpy path */ 3263 memcpy_texture(ctx, dims, 3264 dstFormat, 3265 dstRowStride, dstSlices, 3266 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3267 srcAddr, srcPacking); 3268 } 3269 else { 3270 /* general path */ 3271 const GLuint *tempImage = make_temp_uint_image(ctx, dims, 3272 baseInternalFormat, 3273 baseFormat, 3274 srcWidth, srcHeight, srcDepth, 3275 srcFormat, srcType, 3276 srcAddr, 3277 srcPacking); 3278 const GLuint *src = tempImage; 3279 GLint img, row; 3280 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); 3281 if (!tempImage) 3282 return GL_FALSE; 3283 for (img = 0; img < srcDepth; img++) { 3284 GLubyte *dstRow = dstSlices[img]; 3285 for (row = 0; row < srcHeight; row++) { 3286 GLshort *dstTexel = (GLshort *) dstRow; 3287 GLint i; 3288 if (is_unsigned) { 3289 for (i = 0; i < srcWidth * components; i++) { 3290 dstTexel[i] = (GLshort) MIN2(src[i], 0x7fff); 3291 } 3292 } else { 3293 for (i = 0; i < srcWidth * components; i++) { 3294 dstTexel[i] = (GLshort)CLAMP((GLint) src[i], -0x8000, 0x7fff); 3295 } 3296 } 3297 dstRow += dstRowStride; 3298 src += srcWidth * components; 3299 } 3300 } 3301 3302 free((void *) tempImage); 3303 } 3304 return GL_TRUE; 3305 } 3306 3307 3308 /* non-normalized, signed int32 */ 3309 static GLboolean 3310 _mesa_texstore_rgba_int32(TEXSTORE_PARAMS) 3311 { 3312 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3313 const GLint components = _mesa_components_in_format(baseFormat); 3314 3315 ASSERT(dstFormat == MESA_FORMAT_R_INT32 || 3316 dstFormat == MESA_FORMAT_RG_INT32 || 3317 dstFormat == MESA_FORMAT_RGB_INT32 || 3318 dstFormat == MESA_FORMAT_RGBA_INT32 || 3319 dstFormat == MESA_FORMAT_ALPHA_INT32 || 3320 dstFormat == MESA_FORMAT_INTENSITY_INT32 || 3321 dstFormat == MESA_FORMAT_LUMINANCE_INT32 || 3322 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32); 3323 ASSERT(baseInternalFormat == GL_RGBA || 3324 baseInternalFormat == GL_RGB || 3325 baseInternalFormat == GL_RG || 3326 baseInternalFormat == GL_RED || 3327 baseInternalFormat == GL_ALPHA || 3328 baseInternalFormat == GL_LUMINANCE || 3329 baseInternalFormat == GL_LUMINANCE_ALPHA || 3330 baseInternalFormat == GL_INTENSITY); 3331 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLint)); 3332 3333 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply 3334 * to integer formats. 3335 */ 3336 if (!srcPacking->SwapBytes && 3337 baseInternalFormat == srcFormat && 3338 srcType == GL_INT) { 3339 /* simple memcpy path */ 3340 memcpy_texture(ctx, dims, 3341 dstFormat, 3342 dstRowStride, dstSlices, 3343 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3344 srcAddr, srcPacking); 3345 } 3346 else { 3347 /* general path */ 3348 const GLuint *tempImage = make_temp_uint_image(ctx, dims, 3349 baseInternalFormat, 3350 baseFormat, 3351 srcWidth, srcHeight, srcDepth, 3352 srcFormat, srcType, 3353 srcAddr, 3354 srcPacking); 3355 const GLuint *src = tempImage; 3356 GLint img, row; 3357 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); 3358 if (!tempImage) 3359 return GL_FALSE; 3360 for (img = 0; img < srcDepth; img++) { 3361 GLubyte *dstRow = dstSlices[img]; 3362 for (row = 0; row < srcHeight; row++) { 3363 GLint *dstTexel = (GLint *) dstRow; 3364 GLint i; 3365 if (is_unsigned) { 3366 for (i = 0; i < srcWidth * components; i++) { 3367 dstTexel[i] = (GLint) MIN2(src[i], 0x7fffffff); 3368 } 3369 } else { 3370 for (i = 0; i < srcWidth * components; i++) { 3371 dstTexel[i] = (GLint) src[i]; 3372 } 3373 } 3374 dstRow += dstRowStride; 3375 src += srcWidth * components; 3376 } 3377 } 3378 3379 free((void *) tempImage); 3380 } 3381 return GL_TRUE; 3382 } 3383 3384 3385 /* non-normalized, unsigned int8 */ 3386 static GLboolean 3387 _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS) 3388 { 3389 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3390 const GLint components = _mesa_components_in_format(baseFormat); 3391 3392 ASSERT(dstFormat == MESA_FORMAT_R_UINT8 || 3393 dstFormat == MESA_FORMAT_RG_UINT8 || 3394 dstFormat == MESA_FORMAT_RGB_UINT8 || 3395 dstFormat == MESA_FORMAT_RGBA_UINT8 || 3396 dstFormat == MESA_FORMAT_ALPHA_UINT8 || 3397 dstFormat == MESA_FORMAT_INTENSITY_UINT8 || 3398 dstFormat == MESA_FORMAT_LUMINANCE_UINT8 || 3399 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT8); 3400 ASSERT(baseInternalFormat == GL_RGBA || 3401 baseInternalFormat == GL_RGB || 3402 baseInternalFormat == GL_RG || 3403 baseInternalFormat == GL_RED || 3404 baseInternalFormat == GL_ALPHA || 3405 baseInternalFormat == GL_LUMINANCE || 3406 baseInternalFormat == GL_LUMINANCE_ALPHA || 3407 baseInternalFormat == GL_INTENSITY); 3408 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLubyte)); 3409 3410 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply 3411 * to integer formats. 3412 */ 3413 if (!srcPacking->SwapBytes && 3414 baseInternalFormat == srcFormat && 3415 srcType == GL_UNSIGNED_BYTE) { 3416 /* simple memcpy path */ 3417 memcpy_texture(ctx, dims, 3418 dstFormat, 3419 dstRowStride, dstSlices, 3420 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3421 srcAddr, srcPacking); 3422 } 3423 else { 3424 /* general path */ 3425 const GLuint *tempImage = 3426 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, 3427 srcWidth, srcHeight, srcDepth, 3428 srcFormat, srcType, srcAddr, srcPacking); 3429 const GLuint *src = tempImage; 3430 GLint img, row; 3431 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); 3432 if (!tempImage) 3433 return GL_FALSE; 3434 for (img = 0; img < srcDepth; img++) { 3435 GLubyte *dstRow = dstSlices[img]; 3436 for (row = 0; row < srcHeight; row++) { 3437 GLubyte *dstTexel = (GLubyte *) dstRow; 3438 GLint i; 3439 if (is_unsigned) { 3440 for (i = 0; i < srcWidth * components; i++) { 3441 dstTexel[i] = (GLubyte) MIN2(src[i], 0xff); 3442 } 3443 } else { 3444 for (i = 0; i < srcWidth * components; i++) { 3445 dstTexel[i] = (GLubyte) CLAMP((GLint) src[i], 0, 0xff); 3446 } 3447 } 3448 dstRow += dstRowStride; 3449 src += srcWidth * components; 3450 } 3451 } 3452 3453 free((void *) tempImage); 3454 } 3455 return GL_TRUE; 3456 } 3457 3458 3459 /* non-normalized, unsigned int16 */ 3460 static GLboolean 3461 _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS) 3462 { 3463 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3464 const GLint components = _mesa_components_in_format(baseFormat); 3465 3466 ASSERT(dstFormat == MESA_FORMAT_R_UINT16 || 3467 dstFormat == MESA_FORMAT_RG_UINT16 || 3468 dstFormat == MESA_FORMAT_RGB_UINT16 || 3469 dstFormat == MESA_FORMAT_RGBA_UINT16 || 3470 dstFormat == MESA_FORMAT_ALPHA_UINT16 || 3471 dstFormat == MESA_FORMAT_INTENSITY_UINT16 || 3472 dstFormat == MESA_FORMAT_LUMINANCE_UINT16 || 3473 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT16); 3474 ASSERT(baseInternalFormat == GL_RGBA || 3475 baseInternalFormat == GL_RGB || 3476 baseInternalFormat == GL_RG || 3477 baseInternalFormat == GL_RED || 3478 baseInternalFormat == GL_ALPHA || 3479 baseInternalFormat == GL_LUMINANCE || 3480 baseInternalFormat == GL_LUMINANCE_ALPHA || 3481 baseInternalFormat == GL_INTENSITY); 3482 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLushort)); 3483 3484 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply 3485 * to integer formats. 3486 */ 3487 if (!srcPacking->SwapBytes && 3488 baseInternalFormat == srcFormat && 3489 srcType == GL_UNSIGNED_SHORT) { 3490 /* simple memcpy path */ 3491 memcpy_texture(ctx, dims, 3492 dstFormat, 3493 dstRowStride, dstSlices, 3494 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3495 srcAddr, srcPacking); 3496 } 3497 else { 3498 /* general path */ 3499 const GLuint *tempImage = 3500 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, 3501 srcWidth, srcHeight, srcDepth, 3502 srcFormat, srcType, srcAddr, srcPacking); 3503 const GLuint *src = tempImage; 3504 GLint img, row; 3505 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); 3506 if (!tempImage) 3507 return GL_FALSE; 3508 for (img = 0; img < srcDepth; img++) { 3509 GLubyte *dstRow = dstSlices[img]; 3510 for (row = 0; row < srcHeight; row++) { 3511 GLushort *dstTexel = (GLushort *) dstRow; 3512 GLint i; 3513 if (is_unsigned) { 3514 for (i = 0; i < srcWidth * components; i++) { 3515 dstTexel[i] = (GLushort) MIN2(src[i], 0xffff); 3516 } 3517 } else { 3518 for (i = 0; i < srcWidth * components; i++) { 3519 dstTexel[i] = (GLushort) CLAMP((GLint) src[i], 0, 0xffff); 3520 } 3521 } 3522 dstRow += dstRowStride; 3523 src += srcWidth * components; 3524 } 3525 } 3526 3527 free((void *) tempImage); 3528 } 3529 return GL_TRUE; 3530 } 3531 3532 3533 /* non-normalized, unsigned int32 */ 3534 static GLboolean 3535 _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS) 3536 { 3537 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3538 const GLint components = _mesa_components_in_format(baseFormat); 3539 3540 ASSERT(dstFormat == MESA_FORMAT_R_UINT32 || 3541 dstFormat == MESA_FORMAT_RG_UINT32 || 3542 dstFormat == MESA_FORMAT_RGB_UINT32 || 3543 dstFormat == MESA_FORMAT_RGBA_UINT32 || 3544 dstFormat == MESA_FORMAT_ALPHA_UINT32 || 3545 dstFormat == MESA_FORMAT_INTENSITY_UINT32 || 3546 dstFormat == MESA_FORMAT_LUMINANCE_UINT32 || 3547 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT32); 3548 ASSERT(baseInternalFormat == GL_RGBA || 3549 baseInternalFormat == GL_RGB || 3550 baseInternalFormat == GL_RG || 3551 baseInternalFormat == GL_RED || 3552 baseInternalFormat == GL_ALPHA || 3553 baseInternalFormat == GL_LUMINANCE || 3554 baseInternalFormat == GL_LUMINANCE_ALPHA || 3555 baseInternalFormat == GL_INTENSITY); 3556 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLuint)); 3557 3558 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply 3559 * to integer formats. 3560 */ 3561 if (!srcPacking->SwapBytes && 3562 baseInternalFormat == srcFormat && 3563 srcType == GL_UNSIGNED_INT) { 3564 /* simple memcpy path */ 3565 memcpy_texture(ctx, dims, 3566 dstFormat, 3567 dstRowStride, dstSlices, 3568 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3569 srcAddr, srcPacking); 3570 } 3571 else { 3572 /* general path */ 3573 const GLuint *tempImage = 3574 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, 3575 srcWidth, srcHeight, srcDepth, 3576 srcFormat, srcType, srcAddr, srcPacking); 3577 const GLuint *src = tempImage; 3578 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); 3579 GLint img, row; 3580 if (!tempImage) 3581 return GL_FALSE; 3582 for (img = 0; img < srcDepth; img++) { 3583 GLubyte *dstRow = dstSlices[img]; 3584 for (row = 0; row < srcHeight; row++) { 3585 GLuint *dstTexel = (GLuint *) dstRow; 3586 GLint i; 3587 if (is_unsigned) { 3588 for (i = 0; i < srcWidth * components; i++) { 3589 dstTexel[i] = src[i]; 3590 } 3591 } else { 3592 for (i = 0; i < srcWidth * components; i++) { 3593 dstTexel[i] = MAX2((GLint) src[i], 0); 3594 } 3595 } 3596 dstRow += dstRowStride; 3597 src += srcWidth * components; 3598 } 3599 } 3600 3601 free((void *) tempImage); 3602 } 3603 return GL_TRUE; 3604 } 3605 3606 3607 3608 3609 #if FEATURE_EXT_texture_sRGB 3610 static GLboolean 3611 _mesa_texstore_srgb8(TEXSTORE_PARAMS) 3612 { 3613 gl_format newDstFormat; 3614 GLboolean k; 3615 3616 ASSERT(dstFormat == MESA_FORMAT_SRGB8); 3617 3618 /* reuse normal rgb texstore code */ 3619 newDstFormat = MESA_FORMAT_RGB888; 3620 3621 k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat, 3622 newDstFormat, 3623 dstRowStride, dstSlices, 3624 srcWidth, srcHeight, srcDepth, 3625 srcFormat, srcType, 3626 srcAddr, srcPacking); 3627 return k; 3628 } 3629 3630 3631 static GLboolean 3632 _mesa_texstore_srgba8(TEXSTORE_PARAMS) 3633 { 3634 gl_format newDstFormat; 3635 GLboolean k; 3636 3637 ASSERT(dstFormat == MESA_FORMAT_SRGBA8); 3638 3639 /* reuse normal rgba texstore code */ 3640 newDstFormat = MESA_FORMAT_RGBA8888; 3641 k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat, 3642 newDstFormat, 3643 dstRowStride, dstSlices, 3644 srcWidth, srcHeight, srcDepth, 3645 srcFormat, srcType, 3646 srcAddr, srcPacking); 3647 return k; 3648 } 3649 3650 3651 static GLboolean 3652 _mesa_texstore_sargb8(TEXSTORE_PARAMS) 3653 { 3654 gl_format newDstFormat; 3655 GLboolean k; 3656 3657 ASSERT(dstFormat == MESA_FORMAT_SARGB8); 3658 3659 /* reuse normal rgba texstore code */ 3660 newDstFormat = MESA_FORMAT_ARGB8888; 3661 3662 k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat, 3663 newDstFormat, 3664 dstRowStride, dstSlices, 3665 srcWidth, srcHeight, srcDepth, 3666 srcFormat, srcType, 3667 srcAddr, srcPacking); 3668 return k; 3669 } 3670 3671 3672 static GLboolean 3673 _mesa_texstore_sl8(TEXSTORE_PARAMS) 3674 { 3675 gl_format newDstFormat; 3676 GLboolean k; 3677 3678 ASSERT(dstFormat == MESA_FORMAT_SL8); 3679 3680 newDstFormat = MESA_FORMAT_L8; 3681 3682 /* _mesa_textore_a8 handles luminance8 too */ 3683 k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat, 3684 newDstFormat, 3685 dstRowStride, dstSlices, 3686 srcWidth, srcHeight, srcDepth, 3687 srcFormat, srcType, 3688 srcAddr, srcPacking); 3689 return k; 3690 } 3691 3692 3693 static GLboolean 3694 _mesa_texstore_sla8(TEXSTORE_PARAMS) 3695 { 3696 gl_format newDstFormat; 3697 GLboolean k; 3698 3699 ASSERT(dstFormat == MESA_FORMAT_SLA8); 3700 3701 /* reuse normal luminance/alpha texstore code */ 3702 newDstFormat = MESA_FORMAT_AL88; 3703 3704 k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat, 3705 newDstFormat, 3706 dstRowStride, dstSlices, 3707 srcWidth, srcHeight, srcDepth, 3708 srcFormat, srcType, 3709 srcAddr, srcPacking); 3710 return k; 3711 } 3712 3713 #else 3714 3715 /* these are used only in texstore_funcs[] below */ 3716 #define _mesa_texstore_srgb8 NULL 3717 #define _mesa_texstore_srgba8 NULL 3718 #define _mesa_texstore_sargb8 NULL 3719 #define _mesa_texstore_sl8 NULL 3720 #define _mesa_texstore_sla8 NULL 3721 3722 #endif /* FEATURE_EXT_texture_sRGB */ 3723 3724 static GLboolean 3725 _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS) 3726 { 3727 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3728 3729 ASSERT(dstFormat == MESA_FORMAT_RGB9_E5_FLOAT); 3730 ASSERT(baseInternalFormat == GL_RGB); 3731 3732 if (!ctx->_ImageTransferState && 3733 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 3734 srcPacking->SwapBytes)) { 3735 /* simple memcpy path */ 3736 memcpy_texture(ctx, dims, 3737 dstFormat, 3738 dstRowStride, dstSlices, 3739 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3740 srcAddr, srcPacking); 3741 } 3742 else { 3743 /* general path */ 3744 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 3745 baseInternalFormat, 3746 baseFormat, 3747 srcWidth, srcHeight, srcDepth, 3748 srcFormat, srcType, srcAddr, 3749 srcPacking, 3750 ctx->_ImageTransferState); 3751 const GLfloat *srcRow = tempImage; 3752 GLint img, row, col; 3753 if (!tempImage) 3754 return GL_FALSE; 3755 for (img = 0; img < srcDepth; img++) { 3756 GLubyte *dstRow = dstSlices[img]; 3757 for (row = 0; row < srcHeight; row++) { 3758 GLuint *dstUI = (GLuint*)dstRow; 3759 for (col = 0; col < srcWidth; col++) { 3760 dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]); 3761 } 3762 dstRow += dstRowStride; 3763 srcRow += srcWidth * 3; 3764 } 3765 } 3766 3767 free((void *) tempImage); 3768 } 3769 return GL_TRUE; 3770 } 3771 3772 static GLboolean 3773 _mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS) 3774 { 3775 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3776 3777 ASSERT(dstFormat == MESA_FORMAT_R11_G11_B10_FLOAT); 3778 ASSERT(baseInternalFormat == GL_RGB); 3779 3780 if (!ctx->_ImageTransferState && 3781 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 3782 srcPacking->SwapBytes)) { 3783 /* simple memcpy path */ 3784 memcpy_texture(ctx, dims, 3785 dstFormat, 3786 dstRowStride, dstSlices, 3787 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3788 srcAddr, srcPacking); 3789 } 3790 else { 3791 /* general path */ 3792 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 3793 baseInternalFormat, 3794 baseFormat, 3795 srcWidth, srcHeight, srcDepth, 3796 srcFormat, srcType, srcAddr, 3797 srcPacking, 3798 ctx->_ImageTransferState); 3799 const GLfloat *srcRow = tempImage; 3800 GLint img, row, col; 3801 if (!tempImage) 3802 return GL_FALSE; 3803 for (img = 0; img < srcDepth; img++) { 3804 GLubyte *dstRow = dstSlices[img]; 3805 for (row = 0; row < srcHeight; row++) { 3806 GLuint *dstUI = (GLuint*)dstRow; 3807 for (col = 0; col < srcWidth; col++) { 3808 dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]); 3809 } 3810 dstRow += dstRowStride; 3811 srcRow += srcWidth * 3; 3812 } 3813 } 3814 3815 free((void *) tempImage); 3816 } 3817 return GL_TRUE; 3818 } 3819 3820 3821 static GLboolean 3822 _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) 3823 { 3824 ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_X24S8); 3825 ASSERT(srcFormat == GL_DEPTH_STENCIL || 3826 srcFormat == GL_DEPTH_COMPONENT || 3827 srcFormat == GL_STENCIL_INDEX); 3828 ASSERT(srcFormat != GL_DEPTH_STENCIL || 3829 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 3830 3831 if (srcFormat == GL_DEPTH_STENCIL && 3832 ctx->Pixel.DepthScale == 1.0f && 3833 ctx->Pixel.DepthBias == 0.0f && 3834 !srcPacking->SwapBytes) { 3835 /* simple path */ 3836 memcpy_texture(ctx, dims, 3837 dstFormat, 3838 dstRowStride, dstSlices, 3839 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3840 srcAddr, srcPacking); 3841 } 3842 else if (srcFormat == GL_DEPTH_COMPONENT || 3843 srcFormat == GL_STENCIL_INDEX) { 3844 GLint img, row; 3845 const GLint srcRowStride 3846 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) 3847 / sizeof(uint64_t); 3848 3849 /* In case we only upload depth we need to preserve the stencil */ 3850 for (img = 0; img < srcDepth; img++) { 3851 uint64_t *dstRow = (uint64_t *) dstSlices[img]; 3852 const uint64_t *src 3853 = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr, 3854 srcWidth, srcHeight, 3855 srcFormat, srcType, 3856 img, 0, 0); 3857 for (row = 0; row < srcHeight; row++) { 3858 /* The unpack functions with: 3859 * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV 3860 * only write their own dword, so the other dword (stencil 3861 * or depth) is preserved. */ 3862 if (srcFormat != GL_STENCIL_INDEX) 3863 _mesa_unpack_depth_span(ctx, srcWidth, 3864 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */ 3865 dstRow, /* dst addr */ 3866 ~0U, srcType, src, srcPacking); 3867 3868 if (srcFormat != GL_DEPTH_COMPONENT) 3869 _mesa_unpack_stencil_span(ctx, srcWidth, 3870 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */ 3871 dstRow, /* dst addr */ 3872 srcType, src, srcPacking, 3873 ctx->_ImageTransferState); 3874 3875 src += srcRowStride; 3876 dstRow += dstRowStride / sizeof(uint64_t); 3877 } 3878 } 3879 } 3880 return GL_TRUE; 3881 } 3882 3883 static GLboolean 3884 _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS) 3885 { 3886 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3887 3888 ASSERT(dstFormat == MESA_FORMAT_ARGB2101010_UINT); 3889 ASSERT(_mesa_get_format_bytes(dstFormat) == 4); 3890 3891 if (baseInternalFormat == GL_RGBA && 3892 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 3893 srcPacking->SwapBytes)) { 3894 /* simple memcpy path */ 3895 memcpy_texture(ctx, dims, 3896 dstFormat, 3897 dstRowStride, dstSlices, 3898 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3899 srcAddr, srcPacking); 3900 } 3901 else { 3902 /* general path */ 3903 const GLuint *tempImage = make_temp_uint_image(ctx, dims, 3904 baseInternalFormat, 3905 baseFormat, 3906 srcWidth, srcHeight, 3907 srcDepth, srcFormat, 3908 srcType, srcAddr, 3909 srcPacking); 3910 const GLuint *src = tempImage; 3911 GLint img, row, col; 3912 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); 3913 if (!tempImage) 3914 return GL_FALSE; 3915 for (img = 0; img < srcDepth; img++) { 3916 GLubyte *dstRow = dstSlices[img]; 3917 3918 for (row = 0; row < srcHeight; row++) { 3919 GLuint *dstUI = (GLuint *) dstRow; 3920 if (is_unsigned) { 3921 for (col = 0; col < srcWidth; col++) { 3922 GLushort a,r,g,b; 3923 r = MIN2(src[RCOMP], 0x3ff); 3924 g = MIN2(src[GCOMP], 0x3ff); 3925 b = MIN2(src[BCOMP], 0x3ff); 3926 a = MIN2(src[ACOMP], 0x003); 3927 dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b); 3928 src += 4; 3929 } 3930 } else { 3931 for (col = 0; col < srcWidth; col++) { 3932 GLushort a,r,g,b; 3933 r = CLAMP((GLint) src[RCOMP], 0, 0x3ff); 3934 g = CLAMP((GLint) src[GCOMP], 0, 0x3ff); 3935 b = CLAMP((GLint) src[BCOMP], 0, 0x3ff); 3936 a = CLAMP((GLint) src[ACOMP], 0, 0x003); 3937 dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b); 3938 src += 4; 3939 } 3940 } 3941 dstRow += dstRowStride; 3942 } 3943 } 3944 free((void *) tempImage); 3945 } 3946 return GL_TRUE; 3947 } 3948 3949 static GLboolean 3950 _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS) 3951 { 3952 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3953 3954 ASSERT(dstFormat == MESA_FORMAT_ABGR2101010_UINT); 3955 ASSERT(_mesa_get_format_bytes(dstFormat) == 4); 3956 3957 if (baseInternalFormat == GL_RGBA && 3958 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 3959 srcPacking->SwapBytes)) { 3960 /* simple memcpy path */ 3961 memcpy_texture(ctx, dims, 3962 dstFormat, 3963 dstRowStride, dstSlices, 3964 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3965 srcAddr, srcPacking); 3966 } 3967 else { 3968 /* general path */ 3969 const GLuint *tempImage = make_temp_uint_image(ctx, dims, 3970 baseInternalFormat, 3971 baseFormat, 3972 srcWidth, srcHeight, 3973 srcDepth, srcFormat, 3974 srcType, srcAddr, 3975 srcPacking); 3976 const GLuint *src = tempImage; 3977 GLint img, row, col; 3978 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); 3979 if (!tempImage) 3980 return GL_FALSE; 3981 for (img = 0; img < srcDepth; img++) { 3982 GLubyte *dstRow = dstSlices[img]; 3983 3984 for (row = 0; row < srcHeight; row++) { 3985 GLuint *dstUI = (GLuint *) dstRow; 3986 if (is_unsigned) { 3987 for (col = 0; col < srcWidth; col++) { 3988 GLushort a,r,g,b; 3989 r = MIN2(src[RCOMP], 0x3ff); 3990 g = MIN2(src[GCOMP], 0x3ff); 3991 b = MIN2(src[BCOMP], 0x3ff); 3992 a = MIN2(src[ACOMP], 0x003); 3993 dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r); 3994 src += 4; 3995 } 3996 } else { 3997 for (col = 0; col < srcWidth; col++) { 3998 GLushort a,r,g,b; 3999 r = CLAMP((GLint) src[RCOMP], 0, 0x3ff); 4000 g = CLAMP((GLint) src[GCOMP], 0, 0x3ff); 4001 b = CLAMP((GLint) src[BCOMP], 0, 0x3ff); 4002 a = CLAMP((GLint) src[ACOMP], 0, 0x003); 4003 dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r); 4004 src += 4; 4005 } 4006 } 4007 dstRow += dstRowStride; 4008 } 4009 } 4010 free((void *) tempImage); 4011 } 4012 return GL_TRUE; 4013 } 4014 4015 static GLboolean 4016 _mesa_texstore_null(TEXSTORE_PARAMS) 4017 { 4018 (void) ctx; (void) dims; 4019 (void) baseInternalFormat; 4020 (void) dstFormat; 4021 (void) dstRowStride; (void) dstSlices, 4022 (void) srcWidth; (void) srcHeight; (void) srcDepth; 4023 (void) srcFormat; (void) srcType; 4024 (void) srcAddr; 4025 (void) srcPacking; 4026 4027 /* should never happen */ 4028 _mesa_problem(NULL, "_mesa_texstore_null() is called"); 4029 return GL_FALSE; 4030 } 4031 4032 4033 /** 4034 * Return the StoreTexImageFunc pointer to store an image in the given format. 4035 */ 4036 static StoreTexImageFunc 4037 _mesa_get_texstore_func(gl_format format) 4038 { 4039 static StoreTexImageFunc table[MESA_FORMAT_COUNT]; 4040 static GLboolean initialized = GL_FALSE; 4041 4042 if (!initialized) { 4043 table[MESA_FORMAT_NONE] = _mesa_texstore_null; 4044 4045 table[MESA_FORMAT_RGBA8888] = _mesa_texstore_rgba8888; 4046 table[MESA_FORMAT_RGBA8888_REV] = _mesa_texstore_rgba8888; 4047 table[MESA_FORMAT_ARGB8888] = _mesa_texstore_argb8888; 4048 table[MESA_FORMAT_ARGB8888_REV] = _mesa_texstore_argb8888; 4049 table[MESA_FORMAT_RGBX8888] = _mesa_texstore_rgba8888; 4050 table[MESA_FORMAT_RGBX8888_REV] = _mesa_texstore_rgba8888; 4051 table[MESA_FORMAT_XRGB8888] = _mesa_texstore_argb8888; 4052 table[MESA_FORMAT_XRGB8888_REV] = _mesa_texstore_argb8888; 4053 table[MESA_FORMAT_RGB888] = _mesa_texstore_rgb888; 4054 table[MESA_FORMAT_BGR888] = _mesa_texstore_bgr888; 4055 table[MESA_FORMAT_RGB565] = _mesa_texstore_rgb565; 4056 table[MESA_FORMAT_RGB565_REV] = _mesa_texstore_rgb565; 4057 table[MESA_FORMAT_ARGB4444] = _mesa_texstore_argb4444; 4058 table[MESA_FORMAT_ARGB4444_REV] = _mesa_texstore_argb4444; 4059 table[MESA_FORMAT_RGBA5551] = _mesa_texstore_rgba5551; 4060 table[MESA_FORMAT_ARGB1555] = _mesa_texstore_argb1555; 4061 table[MESA_FORMAT_ARGB1555_REV] = _mesa_texstore_argb1555; 4062 table[MESA_FORMAT_AL44] = _mesa_texstore_unorm44; 4063 table[MESA_FORMAT_AL88] = _mesa_texstore_unorm88; 4064 table[MESA_FORMAT_AL88_REV] = _mesa_texstore_unorm88; 4065 table[MESA_FORMAT_AL1616] = _mesa_texstore_unorm1616; 4066 table[MESA_FORMAT_AL1616_REV] = _mesa_texstore_unorm1616; 4067 table[MESA_FORMAT_RGB332] = _mesa_texstore_rgb332; 4068 table[MESA_FORMAT_A8] = _mesa_texstore_unorm8; 4069 table[MESA_FORMAT_A16] = _mesa_texstore_unorm16; 4070 table[MESA_FORMAT_L8] = _mesa_texstore_unorm8; 4071 table[MESA_FORMAT_L16] = _mesa_texstore_unorm16; 4072 table[MESA_FORMAT_I8] = _mesa_texstore_unorm8; 4073 table[MESA_FORMAT_I16] = _mesa_texstore_unorm16; 4074 table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr; 4075 table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr; 4076 table[MESA_FORMAT_R8] = _mesa_texstore_unorm8; 4077 table[MESA_FORMAT_GR88] = _mesa_texstore_unorm88; 4078 table[MESA_FORMAT_RG88] = _mesa_texstore_unorm88; 4079 table[MESA_FORMAT_R16] = _mesa_texstore_unorm16; 4080 table[MESA_FORMAT_RG1616] = _mesa_texstore_unorm1616; 4081 table[MESA_FORMAT_RG1616_REV] = _mesa_texstore_unorm1616; 4082 table[MESA_FORMAT_ARGB2101010] = _mesa_texstore_argb2101010; 4083 table[MESA_FORMAT_Z24_S8] = _mesa_texstore_z24_s8; 4084 table[MESA_FORMAT_S8_Z24] = _mesa_texstore_s8_z24; 4085 table[MESA_FORMAT_Z16] = _mesa_texstore_z16; 4086 table[MESA_FORMAT_X8_Z24] = _mesa_texstore_x8_z24; 4087 table[MESA_FORMAT_Z24_X8] = _mesa_texstore_z24_x8; 4088 table[MESA_FORMAT_Z32] = _mesa_texstore_z32; 4089 table[MESA_FORMAT_S8] = _mesa_texstore_s8; 4090 table[MESA_FORMAT_SRGB8] = _mesa_texstore_srgb8; 4091 table[MESA_FORMAT_SRGBA8] = _mesa_texstore_srgba8; 4092 table[MESA_FORMAT_SARGB8] = _mesa_texstore_sargb8; 4093 table[MESA_FORMAT_SL8] = _mesa_texstore_sl8; 4094 table[MESA_FORMAT_SLA8] = _mesa_texstore_sla8; 4095 table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1; 4096 table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1; 4097 table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3; 4098 table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5; 4099 table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1; 4100 table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1; 4101 table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1; 4102 table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1; 4103 table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3; 4104 table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5; 4105 table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32; 4106 table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16; 4107 table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32; 4108 table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16; 4109 table[MESA_FORMAT_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32; 4110 table[MESA_FORMAT_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16; 4111 table[MESA_FORMAT_LUMINANCE_FLOAT32] = _mesa_texstore_rgba_float32; 4112 table[MESA_FORMAT_LUMINANCE_FLOAT16] = _mesa_texstore_rgba_float16; 4113 table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32; 4114 table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16; 4115 table[MESA_FORMAT_INTENSITY_FLOAT32] = _mesa_texstore_rgba_float32; 4116 table[MESA_FORMAT_INTENSITY_FLOAT16] = _mesa_texstore_rgba_float16; 4117 table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32; 4118 table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16; 4119 table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32; 4120 table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16; 4121 table[MESA_FORMAT_DUDV8] = _mesa_texstore_dudv8; 4122 table[MESA_FORMAT_SIGNED_R8] = _mesa_texstore_snorm8; 4123 table[MESA_FORMAT_SIGNED_RG88_REV] = _mesa_texstore_snorm88; 4124 table[MESA_FORMAT_SIGNED_RGBX8888] = _mesa_texstore_signed_rgbx8888; 4125 table[MESA_FORMAT_SIGNED_RGBA8888] = _mesa_texstore_signed_rgba8888; 4126 table[MESA_FORMAT_SIGNED_RGBA8888_REV] = _mesa_texstore_signed_rgba8888; 4127 table[MESA_FORMAT_SIGNED_R16] = _mesa_texstore_snorm16; 4128 table[MESA_FORMAT_SIGNED_GR1616] = _mesa_texstore_snorm1616; 4129 table[MESA_FORMAT_SIGNED_RGB_16] = _mesa_texstore_signed_rgba_16; 4130 table[MESA_FORMAT_SIGNED_RGBA_16] = _mesa_texstore_signed_rgba_16; 4131 table[MESA_FORMAT_RGBA_16] = _mesa_texstore_rgba_16; 4132 table[MESA_FORMAT_RED_RGTC1] = _mesa_texstore_red_rgtc1; 4133 table[MESA_FORMAT_SIGNED_RED_RGTC1] = _mesa_texstore_signed_red_rgtc1; 4134 table[MESA_FORMAT_RG_RGTC2] = _mesa_texstore_rg_rgtc2; 4135 table[MESA_FORMAT_SIGNED_RG_RGTC2] = _mesa_texstore_signed_rg_rgtc2; 4136 table[MESA_FORMAT_L_LATC1] = _mesa_texstore_red_rgtc1; 4137 table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1; 4138 table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2; 4139 table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2; 4140 table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8; 4141 table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8; 4142 table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8; 4143 table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88; 4144 table[MESA_FORMAT_SIGNED_I8] = _mesa_texstore_snorm8; 4145 table[MESA_FORMAT_SIGNED_A16] = _mesa_texstore_snorm16; 4146 table[MESA_FORMAT_SIGNED_L16] = _mesa_texstore_snorm16; 4147 table[MESA_FORMAT_SIGNED_AL1616] = _mesa_texstore_snorm1616; 4148 table[MESA_FORMAT_SIGNED_I16] = _mesa_texstore_snorm16; 4149 table[MESA_FORMAT_RGB9_E5_FLOAT] = _mesa_texstore_rgb9_e5; 4150 table[MESA_FORMAT_R11_G11_B10_FLOAT] = _mesa_texstore_r11_g11_b10f; 4151 table[MESA_FORMAT_Z32_FLOAT] = _mesa_texstore_z32; 4152 table[MESA_FORMAT_Z32_FLOAT_X24S8] = _mesa_texstore_z32f_x24s8; 4153 4154 table[MESA_FORMAT_ALPHA_UINT8] = _mesa_texstore_rgba_uint8; 4155 table[MESA_FORMAT_ALPHA_UINT16] = _mesa_texstore_rgba_uint16; 4156 table[MESA_FORMAT_ALPHA_UINT32] = _mesa_texstore_rgba_uint32; 4157 table[MESA_FORMAT_ALPHA_INT8] = _mesa_texstore_rgba_int8; 4158 table[MESA_FORMAT_ALPHA_INT16] = _mesa_texstore_rgba_int16; 4159 table[MESA_FORMAT_ALPHA_INT32] = _mesa_texstore_rgba_int32; 4160 4161 table[MESA_FORMAT_INTENSITY_UINT8] = _mesa_texstore_rgba_uint8; 4162 table[MESA_FORMAT_INTENSITY_UINT16] = _mesa_texstore_rgba_uint16; 4163 table[MESA_FORMAT_INTENSITY_UINT32] = _mesa_texstore_rgba_uint32; 4164 table[MESA_FORMAT_INTENSITY_INT8] = _mesa_texstore_rgba_int8; 4165 table[MESA_FORMAT_INTENSITY_INT16] = _mesa_texstore_rgba_int16; 4166 table[MESA_FORMAT_INTENSITY_INT32] = _mesa_texstore_rgba_int32; 4167 4168 table[MESA_FORMAT_LUMINANCE_UINT8] = _mesa_texstore_rgba_uint8; 4169 table[MESA_FORMAT_LUMINANCE_UINT16] = _mesa_texstore_rgba_uint16; 4170 table[MESA_FORMAT_LUMINANCE_UINT32] = _mesa_texstore_rgba_uint32; 4171 table[MESA_FORMAT_LUMINANCE_INT8] = _mesa_texstore_rgba_int8; 4172 table[MESA_FORMAT_LUMINANCE_INT16] = _mesa_texstore_rgba_int16; 4173 table[MESA_FORMAT_LUMINANCE_INT32] = _mesa_texstore_rgba_int32; 4174 4175 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT8] = _mesa_texstore_rgba_uint8; 4176 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT16] = _mesa_texstore_rgba_uint16; 4177 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT32] = _mesa_texstore_rgba_uint32; 4178 table[MESA_FORMAT_LUMINANCE_ALPHA_INT8] = _mesa_texstore_rgba_int8; 4179 table[MESA_FORMAT_LUMINANCE_ALPHA_INT16] = _mesa_texstore_rgba_int16; 4180 table[MESA_FORMAT_LUMINANCE_ALPHA_INT32] = _mesa_texstore_rgba_int32; 4181 4182 table[MESA_FORMAT_R_INT8] = _mesa_texstore_rgba_int8; 4183 table[MESA_FORMAT_RG_INT8] = _mesa_texstore_rgba_int8; 4184 table[MESA_FORMAT_RGB_INT8] = _mesa_texstore_rgba_int8; 4185 table[MESA_FORMAT_RGBA_INT8] = _mesa_texstore_rgba_int8; 4186 table[MESA_FORMAT_R_INT16] = _mesa_texstore_rgba_int16; 4187 table[MESA_FORMAT_RG_INT16] = _mesa_texstore_rgba_int16; 4188 table[MESA_FORMAT_RGB_INT16] = _mesa_texstore_rgba_int16; 4189 table[MESA_FORMAT_RGBA_INT16] = _mesa_texstore_rgba_int16; 4190 table[MESA_FORMAT_R_INT32] = _mesa_texstore_rgba_int32; 4191 table[MESA_FORMAT_RG_INT32] = _mesa_texstore_rgba_int32; 4192 table[MESA_FORMAT_RGB_INT32] = _mesa_texstore_rgba_int32; 4193 table[MESA_FORMAT_RGBA_INT32] = _mesa_texstore_rgba_int32; 4194 4195 table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8; 4196 table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8; 4197 table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8; 4198 table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8; 4199 table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16; 4200 table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16; 4201 table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16; 4202 table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16; 4203 table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32; 4204 table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32; 4205 table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32; 4206 table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32; 4207 4208 table[MESA_FORMAT_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint; 4209 table[MESA_FORMAT_ABGR2101010_UINT] = _mesa_texstore_abgr2101010_uint; 4210 initialized = GL_TRUE; 4211 } 4212 4213 ASSERT(table[format]); 4214 return table[format]; 4215 } 4216 4217 4218 /** 4219 * Store user data into texture memory. 4220 * Called via glTex[Sub]Image1/2/3D() 4221 */ 4222 GLboolean 4223 _mesa_texstore(TEXSTORE_PARAMS) 4224 { 4225 StoreTexImageFunc storeImage; 4226 GLboolean success; 4227 4228 storeImage = _mesa_get_texstore_func(dstFormat); 4229 4230 success = storeImage(ctx, dims, baseInternalFormat, 4231 dstFormat, 4232 dstRowStride, dstSlices, 4233 srcWidth, srcHeight, srcDepth, 4234 srcFormat, srcType, srcAddr, srcPacking); 4235 return success; 4236 } 4237 4238 4239 /** 4240 * Normally, we'll only _write_ texel data to a texture when we map it. 4241 * But if the user is providing depth or stencil values and the texture 4242 * image is a combined depth/stencil format, we'll actually read from 4243 * the texture buffer too (in order to insert the depth or stencil values. 4244 * \param userFormat the user-provided image format 4245 * \param texFormat the destination texture format 4246 */ 4247 static GLbitfield 4248 get_read_write_mode(GLenum userFormat, gl_format texFormat) 4249 { 4250 if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT) 4251 && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL) 4252 return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; 4253 else 4254 return GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT; 4255 } 4256 4257 4258 /** 4259 * Helper function for storing 1D, 2D, 3D whole and subimages into texture 4260 * memory. 4261 * The source of the image data may be user memory or a PBO. In the later 4262 * case, we'll map the PBO, copy from it, then unmap it. 4263 */ 4264 static void 4265 store_texsubimage(struct gl_context *ctx, 4266 struct gl_texture_image *texImage, 4267 GLint xoffset, GLint yoffset, GLint zoffset, 4268 GLint width, GLint height, GLint depth, 4269 GLenum format, GLenum type, const GLvoid *pixels, 4270 const struct gl_pixelstore_attrib *packing, 4271 const char *caller) 4272 4273 { 4274 const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat); 4275 const GLenum target = texImage->TexObject->Target; 4276 GLboolean success = GL_FALSE; 4277 GLuint dims, slice, numSlices = 1, sliceOffset = 0; 4278 GLint srcImageStride = 0; 4279 const GLubyte *src; 4280 4281 assert(xoffset + width <= texImage->Width); 4282 assert(yoffset + height <= texImage->Height); 4283 assert(zoffset + depth <= texImage->Depth); 4284 4285 switch (target) { 4286 case GL_TEXTURE_1D: 4287 dims = 1; 4288 break; 4289 case GL_TEXTURE_2D_ARRAY: 4290 case GL_TEXTURE_3D: 4291 dims = 3; 4292 break; 4293 default: 4294 dims = 2; 4295 } 4296 4297 /* get pointer to src pixels (may be in a pbo which we'll map here) */ 4298 src = (const GLubyte *) 4299 _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, 4300 format, type, pixels, packing, caller); 4301 if (!src) 4302 return; 4303 4304 /* compute slice info (and do some sanity checks) */ 4305 switch (target) { 4306 case GL_TEXTURE_2D: 4307 case GL_TEXTURE_RECTANGLE: 4308 case GL_TEXTURE_CUBE_MAP: 4309 /* one image slice, nothing special needs to be done */ 4310 break; 4311 case GL_TEXTURE_1D: 4312 assert(height == 1); 4313 assert(depth == 1); 4314 assert(yoffset == 0); 4315 assert(zoffset == 0); 4316 break; 4317 case GL_TEXTURE_1D_ARRAY: 4318 assert(depth == 1); 4319 assert(zoffset == 0); 4320 numSlices = height; 4321 sliceOffset = yoffset; 4322 height = 1; 4323 yoffset = 0; 4324 srcImageStride = _mesa_image_row_stride(packing, width, format, type); 4325 break; 4326 case GL_TEXTURE_2D_ARRAY: 4327 numSlices = depth; 4328 sliceOffset = zoffset; 4329 depth = 1; 4330 zoffset = 0; 4331 srcImageStride = _mesa_image_image_stride(packing, width, height, 4332 format, type); 4333 break; 4334 case GL_TEXTURE_3D: 4335 /* we'll store 3D images as a series of slices */ 4336 numSlices = depth; 4337 sliceOffset = zoffset; 4338 srcImageStride = _mesa_image_image_stride(packing, width, height, 4339 format, type); 4340 break; 4341 default: 4342 _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target); 4343 return; 4344 } 4345 4346 assert(numSlices == 1 || srcImageStride != 0); 4347 4348 for (slice = 0; slice < numSlices; slice++) { 4349 GLubyte *dstMap; 4350 GLint dstRowStride; 4351 4352 ctx->Driver.MapTextureImage(ctx, texImage, 4353 slice + sliceOffset, 4354 xoffset, yoffset, width, height, 4355 mapMode, &dstMap, &dstRowStride); 4356 if (dstMap) { 4357 /* Note: we're only storing a 2D (or 1D) slice at a time but we need 4358 * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is 4359 * used for 3D images. 4360 */ 4361 success = _mesa_texstore(ctx, dims, texImage->_BaseFormat, 4362 texImage->TexFormat, 4363 dstRowStride, 4364 &dstMap, 4365 width, height, 1, /* w, h, d */ 4366 format, type, src, packing); 4367 4368 ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset); 4369 } 4370 4371 src += srcImageStride; 4372 4373 if (!success) 4374 break; 4375 } 4376 4377 if (!success) 4378 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); 4379 4380 _mesa_unmap_teximage_pbo(ctx, packing); 4381 } 4382 4383 4384 4385 /** 4386 * Fallback code for ctx->Driver.TexImage(). 4387 * Basically, allocate storage for the texture image, then copy the 4388 * user's image into it. 4389 */ 4390 void 4391 _mesa_store_teximage(struct gl_context *ctx, 4392 GLuint dims, 4393 struct gl_texture_image *texImage, 4394 GLenum format, GLenum type, const GLvoid *pixels, 4395 const struct gl_pixelstore_attrib *packing) 4396 { 4397 assert(dims == 1 || dims == 2 || dims == 3); 4398 4399 if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0) 4400 return; 4401 4402 /* allocate storage for texture data */ 4403 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { 4404 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); 4405 return; 4406 } 4407 4408 store_texsubimage(ctx, texImage, 4409 0, 0, 0, texImage->Width, texImage->Height, texImage->Depth, 4410 format, type, pixels, packing, "glTexImage"); 4411 } 4412 4413 4414 /* 4415 * Fallback for Driver.TexSubImage(). 4416 */ 4417 void 4418 _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims, 4419 struct gl_texture_image *texImage, 4420 GLint xoffset, GLint yoffset, GLint zoffset, 4421 GLint width, GLint height, GLint depth, 4422 GLenum format, GLenum type, const void *pixels, 4423 const struct gl_pixelstore_attrib *packing) 4424 { 4425 store_texsubimage(ctx, texImage, 4426 xoffset, yoffset, zoffset, width, height, depth, 4427 format, type, pixels, packing, "glTexSubImage"); 4428 } 4429 4430 4431 /** 4432 * Fallback for Driver.CompressedTexImage() 4433 */ 4434 void 4435 _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims, 4436 struct gl_texture_image *texImage, 4437 GLsizei imageSize, const GLvoid *data) 4438 { 4439 /* only 2D compressed images are supported at this time */ 4440 if (dims != 2) { 4441 _mesa_problem(ctx, "Unexpected glCompressedTexImage1D/3D call"); 4442 return; 4443 } 4444 4445 /* This is pretty simple, because unlike the general texstore path we don't 4446 * have to worry about the usual image unpacking or image transfer 4447 * operations. 4448 */ 4449 ASSERT(texImage); 4450 ASSERT(texImage->Width > 0); 4451 ASSERT(texImage->Height > 0); 4452 ASSERT(texImage->Depth == 1); 4453 4454 /* allocate storage for texture data */ 4455 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { 4456 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); 4457 return; 4458 } 4459 4460 _mesa_store_compressed_texsubimage(ctx, dims, texImage, 4461 0, 0, 0, 4462 texImage->Width, texImage->Height, texImage->Depth, 4463 texImage->TexFormat, 4464 imageSize, data); 4465 } 4466 4467 4468 /** 4469 * Fallback for Driver.CompressedTexSubImage() 4470 */ 4471 void 4472 _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, 4473 struct gl_texture_image *texImage, 4474 GLint xoffset, GLint yoffset, GLint zoffset, 4475 GLsizei width, GLsizei height, GLsizei depth, 4476 GLenum format, 4477 GLsizei imageSize, const GLvoid *data) 4478 { 4479 GLint bytesPerRow, dstRowStride, srcRowStride; 4480 GLint i, rows; 4481 GLubyte *dstMap; 4482 const GLubyte *src; 4483 const gl_format texFormat = texImage->TexFormat; 4484 GLuint bw, bh; 4485 4486 if (dims != 2) { 4487 _mesa_problem(ctx, "Unexpected 1D/3D compressed texsubimage call"); 4488 return; 4489 } 4490 4491 _mesa_get_format_block_size(texFormat, &bw, &bh); 4492 4493 /* get pointer to src pixels (may be in a pbo which we'll map here) */ 4494 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data, 4495 &ctx->Unpack, 4496 "glCompressedTexSubImage2D"); 4497 if (!data) 4498 return; 4499 4500 srcRowStride = _mesa_format_row_stride(texFormat, width); 4501 src = (const GLubyte *) data; 4502 4503 /* Map dest texture buffer */ 4504 ctx->Driver.MapTextureImage(ctx, texImage, 0, 4505 xoffset, yoffset, width, height, 4506 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT, 4507 &dstMap, &dstRowStride); 4508 4509 if (dstMap) { 4510 bytesPerRow = srcRowStride; /* bytes per row of blocks */ 4511 rows = (height + bh - 1) / bh; /* rows in blocks */ 4512 4513 /* copy rows of blocks */ 4514 for (i = 0; i < rows; i++) { 4515 memcpy(dstMap, src, bytesPerRow); 4516 dstMap += dstRowStride; 4517 src += srcRowStride; 4518 } 4519 4520 ctx->Driver.UnmapTextureImage(ctx, texImage, 0); 4521 } 4522 else { 4523 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D"); 4524 } 4525 4526 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack); 4527 } 4528