texstore.c revision 5606bd574e264c4beda8eb1d10b48d17e9b8b497
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 79enum { 80 ZERO = 4, 81 ONE = 5 82}; 83 84 85/** 86 * Texture image storage function. 87 */ 88typedef 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 */ 95static GLboolean 96can_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 120enum { 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 143static 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 */ 233static int 234get_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 */ 265static void 266compute_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 */ 318GLfloat * 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 */ 430static GLuint * 431make_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 */ 559GLubyte * 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 */ 677static void 678swizzle_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 791static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE }; 792static 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 */ 799static const GLubyte * 800type_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 */ 820static const GLubyte * 821byteswap_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 */ 844static 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 */ 924static void 925memcpy_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 */ 976static GLboolean 977store_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 */ 1010static 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 */ 1060static 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 */ 1090static 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 */ 1124static 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 */ 1168static 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 */ 1233static 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 1301static 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 1461static 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 1534static 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 1607static 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 1634static 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 1660static 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 1688static 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 */ 1764static 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 */ 1806static 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 */ 1922static 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. */ 1998static 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 2055static 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 2114static 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 2189static 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 */ 2219static 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 */ 2300static 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 2341static 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 */ 2431static 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 */ 2485static 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. */ 2539static 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 */ 2598static 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 */ 2658static 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 */ 2705static 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 */ 2774static 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 */ 2866static 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 */ 2949static 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 */ 3016static 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 */ 3086static 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 */ 3155static 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 if (!tempImage) 3204 return GL_FALSE; 3205 for (img = 0; img < srcDepth; img++) { 3206 GLubyte *dstRow = dstSlices[img]; 3207 for (row = 0; row < srcHeight; row++) { 3208 GLbyte *dstTexel = (GLbyte *) dstRow; 3209 GLint i; 3210 for (i = 0; i < srcWidth * components; i++) { 3211 dstTexel[i] = (GLbyte) src[i]; 3212 } 3213 dstRow += dstRowStride; 3214 src += srcWidth * components; 3215 } 3216 } 3217 3218 free((void *) tempImage); 3219 } 3220 return GL_TRUE; 3221} 3222 3223 3224/* non-normalized, signed int16 */ 3225static GLboolean 3226_mesa_texstore_rgba_int16(TEXSTORE_PARAMS) 3227{ 3228 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3229 const GLint components = _mesa_components_in_format(baseFormat); 3230 3231 ASSERT(dstFormat == MESA_FORMAT_R_INT16 || 3232 dstFormat == MESA_FORMAT_RG_INT16 || 3233 dstFormat == MESA_FORMAT_RGB_INT16 || 3234 dstFormat == MESA_FORMAT_RGBA_INT16 || 3235 dstFormat == MESA_FORMAT_ALPHA_INT16 || 3236 dstFormat == MESA_FORMAT_LUMINANCE_INT16 || 3237 dstFormat == MESA_FORMAT_INTENSITY_INT16 || 3238 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16); 3239 ASSERT(baseInternalFormat == GL_RGBA || 3240 baseInternalFormat == GL_RGB || 3241 baseInternalFormat == GL_RG || 3242 baseInternalFormat == GL_RED || 3243 baseInternalFormat == GL_ALPHA || 3244 baseInternalFormat == GL_LUMINANCE || 3245 baseInternalFormat == GL_LUMINANCE_ALPHA || 3246 baseInternalFormat == GL_INTENSITY); 3247 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLshort)); 3248 3249 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply 3250 * to integer formats. 3251 */ 3252 if (!srcPacking->SwapBytes && 3253 baseInternalFormat == srcFormat && 3254 srcType == GL_SHORT) { 3255 /* simple memcpy path */ 3256 memcpy_texture(ctx, dims, 3257 dstFormat, 3258 dstRowStride, dstSlices, 3259 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3260 srcAddr, srcPacking); 3261 } 3262 else { 3263 /* general path */ 3264 const GLuint *tempImage = make_temp_uint_image(ctx, dims, 3265 baseInternalFormat, 3266 baseFormat, 3267 srcWidth, srcHeight, srcDepth, 3268 srcFormat, srcType, 3269 srcAddr, 3270 srcPacking); 3271 const GLuint *src = tempImage; 3272 GLint img, row; 3273 if (!tempImage) 3274 return GL_FALSE; 3275 for (img = 0; img < srcDepth; img++) { 3276 GLubyte *dstRow = dstSlices[img]; 3277 for (row = 0; row < srcHeight; row++) { 3278 GLshort *dstTexel = (GLshort *) dstRow; 3279 GLint i; 3280 for (i = 0; i < srcWidth * components; i++) { 3281 dstTexel[i] = (GLint) src[i]; 3282 } 3283 dstRow += dstRowStride; 3284 src += srcWidth * components; 3285 } 3286 } 3287 3288 free((void *) tempImage); 3289 } 3290 return GL_TRUE; 3291} 3292 3293 3294/* non-normalized, signed int32 */ 3295static GLboolean 3296_mesa_texstore_rgba_int32(TEXSTORE_PARAMS) 3297{ 3298 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3299 const GLint components = _mesa_components_in_format(baseFormat); 3300 3301 ASSERT(dstFormat == MESA_FORMAT_R_INT32 || 3302 dstFormat == MESA_FORMAT_RG_INT32 || 3303 dstFormat == MESA_FORMAT_RGB_INT32 || 3304 dstFormat == MESA_FORMAT_RGBA_INT32 || 3305 dstFormat == MESA_FORMAT_ALPHA_INT32 || 3306 dstFormat == MESA_FORMAT_INTENSITY_INT32 || 3307 dstFormat == MESA_FORMAT_LUMINANCE_INT32 || 3308 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32); 3309 ASSERT(baseInternalFormat == GL_RGBA || 3310 baseInternalFormat == GL_RGB || 3311 baseInternalFormat == GL_RG || 3312 baseInternalFormat == GL_RED || 3313 baseInternalFormat == GL_ALPHA || 3314 baseInternalFormat == GL_LUMINANCE || 3315 baseInternalFormat == GL_LUMINANCE_ALPHA || 3316 baseInternalFormat == GL_INTENSITY); 3317 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLint)); 3318 3319 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply 3320 * to integer formats. 3321 */ 3322 if (!srcPacking->SwapBytes && 3323 baseInternalFormat == srcFormat && 3324 srcType == GL_INT) { 3325 /* simple memcpy path */ 3326 memcpy_texture(ctx, dims, 3327 dstFormat, 3328 dstRowStride, dstSlices, 3329 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3330 srcAddr, srcPacking); 3331 } 3332 else { 3333 /* general path */ 3334 const GLuint *tempImage = make_temp_uint_image(ctx, dims, 3335 baseInternalFormat, 3336 baseFormat, 3337 srcWidth, srcHeight, srcDepth, 3338 srcFormat, srcType, 3339 srcAddr, 3340 srcPacking); 3341 const GLuint *src = tempImage; 3342 GLint img, row; 3343 if (!tempImage) 3344 return GL_FALSE; 3345 for (img = 0; img < srcDepth; img++) { 3346 GLubyte *dstRow = dstSlices[img]; 3347 for (row = 0; row < srcHeight; row++) { 3348 GLint *dstTexel = (GLint *) dstRow; 3349 GLint i; 3350 for (i = 0; i < srcWidth * components; i++) { 3351 dstTexel[i] = (GLint) src[i]; 3352 } 3353 dstRow += dstRowStride; 3354 src += srcWidth * components; 3355 } 3356 } 3357 3358 free((void *) tempImage); 3359 } 3360 return GL_TRUE; 3361} 3362 3363 3364/* non-normalized, unsigned int8 */ 3365static GLboolean 3366_mesa_texstore_rgba_uint8(TEXSTORE_PARAMS) 3367{ 3368 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3369 const GLint components = _mesa_components_in_format(baseFormat); 3370 3371 ASSERT(dstFormat == MESA_FORMAT_R_UINT8 || 3372 dstFormat == MESA_FORMAT_RG_UINT8 || 3373 dstFormat == MESA_FORMAT_RGB_UINT8 || 3374 dstFormat == MESA_FORMAT_RGBA_UINT8 || 3375 dstFormat == MESA_FORMAT_ALPHA_UINT8 || 3376 dstFormat == MESA_FORMAT_INTENSITY_UINT8 || 3377 dstFormat == MESA_FORMAT_LUMINANCE_UINT8 || 3378 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT8); 3379 ASSERT(baseInternalFormat == GL_RGBA || 3380 baseInternalFormat == GL_RGB || 3381 baseInternalFormat == GL_RG || 3382 baseInternalFormat == GL_RED || 3383 baseInternalFormat == GL_ALPHA || 3384 baseInternalFormat == GL_LUMINANCE || 3385 baseInternalFormat == GL_LUMINANCE_ALPHA || 3386 baseInternalFormat == GL_INTENSITY); 3387 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLubyte)); 3388 3389 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply 3390 * to integer formats. 3391 */ 3392 if (!srcPacking->SwapBytes && 3393 baseInternalFormat == srcFormat && 3394 srcType == GL_UNSIGNED_BYTE) { 3395 /* simple memcpy path */ 3396 memcpy_texture(ctx, dims, 3397 dstFormat, 3398 dstRowStride, dstSlices, 3399 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3400 srcAddr, srcPacking); 3401 } 3402 else { 3403 /* general path */ 3404 const GLuint *tempImage = 3405 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, 3406 srcWidth, srcHeight, srcDepth, 3407 srcFormat, srcType, srcAddr, srcPacking); 3408 const GLuint *src = tempImage; 3409 GLint img, row; 3410 if (!tempImage) 3411 return GL_FALSE; 3412 for (img = 0; img < srcDepth; img++) { 3413 GLubyte *dstRow = dstSlices[img]; 3414 for (row = 0; row < srcHeight; row++) { 3415 GLubyte *dstTexel = (GLubyte *) dstRow; 3416 GLint i; 3417 for (i = 0; i < srcWidth * components; i++) { 3418 dstTexel[i] = (GLubyte) CLAMP(src[i], 0, 0xff); 3419 } 3420 dstRow += dstRowStride; 3421 src += srcWidth * components; 3422 } 3423 } 3424 3425 free((void *) tempImage); 3426 } 3427 return GL_TRUE; 3428} 3429 3430 3431/* non-normalized, unsigned int16 */ 3432static GLboolean 3433_mesa_texstore_rgba_uint16(TEXSTORE_PARAMS) 3434{ 3435 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3436 const GLint components = _mesa_components_in_format(baseFormat); 3437 3438 ASSERT(dstFormat == MESA_FORMAT_R_UINT16 || 3439 dstFormat == MESA_FORMAT_RG_UINT16 || 3440 dstFormat == MESA_FORMAT_RGB_UINT16 || 3441 dstFormat == MESA_FORMAT_RGBA_UINT16 || 3442 dstFormat == MESA_FORMAT_ALPHA_UINT16 || 3443 dstFormat == MESA_FORMAT_INTENSITY_UINT16 || 3444 dstFormat == MESA_FORMAT_LUMINANCE_UINT16 || 3445 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT16); 3446 ASSERT(baseInternalFormat == GL_RGBA || 3447 baseInternalFormat == GL_RGB || 3448 baseInternalFormat == GL_RG || 3449 baseInternalFormat == GL_RED || 3450 baseInternalFormat == GL_ALPHA || 3451 baseInternalFormat == GL_LUMINANCE || 3452 baseInternalFormat == GL_LUMINANCE_ALPHA || 3453 baseInternalFormat == GL_INTENSITY); 3454 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLushort)); 3455 3456 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply 3457 * to integer formats. 3458 */ 3459 if (!srcPacking->SwapBytes && 3460 baseInternalFormat == srcFormat && 3461 srcType == GL_UNSIGNED_SHORT) { 3462 /* simple memcpy path */ 3463 memcpy_texture(ctx, dims, 3464 dstFormat, 3465 dstRowStride, dstSlices, 3466 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3467 srcAddr, srcPacking); 3468 } 3469 else { 3470 /* general path */ 3471 const GLuint *tempImage = 3472 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, 3473 srcWidth, srcHeight, srcDepth, 3474 srcFormat, srcType, srcAddr, srcPacking); 3475 const GLuint *src = tempImage; 3476 GLint img, row; 3477 if (!tempImage) 3478 return GL_FALSE; 3479 for (img = 0; img < srcDepth; img++) { 3480 GLubyte *dstRow = dstSlices[img]; 3481 for (row = 0; row < srcHeight; row++) { 3482 GLushort *dstTexel = (GLushort *) dstRow; 3483 GLint i; 3484 for (i = 0; i < srcWidth * components; i++) { 3485 dstTexel[i] = (GLushort) CLAMP(src[i], 0, 0xffff); 3486 } 3487 dstRow += dstRowStride; 3488 src += srcWidth * components; 3489 } 3490 } 3491 3492 free((void *) tempImage); 3493 } 3494 return GL_TRUE; 3495} 3496 3497 3498/* non-normalized, unsigned int32 */ 3499static GLboolean 3500_mesa_texstore_rgba_uint32(TEXSTORE_PARAMS) 3501{ 3502 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3503 const GLint components = _mesa_components_in_format(baseFormat); 3504 3505 ASSERT(dstFormat == MESA_FORMAT_R_UINT32 || 3506 dstFormat == MESA_FORMAT_RG_UINT32 || 3507 dstFormat == MESA_FORMAT_RGB_UINT32 || 3508 dstFormat == MESA_FORMAT_RGBA_UINT32 || 3509 dstFormat == MESA_FORMAT_ALPHA_UINT32 || 3510 dstFormat == MESA_FORMAT_INTENSITY_UINT32 || 3511 dstFormat == MESA_FORMAT_LUMINANCE_UINT32 || 3512 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT32); 3513 ASSERT(baseInternalFormat == GL_RGBA || 3514 baseInternalFormat == GL_RGB || 3515 baseInternalFormat == GL_RG || 3516 baseInternalFormat == GL_RED || 3517 baseInternalFormat == GL_ALPHA || 3518 baseInternalFormat == GL_LUMINANCE || 3519 baseInternalFormat == GL_LUMINANCE_ALPHA || 3520 baseInternalFormat == GL_INTENSITY); 3521 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLuint)); 3522 3523 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply 3524 * to integer formats. 3525 */ 3526 if (!srcPacking->SwapBytes && 3527 baseInternalFormat == srcFormat && 3528 srcType == GL_UNSIGNED_INT) { 3529 /* simple memcpy path */ 3530 memcpy_texture(ctx, dims, 3531 dstFormat, 3532 dstRowStride, dstSlices, 3533 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3534 srcAddr, srcPacking); 3535 } 3536 else { 3537 /* general path */ 3538 const GLuint *tempImage = 3539 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat, 3540 srcWidth, srcHeight, srcDepth, 3541 srcFormat, srcType, srcAddr, srcPacking); 3542 const GLuint *src = tempImage; 3543 GLint img, row; 3544 if (!tempImage) 3545 return GL_FALSE; 3546 for (img = 0; img < srcDepth; img++) { 3547 GLubyte *dstRow = dstSlices[img]; 3548 for (row = 0; row < srcHeight; row++) { 3549 GLuint *dstTexel = (GLuint *) dstRow; 3550 GLint i; 3551 for (i = 0; i < srcWidth * components; i++) { 3552 dstTexel[i] = src[i]; 3553 } 3554 dstRow += dstRowStride; 3555 src += srcWidth * components; 3556 } 3557 } 3558 3559 free((void *) tempImage); 3560 } 3561 return GL_TRUE; 3562} 3563 3564 3565 3566 3567#if FEATURE_EXT_texture_sRGB 3568static GLboolean 3569_mesa_texstore_srgb8(TEXSTORE_PARAMS) 3570{ 3571 gl_format newDstFormat; 3572 GLboolean k; 3573 3574 ASSERT(dstFormat == MESA_FORMAT_SRGB8); 3575 3576 /* reuse normal rgb texstore code */ 3577 newDstFormat = MESA_FORMAT_RGB888; 3578 3579 k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat, 3580 newDstFormat, 3581 dstRowStride, dstSlices, 3582 srcWidth, srcHeight, srcDepth, 3583 srcFormat, srcType, 3584 srcAddr, srcPacking); 3585 return k; 3586} 3587 3588 3589static GLboolean 3590_mesa_texstore_srgba8(TEXSTORE_PARAMS) 3591{ 3592 gl_format newDstFormat; 3593 GLboolean k; 3594 3595 ASSERT(dstFormat == MESA_FORMAT_SRGBA8); 3596 3597 /* reuse normal rgba texstore code */ 3598 newDstFormat = MESA_FORMAT_RGBA8888; 3599 k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat, 3600 newDstFormat, 3601 dstRowStride, dstSlices, 3602 srcWidth, srcHeight, srcDepth, 3603 srcFormat, srcType, 3604 srcAddr, srcPacking); 3605 return k; 3606} 3607 3608 3609static GLboolean 3610_mesa_texstore_sargb8(TEXSTORE_PARAMS) 3611{ 3612 gl_format newDstFormat; 3613 GLboolean k; 3614 3615 ASSERT(dstFormat == MESA_FORMAT_SARGB8); 3616 3617 /* reuse normal rgba texstore code */ 3618 newDstFormat = MESA_FORMAT_ARGB8888; 3619 3620 k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat, 3621 newDstFormat, 3622 dstRowStride, dstSlices, 3623 srcWidth, srcHeight, srcDepth, 3624 srcFormat, srcType, 3625 srcAddr, srcPacking); 3626 return k; 3627} 3628 3629 3630static GLboolean 3631_mesa_texstore_sl8(TEXSTORE_PARAMS) 3632{ 3633 gl_format newDstFormat; 3634 GLboolean k; 3635 3636 ASSERT(dstFormat == MESA_FORMAT_SL8); 3637 3638 newDstFormat = MESA_FORMAT_L8; 3639 3640 /* _mesa_textore_a8 handles luminance8 too */ 3641 k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat, 3642 newDstFormat, 3643 dstRowStride, dstSlices, 3644 srcWidth, srcHeight, srcDepth, 3645 srcFormat, srcType, 3646 srcAddr, srcPacking); 3647 return k; 3648} 3649 3650 3651static GLboolean 3652_mesa_texstore_sla8(TEXSTORE_PARAMS) 3653{ 3654 gl_format newDstFormat; 3655 GLboolean k; 3656 3657 ASSERT(dstFormat == MESA_FORMAT_SLA8); 3658 3659 /* reuse normal luminance/alpha texstore code */ 3660 newDstFormat = MESA_FORMAT_AL88; 3661 3662 k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat, 3663 newDstFormat, 3664 dstRowStride, dstSlices, 3665 srcWidth, srcHeight, srcDepth, 3666 srcFormat, srcType, 3667 srcAddr, srcPacking); 3668 return k; 3669} 3670 3671#else 3672 3673/* these are used only in texstore_funcs[] below */ 3674#define _mesa_texstore_srgb8 NULL 3675#define _mesa_texstore_srgba8 NULL 3676#define _mesa_texstore_sargb8 NULL 3677#define _mesa_texstore_sl8 NULL 3678#define _mesa_texstore_sla8 NULL 3679 3680#endif /* FEATURE_EXT_texture_sRGB */ 3681 3682static GLboolean 3683_mesa_texstore_rgb9_e5(TEXSTORE_PARAMS) 3684{ 3685 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3686 3687 ASSERT(dstFormat == MESA_FORMAT_RGB9_E5_FLOAT); 3688 ASSERT(baseInternalFormat == GL_RGB); 3689 3690 if (!ctx->_ImageTransferState && 3691 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 3692 srcPacking->SwapBytes)) { 3693 /* simple memcpy path */ 3694 memcpy_texture(ctx, dims, 3695 dstFormat, 3696 dstRowStride, dstSlices, 3697 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3698 srcAddr, srcPacking); 3699 } 3700 else { 3701 /* general path */ 3702 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 3703 baseInternalFormat, 3704 baseFormat, 3705 srcWidth, srcHeight, srcDepth, 3706 srcFormat, srcType, srcAddr, 3707 srcPacking, 3708 ctx->_ImageTransferState); 3709 const GLfloat *srcRow = tempImage; 3710 GLint img, row, col; 3711 if (!tempImage) 3712 return GL_FALSE; 3713 for (img = 0; img < srcDepth; img++) { 3714 GLubyte *dstRow = dstSlices[img]; 3715 for (row = 0; row < srcHeight; row++) { 3716 GLuint *dstUI = (GLuint*)dstRow; 3717 for (col = 0; col < srcWidth; col++) { 3718 dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]); 3719 } 3720 dstRow += dstRowStride; 3721 srcRow += srcWidth * 3; 3722 } 3723 } 3724 3725 free((void *) tempImage); 3726 } 3727 return GL_TRUE; 3728} 3729 3730static GLboolean 3731_mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS) 3732{ 3733 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3734 3735 ASSERT(dstFormat == MESA_FORMAT_R11_G11_B10_FLOAT); 3736 ASSERT(baseInternalFormat == GL_RGB); 3737 3738 if (!ctx->_ImageTransferState && 3739 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 3740 srcPacking->SwapBytes)) { 3741 /* simple memcpy path */ 3742 memcpy_texture(ctx, dims, 3743 dstFormat, 3744 dstRowStride, dstSlices, 3745 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3746 srcAddr, srcPacking); 3747 } 3748 else { 3749 /* general path */ 3750 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims, 3751 baseInternalFormat, 3752 baseFormat, 3753 srcWidth, srcHeight, srcDepth, 3754 srcFormat, srcType, srcAddr, 3755 srcPacking, 3756 ctx->_ImageTransferState); 3757 const GLfloat *srcRow = tempImage; 3758 GLint img, row, col; 3759 if (!tempImage) 3760 return GL_FALSE; 3761 for (img = 0; img < srcDepth; img++) { 3762 GLubyte *dstRow = dstSlices[img]; 3763 for (row = 0; row < srcHeight; row++) { 3764 GLuint *dstUI = (GLuint*)dstRow; 3765 for (col = 0; col < srcWidth; col++) { 3766 dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]); 3767 } 3768 dstRow += dstRowStride; 3769 srcRow += srcWidth * 3; 3770 } 3771 } 3772 3773 free((void *) tempImage); 3774 } 3775 return GL_TRUE; 3776} 3777 3778 3779static GLboolean 3780_mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS) 3781{ 3782 ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_X24S8); 3783 ASSERT(srcFormat == GL_DEPTH_STENCIL || 3784 srcFormat == GL_DEPTH_COMPONENT || 3785 srcFormat == GL_STENCIL_INDEX); 3786 ASSERT(srcFormat != GL_DEPTH_STENCIL || 3787 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV); 3788 3789 if (srcFormat == GL_DEPTH_STENCIL && 3790 ctx->Pixel.DepthScale == 1.0f && 3791 ctx->Pixel.DepthBias == 0.0f && 3792 !srcPacking->SwapBytes) { 3793 /* simple path */ 3794 memcpy_texture(ctx, dims, 3795 dstFormat, 3796 dstRowStride, dstSlices, 3797 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3798 srcAddr, srcPacking); 3799 } 3800 else if (srcFormat == GL_DEPTH_COMPONENT || 3801 srcFormat == GL_STENCIL_INDEX) { 3802 GLint img, row; 3803 const GLint srcRowStride 3804 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) 3805 / sizeof(uint64_t); 3806 3807 /* In case we only upload depth we need to preserve the stencil */ 3808 for (img = 0; img < srcDepth; img++) { 3809 uint64_t *dstRow = (uint64_t *) dstSlices[img]; 3810 const uint64_t *src 3811 = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr, 3812 srcWidth, srcHeight, 3813 srcFormat, srcType, 3814 img, 0, 0); 3815 for (row = 0; row < srcHeight; row++) { 3816 /* The unpack functions with: 3817 * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV 3818 * only write their own dword, so the other dword (stencil 3819 * or depth) is preserved. */ 3820 if (srcFormat != GL_STENCIL_INDEX) 3821 _mesa_unpack_depth_span(ctx, srcWidth, 3822 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */ 3823 dstRow, /* dst addr */ 3824 ~0U, srcType, src, srcPacking); 3825 3826 if (srcFormat != GL_DEPTH_COMPONENT) 3827 _mesa_unpack_stencil_span(ctx, srcWidth, 3828 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */ 3829 dstRow, /* dst addr */ 3830 srcType, src, srcPacking, 3831 ctx->_ImageTransferState); 3832 3833 src += srcRowStride; 3834 dstRow += dstRowStride / sizeof(uint64_t); 3835 } 3836 } 3837 } 3838 return GL_TRUE; 3839} 3840 3841static GLboolean 3842_mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS) 3843{ 3844 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3845 3846 ASSERT(dstFormat == MESA_FORMAT_ARGB2101010_UINT); 3847 ASSERT(_mesa_get_format_bytes(dstFormat) == 4); 3848 3849 if (baseInternalFormat == GL_RGBA && 3850 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 3851 srcPacking->SwapBytes)) { 3852 /* simple memcpy path */ 3853 memcpy_texture(ctx, dims, 3854 dstFormat, 3855 dstRowStride, dstSlices, 3856 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3857 srcAddr, srcPacking); 3858 } 3859 else { 3860 /* general path */ 3861 const GLuint *tempImage = make_temp_uint_image(ctx, dims, 3862 baseInternalFormat, 3863 baseFormat, 3864 srcWidth, srcHeight, 3865 srcDepth, srcFormat, 3866 srcType, srcAddr, 3867 srcPacking); 3868 const GLuint *src = tempImage; 3869 GLint img, row, col; 3870 if (!tempImage) 3871 return GL_FALSE; 3872 for (img = 0; img < srcDepth; img++) { 3873 GLubyte *dstRow = dstSlices[img]; 3874 3875 for (row = 0; row < srcHeight; row++) { 3876 GLuint *dstUI = (GLuint *) dstRow; 3877 for (col = 0; col < srcWidth; col++) { 3878 GLushort a,r,g,b; 3879 r = src[RCOMP]; 3880 g = src[GCOMP]; 3881 b = src[BCOMP]; 3882 a = src[ACOMP]; 3883 dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b); 3884 src += 4; 3885 } 3886 dstRow += dstRowStride; 3887 } 3888 } 3889 free((void *) tempImage); 3890 } 3891 return GL_TRUE; 3892} 3893 3894static GLboolean 3895_mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS) 3896{ 3897 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat); 3898 3899 ASSERT(dstFormat == MESA_FORMAT_ABGR2101010_UINT); 3900 ASSERT(_mesa_get_format_bytes(dstFormat) == 4); 3901 3902 if (baseInternalFormat == GL_RGBA && 3903 _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType, 3904 srcPacking->SwapBytes)) { 3905 /* simple memcpy path */ 3906 memcpy_texture(ctx, dims, 3907 dstFormat, 3908 dstRowStride, dstSlices, 3909 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 3910 srcAddr, srcPacking); 3911 } 3912 else { 3913 /* general path */ 3914 const GLuint *tempImage = make_temp_uint_image(ctx, dims, 3915 baseInternalFormat, 3916 baseFormat, 3917 srcWidth, srcHeight, 3918 srcDepth, srcFormat, 3919 srcType, srcAddr, 3920 srcPacking); 3921 const GLuint *src = tempImage; 3922 GLint img, row, col; 3923 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType); 3924 if (!tempImage) 3925 return GL_FALSE; 3926 for (img = 0; img < srcDepth; img++) { 3927 GLubyte *dstRow = dstSlices[img]; 3928 3929 for (row = 0; row < srcHeight; row++) { 3930 GLuint *dstUI = (GLuint *) dstRow; 3931 if (is_unsigned) { 3932 for (col = 0; col < srcWidth; col++) { 3933 GLushort a,r,g,b; 3934 r = MIN2(src[RCOMP], 0x3ff); 3935 g = MIN2(src[GCOMP], 0x3ff); 3936 b = MIN2(src[BCOMP], 0x3ff); 3937 a = MIN2(src[ACOMP], 0x003); 3938 dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r); 3939 src += 4; 3940 } 3941 } else { 3942 for (col = 0; col < srcWidth; col++) { 3943 GLushort a,r,g,b; 3944 r = CLAMP((GLint) src[RCOMP], 0, 0x3ff); 3945 g = CLAMP((GLint) src[GCOMP], 0, 0x3ff); 3946 b = CLAMP((GLint) src[BCOMP], 0, 0x3ff); 3947 a = CLAMP((GLint) src[ACOMP], 0, 0x003); 3948 dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r); 3949 src += 4; 3950 } 3951 } 3952 dstRow += dstRowStride; 3953 } 3954 } 3955 free((void *) tempImage); 3956 } 3957 return GL_TRUE; 3958} 3959 3960static GLboolean 3961_mesa_texstore_null(TEXSTORE_PARAMS) 3962{ 3963 (void) ctx; (void) dims; 3964 (void) baseInternalFormat; 3965 (void) dstFormat; 3966 (void) dstRowStride; (void) dstSlices, 3967 (void) srcWidth; (void) srcHeight; (void) srcDepth; 3968 (void) srcFormat; (void) srcType; 3969 (void) srcAddr; 3970 (void) srcPacking; 3971 3972 /* should never happen */ 3973 _mesa_problem(NULL, "_mesa_texstore_null() is called"); 3974 return GL_FALSE; 3975} 3976 3977 3978/** 3979 * Return the StoreTexImageFunc pointer to store an image in the given format. 3980 */ 3981static StoreTexImageFunc 3982_mesa_get_texstore_func(gl_format format) 3983{ 3984 static StoreTexImageFunc table[MESA_FORMAT_COUNT]; 3985 static GLboolean initialized = GL_FALSE; 3986 3987 if (!initialized) { 3988 table[MESA_FORMAT_NONE] = _mesa_texstore_null; 3989 3990 table[MESA_FORMAT_RGBA8888] = _mesa_texstore_rgba8888; 3991 table[MESA_FORMAT_RGBA8888_REV] = _mesa_texstore_rgba8888; 3992 table[MESA_FORMAT_ARGB8888] = _mesa_texstore_argb8888; 3993 table[MESA_FORMAT_ARGB8888_REV] = _mesa_texstore_argb8888; 3994 table[MESA_FORMAT_RGBX8888] = _mesa_texstore_rgba8888; 3995 table[MESA_FORMAT_RGBX8888_REV] = _mesa_texstore_rgba8888; 3996 table[MESA_FORMAT_XRGB8888] = _mesa_texstore_argb8888; 3997 table[MESA_FORMAT_XRGB8888_REV] = _mesa_texstore_argb8888; 3998 table[MESA_FORMAT_RGB888] = _mesa_texstore_rgb888; 3999 table[MESA_FORMAT_BGR888] = _mesa_texstore_bgr888; 4000 table[MESA_FORMAT_RGB565] = _mesa_texstore_rgb565; 4001 table[MESA_FORMAT_RGB565_REV] = _mesa_texstore_rgb565; 4002 table[MESA_FORMAT_ARGB4444] = _mesa_texstore_argb4444; 4003 table[MESA_FORMAT_ARGB4444_REV] = _mesa_texstore_argb4444; 4004 table[MESA_FORMAT_RGBA5551] = _mesa_texstore_rgba5551; 4005 table[MESA_FORMAT_ARGB1555] = _mesa_texstore_argb1555; 4006 table[MESA_FORMAT_ARGB1555_REV] = _mesa_texstore_argb1555; 4007 table[MESA_FORMAT_AL44] = _mesa_texstore_unorm44; 4008 table[MESA_FORMAT_AL88] = _mesa_texstore_unorm88; 4009 table[MESA_FORMAT_AL88_REV] = _mesa_texstore_unorm88; 4010 table[MESA_FORMAT_AL1616] = _mesa_texstore_unorm1616; 4011 table[MESA_FORMAT_AL1616_REV] = _mesa_texstore_unorm1616; 4012 table[MESA_FORMAT_RGB332] = _mesa_texstore_rgb332; 4013 table[MESA_FORMAT_A8] = _mesa_texstore_unorm8; 4014 table[MESA_FORMAT_A16] = _mesa_texstore_unorm16; 4015 table[MESA_FORMAT_L8] = _mesa_texstore_unorm8; 4016 table[MESA_FORMAT_L16] = _mesa_texstore_unorm16; 4017 table[MESA_FORMAT_I8] = _mesa_texstore_unorm8; 4018 table[MESA_FORMAT_I16] = _mesa_texstore_unorm16; 4019 table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr; 4020 table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr; 4021 table[MESA_FORMAT_R8] = _mesa_texstore_unorm8; 4022 table[MESA_FORMAT_GR88] = _mesa_texstore_unorm88; 4023 table[MESA_FORMAT_RG88] = _mesa_texstore_unorm88; 4024 table[MESA_FORMAT_R16] = _mesa_texstore_unorm16; 4025 table[MESA_FORMAT_RG1616] = _mesa_texstore_unorm1616; 4026 table[MESA_FORMAT_RG1616_REV] = _mesa_texstore_unorm1616; 4027 table[MESA_FORMAT_ARGB2101010] = _mesa_texstore_argb2101010; 4028 table[MESA_FORMAT_Z24_S8] = _mesa_texstore_z24_s8; 4029 table[MESA_FORMAT_S8_Z24] = _mesa_texstore_s8_z24; 4030 table[MESA_FORMAT_Z16] = _mesa_texstore_z16; 4031 table[MESA_FORMAT_X8_Z24] = _mesa_texstore_x8_z24; 4032 table[MESA_FORMAT_Z24_X8] = _mesa_texstore_z24_x8; 4033 table[MESA_FORMAT_Z32] = _mesa_texstore_z32; 4034 table[MESA_FORMAT_S8] = _mesa_texstore_s8; 4035 table[MESA_FORMAT_SRGB8] = _mesa_texstore_srgb8; 4036 table[MESA_FORMAT_SRGBA8] = _mesa_texstore_srgba8; 4037 table[MESA_FORMAT_SARGB8] = _mesa_texstore_sargb8; 4038 table[MESA_FORMAT_SL8] = _mesa_texstore_sl8; 4039 table[MESA_FORMAT_SLA8] = _mesa_texstore_sla8; 4040 table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1; 4041 table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1; 4042 table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3; 4043 table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5; 4044 table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1; 4045 table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1; 4046 table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1; 4047 table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1; 4048 table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3; 4049 table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5; 4050 table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32; 4051 table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16; 4052 table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32; 4053 table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16; 4054 table[MESA_FORMAT_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32; 4055 table[MESA_FORMAT_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16; 4056 table[MESA_FORMAT_LUMINANCE_FLOAT32] = _mesa_texstore_rgba_float32; 4057 table[MESA_FORMAT_LUMINANCE_FLOAT16] = _mesa_texstore_rgba_float16; 4058 table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32; 4059 table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16; 4060 table[MESA_FORMAT_INTENSITY_FLOAT32] = _mesa_texstore_rgba_float32; 4061 table[MESA_FORMAT_INTENSITY_FLOAT16] = _mesa_texstore_rgba_float16; 4062 table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32; 4063 table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16; 4064 table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32; 4065 table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16; 4066 table[MESA_FORMAT_DUDV8] = _mesa_texstore_dudv8; 4067 table[MESA_FORMAT_SIGNED_R8] = _mesa_texstore_snorm8; 4068 table[MESA_FORMAT_SIGNED_RG88_REV] = _mesa_texstore_snorm88; 4069 table[MESA_FORMAT_SIGNED_RGBX8888] = _mesa_texstore_signed_rgbx8888; 4070 table[MESA_FORMAT_SIGNED_RGBA8888] = _mesa_texstore_signed_rgba8888; 4071 table[MESA_FORMAT_SIGNED_RGBA8888_REV] = _mesa_texstore_signed_rgba8888; 4072 table[MESA_FORMAT_SIGNED_R16] = _mesa_texstore_snorm16; 4073 table[MESA_FORMAT_SIGNED_GR1616] = _mesa_texstore_snorm1616; 4074 table[MESA_FORMAT_SIGNED_RGB_16] = _mesa_texstore_signed_rgba_16; 4075 table[MESA_FORMAT_SIGNED_RGBA_16] = _mesa_texstore_signed_rgba_16; 4076 table[MESA_FORMAT_RGBA_16] = _mesa_texstore_rgba_16; 4077 table[MESA_FORMAT_RED_RGTC1] = _mesa_texstore_red_rgtc1; 4078 table[MESA_FORMAT_SIGNED_RED_RGTC1] = _mesa_texstore_signed_red_rgtc1; 4079 table[MESA_FORMAT_RG_RGTC2] = _mesa_texstore_rg_rgtc2; 4080 table[MESA_FORMAT_SIGNED_RG_RGTC2] = _mesa_texstore_signed_rg_rgtc2; 4081 table[MESA_FORMAT_L_LATC1] = _mesa_texstore_red_rgtc1; 4082 table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1; 4083 table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2; 4084 table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2; 4085 table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8; 4086 table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8; 4087 table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8; 4088 table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88; 4089 table[MESA_FORMAT_SIGNED_I8] = _mesa_texstore_snorm8; 4090 table[MESA_FORMAT_SIGNED_A16] = _mesa_texstore_snorm16; 4091 table[MESA_FORMAT_SIGNED_L16] = _mesa_texstore_snorm16; 4092 table[MESA_FORMAT_SIGNED_AL1616] = _mesa_texstore_snorm1616; 4093 table[MESA_FORMAT_SIGNED_I16] = _mesa_texstore_snorm16; 4094 table[MESA_FORMAT_RGB9_E5_FLOAT] = _mesa_texstore_rgb9_e5; 4095 table[MESA_FORMAT_R11_G11_B10_FLOAT] = _mesa_texstore_r11_g11_b10f; 4096 table[MESA_FORMAT_Z32_FLOAT] = _mesa_texstore_z32; 4097 table[MESA_FORMAT_Z32_FLOAT_X24S8] = _mesa_texstore_z32f_x24s8; 4098 4099 table[MESA_FORMAT_ALPHA_UINT8] = _mesa_texstore_rgba_uint8; 4100 table[MESA_FORMAT_ALPHA_UINT16] = _mesa_texstore_rgba_uint16; 4101 table[MESA_FORMAT_ALPHA_UINT32] = _mesa_texstore_rgba_uint32; 4102 table[MESA_FORMAT_ALPHA_INT8] = _mesa_texstore_rgba_int8; 4103 table[MESA_FORMAT_ALPHA_INT16] = _mesa_texstore_rgba_int16; 4104 table[MESA_FORMAT_ALPHA_INT32] = _mesa_texstore_rgba_int32; 4105 4106 table[MESA_FORMAT_INTENSITY_UINT8] = _mesa_texstore_rgba_uint8; 4107 table[MESA_FORMAT_INTENSITY_UINT16] = _mesa_texstore_rgba_uint16; 4108 table[MESA_FORMAT_INTENSITY_UINT32] = _mesa_texstore_rgba_uint32; 4109 table[MESA_FORMAT_INTENSITY_INT8] = _mesa_texstore_rgba_int8; 4110 table[MESA_FORMAT_INTENSITY_INT16] = _mesa_texstore_rgba_int16; 4111 table[MESA_FORMAT_INTENSITY_INT32] = _mesa_texstore_rgba_int32; 4112 4113 table[MESA_FORMAT_LUMINANCE_UINT8] = _mesa_texstore_rgba_uint8; 4114 table[MESA_FORMAT_LUMINANCE_UINT16] = _mesa_texstore_rgba_uint16; 4115 table[MESA_FORMAT_LUMINANCE_UINT32] = _mesa_texstore_rgba_uint32; 4116 table[MESA_FORMAT_LUMINANCE_INT8] = _mesa_texstore_rgba_int8; 4117 table[MESA_FORMAT_LUMINANCE_INT16] = _mesa_texstore_rgba_int16; 4118 table[MESA_FORMAT_LUMINANCE_INT32] = _mesa_texstore_rgba_int32; 4119 4120 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT8] = _mesa_texstore_rgba_uint8; 4121 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT16] = _mesa_texstore_rgba_uint16; 4122 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT32] = _mesa_texstore_rgba_uint32; 4123 table[MESA_FORMAT_LUMINANCE_ALPHA_INT8] = _mesa_texstore_rgba_int8; 4124 table[MESA_FORMAT_LUMINANCE_ALPHA_INT16] = _mesa_texstore_rgba_int16; 4125 table[MESA_FORMAT_LUMINANCE_ALPHA_INT32] = _mesa_texstore_rgba_int32; 4126 4127 table[MESA_FORMAT_R_INT8] = _mesa_texstore_rgba_int8; 4128 table[MESA_FORMAT_RG_INT8] = _mesa_texstore_rgba_int8; 4129 table[MESA_FORMAT_RGB_INT8] = _mesa_texstore_rgba_int8; 4130 table[MESA_FORMAT_RGBA_INT8] = _mesa_texstore_rgba_int8; 4131 table[MESA_FORMAT_R_INT16] = _mesa_texstore_rgba_int16; 4132 table[MESA_FORMAT_RG_INT16] = _mesa_texstore_rgba_int16; 4133 table[MESA_FORMAT_RGB_INT16] = _mesa_texstore_rgba_int16; 4134 table[MESA_FORMAT_RGBA_INT16] = _mesa_texstore_rgba_int16; 4135 table[MESA_FORMAT_R_INT32] = _mesa_texstore_rgba_int32; 4136 table[MESA_FORMAT_RG_INT32] = _mesa_texstore_rgba_int32; 4137 table[MESA_FORMAT_RGB_INT32] = _mesa_texstore_rgba_int32; 4138 table[MESA_FORMAT_RGBA_INT32] = _mesa_texstore_rgba_int32; 4139 4140 table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8; 4141 table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8; 4142 table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8; 4143 table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8; 4144 table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16; 4145 table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16; 4146 table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16; 4147 table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16; 4148 table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32; 4149 table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32; 4150 table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32; 4151 table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32; 4152 4153 table[MESA_FORMAT_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint; 4154 table[MESA_FORMAT_ABGR2101010_UINT] = _mesa_texstore_abgr2101010_uint; 4155 initialized = GL_TRUE; 4156 } 4157 4158 ASSERT(table[format]); 4159 return table[format]; 4160} 4161 4162 4163/** 4164 * Store user data into texture memory. 4165 * Called via glTex[Sub]Image1/2/3D() 4166 */ 4167GLboolean 4168_mesa_texstore(TEXSTORE_PARAMS) 4169{ 4170 StoreTexImageFunc storeImage; 4171 GLboolean success; 4172 4173 storeImage = _mesa_get_texstore_func(dstFormat); 4174 4175 success = storeImage(ctx, dims, baseInternalFormat, 4176 dstFormat, 4177 dstRowStride, dstSlices, 4178 srcWidth, srcHeight, srcDepth, 4179 srcFormat, srcType, srcAddr, srcPacking); 4180 return success; 4181} 4182 4183 4184/** 4185 * Normally, we'll only _write_ texel data to a texture when we map it. 4186 * But if the user is providing depth or stencil values and the texture 4187 * image is a combined depth/stencil format, we'll actually read from 4188 * the texture buffer too (in order to insert the depth or stencil values. 4189 * \param userFormat the user-provided image format 4190 * \param texFormat the destination texture format 4191 */ 4192static GLbitfield 4193get_read_write_mode(GLenum userFormat, gl_format texFormat) 4194{ 4195 if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT) 4196 && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL) 4197 return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; 4198 else 4199 return GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT; 4200} 4201 4202 4203/** 4204 * Helper function for storing 1D, 2D, 3D whole and subimages into texture 4205 * memory. 4206 * The source of the image data may be user memory or a PBO. In the later 4207 * case, we'll map the PBO, copy from it, then unmap it. 4208 */ 4209static void 4210store_texsubimage(struct gl_context *ctx, 4211 struct gl_texture_image *texImage, 4212 GLint xoffset, GLint yoffset, GLint zoffset, 4213 GLint width, GLint height, GLint depth, 4214 GLenum format, GLenum type, const GLvoid *pixels, 4215 const struct gl_pixelstore_attrib *packing, 4216 const char *caller) 4217 4218{ 4219 const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat); 4220 const GLenum target = texImage->TexObject->Target; 4221 GLboolean success = GL_FALSE; 4222 GLuint dims, slice, numSlices = 1, sliceOffset = 0; 4223 GLint srcImageStride = 0; 4224 const GLubyte *src; 4225 4226 assert(xoffset + width <= texImage->Width); 4227 assert(yoffset + height <= texImage->Height); 4228 assert(zoffset + depth <= texImage->Depth); 4229 4230 switch (target) { 4231 case GL_TEXTURE_1D: 4232 dims = 1; 4233 break; 4234 case GL_TEXTURE_2D_ARRAY: 4235 case GL_TEXTURE_3D: 4236 dims = 3; 4237 break; 4238 default: 4239 dims = 2; 4240 } 4241 4242 /* get pointer to src pixels (may be in a pbo which we'll map here) */ 4243 src = (const GLubyte *) 4244 _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, 4245 format, type, pixels, packing, caller); 4246 if (!src) 4247 return; 4248 4249 /* compute slice info (and do some sanity checks) */ 4250 switch (target) { 4251 case GL_TEXTURE_2D: 4252 case GL_TEXTURE_RECTANGLE: 4253 case GL_TEXTURE_CUBE_MAP: 4254 /* one image slice, nothing special needs to be done */ 4255 break; 4256 case GL_TEXTURE_1D: 4257 assert(height == 1); 4258 assert(depth == 1); 4259 assert(yoffset == 0); 4260 assert(zoffset == 0); 4261 break; 4262 case GL_TEXTURE_1D_ARRAY: 4263 assert(depth == 1); 4264 assert(zoffset == 0); 4265 numSlices = height; 4266 sliceOffset = yoffset; 4267 height = 1; 4268 yoffset = 0; 4269 srcImageStride = _mesa_image_row_stride(packing, width, format, type); 4270 break; 4271 case GL_TEXTURE_2D_ARRAY: 4272 numSlices = depth; 4273 sliceOffset = zoffset; 4274 depth = 1; 4275 zoffset = 0; 4276 srcImageStride = _mesa_image_image_stride(packing, width, height, 4277 format, type); 4278 break; 4279 case GL_TEXTURE_3D: 4280 /* we'll store 3D images as a series of slices */ 4281 numSlices = depth; 4282 sliceOffset = zoffset; 4283 srcImageStride = _mesa_image_image_stride(packing, width, height, 4284 format, type); 4285 break; 4286 default: 4287 _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target); 4288 return; 4289 } 4290 4291 assert(numSlices == 1 || srcImageStride != 0); 4292 4293 for (slice = 0; slice < numSlices; slice++) { 4294 GLubyte *dstMap; 4295 GLint dstRowStride; 4296 4297 ctx->Driver.MapTextureImage(ctx, texImage, 4298 slice + sliceOffset, 4299 xoffset, yoffset, width, height, 4300 mapMode, &dstMap, &dstRowStride); 4301 if (dstMap) { 4302 /* Note: we're only storing a 2D (or 1D) slice at a time but we need 4303 * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is 4304 * used for 3D images. 4305 */ 4306 success = _mesa_texstore(ctx, dims, texImage->_BaseFormat, 4307 texImage->TexFormat, 4308 dstRowStride, 4309 &dstMap, 4310 width, height, 1, /* w, h, d */ 4311 format, type, src, packing); 4312 4313 ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset); 4314 } 4315 4316 src += srcImageStride; 4317 4318 if (!success) 4319 break; 4320 } 4321 4322 if (!success) 4323 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); 4324 4325 _mesa_unmap_teximage_pbo(ctx, packing); 4326} 4327 4328 4329 4330/** 4331 * Fallback code for ctx->Driver.TexImage(). 4332 * Basically, allocate storage for the texture image, then copy the 4333 * user's image into it. 4334 */ 4335void 4336_mesa_store_teximage(struct gl_context *ctx, 4337 GLuint dims, 4338 struct gl_texture_image *texImage, 4339 GLenum format, GLenum type, const GLvoid *pixels, 4340 const struct gl_pixelstore_attrib *packing) 4341{ 4342 assert(dims == 1 || dims == 2 || dims == 3); 4343 4344 if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0) 4345 return; 4346 4347 /* allocate storage for texture data */ 4348 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { 4349 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); 4350 return; 4351 } 4352 4353 store_texsubimage(ctx, texImage, 4354 0, 0, 0, texImage->Width, texImage->Height, texImage->Depth, 4355 format, type, pixels, packing, "glTexImage"); 4356} 4357 4358 4359/* 4360 * Fallback for Driver.TexSubImage(). 4361 */ 4362void 4363_mesa_store_texsubimage(struct gl_context *ctx, GLuint dims, 4364 struct gl_texture_image *texImage, 4365 GLint xoffset, GLint yoffset, GLint zoffset, 4366 GLint width, GLint height, GLint depth, 4367 GLenum format, GLenum type, const void *pixels, 4368 const struct gl_pixelstore_attrib *packing) 4369{ 4370 store_texsubimage(ctx, texImage, 4371 xoffset, yoffset, zoffset, width, height, depth, 4372 format, type, pixels, packing, "glTexSubImage"); 4373} 4374 4375 4376/** 4377 * Fallback for Driver.CompressedTexImage() 4378 */ 4379void 4380_mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims, 4381 struct gl_texture_image *texImage, 4382 GLsizei imageSize, const GLvoid *data) 4383{ 4384 /* only 2D compressed images are supported at this time */ 4385 if (dims != 2) { 4386 _mesa_problem(ctx, "Unexpected glCompressedTexImage1D/3D call"); 4387 return; 4388 } 4389 4390 /* This is pretty simple, because unlike the general texstore path we don't 4391 * have to worry about the usual image unpacking or image transfer 4392 * operations. 4393 */ 4394 ASSERT(texImage); 4395 ASSERT(texImage->Width > 0); 4396 ASSERT(texImage->Height > 0); 4397 ASSERT(texImage->Depth == 1); 4398 4399 /* allocate storage for texture data */ 4400 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { 4401 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); 4402 return; 4403 } 4404 4405 _mesa_store_compressed_texsubimage(ctx, dims, texImage, 4406 0, 0, 0, 4407 texImage->Width, texImage->Height, texImage->Depth, 4408 texImage->TexFormat, 4409 imageSize, data); 4410} 4411 4412 4413/** 4414 * Fallback for Driver.CompressedTexSubImage() 4415 */ 4416void 4417_mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, 4418 struct gl_texture_image *texImage, 4419 GLint xoffset, GLint yoffset, GLint zoffset, 4420 GLsizei width, GLsizei height, GLsizei depth, 4421 GLenum format, 4422 GLsizei imageSize, const GLvoid *data) 4423{ 4424 GLint bytesPerRow, dstRowStride, srcRowStride; 4425 GLint i, rows; 4426 GLubyte *dstMap; 4427 const GLubyte *src; 4428 const gl_format texFormat = texImage->TexFormat; 4429 GLuint bw, bh; 4430 4431 if (dims != 2) { 4432 _mesa_problem(ctx, "Unexpected 1D/3D compressed texsubimage call"); 4433 return; 4434 } 4435 4436 _mesa_get_format_block_size(texFormat, &bw, &bh); 4437 4438 /* these should have been caught sooner */ 4439 ASSERT((width % bw) == 0 || width < bw); 4440 ASSERT((height % bh) == 0 || height < bh); 4441 ASSERT((xoffset % bw) == 0); 4442 ASSERT((yoffset % bh) == 0); 4443 4444 /* get pointer to src pixels (may be in a pbo which we'll map here) */ 4445 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data, 4446 &ctx->Unpack, 4447 "glCompressedTexSubImage2D"); 4448 if (!data) 4449 return; 4450 4451 srcRowStride = _mesa_format_row_stride(texFormat, width); 4452 src = (const GLubyte *) data; 4453 4454 /* Map dest texture buffer */ 4455 ctx->Driver.MapTextureImage(ctx, texImage, 0, 4456 xoffset, yoffset, width, height, 4457 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT, 4458 &dstMap, &dstRowStride); 4459 4460 if (dstMap) { 4461 bytesPerRow = srcRowStride; /* bytes per row of blocks */ 4462 rows = (height + bh - 1) / bh; /* rows in blocks */ 4463 4464 /* copy rows of blocks */ 4465 for (i = 0; i < rows; i++) { 4466 memcpy(dstMap, src, bytesPerRow); 4467 dstMap += dstRowStride; 4468 src += srcRowStride; 4469 } 4470 4471 ctx->Driver.UnmapTextureImage(ctx, texImage, 0); 4472 } 4473 else { 4474 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D"); 4475 } 4476 4477 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack); 4478} 4479