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