Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentexstore.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.3 00004 * 00005 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 /* 00026 * Authors: 00027 * Brian Paul 00028 */ 00029 00054 #include "glheader.h" 00055 #include "bufferobj.h" 00056 #include "colormac.h" 00057 #include "context.h" 00058 #if FEATURE_convolve 00059 #include "convolve.h" 00060 #endif 00061 #include "image.h" 00062 #include "macros.h" 00063 #include "mipmap.h" 00064 #include "imports.h" 00065 #include "texcompress.h" 00066 #include "texformat.h" 00067 #include "teximage.h" 00068 #include "texstore.h" 00069 #include "enums.h" 00070 00071 00072 enum { 00073 ZERO = 4, 00074 ONE = 5 00075 }; 00076 00077 00082 static GLboolean 00083 can_swizzle(GLenum logicalBaseFormat) 00084 { 00085 switch (logicalBaseFormat) { 00086 case GL_RGBA: 00087 case GL_RGB: 00088 case GL_LUMINANCE_ALPHA: 00089 case GL_INTENSITY: 00090 case GL_ALPHA: 00091 case GL_LUMINANCE: 00092 case GL_RED: 00093 case GL_GREEN: 00094 case GL_BLUE: 00095 case GL_BGR: 00096 case GL_BGRA: 00097 case GL_ABGR_EXT: 00098 return GL_TRUE; 00099 default: 00100 return GL_FALSE; 00101 } 00102 } 00103 00104 00105 00106 enum { 00107 IDX_LUMINANCE = 0, 00108 IDX_ALPHA, 00109 IDX_INTENSITY, 00110 IDX_LUMINANCE_ALPHA, 00111 IDX_RGB, 00112 IDX_RGBA, 00113 IDX_RED, 00114 IDX_GREEN, 00115 IDX_BLUE, 00116 IDX_BGR, 00117 IDX_BGRA, 00118 IDX_ABGR, 00119 MAX_IDX 00120 }; 00121 00122 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO) 00123 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO) 00124 #define MAP3(x,y,z) MAP4(x, y, z, ZERO) 00125 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE } 00126 00127 00128 static const struct { 00129 GLubyte format_idx; 00130 GLubyte to_rgba[6]; 00131 GLubyte from_rgba[6]; 00132 } mappings[MAX_IDX] = 00133 { 00134 { 00135 IDX_LUMINANCE, 00136 MAP4(0,0,0,ONE), 00137 MAP1(0) 00138 }, 00139 00140 { 00141 IDX_ALPHA, 00142 MAP4(ZERO, ZERO, ZERO, 0), 00143 MAP1(3) 00144 }, 00145 00146 { 00147 IDX_INTENSITY, 00148 MAP4(0, 0, 0, 0), 00149 MAP1(0), 00150 }, 00151 00152 { 00153 IDX_LUMINANCE_ALPHA, 00154 MAP4(0,0,0,1), 00155 MAP2(0,3) 00156 }, 00157 00158 { 00159 IDX_RGB, 00160 MAP4(0,1,2,ONE), 00161 MAP3(0,1,2) 00162 }, 00163 00164 { 00165 IDX_RGBA, 00166 MAP4(0,1,2,3), 00167 MAP4(0,1,2,3), 00168 }, 00169 00170 00171 { 00172 IDX_RED, 00173 MAP4(0, ZERO, ZERO, ONE), 00174 MAP1(0), 00175 }, 00176 00177 { 00178 IDX_GREEN, 00179 MAP4(ZERO, 0, ZERO, ONE), 00180 MAP1(1), 00181 }, 00182 00183 { 00184 IDX_BLUE, 00185 MAP4(ZERO, ZERO, 0, ONE), 00186 MAP1(2), 00187 }, 00188 00189 { 00190 IDX_BGR, 00191 MAP4(2,1,0,ONE), 00192 MAP3(2,1,0) 00193 }, 00194 00195 { 00196 IDX_BGRA, 00197 MAP4(2,1,0,3), 00198 MAP4(2,1,0,3) 00199 }, 00200 00201 { 00202 IDX_ABGR, 00203 MAP4(3,2,1,0), 00204 MAP4(3,2,1,0) 00205 }, 00206 }; 00207 00208 00209 00213 static int 00214 get_map_idx(GLenum value) 00215 { 00216 switch (value) { 00217 case GL_LUMINANCE: return IDX_LUMINANCE; 00218 case GL_ALPHA: return IDX_ALPHA; 00219 case GL_INTENSITY: return IDX_INTENSITY; 00220 case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA; 00221 case GL_RGB: return IDX_RGB; 00222 case GL_RGBA: return IDX_RGBA; 00223 case GL_RED: return IDX_RED; 00224 case GL_GREEN: return IDX_GREEN; 00225 case GL_BLUE: return IDX_BLUE; 00226 case GL_BGR: return IDX_BGR; 00227 case GL_BGRA: return IDX_BGRA; 00228 case GL_ABGR_EXT: return IDX_ABGR; 00229 default: 00230 _mesa_problem(NULL, "Unexpected inFormat"); 00231 return 0; 00232 } 00233 } 00234 00235 00244 static void 00245 compute_component_mapping(GLenum inFormat, GLenum outFormat, 00246 GLubyte *map) 00247 { 00248 const int inFmt = get_map_idx(inFormat); 00249 const int outFmt = get_map_idx(outFormat); 00250 const GLubyte *in2rgba = mappings[inFmt].to_rgba; 00251 const GLubyte *rgba2out = mappings[outFmt].from_rgba; 00252 int i; 00253 00254 for (i = 0; i < 4; i++) 00255 map[i] = in2rgba[rgba2out[i]]; 00256 00257 map[ZERO] = ZERO; 00258 map[ONE] = ONE; 00259 00260 /* 00261 _mesa_printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n", 00262 inFormat, _mesa_lookup_enum_by_nr(inFormat), 00263 outFormat, _mesa_lookup_enum_by_nr(outFormat), 00264 map[0], 00265 map[1], 00266 map[2], 00267 map[3], 00268 map[4], 00269 map[5]); 00270 */ 00271 } 00272 00273 00274 #if !FEATURE_convolve 00275 static void 00276 _mesa_adjust_image_for_convolution(GLcontext *ctx, GLuint dims, 00277 GLsizei *srcWidth, GLsizei *srcHeight) 00278 { 00279 /* no-op */ 00280 } 00281 #endif 00282 00283 00307 static GLfloat * 00308 make_temp_float_image(GLcontext *ctx, GLuint dims, 00309 GLenum logicalBaseFormat, 00310 GLenum textureBaseFormat, 00311 GLint srcWidth, GLint srcHeight, GLint srcDepth, 00312 GLenum srcFormat, GLenum srcType, 00313 const GLvoid *srcAddr, 00314 const struct gl_pixelstore_attrib *srcPacking) 00315 { 00316 GLuint transferOps = ctx->_ImageTransferState; 00317 GLfloat *tempImage; 00318 00319 ASSERT(dims >= 1 && dims <= 3); 00320 00321 ASSERT(logicalBaseFormat == GL_RGBA || 00322 logicalBaseFormat == GL_RGB || 00323 logicalBaseFormat == GL_LUMINANCE_ALPHA || 00324 logicalBaseFormat == GL_LUMINANCE || 00325 logicalBaseFormat == GL_ALPHA || 00326 logicalBaseFormat == GL_INTENSITY || 00327 logicalBaseFormat == GL_COLOR_INDEX || 00328 logicalBaseFormat == GL_DEPTH_COMPONENT); 00329 00330 ASSERT(textureBaseFormat == GL_RGBA || 00331 textureBaseFormat == GL_RGB || 00332 textureBaseFormat == GL_LUMINANCE_ALPHA || 00333 textureBaseFormat == GL_LUMINANCE || 00334 textureBaseFormat == GL_ALPHA || 00335 textureBaseFormat == GL_INTENSITY || 00336 textureBaseFormat == GL_COLOR_INDEX || 00337 textureBaseFormat == GL_DEPTH_COMPONENT); 00338 00339 /* conventional color image */ 00340 00341 if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) || 00342 (dims >= 2 && ctx->Pixel.Convolution2DEnabled) || 00343 (dims >= 2 && ctx->Pixel.Separable2DEnabled)) { 00344 /* need image convolution */ 00345 const GLuint preConvTransferOps 00346 = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT; 00347 const GLuint postConvTransferOps 00348 = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT; 00349 GLint img, row; 00350 GLint convWidth, convHeight; 00351 GLfloat *convImage; 00352 00353 /* pre-convolution image buffer (3D) */ 00354 tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth 00355 * 4 * sizeof(GLfloat)); 00356 if (!tempImage) 00357 return NULL; 00358 00359 /* post-convolution image buffer (2D) */ 00360 convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight 00361 * 4 * sizeof(GLfloat)); 00362 if (!convImage) { 00363 _mesa_free(tempImage); 00364 return NULL; 00365 } 00366 00367 /* loop over 3D image slices */ 00368 for (img = 0; img < srcDepth; img++) { 00369 GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4); 00370 00371 /* unpack and do transfer ops up to convolution */ 00372 for (row = 0; row < srcHeight; row++) { 00373 const GLvoid *src = _mesa_image_address(dims, srcPacking, 00374 srcAddr, srcWidth, srcHeight, 00375 srcFormat, srcType, img, row, 0); 00376 _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst, 00377 srcFormat, srcType, src, 00378 srcPacking, 00379 preConvTransferOps); 00380 dst += srcWidth * 4; 00381 } 00382 00383 /* size after optional convolution */ 00384 convWidth = srcWidth; 00385 convHeight = srcHeight; 00386 00387 #if FEATURE_convolve 00388 /* do convolution */ 00389 { 00390 GLfloat *src = tempImage + img * (srcWidth * srcHeight * 4); 00391 if (dims == 1) { 00392 ASSERT(ctx->Pixel.Convolution1DEnabled); 00393 _mesa_convolve_1d_image(ctx, &convWidth, src, convImage); 00394 } 00395 else { 00396 if (ctx->Pixel.Convolution2DEnabled) { 00397 _mesa_convolve_2d_image(ctx, &convWidth, &convHeight, 00398 src, convImage); 00399 } 00400 else { 00401 ASSERT(ctx->Pixel.Separable2DEnabled); 00402 _mesa_convolve_sep_image(ctx, &convWidth, &convHeight, 00403 src, convImage); 00404 } 00405 } 00406 } 00407 #endif 00408 /* do post-convolution transfer and pack into tempImage */ 00409 { 00410 const GLint logComponents 00411 = _mesa_components_in_format(logicalBaseFormat); 00412 const GLfloat *src = convImage; 00413 GLfloat *dst = tempImage + img * (convWidth * convHeight * 4); 00414 for (row = 0; row < convHeight; row++) { 00415 _mesa_pack_rgba_span_float(ctx, convWidth, 00416 (GLfloat (*)[4]) src, 00417 logicalBaseFormat, GL_FLOAT, 00418 dst, &ctx->DefaultPacking, 00419 postConvTransferOps); 00420 src += convWidth * 4; 00421 dst += convWidth * logComponents; 00422 } 00423 } 00424 } /* loop over 3D image slices */ 00425 00426 _mesa_free(convImage); 00427 00428 /* might need these below */ 00429 srcWidth = convWidth; 00430 srcHeight = convHeight; 00431 } 00432 else { 00433 /* no convolution */ 00434 const GLint components = _mesa_components_in_format(logicalBaseFormat); 00435 const GLint srcStride = _mesa_image_row_stride(srcPacking, 00436 srcWidth, srcFormat, srcType); 00437 GLfloat *dst; 00438 GLint img, row; 00439 00440 tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth 00441 * components * sizeof(GLfloat)); 00442 if (!tempImage) 00443 return NULL; 00444 00445 dst = tempImage; 00446 for (img = 0; img < srcDepth; img++) { 00447 const GLubyte *src 00448 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, 00449 srcWidth, srcHeight, 00450 srcFormat, srcType, 00451 img, 0, 0); 00452 for (row = 0; row < srcHeight; row++) { 00453 _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat, 00454 dst, srcFormat, srcType, src, 00455 srcPacking, transferOps); 00456 dst += srcWidth * components; 00457 src += srcStride; 00458 } 00459 } 00460 } 00461 00462 if (logicalBaseFormat != textureBaseFormat) { 00463 /* more work */ 00464 GLint texComponents = _mesa_components_in_format(textureBaseFormat); 00465 GLint logComponents = _mesa_components_in_format(logicalBaseFormat); 00466 GLfloat *newImage; 00467 GLint i, n; 00468 GLubyte map[6]; 00469 00470 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ 00471 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || 00472 textureBaseFormat == GL_LUMINANCE_ALPHA); 00473 00474 /* The actual texture format should have at least as many components 00475 * as the logical texture format. 00476 */ 00477 ASSERT(texComponents >= logComponents); 00478 00479 newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth 00480 * texComponents * sizeof(GLfloat)); 00481 if (!newImage) { 00482 _mesa_free(tempImage); 00483 return NULL; 00484 } 00485 00486 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); 00487 00488 n = srcWidth * srcHeight * srcDepth; 00489 for (i = 0; i < n; i++) { 00490 GLint k; 00491 for (k = 0; k < texComponents; k++) { 00492 GLint j = map[k]; 00493 if (j == ZERO) 00494 newImage[i * texComponents + k] = 0.0F; 00495 else if (j == ONE) 00496 newImage[i * texComponents + k] = 1.0F; 00497 else 00498 newImage[i * texComponents + k] = tempImage[i * logComponents + j]; 00499 } 00500 } 00501 00502 _mesa_free(tempImage); 00503 tempImage = newImage; 00504 } 00505 00506 return tempImage; 00507 } 00508 00509 00533 GLchan * 00534 _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims, 00535 GLenum logicalBaseFormat, 00536 GLenum textureBaseFormat, 00537 GLint srcWidth, GLint srcHeight, GLint srcDepth, 00538 GLenum srcFormat, GLenum srcType, 00539 const GLvoid *srcAddr, 00540 const struct gl_pixelstore_attrib *srcPacking) 00541 { 00542 GLuint transferOps = ctx->_ImageTransferState; 00543 const GLint components = _mesa_components_in_format(logicalBaseFormat); 00544 GLboolean freeSrcImage = GL_FALSE; 00545 GLint img, row; 00546 GLchan *tempImage, *dst; 00547 00548 ASSERT(dims >= 1 && dims <= 3); 00549 00550 ASSERT(logicalBaseFormat == GL_RGBA || 00551 logicalBaseFormat == GL_RGB || 00552 logicalBaseFormat == GL_LUMINANCE_ALPHA || 00553 logicalBaseFormat == GL_LUMINANCE || 00554 logicalBaseFormat == GL_ALPHA || 00555 logicalBaseFormat == GL_INTENSITY); 00556 00557 ASSERT(textureBaseFormat == GL_RGBA || 00558 textureBaseFormat == GL_RGB || 00559 textureBaseFormat == GL_LUMINANCE_ALPHA || 00560 textureBaseFormat == GL_LUMINANCE || 00561 textureBaseFormat == GL_ALPHA || 00562 textureBaseFormat == GL_INTENSITY); 00563 00564 #if FEATURE_convolve 00565 if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) || 00566 (dims >= 2 && ctx->Pixel.Convolution2DEnabled) || 00567 (dims >= 2 && ctx->Pixel.Separable2DEnabled)) { 00568 /* get convolved image */ 00569 GLfloat *convImage = make_temp_float_image(ctx, dims, 00570 logicalBaseFormat, 00571 logicalBaseFormat, 00572 srcWidth, srcHeight, srcDepth, 00573 srcFormat, srcType, 00574 srcAddr, srcPacking); 00575 if (!convImage) 00576 return NULL; 00577 /* the convolved image is our new source image */ 00578 srcAddr = convImage; 00579 srcFormat = logicalBaseFormat; 00580 srcType = GL_FLOAT; 00581 srcPacking = &ctx->DefaultPacking; 00582 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 00583 transferOps = 0; 00584 freeSrcImage = GL_TRUE; 00585 } 00586 #endif 00587 00588 /* unpack and transfer the source image */ 00589 tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth 00590 * components * sizeof(GLchan)); 00591 if (!tempImage) 00592 return NULL; 00593 00594 dst = tempImage; 00595 for (img = 0; img < srcDepth; img++) { 00596 const GLint srcStride = _mesa_image_row_stride(srcPacking, 00597 srcWidth, srcFormat, 00598 srcType); 00599 const GLubyte *src 00600 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr, 00601 srcWidth, srcHeight, 00602 srcFormat, srcType, 00603 img, 0, 0); 00604 for (row = 0; row < srcHeight; row++) { 00605 _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst, 00606 srcFormat, srcType, src, srcPacking, 00607 transferOps); 00608 dst += srcWidth * components; 00609 src += srcStride; 00610 } 00611 } 00612 00613 /* If we made a temporary image for convolution, free it here */ 00614 if (freeSrcImage) { 00615 _mesa_free((void *) srcAddr); 00616 } 00617 00618 if (logicalBaseFormat != textureBaseFormat) { 00619 /* one more conversion step */ 00620 GLint texComponents = _mesa_components_in_format(textureBaseFormat); 00621 GLint logComponents = _mesa_components_in_format(logicalBaseFormat); 00622 GLchan *newImage; 00623 GLint i, n; 00624 GLubyte map[6]; 00625 00626 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */ 00627 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA || 00628 textureBaseFormat == GL_LUMINANCE_ALPHA); 00629 00630 /* The actual texture format should have at least as many components 00631 * as the logical texture format. 00632 */ 00633 ASSERT(texComponents >= logComponents); 00634 00635 newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth 00636 * texComponents * sizeof(GLchan)); 00637 if (!newImage) { 00638 _mesa_free(tempImage); 00639 return NULL; 00640 } 00641 00642 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map); 00643 00644 n = srcWidth * srcHeight * srcDepth; 00645 for (i = 0; i < n; i++) { 00646 GLint k; 00647 for (k = 0; k < texComponents; k++) { 00648 GLint j = map[k]; 00649 if (j == ZERO) 00650 newImage[i * texComponents + k] = 0; 00651 else if (j == ONE) 00652 newImage[i * texComponents + k] = CHAN_MAX; 00653 else 00654 newImage[i * texComponents + k] = tempImage[i * logComponents + j]; 00655 } 00656 } 00657 00658 _mesa_free(tempImage); 00659 tempImage = newImage; 00660 } 00661 00662 return tempImage; 00663 } 00664 00665 00677 static void 00678 swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src, 00679 GLuint srcComponents, const GLubyte *map, GLuint count) 00680 { 00681 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \ 00682 do { \ 00683 GLuint i; \ 00684 for (i = 0; i < count; i++) { \ 00685 GLuint j; \ 00686 if (srcComps == 4) { \ 00687 COPY_4UBV(tmp, src); \ 00688 } \ 00689 else { \ 00690 for (j = 0; j < srcComps; j++) { \ 00691 tmp[j] = src[j]; \ 00692 } \ 00693 } \ 00694 src += srcComps; \ 00695 for (j = 0; j < dstComps; j++) { \ 00696 dst[j] = tmp[map[j]]; \ 00697 } \ 00698 dst += dstComps; \ 00699 } \ 00700 } while (0) 00701 00702 GLubyte tmp[6]; 00703 00704 tmp[ZERO] = 0x0; 00705 tmp[ONE] = 0xff; 00706 00707 ASSERT(srcComponents <= 4); 00708 ASSERT(dstComponents <= 4); 00709 00710 switch (dstComponents) { 00711 case 4: 00712 switch (srcComponents) { 00713 case 4: 00714 SWZ_CPY(dst, src, count, 4, 4); 00715 break; 00716 case 3: 00717 SWZ_CPY(dst, src, count, 4, 3); 00718 break; 00719 case 2: 00720 SWZ_CPY(dst, src, count, 4, 2); 00721 break; 00722 case 1: 00723 SWZ_CPY(dst, src, count, 4, 1); 00724 break; 00725 default: 00726 ; 00727 } 00728 break; 00729 case 3: 00730 switch (srcComponents) { 00731 case 4: 00732 SWZ_CPY(dst, src, count, 3, 4); 00733 break; 00734 case 3: 00735 SWZ_CPY(dst, src, count, 3, 3); 00736 break; 00737 case 2: 00738 SWZ_CPY(dst, src, count, 3, 2); 00739 break; 00740 case 1: 00741 SWZ_CPY(dst, src, count, 3, 1); 00742 break; 00743 default: 00744 ; 00745 } 00746 break; 00747 case 2: 00748 switch (srcComponents) { 00749 case 4: 00750 SWZ_CPY(dst, src, count, 2, 4); 00751 break; 00752 case 3: 00753 SWZ_CPY(dst, src, count, 2, 3); 00754 break; 00755 case 2: 00756 SWZ_CPY(dst, src, count, 2, 2); 00757 break; 00758 case 1: 00759 SWZ_CPY(dst, src, count, 2, 1); 00760 break; 00761 default: 00762 ; 00763 } 00764 break; 00765 case 1: 00766 switch (srcComponents) { 00767 case 4: 00768 SWZ_CPY(dst, src, count, 1, 4); 00769 break; 00770 case 3: 00771 SWZ_CPY(dst, src, count, 1, 3); 00772 break; 00773 case 2: 00774 SWZ_CPY(dst, src, count, 1, 2); 00775 break; 00776 case 1: 00777 SWZ_CPY(dst, src, count, 1, 1); 00778 break; 00779 default: 00780 ; 00781 } 00782 break; 00783 default: 00784 ; 00785 } 00786 #undef SWZ_CPY 00787 } 00788 00789 00790 00791 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE }; 00792 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE }; 00793 00794 /* Deal with the _REV input types: 00795 */ 00796 static const GLubyte * 00797 type_mapping( GLenum srcType ) 00798 { 00799 switch (srcType) { 00800 case GL_UNSIGNED_BYTE: 00801 return map_identity; 00802 case GL_UNSIGNED_INT_8_8_8_8: 00803 return _mesa_little_endian() ? map_3210 : map_identity; 00804 case GL_UNSIGNED_INT_8_8_8_8_REV: 00805 return _mesa_little_endian() ? map_identity : map_3210; 00806 default: 00807 return NULL; 00808 } 00809 } 00810 00811 /* Mapping required if input type is 00812 */ 00813 static const GLubyte * 00814 byteswap_mapping( GLboolean swapBytes, 00815 GLenum srcType ) 00816 { 00817 if (!swapBytes) 00818 return map_identity; 00819 00820 switch (srcType) { 00821 case GL_UNSIGNED_BYTE: 00822 return map_identity; 00823 case GL_UNSIGNED_INT_8_8_8_8: 00824 case GL_UNSIGNED_INT_8_8_8_8_REV: 00825 return map_3210; 00826 default: 00827 return NULL; 00828 } 00829 } 00830 00831 00832 00836 static void 00837 _mesa_swizzle_ubyte_image(GLcontext *ctx, 00838 GLuint dimensions, 00839 GLenum srcFormat, 00840 GLenum srcType, 00841 00842 GLenum baseInternalFormat, 00843 00844 const GLubyte *rgba2dst, 00845 GLuint dstComponents, 00846 00847 GLvoid *dstAddr, 00848 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, 00849 GLint dstRowStride, 00850 const GLuint *dstImageOffsets, 00851 00852 GLint srcWidth, GLint srcHeight, GLint srcDepth, 00853 const GLvoid *srcAddr, 00854 const struct gl_pixelstore_attrib *srcPacking ) 00855 { 00856 GLint srcComponents = _mesa_components_in_format(srcFormat); 00857 const GLubyte *srctype2ubyte, *swap; 00858 GLubyte map[4], src2base[6], base2rgba[6]; 00859 GLint i; 00860 const GLint srcRowStride = 00861 _mesa_image_row_stride(srcPacking, srcWidth, 00862 srcFormat, GL_UNSIGNED_BYTE); 00863 const GLint srcImageStride 00864 = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat, 00865 GL_UNSIGNED_BYTE); 00866 const GLubyte *srcImage 00867 = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr, 00868 srcWidth, srcHeight, srcFormat, 00869 GL_UNSIGNED_BYTE, 0, 0, 0); 00870 00871 (void) ctx; 00872 00873 /* Translate from src->baseInternal->GL_RGBA->dst. This will 00874 * correctly deal with RGBA->RGB->RGBA conversions where the final 00875 * A value must be 0xff regardless of the incoming alpha values. 00876 */ 00877 compute_component_mapping(srcFormat, baseInternalFormat, src2base); 00878 compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba); 00879 swap = byteswap_mapping(srcPacking->SwapBytes, srcType); 00880 srctype2ubyte = type_mapping(srcType); 00881 00882 00883 for (i = 0; i < 4; i++) 00884 map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]]; 00885 00886 /* _mesa_printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */ 00887 00888 if (srcRowStride == dstRowStride && 00889 srcComponents == dstComponents && 00890 srcRowStride == srcWidth * srcComponents && 00891 dimensions < 3) { 00892 /* 1 and 2D images only */ 00893 GLubyte *dstImage = (GLubyte *) dstAddr 00894 + dstYoffset * dstRowStride 00895 + dstXoffset * dstComponents; 00896 swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map, 00897 srcWidth * srcHeight); 00898 } 00899 else { 00900 GLint img, row; 00901 for (img = 0; img < srcDepth; img++) { 00902 const GLubyte *srcRow = srcImage; 00903 GLubyte *dstRow = (GLubyte *) dstAddr 00904 + dstImageOffsets[dstZoffset + img] * dstComponents 00905 + dstYoffset * dstRowStride 00906 + dstXoffset * dstComponents; 00907 for (row = 0; row < srcHeight; row++) { 00908 swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth); 00909 dstRow += dstRowStride; 00910 srcRow += srcRowStride; 00911 } 00912 srcImage += srcImageStride; 00913 } 00914 } 00915 } 00916 00917 00923 static void 00924 memcpy_texture(GLcontext *ctx, 00925 GLuint dimensions, 00926 const struct gl_texture_format *dstFormat, 00927 GLvoid *dstAddr, 00928 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, 00929 GLint dstRowStride, 00930 const GLuint *dstImageOffsets, 00931 GLint srcWidth, GLint srcHeight, GLint srcDepth, 00932 GLenum srcFormat, GLenum srcType, 00933 const GLvoid *srcAddr, 00934 const struct gl_pixelstore_attrib *srcPacking) 00935 { 00936 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, 00937 srcFormat, srcType); 00938 const GLint srcImageStride = _mesa_image_image_stride(srcPacking, 00939 srcWidth, srcHeight, srcFormat, srcType); 00940 const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions, 00941 srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0); 00942 const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes; 00943 00944 #if 0 00945 /* XXX update/re-enable for dstImageOffsets array */ 00946 const GLint bytesPerImage = srcHeight * bytesPerRow; 00947 const GLint bytesPerTexture = srcDepth * bytesPerImage; 00948 GLubyte *dstImage = (GLubyte *) dstAddr 00949 + dstZoffset * dstImageStride 00950 + dstYoffset * dstRowStride 00951 + dstXoffset * dstFormat->TexelBytes; 00952 00953 if (dstRowStride == srcRowStride && 00954 dstRowStride == bytesPerRow && 00955 ((dstImageStride == srcImageStride && 00956 dstImageStride == bytesPerImage) || 00957 (srcDepth == 1))) { 00958 /* one big memcpy */ 00959 ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture); 00960 } 00961 else 00962 { 00963 GLint img, row; 00964 for (img = 0; img < srcDepth; img++) { 00965 const GLubyte *srcRow = srcImage; 00966 GLubyte *dstRow = dstImage; 00967 for (row = 0; row < srcHeight; row++) { 00968 ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow); 00969 dstRow += dstRowStride; 00970 srcRow += srcRowStride; 00971 } 00972 srcImage += srcImageStride; 00973 dstImage += dstImageStride; 00974 } 00975 } 00976 #endif 00977 00978 GLint img, row; 00979 for (img = 0; img < srcDepth; img++) { 00980 const GLubyte *srcRow = srcImage; 00981 GLubyte *dstRow = (GLubyte *) dstAddr 00982 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 00983 + dstYoffset * dstRowStride 00984 + dstXoffset * dstFormat->TexelBytes; 00985 for (row = 0; row < srcHeight; row++) { 00986 ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow); 00987 dstRow += dstRowStride; 00988 srcRow += srcRowStride; 00989 } 00990 srcImage += srcImageStride; 00991 } 00992 } 00993 00994 00995 01006 GLboolean 01007 _mesa_texstore_rgba(TEXSTORE_PARAMS) 01008 { 01009 const GLint components = _mesa_components_in_format(baseInternalFormat); 01010 01011 ASSERT(dstFormat == &_mesa_texformat_rgba || 01012 dstFormat == &_mesa_texformat_rgb || 01013 dstFormat == &_mesa_texformat_alpha || 01014 dstFormat == &_mesa_texformat_luminance || 01015 dstFormat == &_mesa_texformat_luminance_alpha || 01016 dstFormat == &_mesa_texformat_intensity); 01017 ASSERT(baseInternalFormat == GL_RGBA || 01018 baseInternalFormat == GL_RGB || 01019 baseInternalFormat == GL_ALPHA || 01020 baseInternalFormat == GL_LUMINANCE || 01021 baseInternalFormat == GL_LUMINANCE_ALPHA || 01022 baseInternalFormat == GL_INTENSITY); 01023 ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan)); 01024 01025 if (!ctx->_ImageTransferState && 01026 !srcPacking->SwapBytes && 01027 baseInternalFormat == srcFormat && 01028 srcType == CHAN_TYPE) { 01029 /* simple memcpy path */ 01030 memcpy_texture(ctx, dims, 01031 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 01032 dstRowStride, 01033 dstImageOffsets, 01034 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 01035 srcAddr, srcPacking); 01036 } 01037 else if (!ctx->_ImageTransferState && 01038 !srcPacking->SwapBytes && 01039 dstFormat == &_mesa_texformat_rgb && 01040 srcFormat == GL_RGBA && 01041 srcType == CHAN_TYPE) { 01042 /* extract RGB from RGBA */ 01043 GLint img, row, col; 01044 for (img = 0; img < srcDepth; img++) { 01045 GLchan *dstImage = (GLchan *) 01046 ((GLubyte *) dstAddr 01047 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01048 + dstYoffset * dstRowStride 01049 + dstXoffset * dstFormat->TexelBytes); 01050 01051 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, 01052 srcWidth, srcFormat, srcType); 01053 GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking, 01054 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); 01055 GLchan *dstRow = dstImage; 01056 for (row = 0; row < srcHeight; row++) { 01057 for (col = 0; col < srcWidth; col++) { 01058 dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP]; 01059 dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP]; 01060 dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP]; 01061 } 01062 dstRow += dstRowStride / sizeof(GLchan); 01063 srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride); 01064 } 01065 } 01066 } 01067 else if (!ctx->_ImageTransferState && 01068 CHAN_TYPE == GL_UNSIGNED_BYTE && 01069 (srcType == GL_UNSIGNED_BYTE || 01070 srcType == GL_UNSIGNED_INT_8_8_8_8 || 01071 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && 01072 can_swizzle(baseInternalFormat) && 01073 can_swizzle(srcFormat)) { 01074 01075 const GLubyte *dstmap; 01076 GLuint components; 01077 01078 /* dstmap - how to swizzle from RGBA to dst format: 01079 */ 01080 if (dstFormat == &_mesa_texformat_rgba) { 01081 dstmap = mappings[IDX_RGBA].from_rgba; 01082 components = 4; 01083 } 01084 else if (dstFormat == &_mesa_texformat_rgb) { 01085 dstmap = mappings[IDX_RGB].from_rgba; 01086 components = 3; 01087 } 01088 else if (dstFormat == &_mesa_texformat_alpha) { 01089 dstmap = mappings[IDX_ALPHA].from_rgba; 01090 components = 1; 01091 } 01092 else if (dstFormat == &_mesa_texformat_luminance) { 01093 dstmap = mappings[IDX_LUMINANCE].from_rgba; 01094 components = 1; 01095 } 01096 else if (dstFormat == &_mesa_texformat_luminance_alpha) { 01097 dstmap = mappings[IDX_LUMINANCE_ALPHA].from_rgba; 01098 components = 2; 01099 } 01100 else if (dstFormat == &_mesa_texformat_intensity) { 01101 dstmap = mappings[IDX_INTENSITY].from_rgba; 01102 components = 1; 01103 } 01104 else { 01105 _mesa_problem(ctx, "Unexpected dstFormat in _mesa_texstore_rgba"); 01106 return GL_FALSE; 01107 } 01108 01109 _mesa_swizzle_ubyte_image(ctx, dims, 01110 srcFormat, 01111 srcType, 01112 baseInternalFormat, 01113 dstmap, components, 01114 dstAddr, dstXoffset, dstYoffset, dstZoffset, 01115 dstRowStride, dstImageOffsets, 01116 srcWidth, srcHeight, srcDepth, srcAddr, 01117 srcPacking); 01118 } 01119 else { 01120 /* general path */ 01121 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 01122 baseInternalFormat, 01123 dstFormat->BaseFormat, 01124 srcWidth, srcHeight, srcDepth, 01125 srcFormat, srcType, srcAddr, 01126 srcPacking); 01127 const GLchan *src = tempImage; 01128 GLint bytesPerRow; 01129 GLint img, row; 01130 if (!tempImage) 01131 return GL_FALSE; 01132 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 01133 bytesPerRow = srcWidth * components * sizeof(GLchan); 01134 for (img = 0; img < srcDepth; img++) { 01135 GLubyte *dstRow = (GLubyte *) dstAddr 01136 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01137 + dstYoffset * dstRowStride 01138 + dstXoffset * dstFormat->TexelBytes; 01139 for (row = 0; row < srcHeight; row++) { 01140 _mesa_memcpy(dstRow, src, bytesPerRow); 01141 dstRow += dstRowStride; 01142 src += srcWidth * components; 01143 } 01144 } 01145 01146 _mesa_free((void *) tempImage); 01147 } 01148 return GL_TRUE; 01149 } 01150 01151 01155 GLboolean 01156 _mesa_texstore_z32(TEXSTORE_PARAMS) 01157 { 01158 const GLuint depthScale = 0xffffffff; 01159 (void) dims; 01160 ASSERT(dstFormat == &_mesa_texformat_z32); 01161 ASSERT(dstFormat->TexelBytes == sizeof(GLuint)); 01162 01163 if (ctx->Pixel.DepthScale == 1.0f && 01164 ctx->Pixel.DepthBias == 0.0f && 01165 !srcPacking->SwapBytes && 01166 baseInternalFormat == GL_DEPTH_COMPONENT && 01167 srcFormat == GL_DEPTH_COMPONENT && 01168 srcType == GL_UNSIGNED_INT) { 01169 /* simple memcpy path */ 01170 memcpy_texture(ctx, dims, 01171 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 01172 dstRowStride, 01173 dstImageOffsets, 01174 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 01175 srcAddr, srcPacking); 01176 } 01177 else { 01178 /* general path */ 01179 GLint img, row; 01180 for (img = 0; img < srcDepth; img++) { 01181 GLubyte *dstRow = (GLubyte *) dstAddr 01182 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01183 + dstYoffset * dstRowStride 01184 + dstXoffset * dstFormat->TexelBytes; 01185 for (row = 0; row < srcHeight; row++) { 01186 const GLvoid *src = _mesa_image_address(dims, srcPacking, 01187 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 01188 _mesa_unpack_depth_span(ctx, srcWidth, 01189 GL_UNSIGNED_INT, (GLuint *) dstRow, 01190 depthScale, srcType, src, srcPacking); 01191 dstRow += dstRowStride; 01192 } 01193 } 01194 } 01195 return GL_TRUE; 01196 } 01197 01198 #define STRIDE_3D 0 01199 01203 GLboolean 01204 _mesa_texstore_z16(TEXSTORE_PARAMS) 01205 { 01206 const GLuint depthScale = 0xffff; 01207 (void) dims; 01208 ASSERT(dstFormat == &_mesa_texformat_z16); 01209 ASSERT(dstFormat->TexelBytes == sizeof(GLushort)); 01210 01211 if (ctx->Pixel.DepthScale == 1.0f && 01212 ctx->Pixel.DepthBias == 0.0f && 01213 !srcPacking->SwapBytes && 01214 baseInternalFormat == GL_DEPTH_COMPONENT && 01215 srcFormat == GL_DEPTH_COMPONENT && 01216 srcType == GL_UNSIGNED_SHORT) { 01217 /* simple memcpy path */ 01218 memcpy_texture(ctx, dims, 01219 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 01220 dstRowStride, 01221 dstImageOffsets, 01222 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 01223 srcAddr, srcPacking); 01224 } 01225 else { 01226 /* general path */ 01227 GLint img, row; 01228 for (img = 0; img < srcDepth; img++) { 01229 GLubyte *dstRow = (GLubyte *) dstAddr 01230 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01231 + dstYoffset * dstRowStride 01232 + dstXoffset * dstFormat->TexelBytes; 01233 for (row = 0; row < srcHeight; row++) { 01234 const GLvoid *src = _mesa_image_address(dims, srcPacking, 01235 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 01236 GLushort *dst16 = (GLushort *) dstRow; 01237 _mesa_unpack_depth_span(ctx, srcWidth, 01238 GL_UNSIGNED_SHORT, dst16, depthScale, 01239 srcType, src, srcPacking); 01240 dstRow += dstRowStride; 01241 } 01242 } 01243 } 01244 return GL_TRUE; 01245 } 01246 01247 01251 GLboolean 01252 _mesa_texstore_rgb565(TEXSTORE_PARAMS) 01253 { 01254 ASSERT(dstFormat == &_mesa_texformat_rgb565 || 01255 dstFormat == &_mesa_texformat_rgb565_rev); 01256 ASSERT(dstFormat->TexelBytes == 2); 01257 01258 if (!ctx->_ImageTransferState && 01259 !srcPacking->SwapBytes && 01260 dstFormat == &_mesa_texformat_rgb565 && 01261 baseInternalFormat == GL_RGB && 01262 srcFormat == GL_RGB && 01263 srcType == GL_UNSIGNED_SHORT_5_6_5) { 01264 /* simple memcpy path */ 01265 memcpy_texture(ctx, dims, 01266 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 01267 dstRowStride, 01268 dstImageOffsets, 01269 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 01270 srcAddr, srcPacking); 01271 } 01272 else if (!ctx->_ImageTransferState && 01273 !srcPacking->SwapBytes && 01274 baseInternalFormat == GL_RGB && 01275 srcFormat == GL_RGB && 01276 srcType == GL_UNSIGNED_BYTE && 01277 dims == 2) { 01278 /* do optimized tex store */ 01279 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, 01280 srcFormat, srcType); 01281 const GLubyte *src = (const GLubyte *) 01282 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight, 01283 srcFormat, srcType, 0, 0, 0); 01284 GLubyte *dst = (GLubyte *) dstAddr 01285 + dstYoffset * dstRowStride 01286 + dstXoffset * dstFormat->TexelBytes; 01287 GLint row, col; 01288 for (row = 0; row < srcHeight; row++) { 01289 const GLubyte *srcUB = (const GLubyte *) src; 01290 GLushort *dstUS = (GLushort *) dst; 01291 /* check for byteswapped format */ 01292 if (dstFormat == &_mesa_texformat_rgb565) { 01293 for (col = 0; col < srcWidth; col++) { 01294 dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] ); 01295 srcUB += 3; 01296 } 01297 } 01298 else { 01299 for (col = 0; col < srcWidth; col++) { 01300 dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] ); 01301 srcUB += 3; 01302 } 01303 } 01304 dst += dstRowStride; 01305 src += srcRowStride; 01306 } 01307 } 01308 else { 01309 /* general path */ 01310 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 01311 baseInternalFormat, 01312 dstFormat->BaseFormat, 01313 srcWidth, srcHeight, srcDepth, 01314 srcFormat, srcType, srcAddr, 01315 srcPacking); 01316 const GLchan *src = tempImage; 01317 GLint img, row, col; 01318 if (!tempImage) 01319 return GL_FALSE; 01320 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 01321 for (img = 0; img < srcDepth; img++) { 01322 GLubyte *dstRow = (GLubyte *) dstAddr 01323 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01324 + dstYoffset * dstRowStride 01325 + dstXoffset * dstFormat->TexelBytes; 01326 for (row = 0; row < srcHeight; row++) { 01327 GLushort *dstUS = (GLushort *) dstRow; 01328 /* check for byteswapped format */ 01329 if (dstFormat == &_mesa_texformat_rgb565) { 01330 for (col = 0; col < srcWidth; col++) { 01331 dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]), 01332 CHAN_TO_UBYTE(src[GCOMP]), 01333 CHAN_TO_UBYTE(src[BCOMP]) ); 01334 src += 3; 01335 } 01336 } 01337 else { 01338 for (col = 0; col < srcWidth; col++) { 01339 dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]), 01340 CHAN_TO_UBYTE(src[GCOMP]), 01341 CHAN_TO_UBYTE(src[BCOMP]) ); 01342 src += 3; 01343 } 01344 } 01345 dstRow += dstRowStride; 01346 } 01347 } 01348 _mesa_free((void *) tempImage); 01349 } 01350 return GL_TRUE; 01351 } 01352 01353 01357 GLboolean 01358 _mesa_texstore_rgba8888(TEXSTORE_PARAMS) 01359 { 01360 const GLboolean littleEndian = _mesa_little_endian(); 01361 01362 ASSERT(dstFormat == &_mesa_texformat_rgba8888 || 01363 dstFormat == &_mesa_texformat_rgba8888_rev); 01364 ASSERT(dstFormat->TexelBytes == 4); 01365 01366 if (!ctx->_ImageTransferState && 01367 !srcPacking->SwapBytes && 01368 dstFormat == &_mesa_texformat_rgba8888 && 01369 baseInternalFormat == GL_RGBA && 01370 ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) || 01371 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) || 01372 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 01373 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian))) { 01374 /* simple memcpy path */ 01375 memcpy_texture(ctx, dims, 01376 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 01377 dstRowStride, 01378 dstImageOffsets, 01379 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 01380 srcAddr, srcPacking); 01381 } 01382 else if (!ctx->_ImageTransferState && 01383 !srcPacking->SwapBytes && 01384 dstFormat == &_mesa_texformat_rgba8888_rev && 01385 baseInternalFormat == GL_RGBA && 01386 ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) || 01387 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) || 01388 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) || 01389 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian))) { 01390 /* simple memcpy path */ 01391 memcpy_texture(ctx, dims, 01392 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 01393 dstRowStride, 01394 dstImageOffsets, 01395 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 01396 srcAddr, srcPacking); 01397 } 01398 else if (!ctx->_ImageTransferState && 01399 (srcType == GL_UNSIGNED_BYTE || 01400 srcType == GL_UNSIGNED_INT_8_8_8_8 || 01401 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && 01402 can_swizzle(baseInternalFormat) && 01403 can_swizzle(srcFormat)) { 01404 01405 GLubyte dstmap[4]; 01406 01407 /* dstmap - how to swizzle from RGBA to dst format: 01408 */ 01409 if ((littleEndian && dstFormat == &_mesa_texformat_rgba8888) || 01410 (!littleEndian && dstFormat == &_mesa_texformat_rgba8888_rev)) { 01411 dstmap[3] = 0; 01412 dstmap[2] = 1; 01413 dstmap[1] = 2; 01414 dstmap[0] = 3; 01415 } 01416 else { 01417 dstmap[3] = 3; 01418 dstmap[2] = 2; 01419 dstmap[1] = 1; 01420 dstmap[0] = 0; 01421 } 01422 01423 _mesa_swizzle_ubyte_image(ctx, dims, 01424 srcFormat, 01425 srcType, 01426 baseInternalFormat, 01427 dstmap, 4, 01428 dstAddr, dstXoffset, dstYoffset, dstZoffset, 01429 dstRowStride, dstImageOffsets, 01430 srcWidth, srcHeight, srcDepth, srcAddr, 01431 srcPacking); 01432 } 01433 else { 01434 /* general path */ 01435 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 01436 baseInternalFormat, 01437 dstFormat->BaseFormat, 01438 srcWidth, srcHeight, srcDepth, 01439 srcFormat, srcType, srcAddr, 01440 srcPacking); 01441 const GLchan *src = tempImage; 01442 GLint img, row, col; 01443 if (!tempImage) 01444 return GL_FALSE; 01445 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 01446 for (img = 0; img < srcDepth; img++) { 01447 GLubyte *dstRow = (GLubyte *) dstAddr 01448 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01449 + dstYoffset * dstRowStride 01450 + dstXoffset * dstFormat->TexelBytes; 01451 for (row = 0; row < srcHeight; row++) { 01452 GLuint *dstUI = (GLuint *) dstRow; 01453 if (dstFormat == &_mesa_texformat_rgba8888) { 01454 for (col = 0; col < srcWidth; col++) { 01455 dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]), 01456 CHAN_TO_UBYTE(src[GCOMP]), 01457 CHAN_TO_UBYTE(src[BCOMP]), 01458 CHAN_TO_UBYTE(src[ACOMP]) ); 01459 src += 4; 01460 } 01461 } 01462 else { 01463 for (col = 0; col < srcWidth; col++) { 01464 dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]), 01465 CHAN_TO_UBYTE(src[GCOMP]), 01466 CHAN_TO_UBYTE(src[BCOMP]), 01467 CHAN_TO_UBYTE(src[ACOMP]) ); 01468 src += 4; 01469 } 01470 } 01471 dstRow += dstRowStride; 01472 } 01473 } 01474 _mesa_free((void *) tempImage); 01475 } 01476 return GL_TRUE; 01477 } 01478 01479 01480 GLboolean 01481 _mesa_texstore_argb8888(TEXSTORE_PARAMS) 01482 { 01483 const GLboolean littleEndian = _mesa_little_endian(); 01484 01485 ASSERT(dstFormat == &_mesa_texformat_argb8888 || 01486 dstFormat == &_mesa_texformat_argb8888_rev); 01487 ASSERT(dstFormat->TexelBytes == 4); 01488 01489 if (!ctx->_ImageTransferState && 01490 !srcPacking->SwapBytes && 01491 dstFormat == &_mesa_texformat_argb8888 && 01492 baseInternalFormat == GL_RGBA && 01493 srcFormat == GL_BGRA && 01494 ((srcType == GL_UNSIGNED_BYTE && littleEndian) || 01495 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) { 01496 /* simple memcpy path (little endian) */ 01497 memcpy_texture(ctx, dims, 01498 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 01499 dstRowStride, 01500 dstImageOffsets, 01501 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 01502 srcAddr, srcPacking); 01503 } 01504 else if (!ctx->_ImageTransferState && 01505 !srcPacking->SwapBytes && 01506 dstFormat == &_mesa_texformat_argb8888_rev && 01507 baseInternalFormat == GL_RGBA && 01508 srcFormat == GL_BGRA && 01509 ((srcType == GL_UNSIGNED_BYTE && !littleEndian) || 01510 srcType == GL_UNSIGNED_INT_8_8_8_8)) { 01511 /* simple memcpy path (big endian) */ 01512 memcpy_texture(ctx, dims, 01513 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 01514 dstRowStride, 01515 dstImageOffsets, 01516 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 01517 srcAddr, srcPacking); 01518 } 01519 else if (!ctx->_ImageTransferState && 01520 !srcPacking->SwapBytes && 01521 dstFormat == &_mesa_texformat_argb8888 && 01522 srcFormat == GL_RGB && 01523 (baseInternalFormat == GL_RGBA || 01524 baseInternalFormat == GL_RGB) && 01525 srcType == GL_UNSIGNED_BYTE) { 01526 int img, row, col; 01527 for (img = 0; img < srcDepth; img++) { 01528 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, 01529 srcWidth, srcFormat, srcType); 01530 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, 01531 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); 01532 GLubyte *dstRow = (GLubyte *) dstAddr 01533 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01534 + dstYoffset * dstRowStride 01535 + dstXoffset * dstFormat->TexelBytes; 01536 for (row = 0; row < srcHeight; row++) { 01537 GLuint *d4 = (GLuint *) dstRow; 01538 for (col = 0; col < srcWidth; col++) { 01539 d4[col] = PACK_COLOR_8888(0xff, 01540 srcRow[col * 3 + RCOMP], 01541 srcRow[col * 3 + GCOMP], 01542 srcRow[col * 3 + BCOMP]); 01543 } 01544 dstRow += dstRowStride; 01545 srcRow += srcRowStride; 01546 } 01547 } 01548 } 01549 else if (!ctx->_ImageTransferState && 01550 !srcPacking->SwapBytes && 01551 dstFormat == &_mesa_texformat_argb8888 && 01552 srcFormat == GL_RGBA && 01553 baseInternalFormat == GL_RGBA && 01554 srcType == GL_UNSIGNED_BYTE) { 01555 /* same as above case, but src data has alpha too */ 01556 GLint img, row, col; 01557 /* For some reason, streaming copies to write-combined regions 01558 * are extremely sensitive to the characteristics of how the 01559 * source data is retrieved. By reordering the source reads to 01560 * be in-order, the speed of this operation increases by half. 01561 * Strangely the same isn't required for the RGB path, above. 01562 */ 01563 for (img = 0; img < srcDepth; img++) { 01564 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, 01565 srcWidth, srcFormat, srcType); 01566 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, 01567 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); 01568 GLubyte *dstRow = (GLubyte *) dstAddr 01569 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01570 + dstYoffset * dstRowStride 01571 + dstXoffset * dstFormat->TexelBytes; 01572 for (row = 0; row < srcHeight; row++) { 01573 GLuint *d4 = (GLuint *) dstRow; 01574 for (col = 0; col < srcWidth; col++) { 01575 d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP], 01576 srcRow[col * 4 + RCOMP], 01577 srcRow[col * 4 + GCOMP], 01578 srcRow[col * 4 + BCOMP]); 01579 } 01580 dstRow += dstRowStride; 01581 srcRow += srcRowStride; 01582 } 01583 } 01584 } 01585 else if (!ctx->_ImageTransferState && 01586 (srcType == GL_UNSIGNED_BYTE || 01587 srcType == GL_UNSIGNED_INT_8_8_8_8 || 01588 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) && 01589 can_swizzle(baseInternalFormat) && 01590 can_swizzle(srcFormat)) { 01591 01592 GLubyte dstmap[4]; 01593 01594 /* dstmap - how to swizzle from RGBA to dst format: 01595 */ 01596 if ((littleEndian && dstFormat == &_mesa_texformat_argb8888) || 01597 (!littleEndian && dstFormat == &_mesa_texformat_argb8888_rev)) { 01598 dstmap[3] = 3; /* alpha */ 01599 dstmap[2] = 0; /* red */ 01600 dstmap[1] = 1; /* green */ 01601 dstmap[0] = 2; /* blue */ 01602 } 01603 else { 01604 assert((littleEndian && dstFormat == &_mesa_texformat_argb8888_rev) || 01605 (!littleEndian && dstFormat == &_mesa_texformat_argb8888)); 01606 dstmap[3] = 2; 01607 dstmap[2] = 1; 01608 dstmap[1] = 0; 01609 dstmap[0] = 3; 01610 } 01611 01612 _mesa_swizzle_ubyte_image(ctx, dims, 01613 srcFormat, 01614 srcType, 01615 01616 baseInternalFormat, 01617 dstmap, 4, 01618 dstAddr, dstXoffset, dstYoffset, dstZoffset, 01619 dstRowStride, 01620 dstImageOffsets, 01621 srcWidth, srcHeight, srcDepth, srcAddr, 01622 srcPacking); 01623 } 01624 else { 01625 /* general path */ 01626 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 01627 baseInternalFormat, 01628 dstFormat->BaseFormat, 01629 srcWidth, srcHeight, srcDepth, 01630 srcFormat, srcType, srcAddr, 01631 srcPacking); 01632 const GLchan *src = tempImage; 01633 GLint img, row, col; 01634 if (!tempImage) 01635 return GL_FALSE; 01636 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 01637 for (img = 0; img < srcDepth; img++) { 01638 GLubyte *dstRow = (GLubyte *) dstAddr 01639 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01640 + dstYoffset * dstRowStride 01641 + dstXoffset * dstFormat->TexelBytes; 01642 for (row = 0; row < srcHeight; row++) { 01643 GLuint *dstUI = (GLuint *) dstRow; 01644 if (dstFormat == &_mesa_texformat_argb8888) { 01645 for (col = 0; col < srcWidth; col++) { 01646 dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]), 01647 CHAN_TO_UBYTE(src[RCOMP]), 01648 CHAN_TO_UBYTE(src[GCOMP]), 01649 CHAN_TO_UBYTE(src[BCOMP]) ); 01650 src += 4; 01651 } 01652 } 01653 else { 01654 for (col = 0; col < srcWidth; col++) { 01655 dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]), 01656 CHAN_TO_UBYTE(src[RCOMP]), 01657 CHAN_TO_UBYTE(src[GCOMP]), 01658 CHAN_TO_UBYTE(src[BCOMP]) ); 01659 src += 4; 01660 } 01661 } 01662 dstRow += dstRowStride; 01663 } 01664 } 01665 _mesa_free((void *) tempImage); 01666 } 01667 return GL_TRUE; 01668 } 01669 01670 01671 GLboolean 01672 _mesa_texstore_rgb888(TEXSTORE_PARAMS) 01673 { 01674 const GLboolean littleEndian = _mesa_little_endian(); 01675 01676 ASSERT(dstFormat == &_mesa_texformat_rgb888); 01677 ASSERT(dstFormat->TexelBytes == 3); 01678 01679 if (!ctx->_ImageTransferState && 01680 !srcPacking->SwapBytes && 01681 baseInternalFormat == GL_RGB && 01682 srcFormat == GL_BGR && 01683 srcType == GL_UNSIGNED_BYTE && 01684 littleEndian) { 01685 /* simple memcpy path */ 01686 memcpy_texture(ctx, dims, 01687 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 01688 dstRowStride, 01689 dstImageOffsets, 01690 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 01691 srcAddr, srcPacking); 01692 } 01693 else if (!ctx->_ImageTransferState && 01694 !srcPacking->SwapBytes && 01695 srcFormat == GL_RGBA && 01696 srcType == GL_UNSIGNED_BYTE) { 01697 /* extract RGB from RGBA */ 01698 GLint img, row, col; 01699 for (img = 0; img < srcDepth; img++) { 01700 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, 01701 srcWidth, srcFormat, srcType); 01702 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, 01703 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); 01704 GLubyte *dstRow = (GLubyte *) dstAddr 01705 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01706 + dstYoffset * dstRowStride 01707 + dstXoffset * dstFormat->TexelBytes; 01708 for (row = 0; row < srcHeight; row++) { 01709 for (col = 0; col < srcWidth; col++) { 01710 dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP]; 01711 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP]; 01712 dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP]; 01713 } 01714 dstRow += dstRowStride; 01715 srcRow += srcRowStride; 01716 } 01717 } 01718 } 01719 else if (!ctx->_ImageTransferState && 01720 srcType == GL_UNSIGNED_BYTE && 01721 can_swizzle(baseInternalFormat) && 01722 can_swizzle(srcFormat)) { 01723 01724 GLubyte dstmap[4]; 01725 01726 /* dstmap - how to swizzle from RGBA to dst format: 01727 */ 01728 dstmap[0] = 2; 01729 dstmap[1] = 1; 01730 dstmap[2] = 0; 01731 dstmap[3] = ONE; /* ? */ 01732 01733 _mesa_swizzle_ubyte_image(ctx, dims, 01734 srcFormat, 01735 srcType, 01736 baseInternalFormat, 01737 dstmap, 3, 01738 dstAddr, dstXoffset, dstYoffset, dstZoffset, 01739 dstRowStride, dstImageOffsets, 01740 srcWidth, srcHeight, srcDepth, srcAddr, 01741 srcPacking); 01742 } 01743 else { 01744 /* general path */ 01745 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 01746 baseInternalFormat, 01747 dstFormat->BaseFormat, 01748 srcWidth, srcHeight, srcDepth, 01749 srcFormat, srcType, srcAddr, 01750 srcPacking); 01751 const GLchan *src = (const GLchan *) tempImage; 01752 GLint img, row, col; 01753 if (!tempImage) 01754 return GL_FALSE; 01755 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 01756 for (img = 0; img < srcDepth; img++) { 01757 GLubyte *dstRow = (GLubyte *) dstAddr 01758 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01759 + dstYoffset * dstRowStride 01760 + dstXoffset * dstFormat->TexelBytes; 01761 for (row = 0; row < srcHeight; row++) { 01762 #if 0 01763 if (littleEndian) { 01764 for (col = 0; col < srcWidth; col++) { 01765 dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]); 01766 dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]); 01767 dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]); 01768 srcUB += 3; 01769 } 01770 } 01771 else { 01772 for (col = 0; col < srcWidth; col++) { 01773 dstRow[col * 3 + 0] = srcUB[BCOMP]; 01774 dstRow[col * 3 + 1] = srcUB[GCOMP]; 01775 dstRow[col * 3 + 2] = srcUB[RCOMP]; 01776 srcUB += 3; 01777 } 01778 } 01779 #else 01780 for (col = 0; col < srcWidth; col++) { 01781 dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]); 01782 dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]); 01783 dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]); 01784 src += 3; 01785 } 01786 #endif 01787 dstRow += dstRowStride; 01788 } 01789 } 01790 _mesa_free((void *) tempImage); 01791 } 01792 return GL_TRUE; 01793 } 01794 01795 01796 GLboolean 01797 _mesa_texstore_bgr888(TEXSTORE_PARAMS) 01798 { 01799 const GLboolean littleEndian = _mesa_little_endian(); 01800 01801 ASSERT(dstFormat == &_mesa_texformat_bgr888); 01802 ASSERT(dstFormat->TexelBytes == 3); 01803 01804 if (!ctx->_ImageTransferState && 01805 !srcPacking->SwapBytes && 01806 baseInternalFormat == GL_RGB && 01807 srcFormat == GL_RGB && 01808 srcType == GL_UNSIGNED_BYTE && 01809 littleEndian) { 01810 /* simple memcpy path */ 01811 memcpy_texture(ctx, dims, 01812 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 01813 dstRowStride, 01814 dstImageOffsets, 01815 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 01816 srcAddr, srcPacking); 01817 } 01818 else if (!ctx->_ImageTransferState && 01819 !srcPacking->SwapBytes && 01820 srcFormat == GL_RGBA && 01821 srcType == GL_UNSIGNED_BYTE) { 01822 /* extract BGR from RGBA */ 01823 int img, row, col; 01824 for (img = 0; img < srcDepth; img++) { 01825 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, 01826 srcWidth, srcFormat, srcType); 01827 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking, 01828 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); 01829 GLubyte *dstRow = (GLubyte *) dstAddr 01830 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01831 + dstYoffset * dstRowStride 01832 + dstXoffset * dstFormat->TexelBytes; 01833 for (row = 0; row < srcHeight; row++) { 01834 for (col = 0; col < srcWidth; col++) { 01835 dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP]; 01836 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP]; 01837 dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP]; 01838 } 01839 dstRow += dstRowStride; 01840 srcRow += srcRowStride; 01841 } 01842 } 01843 } 01844 else if (!ctx->_ImageTransferState && 01845 srcType == GL_UNSIGNED_BYTE && 01846 can_swizzle(baseInternalFormat) && 01847 can_swizzle(srcFormat)) { 01848 01849 GLubyte dstmap[4]; 01850 01851 /* dstmap - how to swizzle from RGBA to dst format: 01852 */ 01853 dstmap[0] = 0; 01854 dstmap[1] = 1; 01855 dstmap[2] = 2; 01856 dstmap[3] = ONE; /* ? */ 01857 01858 _mesa_swizzle_ubyte_image(ctx, dims, 01859 srcFormat, 01860 srcType, 01861 baseInternalFormat, 01862 dstmap, 3, 01863 dstAddr, dstXoffset, dstYoffset, dstZoffset, 01864 dstRowStride, dstImageOffsets, 01865 srcWidth, srcHeight, srcDepth, srcAddr, 01866 srcPacking); 01867 } 01868 else { 01869 /* general path */ 01870 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 01871 baseInternalFormat, 01872 dstFormat->BaseFormat, 01873 srcWidth, srcHeight, srcDepth, 01874 srcFormat, srcType, srcAddr, 01875 srcPacking); 01876 const GLchan *src = (const GLchan *) tempImage; 01877 GLint img, row, col; 01878 if (!tempImage) 01879 return GL_FALSE; 01880 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 01881 for (img = 0; img < srcDepth; img++) { 01882 GLubyte *dstRow = (GLubyte *) dstAddr 01883 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01884 + dstYoffset * dstRowStride 01885 + dstXoffset * dstFormat->TexelBytes; 01886 for (row = 0; row < srcHeight; row++) { 01887 for (col = 0; col < srcWidth; col++) { 01888 dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]); 01889 dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]); 01890 dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]); 01891 src += 3; 01892 } 01893 dstRow += dstRowStride; 01894 } 01895 } 01896 _mesa_free((void *) tempImage); 01897 } 01898 return GL_TRUE; 01899 } 01900 01901 GLboolean 01902 _mesa_texstore_rgba4444(TEXSTORE_PARAMS) 01903 { 01904 ASSERT(dstFormat == &_mesa_texformat_rgba4444); 01905 ASSERT(dstFormat->TexelBytes == 2); 01906 01907 if (!ctx->_ImageTransferState && 01908 !srcPacking->SwapBytes && 01909 dstFormat == &_mesa_texformat_rgba4444 && 01910 baseInternalFormat == GL_RGBA && 01911 srcFormat == GL_RGBA && 01912 srcType == GL_UNSIGNED_SHORT_4_4_4_4){ 01913 /* simple memcpy path */ 01914 memcpy_texture(ctx, dims, 01915 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 01916 dstRowStride, 01917 dstImageOffsets, 01918 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 01919 srcAddr, srcPacking); 01920 } 01921 else { 01922 /* general path */ 01923 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 01924 baseInternalFormat, 01925 dstFormat->BaseFormat, 01926 srcWidth, srcHeight, srcDepth, 01927 srcFormat, srcType, srcAddr, 01928 srcPacking); 01929 const GLchan *src = tempImage; 01930 GLint img, row, col; 01931 if (!tempImage) 01932 return GL_FALSE; 01933 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 01934 for (img = 0; img < srcDepth; img++) { 01935 GLubyte *dstRow = (GLubyte *) dstAddr 01936 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01937 + dstYoffset * dstRowStride 01938 + dstXoffset * dstFormat->TexelBytes; 01939 for (row = 0; row < srcHeight; row++) { 01940 GLushort *dstUS = (GLushort *) dstRow; 01941 for (col = 0; col < srcWidth; col++) { 01942 dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[RCOMP]), 01943 CHAN_TO_UBYTE(src[GCOMP]), 01944 CHAN_TO_UBYTE(src[BCOMP]), 01945 CHAN_TO_UBYTE(src[ACOMP]) ); 01946 src += 4; 01947 } 01948 dstRow += dstRowStride; 01949 } 01950 } 01951 _mesa_free((void *) tempImage); 01952 } 01953 return GL_TRUE; 01954 } 01955 01956 GLboolean 01957 _mesa_texstore_argb4444(TEXSTORE_PARAMS) 01958 { 01959 ASSERT(dstFormat == &_mesa_texformat_argb4444 || 01960 dstFormat == &_mesa_texformat_argb4444_rev); 01961 ASSERT(dstFormat->TexelBytes == 2); 01962 01963 if (!ctx->_ImageTransferState && 01964 !srcPacking->SwapBytes && 01965 dstFormat == &_mesa_texformat_argb4444 && 01966 baseInternalFormat == GL_RGBA && 01967 srcFormat == GL_BGRA && 01968 srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) { 01969 /* simple memcpy path */ 01970 memcpy_texture(ctx, dims, 01971 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 01972 dstRowStride, 01973 dstImageOffsets, 01974 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 01975 srcAddr, srcPacking); 01976 } 01977 else { 01978 /* general path */ 01979 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 01980 baseInternalFormat, 01981 dstFormat->BaseFormat, 01982 srcWidth, srcHeight, srcDepth, 01983 srcFormat, srcType, srcAddr, 01984 srcPacking); 01985 const GLchan *src = tempImage; 01986 GLint img, row, col; 01987 if (!tempImage) 01988 return GL_FALSE; 01989 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 01990 for (img = 0; img < srcDepth; img++) { 01991 GLubyte *dstRow = (GLubyte *) dstAddr 01992 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 01993 + dstYoffset * dstRowStride 01994 + dstXoffset * dstFormat->TexelBytes; 01995 for (row = 0; row < srcHeight; row++) { 01996 GLushort *dstUS = (GLushort *) dstRow; 01997 if (dstFormat == &_mesa_texformat_argb4444) { 01998 for (col = 0; col < srcWidth; col++) { 01999 dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]), 02000 CHAN_TO_UBYTE(src[RCOMP]), 02001 CHAN_TO_UBYTE(src[GCOMP]), 02002 CHAN_TO_UBYTE(src[BCOMP]) ); 02003 src += 4; 02004 } 02005 } 02006 else { 02007 for (col = 0; col < srcWidth; col++) { 02008 dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]), 02009 CHAN_TO_UBYTE(src[RCOMP]), 02010 CHAN_TO_UBYTE(src[GCOMP]), 02011 CHAN_TO_UBYTE(src[BCOMP]) ); 02012 src += 4; 02013 } 02014 } 02015 dstRow += dstRowStride; 02016 } 02017 } 02018 _mesa_free((void *) tempImage); 02019 } 02020 return GL_TRUE; 02021 } 02022 02023 GLboolean 02024 _mesa_texstore_rgba5551(TEXSTORE_PARAMS) 02025 { 02026 ASSERT(dstFormat == &_mesa_texformat_rgba5551); 02027 ASSERT(dstFormat->TexelBytes == 2); 02028 02029 if (!ctx->_ImageTransferState && 02030 !srcPacking->SwapBytes && 02031 dstFormat == &_mesa_texformat_rgba5551 && 02032 baseInternalFormat == GL_RGBA && 02033 srcFormat == GL_RGBA && 02034 srcType == GL_UNSIGNED_SHORT_5_5_5_1) { 02035 /* simple memcpy path */ 02036 memcpy_texture(ctx, dims, 02037 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 02038 dstRowStride, 02039 dstImageOffsets, 02040 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 02041 srcAddr, srcPacking); 02042 } 02043 else { 02044 /* general path */ 02045 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 02046 baseInternalFormat, 02047 dstFormat->BaseFormat, 02048 srcWidth, srcHeight, srcDepth, 02049 srcFormat, srcType, srcAddr, 02050 srcPacking); 02051 const GLchan *src =tempImage; 02052 GLint img, row, col; 02053 if (!tempImage) 02054 return GL_FALSE; 02055 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 02056 for (img = 0; img < srcDepth; img++) { 02057 GLubyte *dstRow = (GLubyte *) dstAddr 02058 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 02059 + dstYoffset * dstRowStride 02060 + dstXoffset * dstFormat->TexelBytes; 02061 for (row = 0; row < srcHeight; row++) { 02062 GLushort *dstUS = (GLushort *) dstRow; 02063 for (col = 0; col < srcWidth; col++) { 02064 dstUS[col] = PACK_COLOR_5551( CHAN_TO_UBYTE(src[RCOMP]), 02065 CHAN_TO_UBYTE(src[GCOMP]), 02066 CHAN_TO_UBYTE(src[BCOMP]), 02067 CHAN_TO_UBYTE(src[ACOMP]) ); 02068 src += 4; 02069 } 02070 dstRow += dstRowStride; 02071 } 02072 } 02073 _mesa_free((void *) tempImage); 02074 } 02075 return GL_TRUE; 02076 } 02077 02078 GLboolean 02079 _mesa_texstore_argb1555(TEXSTORE_PARAMS) 02080 { 02081 ASSERT(dstFormat == &_mesa_texformat_argb1555 || 02082 dstFormat == &_mesa_texformat_argb1555_rev); 02083 ASSERT(dstFormat->TexelBytes == 2); 02084 02085 if (!ctx->_ImageTransferState && 02086 !srcPacking->SwapBytes && 02087 dstFormat == &_mesa_texformat_argb1555 && 02088 baseInternalFormat == GL_RGBA && 02089 srcFormat == GL_BGRA && 02090 srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) { 02091 /* simple memcpy path */ 02092 memcpy_texture(ctx, dims, 02093 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 02094 dstRowStride, 02095 dstImageOffsets, 02096 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 02097 srcAddr, srcPacking); 02098 } 02099 else { 02100 /* general path */ 02101 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 02102 baseInternalFormat, 02103 dstFormat->BaseFormat, 02104 srcWidth, srcHeight, srcDepth, 02105 srcFormat, srcType, srcAddr, 02106 srcPacking); 02107 const GLchan *src =tempImage; 02108 GLint img, row, col; 02109 if (!tempImage) 02110 return GL_FALSE; 02111 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 02112 for (img = 0; img < srcDepth; img++) { 02113 GLubyte *dstRow = (GLubyte *) dstAddr 02114 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 02115 + dstYoffset * dstRowStride 02116 + dstXoffset * dstFormat->TexelBytes; 02117 for (row = 0; row < srcHeight; row++) { 02118 GLushort *dstUS = (GLushort *) dstRow; 02119 if (dstFormat == &_mesa_texformat_argb1555) { 02120 for (col = 0; col < srcWidth; col++) { 02121 dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]), 02122 CHAN_TO_UBYTE(src[RCOMP]), 02123 CHAN_TO_UBYTE(src[GCOMP]), 02124 CHAN_TO_UBYTE(src[BCOMP]) ); 02125 src += 4; 02126 } 02127 } 02128 else { 02129 for (col = 0; col < srcWidth; col++) { 02130 dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]), 02131 CHAN_TO_UBYTE(src[RCOMP]), 02132 CHAN_TO_UBYTE(src[GCOMP]), 02133 CHAN_TO_UBYTE(src[BCOMP]) ); 02134 src += 4; 02135 } 02136 } 02137 dstRow += dstRowStride; 02138 } 02139 } 02140 _mesa_free((void *) tempImage); 02141 } 02142 return GL_TRUE; 02143 } 02144 02145 02146 GLboolean 02147 _mesa_texstore_al88(TEXSTORE_PARAMS) 02148 { 02149 const GLboolean littleEndian = _mesa_little_endian(); 02150 02151 ASSERT(dstFormat == &_mesa_texformat_al88 || 02152 dstFormat == &_mesa_texformat_al88_rev); 02153 ASSERT(dstFormat->TexelBytes == 2); 02154 02155 if (!ctx->_ImageTransferState && 02156 !srcPacking->SwapBytes && 02157 dstFormat == &_mesa_texformat_al88 && 02158 baseInternalFormat == GL_LUMINANCE_ALPHA && 02159 srcFormat == GL_LUMINANCE_ALPHA && 02160 srcType == GL_UNSIGNED_BYTE && 02161 littleEndian) { 02162 /* simple memcpy path */ 02163 memcpy_texture(ctx, dims, 02164 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 02165 dstRowStride, 02166 dstImageOffsets, 02167 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 02168 srcAddr, srcPacking); 02169 } 02170 else if (!ctx->_ImageTransferState && 02171 littleEndian && 02172 srcType == GL_UNSIGNED_BYTE && 02173 can_swizzle(baseInternalFormat) && 02174 can_swizzle(srcFormat)) { 02175 02176 GLubyte dstmap[4]; 02177 02178 /* dstmap - how to swizzle from RGBA to dst format: 02179 */ 02180 if ((littleEndian && dstFormat == &_mesa_texformat_al88) || 02181 (!littleEndian && dstFormat == &_mesa_texformat_al88_rev)) { 02182 dstmap[0] = 0; 02183 dstmap[1] = 3; 02184 } 02185 else { 02186 dstmap[0] = 3; 02187 dstmap[1] = 0; 02188 } 02189 dstmap[2] = ZERO; /* ? */ 02190 dstmap[3] = ONE; /* ? */ 02191 02192 _mesa_swizzle_ubyte_image(ctx, dims, 02193 srcFormat, 02194 srcType, 02195 baseInternalFormat, 02196 dstmap, 2, 02197 dstAddr, dstXoffset, dstYoffset, dstZoffset, 02198 dstRowStride, dstImageOffsets, 02199 srcWidth, srcHeight, srcDepth, srcAddr, 02200 srcPacking); 02201 } 02202 else { 02203 /* general path */ 02204 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 02205 baseInternalFormat, 02206 dstFormat->BaseFormat, 02207 srcWidth, srcHeight, srcDepth, 02208 srcFormat, srcType, srcAddr, 02209 srcPacking); 02210 const GLchan *src = tempImage; 02211 GLint img, row, col; 02212 if (!tempImage) 02213 return GL_FALSE; 02214 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 02215 for (img = 0; img < srcDepth; img++) { 02216 GLubyte *dstRow = (GLubyte *) dstAddr 02217 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 02218 + dstYoffset * dstRowStride 02219 + dstXoffset * dstFormat->TexelBytes; 02220 for (row = 0; row < srcHeight; row++) { 02221 GLushort *dstUS = (GLushort *) dstRow; 02222 if (dstFormat == &_mesa_texformat_al88) { 02223 for (col = 0; col < srcWidth; col++) { 02224 /* src[0] is luminance, src[1] is alpha */ 02225 dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]), 02226 CHAN_TO_UBYTE(src[0]) ); 02227 src += 2; 02228 } 02229 } 02230 else { 02231 for (col = 0; col < srcWidth; col++) { 02232 /* src[0] is luminance, src[1] is alpha */ 02233 dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]), 02234 CHAN_TO_UBYTE(src[0]) ); 02235 src += 2; 02236 } 02237 } 02238 dstRow += dstRowStride; 02239 } 02240 } 02241 _mesa_free((void *) tempImage); 02242 } 02243 return GL_TRUE; 02244 } 02245 02246 02247 GLboolean 02248 _mesa_texstore_rgb332(TEXSTORE_PARAMS) 02249 { 02250 ASSERT(dstFormat == &_mesa_texformat_rgb332); 02251 ASSERT(dstFormat->TexelBytes == 1); 02252 02253 if (!ctx->_ImageTransferState && 02254 !srcPacking->SwapBytes && 02255 baseInternalFormat == GL_RGB && 02256 srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) { 02257 /* simple memcpy path */ 02258 memcpy_texture(ctx, dims, 02259 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 02260 dstRowStride, 02261 dstImageOffsets, 02262 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 02263 srcAddr, srcPacking); 02264 } 02265 else { 02266 /* general path */ 02267 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 02268 baseInternalFormat, 02269 dstFormat->BaseFormat, 02270 srcWidth, srcHeight, srcDepth, 02271 srcFormat, srcType, srcAddr, 02272 srcPacking); 02273 const GLchan *src = tempImage; 02274 GLint img, row, col; 02275 if (!tempImage) 02276 return GL_FALSE; 02277 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 02278 for (img = 0; img < srcDepth; img++) { 02279 GLubyte *dstRow = (GLubyte *) dstAddr 02280 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 02281 + dstYoffset * dstRowStride 02282 + dstXoffset * dstFormat->TexelBytes; 02283 for (row = 0; row < srcHeight; row++) { 02284 for (col = 0; col < srcWidth; col++) { 02285 dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]), 02286 CHAN_TO_UBYTE(src[GCOMP]), 02287 CHAN_TO_UBYTE(src[BCOMP]) ); 02288 src += 3; 02289 } 02290 dstRow += dstRowStride; 02291 } 02292 } 02293 _mesa_free((void *) tempImage); 02294 } 02295 return GL_TRUE; 02296 } 02297 02298 02302 GLboolean 02303 _mesa_texstore_a8(TEXSTORE_PARAMS) 02304 { 02305 ASSERT(dstFormat == &_mesa_texformat_a8 || 02306 dstFormat == &_mesa_texformat_l8 || 02307 dstFormat == &_mesa_texformat_i8); 02308 ASSERT(dstFormat->TexelBytes == 1); 02309 02310 if (!ctx->_ImageTransferState && 02311 !srcPacking->SwapBytes && 02312 baseInternalFormat == srcFormat && 02313 srcType == GL_UNSIGNED_BYTE) { 02314 /* simple memcpy path */ 02315 memcpy_texture(ctx, dims, 02316 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 02317 dstRowStride, 02318 dstImageOffsets, 02319 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 02320 srcAddr, srcPacking); 02321 } 02322 else if (!ctx->_ImageTransferState && 02323 srcType == GL_UNSIGNED_BYTE && 02324 can_swizzle(baseInternalFormat) && 02325 can_swizzle(srcFormat)) { 02326 02327 GLubyte dstmap[4]; 02328 02329 /* dstmap - how to swizzle from RGBA to dst format: 02330 */ 02331 if (dstFormat == &_mesa_texformat_a8) { 02332 dstmap[0] = 3; 02333 } 02334 else { 02335 dstmap[0] = 0; 02336 } 02337 dstmap[1] = ZERO; /* ? */ 02338 dstmap[2] = ZERO; /* ? */ 02339 dstmap[3] = ONE; /* ? */ 02340 02341 _mesa_swizzle_ubyte_image(ctx, dims, 02342 srcFormat, 02343 srcType, 02344 baseInternalFormat, 02345 dstmap, 1, 02346 dstAddr, dstXoffset, dstYoffset, dstZoffset, 02347 dstRowStride, dstImageOffsets, 02348 srcWidth, srcHeight, srcDepth, srcAddr, 02349 srcPacking); 02350 } 02351 else { 02352 /* general path */ 02353 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims, 02354 baseInternalFormat, 02355 dstFormat->BaseFormat, 02356 srcWidth, srcHeight, srcDepth, 02357 srcFormat, srcType, srcAddr, 02358 srcPacking); 02359 const GLchan *src = tempImage; 02360 GLint img, row, col; 02361 if (!tempImage) 02362 return GL_FALSE; 02363 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 02364 for (img = 0; img < srcDepth; img++) { 02365 GLubyte *dstRow = (GLubyte *) dstAddr 02366 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 02367 + dstYoffset * dstRowStride 02368 + dstXoffset * dstFormat->TexelBytes; 02369 for (row = 0; row < srcHeight; row++) { 02370 for (col = 0; col < srcWidth; col++) { 02371 dstRow[col] = CHAN_TO_UBYTE(src[col]); 02372 } 02373 dstRow += dstRowStride; 02374 src += srcWidth; 02375 } 02376 } 02377 _mesa_free((void *) tempImage); 02378 } 02379 return GL_TRUE; 02380 } 02381 02382 02383 02384 GLboolean 02385 _mesa_texstore_ci8(TEXSTORE_PARAMS) 02386 { 02387 (void) dims; (void) baseInternalFormat; 02388 ASSERT(dstFormat == &_mesa_texformat_ci8); 02389 ASSERT(dstFormat->TexelBytes == 1); 02390 ASSERT(baseInternalFormat == GL_COLOR_INDEX); 02391 02392 if (!ctx->_ImageTransferState && 02393 !srcPacking->SwapBytes && 02394 srcFormat == GL_COLOR_INDEX && 02395 srcType == GL_UNSIGNED_BYTE) { 02396 /* simple memcpy path */ 02397 memcpy_texture(ctx, dims, 02398 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 02399 dstRowStride, 02400 dstImageOffsets, 02401 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 02402 srcAddr, srcPacking); 02403 } 02404 else { 02405 /* general path */ 02406 GLint img, row; 02407 for (img = 0; img < srcDepth; img++) { 02408 GLubyte *dstRow = (GLubyte *) dstAddr 02409 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 02410 + dstYoffset * dstRowStride 02411 + dstXoffset * dstFormat->TexelBytes; 02412 for (row = 0; row < srcHeight; row++) { 02413 const GLvoid *src = _mesa_image_address(dims, srcPacking, 02414 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); 02415 _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow, 02416 srcType, src, srcPacking, 02417 ctx->_ImageTransferState); 02418 dstRow += dstRowStride; 02419 } 02420 } 02421 } 02422 return GL_TRUE; 02423 } 02424 02425 02429 GLboolean 02430 _mesa_texstore_ycbcr(TEXSTORE_PARAMS) 02431 { 02432 const GLboolean littleEndian = _mesa_little_endian(); 02433 (void) ctx; (void) dims; (void) baseInternalFormat; 02434 02435 ASSERT((dstFormat == &_mesa_texformat_ycbcr) || 02436 (dstFormat == &_mesa_texformat_ycbcr_rev)); 02437 ASSERT(dstFormat->TexelBytes == 2); 02438 ASSERT(ctx->Extensions.MESA_ycbcr_texture); 02439 ASSERT(srcFormat == GL_YCBCR_MESA); 02440 ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) || 02441 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA)); 02442 ASSERT(baseInternalFormat == GL_YCBCR_MESA); 02443 02444 /* always just memcpy since no pixel transfer ops apply */ 02445 memcpy_texture(ctx, dims, 02446 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 02447 dstRowStride, 02448 dstImageOffsets, 02449 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 02450 srcAddr, srcPacking); 02451 02452 /* Check if we need byte swapping */ 02453 /* XXX the logic here _might_ be wrong */ 02454 if (srcPacking->SwapBytes ^ 02455 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^ 02456 (dstFormat == &_mesa_texformat_ycbcr_rev) ^ 02457 !littleEndian) { 02458 GLint img, row; 02459 for (img = 0; img < srcDepth; img++) { 02460 GLubyte *dstRow = (GLubyte *) dstAddr 02461 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 02462 + dstYoffset * dstRowStride 02463 + dstXoffset * dstFormat->TexelBytes; 02464 for (row = 0; row < srcHeight; row++) { 02465 _mesa_swap2((GLushort *) dstRow, srcWidth); 02466 dstRow += dstRowStride; 02467 } 02468 } 02469 } 02470 return GL_TRUE; 02471 } 02472 02473 02474 02478 GLboolean 02479 _mesa_texstore_z24_s8(TEXSTORE_PARAMS) 02480 { 02481 const GLfloat depthScale = (GLfloat) 0xffffff; 02482 02483 ASSERT(dstFormat == &_mesa_texformat_z24_s8); 02484 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT); 02485 ASSERT(srcType == GL_UNSIGNED_INT_24_8_EXT); 02486 02487 if (ctx->Pixel.DepthScale == 1.0f && 02488 ctx->Pixel.DepthBias == 0.0f && 02489 !srcPacking->SwapBytes) { 02490 /* simple path */ 02491 memcpy_texture(ctx, dims, 02492 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 02493 dstRowStride, 02494 dstImageOffsets, 02495 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 02496 srcAddr, srcPacking); 02497 } 02498 else { 02499 /* general path */ 02500 const GLint srcRowStride 02501 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) 02502 / sizeof(GLuint); 02503 GLint img, row; 02504 02505 for (img = 0; img < srcDepth; img++) { 02506 GLuint *dstRow = (GLuint *) dstAddr 02507 + dstImageOffsets[dstZoffset + img] 02508 + dstYoffset * dstRowStride / sizeof(GLuint) 02509 + dstXoffset; 02510 const GLuint *src 02511 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr, 02512 srcWidth, srcHeight, 02513 srcFormat, srcType, 02514 img, 0, 0); 02515 for (row = 0; row < srcHeight; row++) { 02516 GLubyte stencil[MAX_WIDTH]; 02517 GLint i; 02518 /* the 24 depth bits will be in the high position: */ 02519 _mesa_unpack_depth_span(ctx, srcWidth, 02520 GL_UNSIGNED_INT_24_8_EXT, /* dst type */ 02521 dstRow, /* dst addr */ 02522 (GLuint) depthScale, 02523 srcType, src, srcPacking); 02524 /* get the 8-bit stencil values */ 02525 _mesa_unpack_stencil_span(ctx, srcWidth, 02526 GL_UNSIGNED_BYTE, /* dst type */ 02527 stencil, /* dst addr */ 02528 srcType, src, srcPacking, 02529 ctx->_ImageTransferState); 02530 /* merge stencil values into depth values */ 02531 for (i = 0; i < srcWidth; i++) 02532 dstRow[i] |= stencil[i]; 02533 02534 src += srcRowStride; 02535 dstRow += dstRowStride / sizeof(GLuint); 02536 } 02537 } 02538 } 02539 return GL_TRUE; 02540 } 02541 02542 02546 GLboolean 02547 _mesa_texstore_s8_z24(TEXSTORE_PARAMS) 02548 { 02549 const GLuint depthScale = 0xffffff; 02550 const GLint srcRowStride 02551 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) 02552 / sizeof(GLuint); 02553 GLint img, row; 02554 02555 ASSERT(dstFormat == &_mesa_texformat_s8_z24); 02556 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT); 02557 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT); 02558 02559 /* In case we only upload depth we need to preserve the stencil */ 02560 if (srcFormat == GL_DEPTH_COMPONENT) { 02561 for (img = 0; img < srcDepth; img++) { 02562 GLuint *dstRow = (GLuint *) dstAddr 02563 + dstImageOffsets[dstZoffset + img] 02564 + dstYoffset * dstRowStride / sizeof(GLuint) 02565 + dstXoffset; 02566 const GLuint *src 02567 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr, 02568 srcWidth, srcHeight, 02569 srcFormat, srcType, 02570 img, 0, 0); 02571 for (row = 0; row < srcHeight; row++) { 02572 GLuint depth[MAX_WIDTH]; 02573 GLint i; 02574 _mesa_unpack_depth_span(ctx, srcWidth, 02575 GL_UNSIGNED_INT, /* dst type */ 02576 depth, /* dst addr */ 02577 depthScale, 02578 srcType, src, srcPacking); 02579 02580 for (i = 0; i < srcWidth; i++) 02581 dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000); 02582 02583 src += srcRowStride; 02584 dstRow += dstRowStride / sizeof(GLuint); 02585 } 02586 } 02587 } 02588 else { 02589 for (img = 0; img < srcDepth; img++) { 02590 GLuint *dstRow = (GLuint *) dstAddr 02591 + dstImageOffsets[dstZoffset + img] 02592 + dstYoffset * dstRowStride / sizeof(GLuint) 02593 + dstXoffset; 02594 const GLuint *src 02595 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr, 02596 srcWidth, srcHeight, 02597 srcFormat, srcType, 02598 img, 0, 0); 02599 for (row = 0; row < srcHeight; row++) { 02600 GLubyte stencil[MAX_WIDTH]; 02601 GLint i; 02602 /* the 24 depth bits will be in the low position: */ 02603 _mesa_unpack_depth_span(ctx, srcWidth, 02604 GL_UNSIGNED_INT, /* dst type */ 02605 dstRow, /* dst addr */ 02606 depthScale, 02607 srcType, src, srcPacking); 02608 /* get the 8-bit stencil values */ 02609 _mesa_unpack_stencil_span(ctx, srcWidth, 02610 GL_UNSIGNED_BYTE, /* dst type */ 02611 stencil, /* dst addr */ 02612 srcType, src, srcPacking, 02613 ctx->_ImageTransferState); 02614 /* merge stencil values into depth values */ 02615 for (i = 0; i < srcWidth; i++) 02616 dstRow[i] |= stencil[i] << 24; 02617 02618 src += srcRowStride; 02619 dstRow += dstRowStride / sizeof(GLuint); 02620 } 02621 } 02622 } 02623 return GL_TRUE; 02624 } 02625 02635 GLboolean 02636 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS) 02637 { 02638 const GLint components = _mesa_components_in_format(dstFormat->BaseFormat); 02639 02640 ASSERT(dstFormat == &_mesa_texformat_rgba_float32 || 02641 dstFormat == &_mesa_texformat_rgb_float32 || 02642 dstFormat == &_mesa_texformat_alpha_float32 || 02643 dstFormat == &_mesa_texformat_luminance_float32 || 02644 dstFormat == &_mesa_texformat_luminance_alpha_float32 || 02645 dstFormat == &_mesa_texformat_intensity_float32); 02646 ASSERT(baseInternalFormat == GL_RGBA || 02647 baseInternalFormat == GL_RGB || 02648 baseInternalFormat == GL_ALPHA || 02649 baseInternalFormat == GL_LUMINANCE || 02650 baseInternalFormat == GL_LUMINANCE_ALPHA || 02651 baseInternalFormat == GL_INTENSITY); 02652 ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat)); 02653 02654 if (!ctx->_ImageTransferState && 02655 !srcPacking->SwapBytes && 02656 baseInternalFormat == srcFormat && 02657 srcType == GL_FLOAT) { 02658 /* simple memcpy path */ 02659 memcpy_texture(ctx, dims, 02660 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 02661 dstRowStride, 02662 dstImageOffsets, 02663 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 02664 srcAddr, srcPacking); 02665 } 02666 else { 02667 /* general path */ 02668 const GLfloat *tempImage = make_temp_float_image(ctx, dims, 02669 baseInternalFormat, 02670 dstFormat->BaseFormat, 02671 srcWidth, srcHeight, srcDepth, 02672 srcFormat, srcType, srcAddr, 02673 srcPacking); 02674 const GLfloat *srcRow = tempImage; 02675 GLint bytesPerRow; 02676 GLint img, row; 02677 if (!tempImage) 02678 return GL_FALSE; 02679 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 02680 bytesPerRow = srcWidth * components * sizeof(GLfloat); 02681 for (img = 0; img < srcDepth; img++) { 02682 GLubyte *dstRow = (GLubyte *) dstAddr 02683 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 02684 + dstYoffset * dstRowStride 02685 + dstXoffset * dstFormat->TexelBytes; 02686 for (row = 0; row < srcHeight; row++) { 02687 _mesa_memcpy(dstRow, srcRow, bytesPerRow); 02688 dstRow += dstRowStride; 02689 srcRow += srcWidth * components; 02690 } 02691 } 02692 02693 _mesa_free((void *) tempImage); 02694 } 02695 return GL_TRUE; 02696 } 02697 02698 02702 GLboolean 02703 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS) 02704 { 02705 const GLint components = _mesa_components_in_format(dstFormat->BaseFormat); 02706 02707 ASSERT(dstFormat == &_mesa_texformat_rgba_float16 || 02708 dstFormat == &_mesa_texformat_rgb_float16 || 02709 dstFormat == &_mesa_texformat_alpha_float16 || 02710 dstFormat == &_mesa_texformat_luminance_float16 || 02711 dstFormat == &_mesa_texformat_luminance_alpha_float16 || 02712 dstFormat == &_mesa_texformat_intensity_float16); 02713 ASSERT(baseInternalFormat == GL_RGBA || 02714 baseInternalFormat == GL_RGB || 02715 baseInternalFormat == GL_ALPHA || 02716 baseInternalFormat == GL_LUMINANCE || 02717 baseInternalFormat == GL_LUMINANCE_ALPHA || 02718 baseInternalFormat == GL_INTENSITY); 02719 ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB)); 02720 02721 if (!ctx->_ImageTransferState && 02722 !srcPacking->SwapBytes && 02723 baseInternalFormat == srcFormat && 02724 srcType == GL_HALF_FLOAT_ARB) { 02725 /* simple memcpy path */ 02726 memcpy_texture(ctx, dims, 02727 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset, 02728 dstRowStride, 02729 dstImageOffsets, 02730 srcWidth, srcHeight, srcDepth, srcFormat, srcType, 02731 srcAddr, srcPacking); 02732 } 02733 else { 02734 /* general path */ 02735 const GLfloat *tempImage = make_temp_float_image(ctx, dims, 02736 baseInternalFormat, 02737 dstFormat->BaseFormat, 02738 srcWidth, srcHeight, srcDepth, 02739 srcFormat, srcType, srcAddr, 02740 srcPacking); 02741 const GLfloat *src = tempImage; 02742 GLint img, row; 02743 if (!tempImage) 02744 return GL_FALSE; 02745 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight); 02746 for (img = 0; img < srcDepth; img++) { 02747 GLubyte *dstRow = (GLubyte *) dstAddr 02748 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes 02749 + dstYoffset * dstRowStride 02750 + dstXoffset * dstFormat->TexelBytes; 02751 for (row = 0; row < srcHeight; row++) { 02752 GLhalfARB *dstTexel = (GLhalfARB *) dstRow; 02753 GLint i; 02754 for (i = 0; i < srcWidth * components; i++) { 02755 dstTexel[i] = _mesa_float_to_half(src[i]); 02756 } 02757 dstRow += dstRowStride; 02758 src += srcWidth * components; 02759 } 02760 } 02761 02762 _mesa_free((void *) tempImage); 02763 } 02764 return GL_TRUE; 02765 } 02766 02767 02768 #if FEATURE_EXT_texture_sRGB 02769 GLboolean 02770 _mesa_texstore_srgb8(TEXSTORE_PARAMS) 02771 { 02772 const GLboolean littleEndian = _mesa_little_endian(); 02773 const struct gl_texture_format *newDstFormat; 02774 StoreTexImageFunc store; 02775 GLboolean k; 02776 02777 ASSERT(dstFormat == &_mesa_texformat_srgb8); 02778 02779 /* reuse normal rgb texstore code */ 02780 if (littleEndian) { 02781 newDstFormat = &_mesa_texformat_bgr888; 02782 store = _mesa_texstore_bgr888; 02783 } 02784 else { 02785 newDstFormat = &_mesa_texformat_rgb888; 02786 store = _mesa_texstore_rgb888; 02787 } 02788 02789 k = store(ctx, dims, baseInternalFormat, 02790 newDstFormat, dstAddr, 02791 dstXoffset, dstYoffset, dstZoffset, 02792 dstRowStride, dstImageOffsets, 02793 srcWidth, srcHeight, srcDepth, 02794 srcFormat, srcType, 02795 srcAddr, srcPacking); 02796 return k; 02797 } 02798 02799 02800 GLboolean 02801 _mesa_texstore_srgba8(TEXSTORE_PARAMS) 02802 { 02803 const GLboolean littleEndian = _mesa_little_endian(); 02804 const struct gl_texture_format *newDstFormat; 02805 GLboolean k; 02806 02807 ASSERT(dstFormat == &_mesa_texformat_srgba8); 02808 02809 /* reuse normal rgba texstore code */ 02810 if (littleEndian) 02811 newDstFormat = &_mesa_texformat_rgba8888_rev; 02812 else 02813 newDstFormat = &_mesa_texformat_rgba8888; 02814 02815 k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat, 02816 newDstFormat, dstAddr, 02817 dstXoffset, dstYoffset, dstZoffset, 02818 dstRowStride, dstImageOffsets, 02819 srcWidth, srcHeight, srcDepth, 02820 srcFormat, srcType, 02821 srcAddr, srcPacking); 02822 return k; 02823 } 02824 02825 02826 GLboolean 02827 _mesa_texstore_sl8(TEXSTORE_PARAMS) 02828 { 02829 const struct gl_texture_format *newDstFormat; 02830 GLboolean k; 02831 02832 ASSERT(dstFormat == &_mesa_texformat_sl8); 02833 02834 newDstFormat = &_mesa_texformat_l8; 02835 02836 /* _mesa_textore_a8 handles luminance8 too */ 02837 k = _mesa_texstore_a8(ctx, dims, baseInternalFormat, 02838 newDstFormat, dstAddr, 02839 dstXoffset, dstYoffset, dstZoffset, 02840 dstRowStride, dstImageOffsets, 02841 srcWidth, srcHeight, srcDepth, 02842 srcFormat, srcType, 02843 srcAddr, srcPacking); 02844 return k; 02845 } 02846 02847 02848 GLboolean 02849 _mesa_texstore_sla8(TEXSTORE_PARAMS) 02850 { 02851 const GLboolean littleEndian = _mesa_little_endian(); 02852 const struct gl_texture_format *newDstFormat; 02853 GLboolean k; 02854 02855 ASSERT(dstFormat == &_mesa_texformat_sla8); 02856 02857 /* reuse normal luminance/alpha texstore code */ 02858 if (littleEndian) 02859 newDstFormat = &_mesa_texformat_al88; 02860 else 02861 newDstFormat = &_mesa_texformat_al88_rev; 02862 02863 k = _mesa_texstore_al88(ctx, dims, baseInternalFormat, 02864 newDstFormat, dstAddr, 02865 dstXoffset, dstYoffset, dstZoffset, 02866 dstRowStride, dstImageOffsets, 02867 srcWidth, srcHeight, srcDepth, 02868 srcFormat, srcType, 02869 srcAddr, srcPacking); 02870 return k; 02871 } 02872 02873 #endif /* FEATURE_EXT_texture_sRGB */ 02874 02875 02882 const GLvoid * 02883 _mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions, 02884 GLsizei width, GLsizei height, GLsizei depth, 02885 GLenum format, GLenum type, const GLvoid *pixels, 02886 const struct gl_pixelstore_attrib *unpack, 02887 const char *funcName) 02888 { 02889 GLubyte *buf; 02890 02891 if (unpack->BufferObj->Name == 0) { 02892 /* no PBO */ 02893 return pixels; 02894 } 02895 if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth, 02896 format, type, pixels)) { 02897 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access"); 02898 return NULL; 02899 } 02900 02901 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 02902 GL_READ_ONLY_ARB, unpack->BufferObj); 02903 if (!buf) { 02904 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped"); 02905 return NULL; 02906 } 02907 02908 return ADD_POINTERS(buf, pixels); 02909 } 02910 02911 02919 const GLvoid * 02920 _mesa_validate_pbo_compressed_teximage(GLcontext *ctx, 02921 GLsizei imageSize, const GLvoid *pixels, 02922 const struct gl_pixelstore_attrib *packing, 02923 const char *funcName) 02924 { 02925 GLubyte *buf; 02926 02927 if (packing->BufferObj->Name == 0) { 02928 /* not using a PBO - return pointer unchanged */ 02929 return pixels; 02930 } 02931 if ((const GLubyte *) pixels + imageSize > 02932 ((const GLubyte *) 0) + packing->BufferObj->Size) { 02933 /* out of bounds read! */ 02934 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access"); 02935 return NULL; 02936 } 02937 02938 buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 02939 GL_READ_ONLY_ARB, packing->BufferObj); 02940 if (!buf) { 02941 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped"); 02942 return NULL; 02943 } 02944 02945 return ADD_POINTERS(buf, pixels); 02946 } 02947 02948 02953 void 02954 _mesa_unmap_teximage_pbo(GLcontext *ctx, 02955 const struct gl_pixelstore_attrib *unpack) 02956 { 02957 if (unpack->BufferObj->Name) { 02958 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 02959 unpack->BufferObj); 02960 } 02961 } 02962 02963 02964 02968 static void 02969 fetch_texel_float_to_chan(const struct gl_texture_image *texImage, 02970 GLint i, GLint j, GLint k, GLchan *texelOut) 02971 { 02972 GLfloat temp[4]; 02973 ASSERT(texImage->FetchTexelf); 02974 texImage->FetchTexelf(texImage, i, j, k, temp); 02975 if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT || 02976 texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) { 02977 /* just one channel */ 02978 UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]); 02979 } 02980 else { 02981 /* four channels */ 02982 UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]); 02983 UNCLAMPED_FLOAT_TO_CHAN(texelOut[1], temp[1]); 02984 UNCLAMPED_FLOAT_TO_CHAN(texelOut[2], temp[2]); 02985 UNCLAMPED_FLOAT_TO_CHAN(texelOut[3], temp[3]); 02986 } 02987 } 02988 02989 02993 static void 02994 fetch_texel_chan_to_float(const struct gl_texture_image *texImage, 02995 GLint i, GLint j, GLint k, GLfloat *texelOut) 02996 { 02997 GLchan temp[4]; 02998 ASSERT(texImage->FetchTexelc); 02999 texImage->FetchTexelc(texImage, i, j, k, temp); 03000 if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT || 03001 texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) { 03002 /* just one channel */ 03003 texelOut[0] = CHAN_TO_FLOAT(temp[0]); 03004 } 03005 else { 03006 /* four channels */ 03007 texelOut[0] = CHAN_TO_FLOAT(temp[0]); 03008 texelOut[1] = CHAN_TO_FLOAT(temp[1]); 03009 texelOut[2] = CHAN_TO_FLOAT(temp[2]); 03010 texelOut[3] = CHAN_TO_FLOAT(temp[3]); 03011 } 03012 } 03013 03014 03018 void 03019 _mesa_set_fetch_functions(struct gl_texture_image *texImage, GLuint dims) 03020 { 03021 ASSERT(dims == 1 || dims == 2 || dims == 3); 03022 ASSERT(texImage->TexFormat); 03023 03024 switch (dims) { 03025 case 1: 03026 texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D; 03027 texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df; 03028 break; 03029 case 2: 03030 texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D; 03031 texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df; 03032 break; 03033 case 3: 03034 texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D; 03035 texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df; 03036 break; 03037 default: 03038 ; 03039 } 03040 03041 /* now check if we need to use a float/chan adaptor */ 03042 if (!texImage->FetchTexelc) { 03043 texImage->FetchTexelc = fetch_texel_float_to_chan; 03044 } 03045 else if (!texImage->FetchTexelf) { 03046 texImage->FetchTexelf = fetch_texel_chan_to_float; 03047 } 03048 03049 03050 ASSERT(texImage->FetchTexelc); 03051 ASSERT(texImage->FetchTexelf); 03052 } 03053 03054 03066 static void 03067 choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage, 03068 GLuint dims, 03069 GLenum format, GLenum type, GLint internalFormat) 03070 { 03071 ASSERT(dims == 1 || dims == 2 || dims == 3); 03072 ASSERT(ctx->Driver.ChooseTextureFormat); 03073 03074 texImage->TexFormat 03075 = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type); 03076 03077 ASSERT(texImage->TexFormat); 03078 03079 _mesa_set_fetch_functions(texImage, dims); 03080 03081 if (texImage->TexFormat->TexelBytes == 0) { 03082 /* must be a compressed format */ 03083 texImage->IsCompressed = GL_TRUE; 03084 texImage->CompressedSize = 03085 ctx->Driver.CompressedTextureSize(ctx, texImage->Width, 03086 texImage->Height, texImage->Depth, 03087 texImage->TexFormat->MesaFormat); 03088 } 03089 else { 03090 /* non-compressed format */ 03091 texImage->IsCompressed = GL_FALSE; 03092 texImage->CompressedSize = 0; 03093 } 03094 } 03095 03096 03097 03106 void 03107 _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, 03108 GLint internalFormat, 03109 GLint width, GLint border, 03110 GLenum format, GLenum type, const GLvoid *pixels, 03111 const struct gl_pixelstore_attrib *packing, 03112 struct gl_texture_object *texObj, 03113 struct gl_texture_image *texImage) 03114 { 03115 GLint sizeInBytes; 03116 (void) border; 03117 03118 choose_texture_format(ctx, texImage, 1, format, type, internalFormat); 03119 03120 /* allocate memory */ 03121 if (texImage->IsCompressed) 03122 sizeInBytes = texImage->CompressedSize; 03123 else 03124 sizeInBytes = texImage->Width * texImage->TexFormat->TexelBytes; 03125 texImage->Data = _mesa_alloc_texmemory(sizeInBytes); 03126 if (!texImage->Data) { 03127 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); 03128 return; 03129 } 03130 03131 pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, 03132 pixels, packing, "glTexImage1D"); 03133 if (!pixels) { 03134 /* Note: we check for a NULL image pointer here, _after_ we allocated 03135 * memory for the texture. That's what the GL spec calls for. 03136 */ 03137 return; 03138 } 03139 else { 03140 const GLint dstRowStride = 0; 03141 GLboolean success; 03142 ASSERT(texImage->TexFormat->StoreImage); 03143 success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat, 03144 texImage->TexFormat, 03145 texImage->Data, 03146 0, 0, 0, /* dstX/Y/Zoffset */ 03147 dstRowStride, 03148 texImage->ImageOffsets, 03149 width, 1, 1, 03150 format, type, pixels, packing); 03151 if (!success) { 03152 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); 03153 } 03154 } 03155 03156 /* GL_SGIS_generate_mipmap */ 03157 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 03158 ctx->Driver.GenerateMipmap(ctx, target, texObj); 03159 } 03160 03161 _mesa_unmap_teximage_pbo(ctx, packing); 03162 } 03163 03164 03175 void 03176 _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, 03177 GLint internalFormat, 03178 GLint width, GLint height, GLint border, 03179 GLenum format, GLenum type, const void *pixels, 03180 const struct gl_pixelstore_attrib *packing, 03181 struct gl_texture_object *texObj, 03182 struct gl_texture_image *texImage) 03183 { 03184 GLint texelBytes, sizeInBytes; 03185 (void) border; 03186 03187 choose_texture_format(ctx, texImage, 2, format, type, internalFormat); 03188 03189 texelBytes = texImage->TexFormat->TexelBytes; 03190 03191 /* allocate memory */ 03192 if (texImage->IsCompressed) 03193 sizeInBytes = texImage->CompressedSize; 03194 else 03195 sizeInBytes = texImage->Width * texImage->Height * texelBytes; 03196 texImage->Data = _mesa_alloc_texmemory(sizeInBytes); 03197 if (!texImage->Data) { 03198 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); 03199 return; 03200 } 03201 03202 pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type, 03203 pixels, packing, "glTexImage2D"); 03204 if (!pixels) { 03205 /* Note: we check for a NULL image pointer here, _after_ we allocated 03206 * memory for the texture. That's what the GL spec calls for. 03207 */ 03208 return; 03209 } 03210 else { 03211 GLint dstRowStride; 03212 GLboolean success; 03213 if (texImage->IsCompressed) { 03214 dstRowStride 03215 = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); 03216 } 03217 else { 03218 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes; 03219 } 03220 ASSERT(texImage->TexFormat->StoreImage); 03221 success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat, 03222 texImage->TexFormat, 03223 texImage->Data, 03224 0, 0, 0, /* dstX/Y/Zoffset */ 03225 dstRowStride, 03226 texImage->ImageOffsets, 03227 width, height, 1, 03228 format, type, pixels, packing); 03229 if (!success) { 03230 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); 03231 } 03232 } 03233 03234 /* GL_SGIS_generate_mipmap */ 03235 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 03236 ctx->Driver.GenerateMipmap(ctx, target, texObj); 03237 } 03238 03239 _mesa_unmap_teximage_pbo(ctx, packing); 03240 } 03241 03242 03243 03249 void 03250 _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, 03251 GLint internalFormat, 03252 GLint width, GLint height, GLint depth, GLint border, 03253 GLenum format, GLenum type, const void *pixels, 03254 const struct gl_pixelstore_attrib *packing, 03255 struct gl_texture_object *texObj, 03256 struct gl_texture_image *texImage) 03257 { 03258 GLint texelBytes, sizeInBytes; 03259 (void) border; 03260 03261 choose_texture_format(ctx, texImage, 3, format, type, internalFormat); 03262 03263 texelBytes = texImage->TexFormat->TexelBytes; 03264 03265 /* allocate memory */ 03266 if (texImage->IsCompressed) 03267 sizeInBytes = texImage->CompressedSize; 03268 else 03269 sizeInBytes = width * height * depth * texelBytes; 03270 texImage->Data = _mesa_alloc_texmemory(sizeInBytes); 03271 if (!texImage->Data) { 03272 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); 03273 return; 03274 } 03275 03276 pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format, 03277 type, pixels, packing, "glTexImage3D"); 03278 if (!pixels) { 03279 /* Note: we check for a NULL image pointer here, _after_ we allocated 03280 * memory for the texture. That's what the GL spec calls for. 03281 */ 03282 return; 03283 } 03284 else { 03285 GLint dstRowStride; 03286 GLboolean success; 03287 if (texImage->IsCompressed) { 03288 dstRowStride 03289 = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); 03290 } 03291 else { 03292 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes; 03293 } 03294 ASSERT(texImage->TexFormat->StoreImage); 03295 success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat, 03296 texImage->TexFormat, 03297 texImage->Data, 03298 0, 0, 0, /* dstX/Y/Zoffset */ 03299 dstRowStride, 03300 texImage->ImageOffsets, 03301 width, height, depth, 03302 format, type, pixels, packing); 03303 if (!success) { 03304 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); 03305 } 03306 } 03307 03308 /* GL_SGIS_generate_mipmap */ 03309 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 03310 ctx->Driver.GenerateMipmap(ctx, target, texObj); 03311 } 03312 03313 _mesa_unmap_teximage_pbo(ctx, packing); 03314 } 03315 03316 03317 03318 03319 /* 03320 * This is the software fallback for Driver.TexSubImage1D() 03321 * and Driver.CopyTexSubImage1D(). 03322 */ 03323 void 03324 _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, 03325 GLint xoffset, GLint width, 03326 GLenum format, GLenum type, const void *pixels, 03327 const struct gl_pixelstore_attrib *packing, 03328 struct gl_texture_object *texObj, 03329 struct gl_texture_image *texImage) 03330 { 03331 /* get pointer to src pixels (may be in a pbo which we'll map here) */ 03332 pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type, 03333 pixels, packing, "glTexSubImage1D"); 03334 if (!pixels) 03335 return; 03336 03337 { 03338 const GLint dstRowStride = 0; 03339 GLboolean success; 03340 ASSERT(texImage->TexFormat->StoreImage); 03341 success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat, 03342 texImage->TexFormat, 03343 texImage->Data, 03344 xoffset, 0, 0, /* offsets */ 03345 dstRowStride, 03346 texImage->ImageOffsets, 03347 width, 1, 1, 03348 format, type, pixels, packing); 03349 if (!success) { 03350 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); 03351 } 03352 } 03353 03354 /* GL_SGIS_generate_mipmap */ 03355 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 03356 ctx->Driver.GenerateMipmap(ctx, target, texObj); 03357 } 03358 03359 _mesa_unmap_teximage_pbo(ctx, packing); 03360 } 03361 03362 03363 03368 void 03369 _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, 03370 GLint xoffset, GLint yoffset, 03371 GLint width, GLint height, 03372 GLenum format, GLenum type, const void *pixels, 03373 const struct gl_pixelstore_attrib *packing, 03374 struct gl_texture_object *texObj, 03375 struct gl_texture_image *texImage) 03376 { 03377 /* get pointer to src pixels (may be in a pbo which we'll map here) */ 03378 pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type, 03379 pixels, packing, "glTexSubImage2D"); 03380 if (!pixels) 03381 return; 03382 03383 { 03384 GLint dstRowStride = 0; 03385 GLboolean success; 03386 if (texImage->IsCompressed) { 03387 dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, 03388 texImage->Width); 03389 } 03390 else { 03391 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes; 03392 } 03393 ASSERT(texImage->TexFormat->StoreImage); 03394 success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat, 03395 texImage->TexFormat, 03396 texImage->Data, 03397 xoffset, yoffset, 0, 03398 dstRowStride, 03399 texImage->ImageOffsets, 03400 width, height, 1, 03401 format, type, pixels, packing); 03402 if (!success) { 03403 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); 03404 } 03405 } 03406 03407 /* GL_SGIS_generate_mipmap */ 03408 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 03409 ctx->Driver.GenerateMipmap(ctx, target, texObj); 03410 } 03411 03412 _mesa_unmap_teximage_pbo(ctx, packing); 03413 } 03414 03415 03416 /* 03417 * This is the software fallback for Driver.TexSubImage3D(). 03418 * and Driver.CopyTexSubImage3D(). 03419 */ 03420 void 03421 _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, 03422 GLint xoffset, GLint yoffset, GLint zoffset, 03423 GLint width, GLint height, GLint depth, 03424 GLenum format, GLenum type, const void *pixels, 03425 const struct gl_pixelstore_attrib *packing, 03426 struct gl_texture_object *texObj, 03427 struct gl_texture_image *texImage) 03428 { 03429 /* get pointer to src pixels (may be in a pbo which we'll map here) */ 03430 pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format, 03431 type, pixels, packing, 03432 "glTexSubImage3D"); 03433 if (!pixels) 03434 return; 03435 03436 { 03437 GLint dstRowStride; 03438 GLboolean success; 03439 if (texImage->IsCompressed) { 03440 dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, 03441 texImage->Width); 03442 } 03443 else { 03444 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes; 03445 } 03446 ASSERT(texImage->TexFormat->StoreImage); 03447 success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat, 03448 texImage->TexFormat, 03449 texImage->Data, 03450 xoffset, yoffset, zoffset, 03451 dstRowStride, 03452 texImage->ImageOffsets, 03453 width, height, depth, 03454 format, type, pixels, packing); 03455 if (!success) { 03456 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D"); 03457 } 03458 } 03459 03460 /* GL_SGIS_generate_mipmap */ 03461 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 03462 ctx->Driver.GenerateMipmap(ctx, target, texObj); 03463 } 03464 03465 _mesa_unmap_teximage_pbo(ctx, packing); 03466 } 03467 03468 03469 /* 03470 * Fallback for Driver.CompressedTexImage1D() 03471 */ 03472 void 03473 _mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level, 03474 GLint internalFormat, 03475 GLint width, GLint border, 03476 GLsizei imageSize, const GLvoid *data, 03477 struct gl_texture_object *texObj, 03478 struct gl_texture_image *texImage) 03479 { 03480 /* this space intentionally left blank */ 03481 (void) ctx; 03482 (void) target; (void) level; 03483 (void) internalFormat; 03484 (void) width; (void) border; 03485 (void) imageSize; (void) data; 03486 (void) texObj; 03487 (void) texImage; 03488 } 03489 03490 03491 03495 void 03496 _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, 03497 GLint internalFormat, 03498 GLint width, GLint height, GLint border, 03499 GLsizei imageSize, const GLvoid *data, 03500 struct gl_texture_object *texObj, 03501 struct gl_texture_image *texImage) 03502 { 03503 (void) width; (void) height; (void) border; 03504 03505 /* This is pretty simple, basically just do a memcpy without worrying 03506 * about the usual image unpacking or image transfer operations. 03507 */ 03508 ASSERT(texObj); 03509 ASSERT(texImage); 03510 ASSERT(texImage->Width > 0); 03511 ASSERT(texImage->Height > 0); 03512 ASSERT(texImage->Depth == 1); 03513 ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */ 03514 03515 choose_texture_format(ctx, texImage, 2, 0, 0, internalFormat); 03516 03517 /* allocate storage */ 03518 texImage->Data = _mesa_alloc_texmemory(imageSize); 03519 if (!texImage->Data) { 03520 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB"); 03521 return; 03522 } 03523 03524 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data, 03525 &ctx->Unpack, 03526 "glCompressedTexImage2D"); 03527 if (!data) 03528 return; 03529 03530 /* copy the data */ 03531 ASSERT(texImage->CompressedSize == (GLuint) imageSize); 03532 MEMCPY(texImage->Data, data, imageSize); 03533 03534 /* GL_SGIS_generate_mipmap */ 03535 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 03536 ctx->Driver.GenerateMipmap(ctx, target, texObj); 03537 } 03538 03539 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack); 03540 } 03541 03542 03543 03544 /* 03545 * Fallback for Driver.CompressedTexImage3D() 03546 */ 03547 void 03548 _mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level, 03549 GLint internalFormat, 03550 GLint width, GLint height, GLint depth, 03551 GLint border, 03552 GLsizei imageSize, const GLvoid *data, 03553 struct gl_texture_object *texObj, 03554 struct gl_texture_image *texImage) 03555 { 03556 /* this space intentionally left blank */ 03557 (void) ctx; 03558 (void) target; (void) level; 03559 (void) internalFormat; 03560 (void) width; (void) height; (void) depth; 03561 (void) border; 03562 (void) imageSize; (void) data; 03563 (void) texObj; 03564 (void) texImage; 03565 } 03566 03567 03568 03572 void 03573 _mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target, 03574 GLint level, 03575 GLint xoffset, GLsizei width, 03576 GLenum format, 03577 GLsizei imageSize, const GLvoid *data, 03578 struct gl_texture_object *texObj, 03579 struct gl_texture_image *texImage) 03580 { 03581 /* there are no compressed 1D texture formats yet */ 03582 (void) ctx; 03583 (void) target; (void) level; 03584 (void) xoffset; (void) width; 03585 (void) format; 03586 (void) imageSize; (void) data; 03587 (void) texObj; 03588 (void) texImage; 03589 } 03590 03591 03595 void 03596 _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target, 03597 GLint level, 03598 GLint xoffset, GLint yoffset, 03599 GLsizei width, GLsizei height, 03600 GLenum format, 03601 GLsizei imageSize, const GLvoid *data, 03602 struct gl_texture_object *texObj, 03603 struct gl_texture_image *texImage) 03604 { 03605 GLint bytesPerRow, destRowStride, srcRowStride; 03606 GLint i, rows; 03607 GLubyte *dest; 03608 const GLubyte *src; 03609 const GLuint mesaFormat = texImage->TexFormat->MesaFormat; 03610 03611 (void) format; 03612 03613 /* these should have been caught sooner */ 03614 ASSERT((width & 3) == 0 || width == 2 || width == 1); 03615 ASSERT((height & 3) == 0 || height == 2 || height == 1); 03616 ASSERT((xoffset & 3) == 0); 03617 ASSERT((yoffset & 3) == 0); 03618 03619 /* get pointer to src pixels (may be in a pbo which we'll map here) */ 03620 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data, 03621 &ctx->Unpack, 03622 "glCompressedTexSubImage2D"); 03623 if (!data) 03624 return; 03625 03626 srcRowStride = _mesa_compressed_row_stride(mesaFormat, width); 03627 src = (const GLubyte *) data; 03628 03629 destRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width); 03630 dest = _mesa_compressed_image_address(xoffset, yoffset, 0, 03631 texImage->TexFormat->MesaFormat, 03632 texImage->Width, 03633 (GLubyte *) texImage->Data); 03634 03635 bytesPerRow = srcRowStride; 03636 rows = height / 4; 03637 03638 for (i = 0; i < rows; i++) { 03639 MEMCPY(dest, src, bytesPerRow); 03640 dest += destRowStride; 03641 src += srcRowStride; 03642 } 03643 03644 /* GL_SGIS_generate_mipmap */ 03645 if (level == texObj->BaseLevel && texObj->GenerateMipmap) { 03646 ctx->Driver.GenerateMipmap(ctx, target, texObj); 03647 } 03648 03649 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack); 03650 } 03651 03652 03656 void 03657 _mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target, 03658 GLint level, 03659 GLint xoffset, GLint yoffset, GLint zoffset, 03660 GLsizei width, GLsizei height, GLsizei depth, 03661 GLenum format, 03662 GLsizei imageSize, const GLvoid *data, 03663 struct gl_texture_object *texObj, 03664 struct gl_texture_image *texImage) 03665 { 03666 /* there are no compressed 3D texture formats yet */ 03667 (void) ctx; 03668 (void) target; (void) level; 03669 (void) xoffset; (void) yoffset; (void) zoffset; 03670 (void) width; (void) height; (void) depth; 03671 (void) format; 03672 (void) imageSize; (void) data; 03673 (void) texObj; 03674 (void) texImage; 03675 } 03676 03677 03678 03679 03680 #if FEATURE_EXT_texture_sRGB 03681 03685 static GLboolean 03686 is_srgb_teximage(const struct gl_texture_image *texImage) 03687 { 03688 switch (texImage->TexFormat->MesaFormat) { 03689 case MESA_FORMAT_SRGB8: 03690 case MESA_FORMAT_SRGBA8: 03691 case MESA_FORMAT_SL8: 03692 case MESA_FORMAT_SLA8: 03693 return GL_TRUE; 03694 default: 03695 return GL_FALSE; 03696 } 03697 } 03698 03699 #endif /* FEATURE_EXT_texture_sRGB */ 03700 03701 03706 void 03707 _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, 03708 GLenum format, GLenum type, GLvoid *pixels, 03709 struct gl_texture_object *texObj, 03710 struct gl_texture_image *texImage) 03711 { 03712 const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; 03713 03714 if (ctx->Pack.BufferObj->Name) { 03715 /* Packing texture image into a PBO. 03716 * Map the (potentially) VRAM-based buffer into our process space so 03717 * we can write into it with the code below. 03718 * A hardware driver might use a sophisticated blit to move the 03719 * texture data to the PBO if the PBO is in VRAM along with the texture. 03720 */ 03721 GLubyte *buf = (GLubyte *) 03722 ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 03723 GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj); 03724 if (!buf) { 03725 /* buffer is already mapped - that's an error */ 03726 _mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)"); 03727 return; 03728 } 03729 /* <pixels> was an offset into the PBO. 03730 * Now make it a real, client-side pointer inside the mapped region. 03731 */ 03732 pixels = ADD_POINTERS(buf, pixels); 03733 } 03734 else if (!pixels) { 03735 /* not an error */ 03736 return; 03737 } 03738 03739 { 03740 const GLint width = texImage->Width; 03741 const GLint height = texImage->Height; 03742 const GLint depth = texImage->Depth; 03743 GLint img, row; 03744 for (img = 0; img < depth; img++) { 03745 for (row = 0; row < height; row++) { 03746 /* compute destination address in client memory */ 03747 GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels, 03748 width, height, format, type, 03749 img, row, 0); 03750 assert(dest); 03751 03752 if (format == GL_COLOR_INDEX) { 03753 GLuint indexRow[MAX_WIDTH]; 03754 GLint col; 03755 /* Can't use FetchTexel here because that returns RGBA */ 03756 if (texImage->TexFormat->IndexBits == 8) { 03757 const GLubyte *src = (const GLubyte *) texImage->Data; 03758 src += width * (img * texImage->Height + row); 03759 for (col = 0; col < width; col++) { 03760 indexRow[col] = src[col]; 03761 } 03762 } 03763 else if (texImage->TexFormat->IndexBits == 16) { 03764 const GLushort *src = (const GLushort *) texImage->Data; 03765 src += width * (img * texImage->Height + row); 03766 for (col = 0; col < width; col++) { 03767 indexRow[col] = src[col]; 03768 } 03769 } 03770 else { 03771 _mesa_problem(ctx, 03772 "Color index problem in _mesa_GetTexImage"); 03773 } 03774 _mesa_pack_index_span(ctx, width, type, dest, 03775 indexRow, &ctx->Pack, 03776 0 /* no image transfer */); 03777 } 03778 else if (format == GL_DEPTH_COMPONENT) { 03779 GLfloat depthRow[MAX_WIDTH]; 03780 GLint col; 03781 for (col = 0; col < width; col++) { 03782 (*texImage->FetchTexelf)(texImage, col, row, img, 03783 depthRow + col); 03784 } 03785 _mesa_pack_depth_span(ctx, width, dest, type, 03786 depthRow, &ctx->Pack); 03787 } 03788 else if (format == GL_DEPTH_STENCIL_EXT) { 03789 /* XXX Note: we're bypassing texImage->FetchTexel()! */ 03790 const GLuint *src = (const GLuint *) texImage->Data; 03791 src += width * row + width * height * img; 03792 _mesa_memcpy(dest, src, width * sizeof(GLuint)); 03793 if (ctx->Pack.SwapBytes) { 03794 _mesa_swap4((GLuint *) dest, width); 03795 } 03796 } 03797 else if (format == GL_YCBCR_MESA) { 03798 /* No pixel transfer */ 03799 const GLint rowstride = texImage->RowStride; 03800 MEMCPY(dest, 03801 (const GLushort *) texImage->Data + row * rowstride, 03802 width * sizeof(GLushort)); 03803 /* check for byte swapping */ 03804 if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR 03805 && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) || 03806 (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV 03807 && type == GL_UNSIGNED_SHORT_8_8_MESA)) { 03808 if (!ctx->Pack.SwapBytes) 03809 _mesa_swap2((GLushort *) dest, width); 03810 } 03811 else if (ctx->Pack.SwapBytes) { 03812 _mesa_swap2((GLushort *) dest, width); 03813 } 03814 } 03815 #if FEATURE_EXT_texture_sRGB 03816 else if (is_srgb_teximage(texImage)) { 03817 /* no pixel transfer and no non-linear to linear conversion */ 03818 const GLint comps = texImage->TexFormat->TexelBytes; 03819 const GLint rowstride = comps * texImage->RowStride; 03820 MEMCPY(dest, 03821 (const GLubyte *) texImage->Data + row * rowstride, 03822 comps * width * sizeof(GLubyte)); 03823 } 03824 #endif /* FEATURE_EXT_texture_sRGB */ 03825 else { 03826 /* general case: convert row to RGBA format */ 03827 GLfloat rgba[MAX_WIDTH][4]; 03828 GLint col; 03829 GLbitfield transferOps = 0x0; 03830 03831 if (type == GL_FLOAT && 03832 ((ctx->Color.ClampReadColor == GL_TRUE) || 03833 (ctx->Color.ClampReadColor == GL_FIXED_ONLY_ARB && 03834 texImage->TexFormat->DataType != GL_FLOAT))) 03835 transferOps |= IMAGE_CLAMP_BIT; 03836 03837 for (col = 0; col < width; col++) { 03838 (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]); 03839 if (texImage->TexFormat->BaseFormat == GL_ALPHA) { 03840 rgba[col][RCOMP] = 0.0; 03841 rgba[col][GCOMP] = 0.0; 03842 rgba[col][BCOMP] = 0.0; 03843 } 03844 else if (texImage->TexFormat->BaseFormat == GL_LUMINANCE) { 03845 rgba[col][GCOMP] = 0.0; 03846 rgba[col][BCOMP] = 0.0; 03847 rgba[col][ACOMP] = 1.0; 03848 } 03849 else if (texImage->TexFormat->BaseFormat == GL_LUMINANCE_ALPHA) { 03850 rgba[col][GCOMP] = 0.0; 03851 rgba[col][BCOMP] = 0.0; 03852 } 03853 else if (texImage->TexFormat->BaseFormat == GL_INTENSITY) { 03854 rgba[col][GCOMP] = 0.0; 03855 rgba[col][BCOMP] = 0.0; 03856 rgba[col][ACOMP] = 1.0; 03857 } 03858 } 03859 _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, 03860 format, type, dest, 03861 &ctx->Pack, transferOps /*image xfer ops*/); 03862 } /* format */ 03863 } /* row */ 03864 } /* img */ 03865 } 03866 03867 if (ctx->Pack.BufferObj->Name) { 03868 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 03869 ctx->Pack.BufferObj); 03870 } 03871 } 03872 03873 03874 03879 void 03880 _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level, 03881 GLvoid *img, 03882 struct gl_texture_object *texObj, 03883 struct gl_texture_image *texImage) 03884 { 03885 GLuint size; 03886 03887 if (ctx->Pack.BufferObj->Name) { 03888 /* pack texture image into a PBO */ 03889 GLubyte *buf; 03890 if ((const GLubyte *) img + texImage->CompressedSize > 03891 (const GLubyte *) ctx->Pack.BufferObj->Size) { 03892 _mesa_error(ctx, GL_INVALID_OPERATION, 03893 "glGetCompressedTexImage(invalid PBO access)"); 03894 return; 03895 } 03896 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 03897 GL_WRITE_ONLY_ARB, 03898 ctx->Pack.BufferObj); 03899 if (!buf) { 03900 /* buffer is already mapped - that's an error */ 03901 _mesa_error(ctx, GL_INVALID_OPERATION, 03902 "glGetCompressedTexImage(PBO is mapped)"); 03903 return; 03904 } 03905 img = ADD_POINTERS(buf, img); 03906 } 03907 else if (!img) { 03908 /* not an error */ 03909 return; 03910 } 03911 03912 /* don't use texImage->CompressedSize since that may be padded out */ 03913 size = _mesa_compressed_texture_size(ctx, texImage->Width, texImage->Height, 03914 texImage->Depth, 03915 texImage->TexFormat->MesaFormat); 03916 03917 /* just memcpy, no pixelstore or pixel transfer */ 03918 _mesa_memcpy(img, texImage->Data, size); 03919 03920 if (ctx->Pack.BufferObj->Name) { 03921 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, 03922 ctx->Pack.BufferObj); 03923 } 03924 } Generated on Sun May 27 2012 04:19:22 for ReactOS by
1.7.6.1
|