2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (c) 2008-2009 VMware, Inc.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 * The GL texture image functions in teximage.c basically just do
33 * error checking and data structure allocation. They in turn call
34 * device driver functions which actually copy/convert/store the user's
37 * However, most device drivers will be able to use the fallback functions
38 * in this file. That is, most drivers will have the following bit of
40 * ctx->Driver.TexImage1D = _mesa_store_teximage1d;
41 * ctx->Driver.TexImage2D = _mesa_store_teximage2d;
42 * ctx->Driver.TexImage3D = _mesa_store_teximage3d;
45 * Texture image processing is actually kind of complicated. We have to do:
46 * Format/type conversions
48 * pixel transfer (scale, bais, lookup, convolution!, etc)
50 * These functions can handle most everything, including processing full
51 * images and sub-images.
56 #include "bufferobj.h"
66 #include "texcompress.h"
67 #include "texformat.h"
80 * Return GL_TRUE if the given image format is one that be converted
81 * to another format by swizzling.
84 can_swizzle(GLenum logicalBaseFormat)
86 switch (logicalBaseFormat) {
89 case GL_LUMINANCE_ALPHA:
123 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO)
124 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO)
125 #define MAP3(x,y,z) MAP4(x, y, z, ZERO)
126 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
129 static const struct {
132 GLubyte from_rgba[6];
133 } mappings[MAX_IDX] =
143 MAP4(ZERO, ZERO, ZERO, 0),
174 MAP4(0, ZERO, ZERO, ONE),
180 MAP4(ZERO, 0, ZERO, ONE),
186 MAP4(ZERO, ZERO, 0, ONE),
212 * Convert a GL image format enum to an IDX_* value (see above).
215 get_map_idx(GLenum value)
218 case GL_LUMINANCE: return IDX_LUMINANCE;
219 case GL_ALPHA: return IDX_ALPHA;
220 case GL_INTENSITY: return IDX_INTENSITY;
221 case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
222 case GL_RGB: return IDX_RGB;
223 case GL_RGBA: return IDX_RGBA;
224 case GL_RED: return IDX_RED;
225 case GL_GREEN: return IDX_GREEN;
226 case GL_BLUE: return IDX_BLUE;
227 case GL_BGR: return IDX_BGR;
228 case GL_BGRA: return IDX_BGRA;
229 case GL_ABGR_EXT: return IDX_ABGR;
231 _mesa_problem(NULL, "Unexpected inFormat");
238 * When promoting texture formats (see below) we need to compute the
239 * mapping of dest components back to source components.
240 * This function does that.
241 * \param inFormat the incoming format of the texture
242 * \param outFormat the final texture format
243 * \return map[6] a full 6-component map
246 compute_component_mapping(GLenum inFormat, GLenum outFormat,
249 const int inFmt = get_map_idx(inFormat);
250 const int outFmt = get_map_idx(outFormat);
251 const GLubyte *in2rgba = mappings[inFmt].to_rgba;
252 const GLubyte *rgba2out = mappings[outFmt].from_rgba;
255 for (i = 0; i < 4; i++)
256 map[i] = in2rgba[rgba2out[i]];
262 _mesa_printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
263 inFormat, _mesa_lookup_enum_by_nr(inFormat),
264 outFormat, _mesa_lookup_enum_by_nr(outFormat),
275 #if !FEATURE_convolve
277 _mesa_adjust_image_for_convolution(GLcontext *ctx, GLuint dims,
278 GLsizei *srcWidth, GLsizei *srcHeight)
286 * Make a temporary (color) texture image with GLfloat components.
287 * Apply all needed pixel unpacking and pixel transfer operations.
288 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
289 * Suppose the user specifies GL_LUMINANCE as the internal texture format
290 * but the graphics hardware doesn't support luminance textures. So, might
291 * use an RGB hardware format instead.
292 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
294 * \param ctx the rendering context
295 * \param dims image dimensions: 1, 2 or 3
296 * \param logicalBaseFormat basic texture derived from the user's
297 * internal texture format value
298 * \param textureBaseFormat the actual basic format of the texture
299 * \param srcWidth source image width
300 * \param srcHeight source image height
301 * \param srcDepth source image depth
302 * \param srcFormat source image format
303 * \param srcType source image type
304 * \param srcAddr source image address
305 * \param srcPacking source image pixel packing
306 * \return resulting image with format = textureBaseFormat and type = GLfloat.
309 make_temp_float_image(GLcontext *ctx, GLuint dims,
310 GLenum logicalBaseFormat,
311 GLenum textureBaseFormat,
312 GLint srcWidth, GLint srcHeight, GLint srcDepth,
313 GLenum srcFormat, GLenum srcType,
314 const GLvoid *srcAddr,
315 const struct gl_pixelstore_attrib *srcPacking)
317 GLuint transferOps = ctx->_ImageTransferState;
320 ASSERT(dims >= 1 && dims <= 3);
322 ASSERT(logicalBaseFormat == GL_RGBA ||
323 logicalBaseFormat == GL_RGB ||
324 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
325 logicalBaseFormat == GL_LUMINANCE ||
326 logicalBaseFormat == GL_ALPHA ||
327 logicalBaseFormat == GL_INTENSITY ||
328 logicalBaseFormat == GL_COLOR_INDEX ||
329 logicalBaseFormat == GL_DEPTH_COMPONENT);
331 ASSERT(textureBaseFormat == GL_RGBA ||
332 textureBaseFormat == GL_RGB ||
333 textureBaseFormat == GL_LUMINANCE_ALPHA ||
334 textureBaseFormat == GL_LUMINANCE ||
335 textureBaseFormat == GL_ALPHA ||
336 textureBaseFormat == GL_INTENSITY ||
337 textureBaseFormat == GL_COLOR_INDEX ||
338 textureBaseFormat == GL_DEPTH_COMPONENT);
340 /* conventional color image */
342 if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
343 (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
344 (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
345 /* need image convolution */
346 const GLuint preConvTransferOps
347 = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
348 const GLuint postConvTransferOps
349 = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
351 GLint convWidth, convHeight;
354 /* pre-convolution image buffer (3D) */
355 tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
356 * 4 * sizeof(GLfloat));
360 /* post-convolution image buffer (2D) */
361 convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight
362 * 4 * sizeof(GLfloat));
364 _mesa_free(tempImage);
368 /* loop over 3D image slices */
369 for (img = 0; img < srcDepth; img++) {
370 GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4);
372 /* unpack and do transfer ops up to convolution */
373 for (row = 0; row < srcHeight; row++) {
374 const GLvoid *src = _mesa_image_address(dims, srcPacking,
375 srcAddr, srcWidth, srcHeight,
376 srcFormat, srcType, img, row, 0);
377 _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst,
378 srcFormat, srcType, src,
384 /* size after optional convolution */
385 convWidth = srcWidth;
386 convHeight = srcHeight;
391 GLfloat *src = tempImage + img * (srcWidth * srcHeight * 4);
393 ASSERT(ctx->Pixel.Convolution1DEnabled);
394 _mesa_convolve_1d_image(ctx, &convWidth, src, convImage);
397 if (ctx->Pixel.Convolution2DEnabled) {
398 _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
402 ASSERT(ctx->Pixel.Separable2DEnabled);
403 _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
409 /* do post-convolution transfer and pack into tempImage */
411 const GLint logComponents
412 = _mesa_components_in_format(logicalBaseFormat);
413 const GLfloat *src = convImage;
414 GLfloat *dst = tempImage + img * (convWidth * convHeight * 4);
415 for (row = 0; row < convHeight; row++) {
416 _mesa_pack_rgba_span_float(ctx, convWidth,
417 (GLfloat (*)[4]) src,
418 logicalBaseFormat, GL_FLOAT,
419 dst, &ctx->DefaultPacking,
420 postConvTransferOps);
421 src += convWidth * 4;
422 dst += convWidth * logComponents;
425 } /* loop over 3D image slices */
427 _mesa_free(convImage);
429 /* might need these below */
430 srcWidth = convWidth;
431 srcHeight = convHeight;
435 const GLint components = _mesa_components_in_format(logicalBaseFormat);
436 const GLint srcStride = _mesa_image_row_stride(srcPacking,
437 srcWidth, srcFormat, srcType);
441 tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
442 * components * sizeof(GLfloat));
447 for (img = 0; img < srcDepth; img++) {
449 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
453 for (row = 0; row < srcHeight; row++) {
454 _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
455 dst, srcFormat, srcType, src,
456 srcPacking, transferOps);
457 dst += srcWidth * components;
463 if (logicalBaseFormat != textureBaseFormat) {
465 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
466 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
471 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
472 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
473 textureBaseFormat == GL_LUMINANCE_ALPHA);
475 /* The actual texture format should have at least as many components
476 * as the logical texture format.
478 ASSERT(texComponents >= logComponents);
480 newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
481 * texComponents * sizeof(GLfloat));
483 _mesa_free(tempImage);
487 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
489 n = srcWidth * srcHeight * srcDepth;
490 for (i = 0; i < n; i++) {
492 for (k = 0; k < texComponents; k++) {
495 newImage[i * texComponents + k] = 0.0F;
497 newImage[i * texComponents + k] = 1.0F;
499 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
503 _mesa_free(tempImage);
504 tempImage = newImage;
512 * Make a temporary (color) texture image with GLchan components.
513 * Apply all needed pixel unpacking and pixel transfer operations.
514 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
515 * Suppose the user specifies GL_LUMINANCE as the internal texture format
516 * but the graphics hardware doesn't support luminance textures. So, might
517 * use an RGB hardware format instead.
518 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
520 * \param ctx the rendering context
521 * \param dims image dimensions: 1, 2 or 3
522 * \param logicalBaseFormat basic texture derived from the user's
523 * internal texture format value
524 * \param textureBaseFormat the actual basic format of the texture
525 * \param srcWidth source image width
526 * \param srcHeight source image height
527 * \param srcDepth source image depth
528 * \param srcFormat source image format
529 * \param srcType source image type
530 * \param srcAddr source image address
531 * \param srcPacking source image pixel packing
532 * \return resulting image with format = textureBaseFormat and type = GLchan.
535 _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
536 GLenum logicalBaseFormat,
537 GLenum textureBaseFormat,
538 GLint srcWidth, GLint srcHeight, GLint srcDepth,
539 GLenum srcFormat, GLenum srcType,
540 const GLvoid *srcAddr,
541 const struct gl_pixelstore_attrib *srcPacking)
543 GLuint transferOps = ctx->_ImageTransferState;
544 const GLint components = _mesa_components_in_format(logicalBaseFormat);
545 GLboolean freeSrcImage = GL_FALSE;
547 GLchan *tempImage, *dst;
549 ASSERT(dims >= 1 && dims <= 3);
551 ASSERT(logicalBaseFormat == GL_RGBA ||
552 logicalBaseFormat == GL_RGB ||
553 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
554 logicalBaseFormat == GL_LUMINANCE ||
555 logicalBaseFormat == GL_ALPHA ||
556 logicalBaseFormat == GL_INTENSITY);
558 ASSERT(textureBaseFormat == GL_RGBA ||
559 textureBaseFormat == GL_RGB ||
560 textureBaseFormat == GL_LUMINANCE_ALPHA ||
561 textureBaseFormat == GL_LUMINANCE ||
562 textureBaseFormat == GL_ALPHA ||
563 textureBaseFormat == GL_INTENSITY);
566 if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
567 (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
568 (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
569 /* get convolved image */
570 GLfloat *convImage = make_temp_float_image(ctx, dims,
573 srcWidth, srcHeight, srcDepth,
575 srcAddr, srcPacking);
578 /* the convolved image is our new source image */
580 srcFormat = logicalBaseFormat;
582 srcPacking = &ctx->DefaultPacking;
583 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
585 freeSrcImage = GL_TRUE;
589 /* unpack and transfer the source image */
590 tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
591 * components * sizeof(GLchan));
596 for (img = 0; img < srcDepth; img++) {
597 const GLint srcStride = _mesa_image_row_stride(srcPacking,
601 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
605 for (row = 0; row < srcHeight; row++) {
606 _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst,
607 srcFormat, srcType, src, srcPacking,
609 dst += srcWidth * components;
614 /* If we made a temporary image for convolution, free it here */
616 _mesa_free((void *) srcAddr);
619 if (logicalBaseFormat != textureBaseFormat) {
620 /* one more conversion step */
621 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
622 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
627 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
628 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
629 textureBaseFormat == GL_LUMINANCE_ALPHA);
631 /* The actual texture format should have at least as many components
632 * as the logical texture format.
634 ASSERT(texComponents >= logComponents);
636 newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
637 * texComponents * sizeof(GLchan));
639 _mesa_free(tempImage);
643 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
645 n = srcWidth * srcHeight * srcDepth;
646 for (i = 0; i < n; i++) {
648 for (k = 0; k < texComponents; k++) {
651 newImage[i * texComponents + k] = 0;
653 newImage[i * texComponents + k] = CHAN_MAX;
655 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
659 _mesa_free(tempImage);
660 tempImage = newImage;
668 * Copy GLubyte pixels from <src> to <dst> with swizzling.
669 * \param dst destination pixels
670 * \param dstComponents number of color components in destination pixels
671 * \param src source pixels
672 * \param srcComponents number of color components in source pixels
673 * \param map the swizzle mapping. map[X] says where to find the X component
674 * in the source image's pixels. For example, if the source image
675 * is GL_BGRA and X = red, map[0] yields 2.
676 * \param count number of pixels to copy/swizzle.
679 swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
680 GLuint srcComponents, const GLubyte *map, GLuint count)
682 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
685 for (i = 0; i < count; i++) { \
687 if (srcComps == 4) { \
688 COPY_4UBV(tmp, src); \
691 for (j = 0; j < srcComps; j++) { \
696 for (j = 0; j < dstComps; j++) { \
697 dst[j] = tmp[map[j]]; \
708 ASSERT(srcComponents <= 4);
709 ASSERT(dstComponents <= 4);
711 switch (dstComponents) {
713 switch (srcComponents) {
715 SWZ_CPY(dst, src, count, 4, 4);
718 SWZ_CPY(dst, src, count, 4, 3);
721 SWZ_CPY(dst, src, count, 4, 2);
724 SWZ_CPY(dst, src, count, 4, 1);
731 switch (srcComponents) {
733 SWZ_CPY(dst, src, count, 3, 4);
736 SWZ_CPY(dst, src, count, 3, 3);
739 SWZ_CPY(dst, src, count, 3, 2);
742 SWZ_CPY(dst, src, count, 3, 1);
749 switch (srcComponents) {
751 SWZ_CPY(dst, src, count, 2, 4);
754 SWZ_CPY(dst, src, count, 2, 3);
757 SWZ_CPY(dst, src, count, 2, 2);
760 SWZ_CPY(dst, src, count, 2, 1);
767 switch (srcComponents) {
769 SWZ_CPY(dst, src, count, 1, 4);
772 SWZ_CPY(dst, src, count, 1, 3);
775 SWZ_CPY(dst, src, count, 1, 2);
778 SWZ_CPY(dst, src, count, 1, 1);
792 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
793 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
795 /* Deal with the _REV input types:
797 static const GLubyte *
798 type_mapping( GLenum srcType )
802 case GL_UNSIGNED_BYTE:
804 case GL_UNSIGNED_INT_8_8_8_8:
805 return _mesa_little_endian() ? map_3210 : map_identity;
806 case GL_UNSIGNED_INT_8_8_8_8_REV:
807 return _mesa_little_endian() ? map_identity : map_3210;
813 /* Mapping required if input type is
815 static const GLubyte *
816 byteswap_mapping( GLboolean swapBytes,
824 case GL_UNSIGNED_BYTE:
826 case GL_UNSIGNED_INT_8_8_8_8:
827 case GL_UNSIGNED_INT_8_8_8_8_REV:
837 * Transfer a GLubyte texture image with component swizzling.
840 _mesa_swizzle_ubyte_image(GLcontext *ctx,
845 GLenum baseInternalFormat,
847 const GLubyte *rgba2dst,
848 GLuint dstComponents,
851 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
853 const GLuint *dstImageOffsets,
855 GLint srcWidth, GLint srcHeight, GLint srcDepth,
856 const GLvoid *srcAddr,
857 const struct gl_pixelstore_attrib *srcPacking )
859 GLint srcComponents = _mesa_components_in_format(srcFormat);
860 const GLubyte *srctype2ubyte, *swap;
861 GLubyte map[4], src2base[6], base2rgba[6];
863 const GLint srcRowStride =
864 _mesa_image_row_stride(srcPacking, srcWidth,
865 srcFormat, GL_UNSIGNED_BYTE);
866 const GLint srcImageStride
867 = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
869 const GLubyte *srcImage
870 = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
871 srcWidth, srcHeight, srcFormat,
872 GL_UNSIGNED_BYTE, 0, 0, 0);
876 /* Translate from src->baseInternal->GL_RGBA->dst. This will
877 * correctly deal with RGBA->RGB->RGBA conversions where the final
878 * A value must be 0xff regardless of the incoming alpha values.
880 compute_component_mapping(srcFormat, baseInternalFormat, src2base);
881 compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba);
882 swap = byteswap_mapping(srcPacking->SwapBytes, srcType);
883 srctype2ubyte = type_mapping(srcType);
886 for (i = 0; i < 4; i++)
887 map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]];
889 /* _mesa_printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */
891 if (srcComponents == dstComponents &&
892 srcRowStride == dstRowStride &&
893 srcRowStride == srcWidth * srcComponents &&
895 /* 1 and 2D images only */
896 GLubyte *dstImage = (GLubyte *) dstAddr
897 + dstYoffset * dstRowStride
898 + dstXoffset * dstComponents;
899 swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
900 srcWidth * srcHeight);
904 for (img = 0; img < srcDepth; img++) {
905 const GLubyte *srcRow = srcImage;
906 GLubyte *dstRow = (GLubyte *) dstAddr
907 + dstImageOffsets[dstZoffset + img] * dstComponents
908 + dstYoffset * dstRowStride
909 + dstXoffset * dstComponents;
910 for (row = 0; row < srcHeight; row++) {
911 swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
912 dstRow += dstRowStride;
913 srcRow += srcRowStride;
915 srcImage += srcImageStride;
922 * Teximage storage routine for when a simple memcpy will do.
923 * No pixel transfer operations or special texel encodings allowed.
924 * 1D, 2D and 3D images supported.
927 memcpy_texture(GLcontext *ctx,
929 const struct gl_texture_format *dstFormat,
931 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
933 const GLuint *dstImageOffsets,
934 GLint srcWidth, GLint srcHeight, GLint srcDepth,
935 GLenum srcFormat, GLenum srcType,
936 const GLvoid *srcAddr,
937 const struct gl_pixelstore_attrib *srcPacking)
939 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
941 const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
942 srcWidth, srcHeight, srcFormat, srcType);
943 const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
944 srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
945 const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
948 /* XXX update/re-enable for dstImageOffsets array */
949 const GLint bytesPerImage = srcHeight * bytesPerRow;
950 const GLint bytesPerTexture = srcDepth * bytesPerImage;
951 GLubyte *dstImage = (GLubyte *) dstAddr
952 + dstZoffset * dstImageStride
953 + dstYoffset * dstRowStride
954 + dstXoffset * dstFormat->TexelBytes;
956 if (dstRowStride == srcRowStride &&
957 dstRowStride == bytesPerRow &&
958 ((dstImageStride == srcImageStride &&
959 dstImageStride == bytesPerImage) ||
962 ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture);
967 for (img = 0; img < srcDepth; img++) {
968 const GLubyte *srcRow = srcImage;
969 GLubyte *dstRow = dstImage;
970 for (row = 0; row < srcHeight; row++) {
971 ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
972 dstRow += dstRowStride;
973 srcRow += srcRowStride;
975 srcImage += srcImageStride;
976 dstImage += dstImageStride;
982 for (img = 0; img < srcDepth; img++) {
983 const GLubyte *srcRow = srcImage;
984 GLubyte *dstRow = (GLubyte *) dstAddr
985 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
986 + dstYoffset * dstRowStride
987 + dstXoffset * dstFormat->TexelBytes;
988 for (row = 0; row < srcHeight; row++) {
989 ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
990 dstRow += dstRowStride;
991 srcRow += srcRowStride;
993 srcImage += srcImageStride;
1000 * Store an image in any of the formats:
1001 * _mesa_texformat_rgba
1002 * _mesa_texformat_rgb
1003 * _mesa_texformat_alpha
1004 * _mesa_texformat_luminance
1005 * _mesa_texformat_luminance_alpha
1006 * _mesa_texformat_intensity
1010 _mesa_texstore_rgba(TEXSTORE_PARAMS)
1012 const GLint components = _mesa_components_in_format(baseInternalFormat);
1014 ASSERT(dstFormat == &_mesa_texformat_rgba ||
1015 dstFormat == &_mesa_texformat_rgb ||
1016 dstFormat == &_mesa_texformat_alpha ||
1017 dstFormat == &_mesa_texformat_luminance ||
1018 dstFormat == &_mesa_texformat_luminance_alpha ||
1019 dstFormat == &_mesa_texformat_intensity);
1020 ASSERT(baseInternalFormat == GL_RGBA ||
1021 baseInternalFormat == GL_RGB ||
1022 baseInternalFormat == GL_ALPHA ||
1023 baseInternalFormat == GL_LUMINANCE ||
1024 baseInternalFormat == GL_LUMINANCE_ALPHA ||
1025 baseInternalFormat == GL_INTENSITY);
1026 ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan));
1028 if (!ctx->_ImageTransferState &&
1029 !srcPacking->SwapBytes &&
1030 baseInternalFormat == srcFormat &&
1031 srcType == CHAN_TYPE) {
1032 /* simple memcpy path */
1033 memcpy_texture(ctx, dims,
1034 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1037 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1038 srcAddr, srcPacking);
1040 else if (!ctx->_ImageTransferState &&
1041 !srcPacking->SwapBytes &&
1042 dstFormat == &_mesa_texformat_rgb &&
1043 srcFormat == GL_RGBA &&
1044 srcType == CHAN_TYPE) {
1045 /* extract RGB from RGBA */
1046 GLint img, row, col;
1047 for (img = 0; img < srcDepth; img++) {
1048 GLchan *dstImage = (GLchan *)
1049 ((GLubyte *) dstAddr
1050 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1051 + dstYoffset * dstRowStride
1052 + dstXoffset * dstFormat->TexelBytes);
1054 const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1055 srcWidth, srcFormat, srcType);
1056 GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking,
1057 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1058 GLchan *dstRow = dstImage;
1059 for (row = 0; row < srcHeight; row++) {
1060 for (col = 0; col < srcWidth; col++) {
1061 dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP];
1062 dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP];
1063 dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP];
1065 dstRow += dstRowStride / sizeof(GLchan);
1066 srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
1070 else if (!ctx->_ImageTransferState &&
1071 CHAN_TYPE == GL_UNSIGNED_BYTE &&
1072 (srcType == GL_UNSIGNED_BYTE ||
1073 srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1074 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1075 can_swizzle(baseInternalFormat) &&
1076 can_swizzle(srcFormat)) {
1078 const GLubyte *dstmap;
1081 /* dstmap - how to swizzle from RGBA to dst format:
1083 if (dstFormat == &_mesa_texformat_rgba) {
1084 dstmap = mappings[IDX_RGBA].from_rgba;
1087 else if (dstFormat == &_mesa_texformat_rgb) {
1088 dstmap = mappings[IDX_RGB].from_rgba;
1091 else if (dstFormat == &_mesa_texformat_alpha) {
1092 dstmap = mappings[IDX_ALPHA].from_rgba;
1095 else if (dstFormat == &_mesa_texformat_luminance) {
1096 dstmap = mappings[IDX_LUMINANCE].from_rgba;
1099 else if (dstFormat == &_mesa_texformat_luminance_alpha) {
1100 dstmap = mappings[IDX_LUMINANCE_ALPHA].from_rgba;
1103 else if (dstFormat == &_mesa_texformat_intensity) {
1104 dstmap = mappings[IDX_INTENSITY].from_rgba;
1108 _mesa_problem(ctx, "Unexpected dstFormat in _mesa_texstore_rgba");
1112 _mesa_swizzle_ubyte_image(ctx, dims,
1117 dstAddr, dstXoffset, dstYoffset, dstZoffset,
1118 dstRowStride, dstImageOffsets,
1119 srcWidth, srcHeight, srcDepth, srcAddr,
1124 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1126 dstFormat->BaseFormat,
1127 srcWidth, srcHeight, srcDepth,
1128 srcFormat, srcType, srcAddr,
1130 const GLchan *src = tempImage;
1135 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1136 bytesPerRow = srcWidth * components * sizeof(GLchan);
1137 for (img = 0; img < srcDepth; img++) {
1138 GLubyte *dstRow = (GLubyte *) dstAddr
1139 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1140 + dstYoffset * dstRowStride
1141 + dstXoffset * dstFormat->TexelBytes;
1142 for (row = 0; row < srcHeight; row++) {
1143 _mesa_memcpy(dstRow, src, bytesPerRow);
1144 dstRow += dstRowStride;
1145 src += srcWidth * components;
1149 _mesa_free((void *) tempImage);
1156 * Store a 32-bit integer depth component texture image.
1159 _mesa_texstore_z32(TEXSTORE_PARAMS)
1161 const GLuint depthScale = 0xffffffff;
1163 ASSERT(dstFormat == &_mesa_texformat_z32);
1164 ASSERT(dstFormat->TexelBytes == sizeof(GLuint));
1166 if (ctx->Pixel.DepthScale == 1.0f &&
1167 ctx->Pixel.DepthBias == 0.0f &&
1168 !srcPacking->SwapBytes &&
1169 baseInternalFormat == GL_DEPTH_COMPONENT &&
1170 srcFormat == GL_DEPTH_COMPONENT &&
1171 srcType == GL_UNSIGNED_INT) {
1172 /* simple memcpy path */
1173 memcpy_texture(ctx, dims,
1174 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1177 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1178 srcAddr, srcPacking);
1183 for (img = 0; img < srcDepth; img++) {
1184 GLubyte *dstRow = (GLubyte *) dstAddr
1185 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1186 + dstYoffset * dstRowStride
1187 + dstXoffset * dstFormat->TexelBytes;
1188 for (row = 0; row < srcHeight; row++) {
1189 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1190 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1191 _mesa_unpack_depth_span(ctx, srcWidth,
1192 GL_UNSIGNED_INT, (GLuint *) dstRow,
1193 depthScale, srcType, src, srcPacking);
1194 dstRow += dstRowStride;
1204 * Store a 16-bit integer depth component texture image.
1207 _mesa_texstore_z16(TEXSTORE_PARAMS)
1209 const GLuint depthScale = 0xffff;
1211 ASSERT(dstFormat == &_mesa_texformat_z16);
1212 ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
1214 if (ctx->Pixel.DepthScale == 1.0f &&
1215 ctx->Pixel.DepthBias == 0.0f &&
1216 !srcPacking->SwapBytes &&
1217 baseInternalFormat == GL_DEPTH_COMPONENT &&
1218 srcFormat == GL_DEPTH_COMPONENT &&
1219 srcType == GL_UNSIGNED_SHORT) {
1220 /* simple memcpy path */
1221 memcpy_texture(ctx, dims,
1222 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1225 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1226 srcAddr, srcPacking);
1231 for (img = 0; img < srcDepth; img++) {
1232 GLubyte *dstRow = (GLubyte *) dstAddr
1233 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1234 + dstYoffset * dstRowStride
1235 + dstXoffset * dstFormat->TexelBytes;
1236 for (row = 0; row < srcHeight; row++) {
1237 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1238 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1239 GLushort *dst16 = (GLushort *) dstRow;
1240 _mesa_unpack_depth_span(ctx, srcWidth,
1241 GL_UNSIGNED_SHORT, dst16, depthScale,
1242 srcType, src, srcPacking);
1243 dstRow += dstRowStride;
1252 * Store an rgb565 or rgb565_rev texture image.
1255 _mesa_texstore_rgb565(TEXSTORE_PARAMS)
1257 ASSERT(dstFormat == &_mesa_texformat_rgb565 ||
1258 dstFormat == &_mesa_texformat_rgb565_rev);
1259 ASSERT(dstFormat->TexelBytes == 2);
1261 if (!ctx->_ImageTransferState &&
1262 !srcPacking->SwapBytes &&
1263 dstFormat == &_mesa_texformat_rgb565 &&
1264 baseInternalFormat == GL_RGB &&
1265 srcFormat == GL_RGB &&
1266 srcType == GL_UNSIGNED_SHORT_5_6_5) {
1267 /* simple memcpy path */
1268 memcpy_texture(ctx, dims,
1269 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1272 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1273 srcAddr, srcPacking);
1275 else if (!ctx->_ImageTransferState &&
1276 !srcPacking->SwapBytes &&
1277 baseInternalFormat == GL_RGB &&
1278 srcFormat == GL_RGB &&
1279 srcType == GL_UNSIGNED_BYTE &&
1281 /* do optimized tex store */
1282 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
1283 srcFormat, srcType);
1284 const GLubyte *src = (const GLubyte *)
1285 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
1286 srcFormat, srcType, 0, 0, 0);
1287 GLubyte *dst = (GLubyte *) dstAddr
1288 + dstYoffset * dstRowStride
1289 + dstXoffset * dstFormat->TexelBytes;
1291 for (row = 0; row < srcHeight; row++) {
1292 const GLubyte *srcUB = (const GLubyte *) src;
1293 GLushort *dstUS = (GLushort *) dst;
1294 /* check for byteswapped format */
1295 if (dstFormat == &_mesa_texformat_rgb565) {
1296 for (col = 0; col < srcWidth; col++) {
1297 dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
1302 for (col = 0; col < srcWidth; col++) {
1303 dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
1307 dst += dstRowStride;
1308 src += srcRowStride;
1313 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1315 dstFormat->BaseFormat,
1316 srcWidth, srcHeight, srcDepth,
1317 srcFormat, srcType, srcAddr,
1319 const GLchan *src = tempImage;
1320 GLint img, row, col;
1323 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1324 for (img = 0; img < srcDepth; img++) {
1325 GLubyte *dstRow = (GLubyte *) dstAddr
1326 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1327 + dstYoffset * dstRowStride
1328 + dstXoffset * dstFormat->TexelBytes;
1329 for (row = 0; row < srcHeight; row++) {
1330 GLushort *dstUS = (GLushort *) dstRow;
1331 /* check for byteswapped format */
1332 if (dstFormat == &_mesa_texformat_rgb565) {
1333 for (col = 0; col < srcWidth; col++) {
1334 dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
1335 CHAN_TO_UBYTE(src[GCOMP]),
1336 CHAN_TO_UBYTE(src[BCOMP]) );
1341 for (col = 0; col < srcWidth; col++) {
1342 dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
1343 CHAN_TO_UBYTE(src[GCOMP]),
1344 CHAN_TO_UBYTE(src[BCOMP]) );
1348 dstRow += dstRowStride;
1351 _mesa_free((void *) tempImage);
1358 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1361 _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
1363 const GLboolean littleEndian = _mesa_little_endian();
1365 ASSERT(dstFormat == &_mesa_texformat_rgba8888 ||
1366 dstFormat == &_mesa_texformat_rgba8888_rev);
1367 ASSERT(dstFormat->TexelBytes == 4);
1369 if (!ctx->_ImageTransferState &&
1370 !srcPacking->SwapBytes &&
1371 dstFormat == &_mesa_texformat_rgba8888 &&
1372 baseInternalFormat == GL_RGBA &&
1373 ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1374 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1375 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
1376 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian))) {
1377 /* simple memcpy path */
1378 memcpy_texture(ctx, dims,
1379 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1382 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1383 srcAddr, srcPacking);
1385 else if (!ctx->_ImageTransferState &&
1386 !srcPacking->SwapBytes &&
1387 dstFormat == &_mesa_texformat_rgba8888_rev &&
1388 baseInternalFormat == GL_RGBA &&
1389 ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
1390 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1391 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1392 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian))) {
1393 /* simple memcpy path */
1394 memcpy_texture(ctx, dims,
1395 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1398 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1399 srcAddr, srcPacking);
1401 else if (!ctx->_ImageTransferState &&
1402 (srcType == GL_UNSIGNED_BYTE ||
1403 srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1404 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1405 can_swizzle(baseInternalFormat) &&
1406 can_swizzle(srcFormat)) {
1410 /* dstmap - how to swizzle from RGBA to dst format:
1412 if ((littleEndian && dstFormat == &_mesa_texformat_rgba8888) ||
1413 (!littleEndian && dstFormat == &_mesa_texformat_rgba8888_rev)) {
1426 _mesa_swizzle_ubyte_image(ctx, dims,
1431 dstAddr, dstXoffset, dstYoffset, dstZoffset,
1432 dstRowStride, dstImageOffsets,
1433 srcWidth, srcHeight, srcDepth, srcAddr,
1438 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1440 dstFormat->BaseFormat,
1441 srcWidth, srcHeight, srcDepth,
1442 srcFormat, srcType, srcAddr,
1444 const GLchan *src = tempImage;
1445 GLint img, row, col;
1448 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1449 for (img = 0; img < srcDepth; img++) {
1450 GLubyte *dstRow = (GLubyte *) dstAddr
1451 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1452 + dstYoffset * dstRowStride
1453 + dstXoffset * dstFormat->TexelBytes;
1454 for (row = 0; row < srcHeight; row++) {
1455 GLuint *dstUI = (GLuint *) dstRow;
1456 if (dstFormat == &_mesa_texformat_rgba8888) {
1457 for (col = 0; col < srcWidth; col++) {
1458 dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
1459 CHAN_TO_UBYTE(src[GCOMP]),
1460 CHAN_TO_UBYTE(src[BCOMP]),
1461 CHAN_TO_UBYTE(src[ACOMP]) );
1466 for (col = 0; col < srcWidth; col++) {
1467 dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
1468 CHAN_TO_UBYTE(src[GCOMP]),
1469 CHAN_TO_UBYTE(src[BCOMP]),
1470 CHAN_TO_UBYTE(src[ACOMP]) );
1474 dstRow += dstRowStride;
1477 _mesa_free((void *) tempImage);
1484 _mesa_texstore_argb8888(TEXSTORE_PARAMS)
1486 const GLboolean littleEndian = _mesa_little_endian();
1488 ASSERT(dstFormat == &_mesa_texformat_argb8888 ||
1489 dstFormat == &_mesa_texformat_argb8888_rev);
1490 ASSERT(dstFormat->TexelBytes == 4);
1492 if (!ctx->_ImageTransferState &&
1493 !srcPacking->SwapBytes &&
1494 dstFormat == &_mesa_texformat_argb8888 &&
1495 baseInternalFormat == GL_RGBA &&
1496 srcFormat == GL_BGRA &&
1497 ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1498 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
1499 /* simple memcpy path (little endian) */
1500 memcpy_texture(ctx, dims,
1501 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1504 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1505 srcAddr, srcPacking);
1507 else if (!ctx->_ImageTransferState &&
1508 !srcPacking->SwapBytes &&
1509 dstFormat == &_mesa_texformat_argb8888_rev &&
1510 baseInternalFormat == GL_RGBA &&
1511 srcFormat == GL_BGRA &&
1512 ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1513 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
1514 /* simple memcpy path (big endian) */
1515 memcpy_texture(ctx, dims,
1516 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1519 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1520 srcAddr, srcPacking);
1522 else if (!ctx->_ImageTransferState &&
1523 !srcPacking->SwapBytes &&
1524 dstFormat == &_mesa_texformat_argb8888 &&
1525 srcFormat == GL_RGB &&
1526 (baseInternalFormat == GL_RGBA ||
1527 baseInternalFormat == GL_RGB) &&
1528 srcType == GL_UNSIGNED_BYTE) {
1530 for (img = 0; img < srcDepth; img++) {
1531 const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1532 srcWidth, srcFormat, srcType);
1533 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1534 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1535 GLubyte *dstRow = (GLubyte *) dstAddr
1536 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1537 + dstYoffset * dstRowStride
1538 + dstXoffset * dstFormat->TexelBytes;
1539 for (row = 0; row < srcHeight; row++) {
1540 GLuint *d4 = (GLuint *) dstRow;
1541 for (col = 0; col < srcWidth; col++) {
1542 d4[col] = PACK_COLOR_8888(0xff,
1543 srcRow[col * 3 + RCOMP],
1544 srcRow[col * 3 + GCOMP],
1545 srcRow[col * 3 + BCOMP]);
1547 dstRow += dstRowStride;
1548 srcRow += srcRowStride;
1552 else if (!ctx->_ImageTransferState &&
1553 !srcPacking->SwapBytes &&
1554 dstFormat == &_mesa_texformat_argb8888 &&
1555 srcFormat == GL_RGBA &&
1556 baseInternalFormat == GL_RGBA &&
1557 srcType == GL_UNSIGNED_BYTE) {
1558 /* same as above case, but src data has alpha too */
1559 GLint img, row, col;
1560 /* For some reason, streaming copies to write-combined regions
1561 * are extremely sensitive to the characteristics of how the
1562 * source data is retrieved. By reordering the source reads to
1563 * be in-order, the speed of this operation increases by half.
1564 * Strangely the same isn't required for the RGB path, above.
1566 for (img = 0; img < srcDepth; img++) {
1567 const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1568 srcWidth, srcFormat, srcType);
1569 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1570 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1571 GLubyte *dstRow = (GLubyte *) dstAddr
1572 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1573 + dstYoffset * dstRowStride
1574 + dstXoffset * dstFormat->TexelBytes;
1575 for (row = 0; row < srcHeight; row++) {
1576 GLuint *d4 = (GLuint *) dstRow;
1577 for (col = 0; col < srcWidth; col++) {
1578 d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
1579 srcRow[col * 4 + RCOMP],
1580 srcRow[col * 4 + GCOMP],
1581 srcRow[col * 4 + BCOMP]);
1583 dstRow += dstRowStride;
1584 srcRow += srcRowStride;
1588 else if (!ctx->_ImageTransferState &&
1589 (srcType == GL_UNSIGNED_BYTE ||
1590 srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1591 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1592 can_swizzle(baseInternalFormat) &&
1593 can_swizzle(srcFormat)) {
1597 /* dstmap - how to swizzle from RGBA to dst format:
1599 if ((littleEndian && dstFormat == &_mesa_texformat_argb8888) ||
1600 (!littleEndian && dstFormat == &_mesa_texformat_argb8888_rev)) {
1601 dstmap[3] = 3; /* alpha */
1602 dstmap[2] = 0; /* red */
1603 dstmap[1] = 1; /* green */
1604 dstmap[0] = 2; /* blue */
1607 assert((littleEndian && dstFormat == &_mesa_texformat_argb8888_rev) ||
1608 (!littleEndian && dstFormat == &_mesa_texformat_argb8888));
1615 _mesa_swizzle_ubyte_image(ctx, dims,
1621 dstAddr, dstXoffset, dstYoffset, dstZoffset,
1624 srcWidth, srcHeight, srcDepth, srcAddr,
1629 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1631 dstFormat->BaseFormat,
1632 srcWidth, srcHeight, srcDepth,
1633 srcFormat, srcType, srcAddr,
1635 const GLchan *src = tempImage;
1636 GLint img, row, col;
1639 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1640 for (img = 0; img < srcDepth; img++) {
1641 GLubyte *dstRow = (GLubyte *) dstAddr
1642 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1643 + dstYoffset * dstRowStride
1644 + dstXoffset * dstFormat->TexelBytes;
1645 for (row = 0; row < srcHeight; row++) {
1646 GLuint *dstUI = (GLuint *) dstRow;
1647 if (dstFormat == &_mesa_texformat_argb8888) {
1648 for (col = 0; col < srcWidth; col++) {
1649 dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
1650 CHAN_TO_UBYTE(src[RCOMP]),
1651 CHAN_TO_UBYTE(src[GCOMP]),
1652 CHAN_TO_UBYTE(src[BCOMP]) );
1657 for (col = 0; col < srcWidth; col++) {
1658 dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
1659 CHAN_TO_UBYTE(src[RCOMP]),
1660 CHAN_TO_UBYTE(src[GCOMP]),
1661 CHAN_TO_UBYTE(src[BCOMP]) );
1665 dstRow += dstRowStride;
1668 _mesa_free((void *) tempImage);
1675 _mesa_texstore_rgb888(TEXSTORE_PARAMS)
1677 const GLboolean littleEndian = _mesa_little_endian();
1679 ASSERT(dstFormat == &_mesa_texformat_rgb888);
1680 ASSERT(dstFormat->TexelBytes == 3);
1682 if (!ctx->_ImageTransferState &&
1683 !srcPacking->SwapBytes &&
1684 baseInternalFormat == GL_RGB &&
1685 srcFormat == GL_BGR &&
1686 srcType == GL_UNSIGNED_BYTE &&
1688 /* simple memcpy path */
1689 memcpy_texture(ctx, dims,
1690 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1693 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1694 srcAddr, srcPacking);
1696 else if (!ctx->_ImageTransferState &&
1697 !srcPacking->SwapBytes &&
1698 srcFormat == GL_RGBA &&
1699 srcType == GL_UNSIGNED_BYTE) {
1700 /* extract RGB from RGBA */
1701 GLint img, row, col;
1702 for (img = 0; img < srcDepth; img++) {
1703 const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1704 srcWidth, srcFormat, srcType);
1705 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1706 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1707 GLubyte *dstRow = (GLubyte *) dstAddr
1708 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1709 + dstYoffset * dstRowStride
1710 + dstXoffset * dstFormat->TexelBytes;
1711 for (row = 0; row < srcHeight; row++) {
1712 for (col = 0; col < srcWidth; col++) {
1713 dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1714 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1715 dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1717 dstRow += dstRowStride;
1718 srcRow += srcRowStride;
1722 else if (!ctx->_ImageTransferState &&
1723 srcType == GL_UNSIGNED_BYTE &&
1724 can_swizzle(baseInternalFormat) &&
1725 can_swizzle(srcFormat)) {
1729 /* dstmap - how to swizzle from RGBA to dst format:
1734 dstmap[3] = ONE; /* ? */
1736 _mesa_swizzle_ubyte_image(ctx, dims,
1741 dstAddr, dstXoffset, dstYoffset, dstZoffset,
1742 dstRowStride, dstImageOffsets,
1743 srcWidth, srcHeight, srcDepth, srcAddr,
1748 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1750 dstFormat->BaseFormat,
1751 srcWidth, srcHeight, srcDepth,
1752 srcFormat, srcType, srcAddr,
1754 const GLchan *src = (const GLchan *) tempImage;
1755 GLint img, row, col;
1758 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1759 for (img = 0; img < srcDepth; img++) {
1760 GLubyte *dstRow = (GLubyte *) dstAddr
1761 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1762 + dstYoffset * dstRowStride
1763 + dstXoffset * dstFormat->TexelBytes;
1764 for (row = 0; row < srcHeight; row++) {
1767 for (col = 0; col < srcWidth; col++) {
1768 dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1769 dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1770 dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1775 for (col = 0; col < srcWidth; col++) {
1776 dstRow[col * 3 + 0] = srcUB[BCOMP];
1777 dstRow[col * 3 + 1] = srcUB[GCOMP];
1778 dstRow[col * 3 + 2] = srcUB[RCOMP];
1783 for (col = 0; col < srcWidth; col++) {
1784 dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
1785 dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1786 dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
1790 dstRow += dstRowStride;
1793 _mesa_free((void *) tempImage);
1800 _mesa_texstore_bgr888(TEXSTORE_PARAMS)
1802 const GLboolean littleEndian = _mesa_little_endian();
1804 ASSERT(dstFormat == &_mesa_texformat_bgr888);
1805 ASSERT(dstFormat->TexelBytes == 3);
1807 if (!ctx->_ImageTransferState &&
1808 !srcPacking->SwapBytes &&
1809 baseInternalFormat == GL_RGB &&
1810 srcFormat == GL_RGB &&
1811 srcType == GL_UNSIGNED_BYTE &&
1813 /* simple memcpy path */
1814 memcpy_texture(ctx, dims,
1815 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1818 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1819 srcAddr, srcPacking);
1821 else if (!ctx->_ImageTransferState &&
1822 !srcPacking->SwapBytes &&
1823 srcFormat == GL_RGBA &&
1824 srcType == GL_UNSIGNED_BYTE) {
1825 /* extract BGR from RGBA */
1827 for (img = 0; img < srcDepth; img++) {
1828 const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1829 srcWidth, srcFormat, srcType);
1830 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1831 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1832 GLubyte *dstRow = (GLubyte *) dstAddr
1833 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1834 + dstYoffset * dstRowStride
1835 + dstXoffset * dstFormat->TexelBytes;
1836 for (row = 0; row < srcHeight; row++) {
1837 for (col = 0; col < srcWidth; col++) {
1838 dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1839 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1840 dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1842 dstRow += dstRowStride;
1843 srcRow += srcRowStride;
1847 else if (!ctx->_ImageTransferState &&
1848 srcType == GL_UNSIGNED_BYTE &&
1849 can_swizzle(baseInternalFormat) &&
1850 can_swizzle(srcFormat)) {
1854 /* dstmap - how to swizzle from RGBA to dst format:
1859 dstmap[3] = ONE; /* ? */
1861 _mesa_swizzle_ubyte_image(ctx, dims,
1866 dstAddr, dstXoffset, dstYoffset, dstZoffset,
1867 dstRowStride, dstImageOffsets,
1868 srcWidth, srcHeight, srcDepth, srcAddr,
1873 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1875 dstFormat->BaseFormat,
1876 srcWidth, srcHeight, srcDepth,
1877 srcFormat, srcType, srcAddr,
1879 const GLchan *src = (const GLchan *) tempImage;
1880 GLint img, row, col;
1883 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1884 for (img = 0; img < srcDepth; img++) {
1885 GLubyte *dstRow = (GLubyte *) dstAddr
1886 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1887 + dstYoffset * dstRowStride
1888 + dstXoffset * dstFormat->TexelBytes;
1889 for (row = 0; row < srcHeight; row++) {
1890 for (col = 0; col < srcWidth; col++) {
1891 dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1892 dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1893 dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1896 dstRow += dstRowStride;
1899 _mesa_free((void *) tempImage);
1905 _mesa_texstore_rgba4444(TEXSTORE_PARAMS)
1907 ASSERT(dstFormat == &_mesa_texformat_rgba4444);
1908 ASSERT(dstFormat->TexelBytes == 2);
1910 if (!ctx->_ImageTransferState &&
1911 !srcPacking->SwapBytes &&
1912 dstFormat == &_mesa_texformat_rgba4444 &&
1913 baseInternalFormat == GL_RGBA &&
1914 srcFormat == GL_RGBA &&
1915 srcType == GL_UNSIGNED_SHORT_4_4_4_4){
1916 /* simple memcpy path */
1917 memcpy_texture(ctx, dims,
1918 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1921 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1922 srcAddr, srcPacking);
1926 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1928 dstFormat->BaseFormat,
1929 srcWidth, srcHeight, srcDepth,
1930 srcFormat, srcType, srcAddr,
1932 const GLchan *src = tempImage;
1933 GLint img, row, col;
1936 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1937 for (img = 0; img < srcDepth; img++) {
1938 GLubyte *dstRow = (GLubyte *) dstAddr
1939 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1940 + dstYoffset * dstRowStride
1941 + dstXoffset * dstFormat->TexelBytes;
1942 for (row = 0; row < srcHeight; row++) {
1943 GLushort *dstUS = (GLushort *) dstRow;
1944 for (col = 0; col < srcWidth; col++) {
1945 dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[RCOMP]),
1946 CHAN_TO_UBYTE(src[GCOMP]),
1947 CHAN_TO_UBYTE(src[BCOMP]),
1948 CHAN_TO_UBYTE(src[ACOMP]) );
1951 dstRow += dstRowStride;
1954 _mesa_free((void *) tempImage);
1960 _mesa_texstore_argb4444(TEXSTORE_PARAMS)
1962 ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
1963 dstFormat == &_mesa_texformat_argb4444_rev);
1964 ASSERT(dstFormat->TexelBytes == 2);
1966 if (!ctx->_ImageTransferState &&
1967 !srcPacking->SwapBytes &&
1968 dstFormat == &_mesa_texformat_argb4444 &&
1969 baseInternalFormat == GL_RGBA &&
1970 srcFormat == GL_BGRA &&
1971 srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
1972 /* simple memcpy path */
1973 memcpy_texture(ctx, dims,
1974 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1977 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1978 srcAddr, srcPacking);
1982 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1984 dstFormat->BaseFormat,
1985 srcWidth, srcHeight, srcDepth,
1986 srcFormat, srcType, srcAddr,
1988 const GLchan *src = tempImage;
1989 GLint img, row, col;
1992 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1993 for (img = 0; img < srcDepth; img++) {
1994 GLubyte *dstRow = (GLubyte *) dstAddr
1995 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1996 + dstYoffset * dstRowStride
1997 + dstXoffset * dstFormat->TexelBytes;
1998 for (row = 0; row < srcHeight; row++) {
1999 GLushort *dstUS = (GLushort *) dstRow;
2000 if (dstFormat == &_mesa_texformat_argb4444) {
2001 for (col = 0; col < srcWidth; col++) {
2002 dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
2003 CHAN_TO_UBYTE(src[RCOMP]),
2004 CHAN_TO_UBYTE(src[GCOMP]),
2005 CHAN_TO_UBYTE(src[BCOMP]) );
2010 for (col = 0; col < srcWidth; col++) {
2011 dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
2012 CHAN_TO_UBYTE(src[RCOMP]),
2013 CHAN_TO_UBYTE(src[GCOMP]),
2014 CHAN_TO_UBYTE(src[BCOMP]) );
2018 dstRow += dstRowStride;
2021 _mesa_free((void *) tempImage);
2027 _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
2029 ASSERT(dstFormat == &_mesa_texformat_rgba5551);
2030 ASSERT(dstFormat->TexelBytes == 2);
2032 if (!ctx->_ImageTransferState &&
2033 !srcPacking->SwapBytes &&
2034 dstFormat == &_mesa_texformat_rgba5551 &&
2035 baseInternalFormat == GL_RGBA &&
2036 srcFormat == GL_RGBA &&
2037 srcType == GL_UNSIGNED_SHORT_5_5_5_1) {
2038 /* simple memcpy path */
2039 memcpy_texture(ctx, dims,
2040 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2043 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2044 srcAddr, srcPacking);
2048 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2050 dstFormat->BaseFormat,
2051 srcWidth, srcHeight, srcDepth,
2052 srcFormat, srcType, srcAddr,
2054 const GLchan *src =tempImage;
2055 GLint img, row, col;
2058 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2059 for (img = 0; img < srcDepth; img++) {
2060 GLubyte *dstRow = (GLubyte *) dstAddr
2061 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2062 + dstYoffset * dstRowStride
2063 + dstXoffset * dstFormat->TexelBytes;
2064 for (row = 0; row < srcHeight; row++) {
2065 GLushort *dstUS = (GLushort *) dstRow;
2066 for (col = 0; col < srcWidth; col++) {
2067 dstUS[col] = PACK_COLOR_5551( CHAN_TO_UBYTE(src[RCOMP]),
2068 CHAN_TO_UBYTE(src[GCOMP]),
2069 CHAN_TO_UBYTE(src[BCOMP]),
2070 CHAN_TO_UBYTE(src[ACOMP]) );
2073 dstRow += dstRowStride;
2076 _mesa_free((void *) tempImage);
2082 _mesa_texstore_argb1555(TEXSTORE_PARAMS)
2084 ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
2085 dstFormat == &_mesa_texformat_argb1555_rev);
2086 ASSERT(dstFormat->TexelBytes == 2);
2088 if (!ctx->_ImageTransferState &&
2089 !srcPacking->SwapBytes &&
2090 dstFormat == &_mesa_texformat_argb1555 &&
2091 baseInternalFormat == GL_RGBA &&
2092 srcFormat == GL_BGRA &&
2093 srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
2094 /* simple memcpy path */
2095 memcpy_texture(ctx, dims,
2096 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2099 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2100 srcAddr, srcPacking);
2104 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2106 dstFormat->BaseFormat,
2107 srcWidth, srcHeight, srcDepth,
2108 srcFormat, srcType, srcAddr,
2110 const GLchan *src =tempImage;
2111 GLint img, row, col;
2114 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2115 for (img = 0; img < srcDepth; img++) {
2116 GLubyte *dstRow = (GLubyte *) dstAddr
2117 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2118 + dstYoffset * dstRowStride
2119 + dstXoffset * dstFormat->TexelBytes;
2120 for (row = 0; row < srcHeight; row++) {
2121 GLushort *dstUS = (GLushort *) dstRow;
2122 if (dstFormat == &_mesa_texformat_argb1555) {
2123 for (col = 0; col < srcWidth; col++) {
2124 dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
2125 CHAN_TO_UBYTE(src[RCOMP]),
2126 CHAN_TO_UBYTE(src[GCOMP]),
2127 CHAN_TO_UBYTE(src[BCOMP]) );
2132 for (col = 0; col < srcWidth; col++) {
2133 dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
2134 CHAN_TO_UBYTE(src[RCOMP]),
2135 CHAN_TO_UBYTE(src[GCOMP]),
2136 CHAN_TO_UBYTE(src[BCOMP]) );
2140 dstRow += dstRowStride;
2143 _mesa_free((void *) tempImage);
2150 _mesa_texstore_al88(TEXSTORE_PARAMS)
2152 const GLboolean littleEndian = _mesa_little_endian();
2154 ASSERT(dstFormat == &_mesa_texformat_al88 ||
2155 dstFormat == &_mesa_texformat_al88_rev);
2156 ASSERT(dstFormat->TexelBytes == 2);
2158 if (!ctx->_ImageTransferState &&
2159 !srcPacking->SwapBytes &&
2160 dstFormat == &_mesa_texformat_al88 &&
2161 baseInternalFormat == GL_LUMINANCE_ALPHA &&
2162 srcFormat == GL_LUMINANCE_ALPHA &&
2163 srcType == GL_UNSIGNED_BYTE &&
2165 /* simple memcpy path */
2166 memcpy_texture(ctx, dims,
2167 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2170 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2171 srcAddr, srcPacking);
2173 else if (!ctx->_ImageTransferState &&
2175 srcType == GL_UNSIGNED_BYTE &&
2176 can_swizzle(baseInternalFormat) &&
2177 can_swizzle(srcFormat)) {
2181 /* dstmap - how to swizzle from RGBA to dst format:
2183 if ((littleEndian && dstFormat == &_mesa_texformat_al88) ||
2184 (!littleEndian && dstFormat == &_mesa_texformat_al88_rev)) {
2192 dstmap[2] = ZERO; /* ? */
2193 dstmap[3] = ONE; /* ? */
2195 _mesa_swizzle_ubyte_image(ctx, dims,
2200 dstAddr, dstXoffset, dstYoffset, dstZoffset,
2201 dstRowStride, dstImageOffsets,
2202 srcWidth, srcHeight, srcDepth, srcAddr,
2207 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2209 dstFormat->BaseFormat,
2210 srcWidth, srcHeight, srcDepth,
2211 srcFormat, srcType, srcAddr,
2213 const GLchan *src = tempImage;
2214 GLint img, row, col;
2217 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2218 for (img = 0; img < srcDepth; img++) {
2219 GLubyte *dstRow = (GLubyte *) dstAddr
2220 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2221 + dstYoffset * dstRowStride
2222 + dstXoffset * dstFormat->TexelBytes;
2223 for (row = 0; row < srcHeight; row++) {
2224 GLushort *dstUS = (GLushort *) dstRow;
2225 if (dstFormat == &_mesa_texformat_al88) {
2226 for (col = 0; col < srcWidth; col++) {
2227 /* src[0] is luminance, src[1] is alpha */
2228 dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
2229 CHAN_TO_UBYTE(src[0]) );
2234 for (col = 0; col < srcWidth; col++) {
2235 /* src[0] is luminance, src[1] is alpha */
2236 dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
2237 CHAN_TO_UBYTE(src[0]) );
2241 dstRow += dstRowStride;
2244 _mesa_free((void *) tempImage);
2251 _mesa_texstore_rgb332(TEXSTORE_PARAMS)
2253 ASSERT(dstFormat == &_mesa_texformat_rgb332);
2254 ASSERT(dstFormat->TexelBytes == 1);
2256 if (!ctx->_ImageTransferState &&
2257 !srcPacking->SwapBytes &&
2258 baseInternalFormat == GL_RGB &&
2259 srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
2260 /* simple memcpy path */
2261 memcpy_texture(ctx, dims,
2262 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2265 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2266 srcAddr, srcPacking);
2270 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2272 dstFormat->BaseFormat,
2273 srcWidth, srcHeight, srcDepth,
2274 srcFormat, srcType, srcAddr,
2276 const GLchan *src = tempImage;
2277 GLint img, row, col;
2280 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2281 for (img = 0; img < srcDepth; img++) {
2282 GLubyte *dstRow = (GLubyte *) dstAddr
2283 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2284 + dstYoffset * dstRowStride
2285 + dstXoffset * dstFormat->TexelBytes;
2286 for (row = 0; row < srcHeight; row++) {
2287 for (col = 0; col < srcWidth; col++) {
2288 dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
2289 CHAN_TO_UBYTE(src[GCOMP]),
2290 CHAN_TO_UBYTE(src[BCOMP]) );
2293 dstRow += dstRowStride;
2296 _mesa_free((void *) tempImage);
2303 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2306 _mesa_texstore_a8(TEXSTORE_PARAMS)
2308 ASSERT(dstFormat == &_mesa_texformat_a8 ||
2309 dstFormat == &_mesa_texformat_l8 ||
2310 dstFormat == &_mesa_texformat_i8);
2311 ASSERT(dstFormat->TexelBytes == 1);
2313 if (!ctx->_ImageTransferState &&
2314 !srcPacking->SwapBytes &&
2315 baseInternalFormat == srcFormat &&
2316 srcType == GL_UNSIGNED_BYTE) {
2317 /* simple memcpy path */
2318 memcpy_texture(ctx, dims,
2319 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2322 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2323 srcAddr, srcPacking);
2325 else if (!ctx->_ImageTransferState &&
2326 srcType == GL_UNSIGNED_BYTE &&
2327 can_swizzle(baseInternalFormat) &&
2328 can_swizzle(srcFormat)) {
2332 /* dstmap - how to swizzle from RGBA to dst format:
2334 if (dstFormat == &_mesa_texformat_a8) {
2340 dstmap[1] = ZERO; /* ? */
2341 dstmap[2] = ZERO; /* ? */
2342 dstmap[3] = ONE; /* ? */
2344 _mesa_swizzle_ubyte_image(ctx, dims,
2349 dstAddr, dstXoffset, dstYoffset, dstZoffset,
2350 dstRowStride, dstImageOffsets,
2351 srcWidth, srcHeight, srcDepth, srcAddr,
2356 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2358 dstFormat->BaseFormat,
2359 srcWidth, srcHeight, srcDepth,
2360 srcFormat, srcType, srcAddr,
2362 const GLchan *src = tempImage;
2363 GLint img, row, col;
2366 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2367 for (img = 0; img < srcDepth; img++) {
2368 GLubyte *dstRow = (GLubyte *) dstAddr
2369 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2370 + dstYoffset * dstRowStride
2371 + dstXoffset * dstFormat->TexelBytes;
2372 for (row = 0; row < srcHeight; row++) {
2373 for (col = 0; col < srcWidth; col++) {
2374 dstRow[col] = CHAN_TO_UBYTE(src[col]);
2376 dstRow += dstRowStride;
2380 _mesa_free((void *) tempImage);
2388 _mesa_texstore_ci8(TEXSTORE_PARAMS)
2390 (void) dims; (void) baseInternalFormat;
2391 ASSERT(dstFormat == &_mesa_texformat_ci8);
2392 ASSERT(dstFormat->TexelBytes == 1);
2393 ASSERT(baseInternalFormat == GL_COLOR_INDEX);
2395 if (!ctx->_ImageTransferState &&
2396 !srcPacking->SwapBytes &&
2397 srcFormat == GL_COLOR_INDEX &&
2398 srcType == GL_UNSIGNED_BYTE) {
2399 /* simple memcpy path */
2400 memcpy_texture(ctx, dims,
2401 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2404 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2405 srcAddr, srcPacking);
2410 for (img = 0; img < srcDepth; img++) {
2411 GLubyte *dstRow = (GLubyte *) dstAddr
2412 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2413 + dstYoffset * dstRowStride
2414 + dstXoffset * dstFormat->TexelBytes;
2415 for (row = 0; row < srcHeight; row++) {
2416 const GLvoid *src = _mesa_image_address(dims, srcPacking,
2417 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
2418 _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
2419 srcType, src, srcPacking,
2420 ctx->_ImageTransferState);
2421 dstRow += dstRowStride;
2430 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
2433 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
2435 const GLboolean littleEndian = _mesa_little_endian();
2436 (void) ctx; (void) dims; (void) baseInternalFormat;
2438 ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
2439 (dstFormat == &_mesa_texformat_ycbcr_rev));
2440 ASSERT(dstFormat->TexelBytes == 2);
2441 ASSERT(ctx->Extensions.MESA_ycbcr_texture);
2442 ASSERT(srcFormat == GL_YCBCR_MESA);
2443 ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
2444 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
2445 ASSERT(baseInternalFormat == GL_YCBCR_MESA);
2447 /* always just memcpy since no pixel transfer ops apply */
2448 memcpy_texture(ctx, dims,
2449 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2452 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2453 srcAddr, srcPacking);
2455 /* Check if we need byte swapping */
2456 /* XXX the logic here _might_ be wrong */
2457 if (srcPacking->SwapBytes ^
2458 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
2459 (dstFormat == &_mesa_texformat_ycbcr_rev) ^
2462 for (img = 0; img < srcDepth; img++) {
2463 GLubyte *dstRow = (GLubyte *) dstAddr
2464 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2465 + dstYoffset * dstRowStride
2466 + dstXoffset * dstFormat->TexelBytes;
2467 for (row = 0; row < srcHeight; row++) {
2468 _mesa_swap2((GLushort *) dstRow, srcWidth);
2469 dstRow += dstRowStride;
2477 _mesa_texstore_dudv8(TEXSTORE_PARAMS)
2479 const GLboolean littleEndian = _mesa_little_endian();
2481 ASSERT(dstFormat == &_mesa_texformat_dudv8);
2482 ASSERT(dstFormat->TexelBytes == 2);
2483 ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
2484 ASSERT((srcFormat == GL_DU8DV8_ATI) ||
2485 (srcFormat == GL_DUDV_ATI));
2486 ASSERT(baseInternalFormat == GL_DUDV_ATI);
2488 if (!srcPacking->SwapBytes && srcType == GL_BYTE &&
2490 /* simple memcpy path */
2491 memcpy_texture(ctx, dims,
2492 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2495 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2496 srcAddr, srcPacking);
2498 else if (srcType == GL_BYTE) {
2502 /* dstmap - how to swizzle from RGBA to dst format:
2512 dstmap[2] = ZERO; /* ? */
2513 dstmap[3] = ONE; /* ? */
2515 _mesa_swizzle_ubyte_image(ctx, dims,
2516 GL_LUMINANCE_ALPHA, /* hack */
2517 GL_UNSIGNED_BYTE, /* hack */
2518 GL_LUMINANCE_ALPHA, /* hack */
2520 dstAddr, dstXoffset, dstYoffset, dstZoffset,
2521 dstRowStride, dstImageOffsets,
2522 srcWidth, srcHeight, srcDepth, srcAddr,
2526 /* general path - note this is defined for 2d textures only */
2527 const GLint components = _mesa_components_in_format(baseInternalFormat);
2528 const GLint srcStride = _mesa_image_row_stride(srcPacking,
2529 srcWidth, srcFormat, srcType);
2530 GLbyte *tempImage, *dst, *src;
2533 tempImage = (GLbyte *) _mesa_malloc(srcWidth * srcHeight * srcDepth
2534 * components * sizeof(GLbyte));
2538 src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2539 srcWidth, srcHeight,
2544 for (row = 0; row < srcHeight; row++) {
2545 _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat,
2546 dst, srcFormat, srcType, src,
2548 dst += srcWidth * components;
2553 dst = (GLbyte *) dstAddr
2554 + dstYoffset * dstRowStride
2555 + dstXoffset * dstFormat->TexelBytes;
2556 for (row = 0; row < srcHeight; row++) {
2557 memcpy(dst, src, srcWidth * dstFormat->TexelBytes);
2558 dst += dstRowStride;
2559 src += srcWidth * dstFormat->TexelBytes;
2561 _mesa_free((void *) tempImage);
2567 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or MESA_FORMAT_SIGNED_RGBA8888_REV
2570 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
2572 const GLboolean littleEndian = _mesa_little_endian();
2574 ASSERT(dstFormat == &_mesa_texformat_signed_rgba8888 ||
2575 dstFormat == &_mesa_texformat_signed_rgba8888_rev);
2576 ASSERT(dstFormat->TexelBytes == 4);
2578 if (!ctx->_ImageTransferState &&
2579 !srcPacking->SwapBytes &&
2580 dstFormat == &_mesa_texformat_signed_rgba8888 &&
2581 baseInternalFormat == GL_RGBA &&
2582 ((srcFormat == GL_RGBA && srcType == GL_BYTE && !littleEndian) ||
2583 (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && littleEndian))) {
2584 /* simple memcpy path */
2585 memcpy_texture(ctx, dims,
2586 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2589 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2590 srcAddr, srcPacking);
2592 else if (!ctx->_ImageTransferState &&
2593 !srcPacking->SwapBytes &&
2594 dstFormat == &_mesa_texformat_signed_rgba8888_rev &&
2595 baseInternalFormat == GL_RGBA &&
2596 ((srcFormat == GL_RGBA && srcType == GL_BYTE && littleEndian) ||
2597 (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && !littleEndian))) {
2598 /* simple memcpy path */
2599 memcpy_texture(ctx, dims,
2600 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2603 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2604 srcAddr, srcPacking);
2606 else if (!ctx->_ImageTransferState &&
2607 (srcType == GL_BYTE) &&
2608 can_swizzle(baseInternalFormat) &&
2609 can_swizzle(srcFormat)) {
2613 /* dstmap - how to swizzle from RGBA to dst format:
2615 if ((littleEndian && dstFormat == &_mesa_texformat_signed_rgba8888) ||
2616 (!littleEndian && dstFormat == &_mesa_texformat_signed_rgba8888_rev)) {
2629 _mesa_swizzle_ubyte_image(ctx, dims,
2634 dstAddr, dstXoffset, dstYoffset, dstZoffset,
2635 dstRowStride, dstImageOffsets,
2636 srcWidth, srcHeight, srcDepth, srcAddr,
2641 const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2643 dstFormat->BaseFormat,
2644 srcWidth, srcHeight, srcDepth,
2645 srcFormat, srcType, srcAddr,
2647 const GLfloat *srcRow = tempImage;
2648 GLint img, row, col;
2651 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2652 for (img = 0; img < srcDepth; img++) {
2653 GLubyte *dstRow = (GLubyte *) dstAddr
2654 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2655 + dstYoffset * dstRowStride
2656 + dstXoffset * dstFormat->TexelBytes;
2657 for (row = 0; row < srcHeight; row++) {
2658 GLuint *dstUI = (GLuint *) dstRow;
2659 if (dstFormat == &_mesa_texformat_signed_rgba8888) {
2660 for (col = 0; col < srcWidth; col++) {
2661 dstUI[col] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
2662 FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
2663 FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
2664 FLOAT_TO_BYTE_TEX(srcRow[ACOMP]) );
2669 for (col = 0; col < srcWidth; col++) {
2670 dstUI[col] = PACK_COLOR_8888_REV( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
2671 FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
2672 FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
2673 FLOAT_TO_BYTE_TEX(srcRow[ACOMP]) );
2677 dstRow += dstRowStride;
2680 _mesa_free((void *) tempImage);
2686 * Store a combined depth/stencil texture image.
2689 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
2691 const GLfloat depthScale = (GLfloat) 0xffffff;
2692 const GLint srcRowStride
2693 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
2697 ASSERT(dstFormat == &_mesa_texformat_z24_s8);
2698 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
2699 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
2701 /* In case we only upload depth we need to preserve the stencil */
2702 if (srcFormat == GL_DEPTH_COMPONENT) {
2703 for (img = 0; img < srcDepth; img++) {
2704 GLuint *dstRow = (GLuint *) dstAddr
2705 + dstImageOffsets[dstZoffset + img]
2706 + dstYoffset * dstRowStride / sizeof(GLuint)
2709 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2710 srcWidth, srcHeight,
2713 for (row = 0; row < srcHeight; row++) {
2714 GLuint depth[MAX_WIDTH];
2716 _mesa_unpack_depth_span(ctx, srcWidth,
2717 GL_UNSIGNED_INT, /* dst type */
2718 depth, /* dst addr */
2720 srcType, src, srcPacking);
2722 for (i = 0; i < srcWidth; i++)
2723 dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
2725 src += srcRowStride;
2726 dstRow += dstRowStride / sizeof(GLuint);
2730 else if (ctx->Pixel.DepthScale == 1.0f &&
2731 ctx->Pixel.DepthBias == 0.0f &&
2732 !srcPacking->SwapBytes) {
2734 memcpy_texture(ctx, dims,
2735 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2738 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2739 srcAddr, srcPacking);
2743 const GLint srcRowStride
2744 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
2748 for (img = 0; img < srcDepth; img++) {
2749 GLuint *dstRow = (GLuint *) dstAddr
2750 + dstImageOffsets[dstZoffset + img]
2751 + dstYoffset * dstRowStride / sizeof(GLuint)
2754 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2755 srcWidth, srcHeight,
2758 for (row = 0; row < srcHeight; row++) {
2759 GLubyte stencil[MAX_WIDTH];
2761 /* the 24 depth bits will be in the high position: */
2762 _mesa_unpack_depth_span(ctx, srcWidth,
2763 GL_UNSIGNED_INT_24_8_EXT, /* dst type */
2764 dstRow, /* dst addr */
2765 (GLuint) depthScale,
2766 srcType, src, srcPacking);
2767 /* get the 8-bit stencil values */
2768 _mesa_unpack_stencil_span(ctx, srcWidth,
2769 GL_UNSIGNED_BYTE, /* dst type */
2770 stencil, /* dst addr */
2771 srcType, src, srcPacking,
2772 ctx->_ImageTransferState);
2773 /* merge stencil values into depth values */
2774 for (i = 0; i < srcWidth; i++)
2775 dstRow[i] |= stencil[i];
2777 src += srcRowStride;
2778 dstRow += dstRowStride / sizeof(GLuint);
2787 * Store a combined depth/stencil texture image.
2790 _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
2792 const GLuint depthScale = 0xffffff;
2793 const GLint srcRowStride
2794 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
2798 ASSERT(dstFormat == &_mesa_texformat_s8_z24);
2799 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
2800 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
2802 /* In case we only upload depth we need to preserve the stencil */
2803 if (srcFormat == GL_DEPTH_COMPONENT) {
2804 for (img = 0; img < srcDepth; img++) {
2805 GLuint *dstRow = (GLuint *) dstAddr
2806 + dstImageOffsets[dstZoffset + img]
2807 + dstYoffset * dstRowStride / sizeof(GLuint)
2810 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2811 srcWidth, srcHeight,
2814 for (row = 0; row < srcHeight; row++) {
2815 GLuint depth[MAX_WIDTH];
2817 _mesa_unpack_depth_span(ctx, srcWidth,
2818 GL_UNSIGNED_INT, /* dst type */
2819 depth, /* dst addr */
2821 srcType, src, srcPacking);
2823 for (i = 0; i < srcWidth; i++)
2824 dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
2826 src += srcRowStride;
2827 dstRow += dstRowStride / sizeof(GLuint);
2832 for (img = 0; img < srcDepth; img++) {
2833 GLuint *dstRow = (GLuint *) dstAddr
2834 + dstImageOffsets[dstZoffset + img]
2835 + dstYoffset * dstRowStride / sizeof(GLuint)
2838 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2839 srcWidth, srcHeight,
2842 for (row = 0; row < srcHeight; row++) {
2843 GLubyte stencil[MAX_WIDTH];
2845 /* the 24 depth bits will be in the low position: */
2846 _mesa_unpack_depth_span(ctx, srcWidth,
2847 GL_UNSIGNED_INT, /* dst type */
2848 dstRow, /* dst addr */
2850 srcType, src, srcPacking);
2851 /* get the 8-bit stencil values */
2852 _mesa_unpack_stencil_span(ctx, srcWidth,
2853 GL_UNSIGNED_BYTE, /* dst type */
2854 stencil, /* dst addr */
2855 srcType, src, srcPacking,
2856 ctx->_ImageTransferState);
2857 /* merge stencil values into depth values */
2858 for (i = 0; i < srcWidth; i++)
2859 dstRow[i] |= stencil[i] << 24;
2861 src += srcRowStride;
2862 dstRow += dstRowStride / sizeof(GLuint);
2870 * Store an image in any of the formats:
2871 * _mesa_texformat_rgba_float32
2872 * _mesa_texformat_rgb_float32
2873 * _mesa_texformat_alpha_float32
2874 * _mesa_texformat_luminance_float32
2875 * _mesa_texformat_luminance_alpha_float32
2876 * _mesa_texformat_intensity_float32
2879 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
2881 const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
2883 ASSERT(dstFormat == &_mesa_texformat_rgba_float32 ||
2884 dstFormat == &_mesa_texformat_rgb_float32 ||
2885 dstFormat == &_mesa_texformat_alpha_float32 ||
2886 dstFormat == &_mesa_texformat_luminance_float32 ||
2887 dstFormat == &_mesa_texformat_luminance_alpha_float32 ||
2888 dstFormat == &_mesa_texformat_intensity_float32);
2889 ASSERT(baseInternalFormat == GL_RGBA ||
2890 baseInternalFormat == GL_RGB ||
2891 baseInternalFormat == GL_ALPHA ||
2892 baseInternalFormat == GL_LUMINANCE ||
2893 baseInternalFormat == GL_LUMINANCE_ALPHA ||
2894 baseInternalFormat == GL_INTENSITY);
2895 ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat));
2897 if (!ctx->_ImageTransferState &&
2898 !srcPacking->SwapBytes &&
2899 baseInternalFormat == srcFormat &&
2900 srcType == GL_FLOAT) {
2901 /* simple memcpy path */
2902 memcpy_texture(ctx, dims,
2903 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2906 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2907 srcAddr, srcPacking);
2911 const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2913 dstFormat->BaseFormat,
2914 srcWidth, srcHeight, srcDepth,
2915 srcFormat, srcType, srcAddr,
2917 const GLfloat *srcRow = tempImage;
2922 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2923 bytesPerRow = srcWidth * components * sizeof(GLfloat);
2924 for (img = 0; img < srcDepth; img++) {
2925 GLubyte *dstRow = (GLubyte *) dstAddr
2926 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2927 + dstYoffset * dstRowStride
2928 + dstXoffset * dstFormat->TexelBytes;
2929 for (row = 0; row < srcHeight; row++) {
2930 _mesa_memcpy(dstRow, srcRow, bytesPerRow);
2931 dstRow += dstRowStride;
2932 srcRow += srcWidth * components;
2936 _mesa_free((void *) tempImage);
2943 * As above, but store 16-bit floats.
2946 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
2948 const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
2950 ASSERT(dstFormat == &_mesa_texformat_rgba_float16 ||
2951 dstFormat == &_mesa_texformat_rgb_float16 ||
2952 dstFormat == &_mesa_texformat_alpha_float16 ||
2953 dstFormat == &_mesa_texformat_luminance_float16 ||
2954 dstFormat == &_mesa_texformat_luminance_alpha_float16 ||
2955 dstFormat == &_mesa_texformat_intensity_float16);
2956 ASSERT(baseInternalFormat == GL_RGBA ||
2957 baseInternalFormat == GL_RGB ||
2958 baseInternalFormat == GL_ALPHA ||
2959 baseInternalFormat == GL_LUMINANCE ||
2960 baseInternalFormat == GL_LUMINANCE_ALPHA ||
2961 baseInternalFormat == GL_INTENSITY);
2962 ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
2964 if (!ctx->_ImageTransferState &&
2965 !srcPacking->SwapBytes &&
2966 baseInternalFormat == srcFormat &&
2967 srcType == GL_HALF_FLOAT_ARB) {
2968 /* simple memcpy path */
2969 memcpy_texture(ctx, dims,
2970 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2973 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2974 srcAddr, srcPacking);
2978 const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2980 dstFormat->BaseFormat,
2981 srcWidth, srcHeight, srcDepth,
2982 srcFormat, srcType, srcAddr,
2984 const GLfloat *src = tempImage;
2988 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2989 for (img = 0; img < srcDepth; img++) {
2990 GLubyte *dstRow = (GLubyte *) dstAddr
2991 + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2992 + dstYoffset * dstRowStride
2993 + dstXoffset * dstFormat->TexelBytes;
2994 for (row = 0; row < srcHeight; row++) {
2995 GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
2997 for (i = 0; i < srcWidth * components; i++) {
2998 dstTexel[i] = _mesa_float_to_half(src[i]);
3000 dstRow += dstRowStride;
3001 src += srcWidth * components;
3005 _mesa_free((void *) tempImage);
3011 #if FEATURE_EXT_texture_sRGB
3013 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
3015 const struct gl_texture_format *newDstFormat;
3016 StoreTexImageFunc store;
3019 ASSERT(dstFormat == &_mesa_texformat_srgb8);
3021 /* reuse normal rgb texstore code */
3022 newDstFormat = &_mesa_texformat_rgb888;
3023 store = _mesa_texstore_rgb888;
3025 k = store(ctx, dims, baseInternalFormat,
3026 newDstFormat, dstAddr,
3027 dstXoffset, dstYoffset, dstZoffset,
3028 dstRowStride, dstImageOffsets,
3029 srcWidth, srcHeight, srcDepth,
3031 srcAddr, srcPacking);
3037 _mesa_texstore_srgba8(TEXSTORE_PARAMS)
3039 const struct gl_texture_format *newDstFormat;
3042 ASSERT(dstFormat == &_mesa_texformat_srgba8);
3044 /* reuse normal rgba texstore code */
3045 newDstFormat = &_mesa_texformat_rgba8888;
3047 k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
3048 newDstFormat, dstAddr,
3049 dstXoffset, dstYoffset, dstZoffset,
3050 dstRowStride, dstImageOffsets,
3051 srcWidth, srcHeight, srcDepth,
3053 srcAddr, srcPacking);
3059 _mesa_texstore_sargb8(TEXSTORE_PARAMS)
3061 const struct gl_texture_format *newDstFormat;
3064 ASSERT(dstFormat == &_mesa_texformat_sargb8);
3066 /* reuse normal rgba texstore code */
3067 newDstFormat = &_mesa_texformat_argb8888;
3069 k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
3070 newDstFormat, dstAddr,
3071 dstXoffset, dstYoffset, dstZoffset,
3072 dstRowStride, dstImageOffsets,
3073 srcWidth, srcHeight, srcDepth,
3075 srcAddr, srcPacking);
3081 _mesa_texstore_sl8(TEXSTORE_PARAMS)
3083 const struct gl_texture_format *newDstFormat;
3086 ASSERT(dstFormat == &_mesa_texformat_sl8);
3088 newDstFormat = &_mesa_texformat_l8;
3090 /* _mesa_textore_a8 handles luminance8 too */
3091 k = _mesa_texstore_a8(ctx, dims, baseInternalFormat,
3092 newDstFormat, dstAddr,
3093 dstXoffset, dstYoffset, dstZoffset,
3094 dstRowStride, dstImageOffsets,
3095 srcWidth, srcHeight, srcDepth,
3097 srcAddr, srcPacking);
3103 _mesa_texstore_sla8(TEXSTORE_PARAMS)
3105 const struct gl_texture_format *newDstFormat;
3108 ASSERT(dstFormat == &_mesa_texformat_sla8);
3110 /* reuse normal luminance/alpha texstore code */
3111 newDstFormat = &_mesa_texformat_al88;
3113 k = _mesa_texstore_al88(ctx, dims, baseInternalFormat,
3114 newDstFormat, dstAddr,
3115 dstXoffset, dstYoffset, dstZoffset,
3116 dstRowStride, dstImageOffsets,
3117 srcWidth, srcHeight, srcDepth,
3119 srcAddr, srcPacking);
3123 #endif /* FEATURE_EXT_texture_sRGB */
3127 * Check if an unpack PBO is active prior to fetching a texture image.
3128 * If so, do bounds checking and map the buffer into main memory.
3129 * Any errors detected will be recorded.
3130 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3133 _mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
3134 GLsizei width, GLsizei height, GLsizei depth,
3135 GLenum format, GLenum type, const GLvoid *pixels,
3136 const struct gl_pixelstore_attrib *unpack,
3137 const char *funcName)
3141 if (!_mesa_is_bufferobj(unpack->BufferObj)) {
3145 if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
3146 format, type, pixels)) {
3147 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
3151 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
3152 GL_READ_ONLY_ARB, unpack->BufferObj);
3154 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
3158 return ADD_POINTERS(buf, pixels);
3163 * Check if an unpack PBO is active prior to fetching a compressed texture
3165 * If so, do bounds checking and map the buffer into main memory.
3166 * Any errors detected will be recorded.
3167 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3170 _mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
3171 GLsizei imageSize, const GLvoid *pixels,
3172 const struct gl_pixelstore_attrib *packing,
3173 const char *funcName)
3177 if (!_mesa_is_bufferobj(packing->BufferObj)) {
3178 /* not using a PBO - return pointer unchanged */
3181 if ((const GLubyte *) pixels + imageSize >
3182 ((const GLubyte *) 0) + packing->BufferObj->Size) {
3183 /* out of bounds read! */
3184 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
3188 buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
3189 GL_READ_ONLY_ARB, packing->BufferObj);
3191 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
3195 return ADD_POINTERS(buf, pixels);
3200 * This function must be called after either of the validate_pbo_*_teximage()
3201 * functions. It unmaps the PBO buffer if it was mapped earlier.
3204 _mesa_unmap_teximage_pbo(GLcontext *ctx,
3205 const struct gl_pixelstore_attrib *unpack)
3207 if (_mesa_is_bufferobj(unpack->BufferObj)) {
3208 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
3216 * Adaptor for fetching a GLchan texel from a float-valued texture.
3219 fetch_texel_float_to_chan(const struct gl_texture_image *texImage,
3220 GLint i, GLint j, GLint k, GLchan *texelOut)
3223 ASSERT(texImage->FetchTexelf);
3224 texImage->FetchTexelf(texImage, i, j, k, temp);
3225 if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
3226 texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
3227 /* just one channel */
3228 UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
3232 UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
3233 UNCLAMPED_FLOAT_TO_CHAN(texelOut[1], temp[1]);
3234 UNCLAMPED_FLOAT_TO_CHAN(texelOut[2], temp[2]);
3235 UNCLAMPED_FLOAT_TO_CHAN(texelOut[3], temp[3]);
3241 * Adaptor for fetching a float texel from a GLchan-valued texture.
3244 fetch_texel_chan_to_float(const struct gl_texture_image *texImage,
3245 GLint i, GLint j, GLint k, GLfloat *texelOut)
3248 ASSERT(texImage->FetchTexelc);
3249 texImage->FetchTexelc(texImage, i, j, k, temp);
3250 if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
3251 texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
3252 /* just one channel */
3253 texelOut[0] = CHAN_TO_FLOAT(temp[0]);
3257 texelOut[0] = CHAN_TO_FLOAT(temp[0]);
3258 texelOut[1] = CHAN_TO_FLOAT(temp[1]);
3259 texelOut[2] = CHAN_TO_FLOAT(temp[2]);
3260 texelOut[3] = CHAN_TO_FLOAT(temp[3]);
3266 * Initialize the texture image's FetchTexelc and FetchTexelf methods.
3269 _mesa_set_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
3271 ASSERT(dims == 1 || dims == 2 || dims == 3);
3272 ASSERT(texImage->TexFormat);
3276 texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
3277 texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
3280 texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
3281 texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
3284 texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
3285 texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
3291 /* now check if we need to use a float/chan adaptor */
3292 if (!texImage->FetchTexelc) {
3293 texImage->FetchTexelc = fetch_texel_float_to_chan;
3295 else if (!texImage->FetchTexelf) {
3296 texImage->FetchTexelf = fetch_texel_chan_to_float;
3300 ASSERT(texImage->FetchTexelc);
3301 ASSERT(texImage->FetchTexelf);
3306 * Choose the actual storage format for a new texture image.
3307 * Mainly, this is a wrapper for the driver's ChooseTextureFormat() function.
3308 * Also set some other texImage fields related to texture compression, etc.
3309 * \param ctx rendering context
3310 * \param texImage the gl_texture_image
3311 * \param dims texture dimensions (1, 2 or 3)
3312 * \param format the user-specified format parameter
3313 * \param type the user-specified type parameter
3314 * \param internalFormat the user-specified internal format hint
3317 choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
3319 GLenum format, GLenum type, GLint internalFormat)
3321 ASSERT(dims == 1 || dims == 2 || dims == 3);
3322 ASSERT(ctx->Driver.ChooseTextureFormat);
3325 = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
3327 ASSERT(texImage->TexFormat);
3329 _mesa_set_fetch_functions(texImage, dims);
3331 if (texImage->TexFormat->TexelBytes == 0) {
3332 /* must be a compressed format */
3333 texImage->IsCompressed = GL_TRUE;
3334 texImage->CompressedSize =
3335 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
3336 texImage->Height, texImage->Depth,
3337 texImage->TexFormat->MesaFormat);
3340 /* non-compressed format */
3341 texImage->IsCompressed = GL_FALSE;
3342 texImage->CompressedSize = 0;
3349 * This is the software fallback for Driver.TexImage1D()
3350 * and Driver.CopyTexImage1D().
3351 * \sa _mesa_store_teximage2d()
3352 * Note that the width may not be the actual texture width since it may
3353 * be changed by convolution w/ GL_REDUCE. The texImage->Width field will
3354 * have the actual texture size.
3357 _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
3358 GLint internalFormat,
3359 GLint width, GLint border,
3360 GLenum format, GLenum type, const GLvoid *pixels,
3361 const struct gl_pixelstore_attrib *packing,
3362 struct gl_texture_object *texObj,
3363 struct gl_texture_image *texImage)
3368 choose_texture_format(ctx, texImage, 1, format, type, internalFormat);
3370 /* allocate memory */
3371 if (texImage->IsCompressed)
3372 sizeInBytes = texImage->CompressedSize;
3374 sizeInBytes = texImage->Width * texImage->TexFormat->TexelBytes;
3375 texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
3376 if (!texImage->Data) {
3377 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
3381 pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
3382 pixels, packing, "glTexImage1D");
3384 /* Note: we check for a NULL image pointer here, _after_ we allocated
3385 * memory for the texture. That's what the GL spec calls for.
3390 const GLint dstRowStride = 0;
3392 ASSERT(texImage->TexFormat->StoreImage);
3393 success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
3394 texImage->TexFormat,
3396 0, 0, 0, /* dstX/Y/Zoffset */
3398 texImage->ImageOffsets,
3400 format, type, pixels, packing);
3402 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
3406 /* GL_SGIS_generate_mipmap */
3407 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
3408 ctx->Driver.GenerateMipmap(ctx, target, texObj);
3411 _mesa_unmap_teximage_pbo(ctx, packing);
3416 * This is the software fallback for Driver.TexImage2D()
3417 * and Driver.CopyTexImage2D().
3419 * This function is oriented toward storing images in main memory, rather
3420 * than VRAM. Device driver's can easily plug in their own replacement.
3422 * Note: width and height may be pre-convolved dimensions, but
3423 * texImage->Width and texImage->Height will be post-convolved dimensions.
3426 _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
3427 GLint internalFormat,
3428 GLint width, GLint height, GLint border,
3429 GLenum format, GLenum type, const void *pixels,
3430 const struct gl_pixelstore_attrib *packing,
3431 struct gl_texture_object *texObj,
3432 struct gl_texture_image *texImage)
3434 GLint texelBytes, sizeInBytes;
3437 choose_texture_format(ctx, texImage, 2, format, type, internalFormat);
3439 texelBytes = texImage->TexFormat->TexelBytes;
3441 /* allocate memory */
3442 if (texImage->IsCompressed)
3443 sizeInBytes = texImage->CompressedSize;
3445 sizeInBytes = texImage->Width * texImage->Height * texelBytes;
3446 texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
3447 if (!texImage->Data) {
3448 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
3452 pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
3453 pixels, packing, "glTexImage2D");
3455 /* Note: we check for a NULL image pointer here, _after_ we allocated
3456 * memory for the texture. That's what the GL spec calls for.
3463 if (texImage->IsCompressed) {
3465 = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
3468 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
3470 ASSERT(texImage->TexFormat->StoreImage);
3471 success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
3472 texImage->TexFormat,
3474 0, 0, 0, /* dstX/Y/Zoffset */
3476 texImage->ImageOffsets,
3478 format, type, pixels, packing);
3480 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
3484 /* GL_SGIS_generate_mipmap */
3485 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
3486 ctx->Driver.GenerateMipmap(ctx, target, texObj);
3489 _mesa_unmap_teximage_pbo(ctx, packing);
3495 * This is the software fallback for Driver.TexImage3D()
3496 * and Driver.CopyTexImage3D().
3497 * \sa _mesa_store_teximage2d()
3500 _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
3501 GLint internalFormat,
3502 GLint width, GLint height, GLint depth, GLint border,
3503 GLenum format, GLenum type, const void *pixels,
3504 const struct gl_pixelstore_attrib *packing,
3505 struct gl_texture_object *texObj,
3506 struct gl_texture_image *texImage)
3508 GLint texelBytes, sizeInBytes;
3511 choose_texture_format(ctx, texImage, 3, format, type, internalFormat);
3513 texelBytes = texImage->TexFormat->TexelBytes;
3515 /* allocate memory */
3516 if (texImage->IsCompressed)
3517 sizeInBytes = texImage->CompressedSize;
3519 sizeInBytes = width * height * depth * texelBytes;
3520 texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
3521 if (!texImage->Data) {
3522 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
3526 pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
3527 type, pixels, packing, "glTexImage3D");
3529 /* Note: we check for a NULL image pointer here, _after_ we allocated
3530 * memory for the texture. That's what the GL spec calls for.
3537 if (texImage->IsCompressed) {
3539 = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
3542 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
3544 ASSERT(texImage->TexFormat->StoreImage);
3545 success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
3546 texImage->TexFormat,
3548 0, 0, 0, /* dstX/Y/Zoffset */
3550 texImage->ImageOffsets,
3551 width, height, depth,
3552 format, type, pixels, packing);
3554 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
3558 /* GL_SGIS_generate_mipmap */
3559 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
3560 ctx->Driver.GenerateMipmap(ctx, target, texObj);
3563 _mesa_unmap_teximage_pbo(ctx, packing);
3570 * This is the software fallback for Driver.TexSubImage1D()
3571 * and Driver.CopyTexSubImage1D().
3574 _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
3575 GLint xoffset, GLint width,
3576 GLenum format, GLenum type, const void *pixels,
3577 const struct gl_pixelstore_attrib *packing,
3578 struct gl_texture_object *texObj,
3579 struct gl_texture_image *texImage)
3581 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3582 pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
3583 pixels, packing, "glTexSubImage1D");
3588 const GLint dstRowStride = 0;
3590 ASSERT(texImage->TexFormat->StoreImage);
3591 success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
3592 texImage->TexFormat,
3594 xoffset, 0, 0, /* offsets */
3596 texImage->ImageOffsets,
3598 format, type, pixels, packing);
3600 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
3604 /* GL_SGIS_generate_mipmap */
3605 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
3606 ctx->Driver.GenerateMipmap(ctx, target, texObj);
3609 _mesa_unmap_teximage_pbo(ctx, packing);
3615 * This is the software fallback for Driver.TexSubImage2D()
3616 * and Driver.CopyTexSubImage2D().
3619 _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
3620 GLint xoffset, GLint yoffset,
3621 GLint width, GLint height,
3622 GLenum format, GLenum type, const void *pixels,
3623 const struct gl_pixelstore_attrib *packing,
3624 struct gl_texture_object *texObj,
3625 struct gl_texture_image *texImage)
3627 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3628 pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
3629 pixels, packing, "glTexSubImage2D");
3634 GLint dstRowStride = 0;
3636 if (texImage->IsCompressed) {
3637 dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
3641 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
3643 ASSERT(texImage->TexFormat->StoreImage);
3644 success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
3645 texImage->TexFormat,
3647 xoffset, yoffset, 0,
3649 texImage->ImageOffsets,
3651 format, type, pixels, packing);
3653 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
3657 /* GL_SGIS_generate_mipmap */
3658 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
3659 ctx->Driver.GenerateMipmap(ctx, target, texObj);
3662 _mesa_unmap_teximage_pbo(ctx, packing);
3667 * This is the software fallback for Driver.TexSubImage3D().
3668 * and Driver.CopyTexSubImage3D().
3671 _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
3672 GLint xoffset, GLint yoffset, GLint zoffset,
3673 GLint width, GLint height, GLint depth,
3674 GLenum format, GLenum type, const void *pixels,
3675 const struct gl_pixelstore_attrib *packing,
3676 struct gl_texture_object *texObj,
3677 struct gl_texture_image *texImage)
3679 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3680 pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
3681 type, pixels, packing,
3689 if (texImage->IsCompressed) {
3690 dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
3694 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
3696 ASSERT(texImage->TexFormat->StoreImage);
3697 success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
3698 texImage->TexFormat,
3700 xoffset, yoffset, zoffset,
3702 texImage->ImageOffsets,
3703 width, height, depth,
3704 format, type, pixels, packing);
3706 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
3710 /* GL_SGIS_generate_mipmap */
3711 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
3712 ctx->Driver.GenerateMipmap(ctx, target, texObj);
3715 _mesa_unmap_teximage_pbo(ctx, packing);
3720 * Fallback for Driver.CompressedTexImage1D()
3723 _mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
3724 GLint internalFormat,
3725 GLint width, GLint border,
3726 GLsizei imageSize, const GLvoid *data,
3727 struct gl_texture_object *texObj,
3728 struct gl_texture_image *texImage)
3730 /* this space intentionally left blank */
3732 (void) target; (void) level;
3733 (void) internalFormat;
3734 (void) width; (void) border;
3735 (void) imageSize; (void) data;
3743 * Fallback for Driver.CompressedTexImage2D()
3746 _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
3747 GLint internalFormat,
3748 GLint width, GLint height, GLint border,
3749 GLsizei imageSize, const GLvoid *data,
3750 struct gl_texture_object *texObj,
3751 struct gl_texture_image *texImage)
3753 (void) width; (void) height; (void) border;
3755 /* This is pretty simple, basically just do a memcpy without worrying
3756 * about the usual image unpacking or image transfer operations.
3760 ASSERT(texImage->Width > 0);
3761 ASSERT(texImage->Height > 0);
3762 ASSERT(texImage->Depth == 1);
3763 ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
3765 choose_texture_format(ctx, texImage, 2, 0, 0, internalFormat);
3767 /* allocate storage */
3768 texImage->Data = _mesa_alloc_texmemory(imageSize);
3769 if (!texImage->Data) {
3770 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
3774 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
3776 "glCompressedTexImage2D");
3781 ASSERT(texImage->CompressedSize == (GLuint) imageSize);
3782 MEMCPY(texImage->Data, data, imageSize);
3784 /* GL_SGIS_generate_mipmap */
3785 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
3786 ctx->Driver.GenerateMipmap(ctx, target, texObj);
3789 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
3795 * Fallback for Driver.CompressedTexImage3D()
3798 _mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
3799 GLint internalFormat,
3800 GLint width, GLint height, GLint depth,
3802 GLsizei imageSize, const GLvoid *data,
3803 struct gl_texture_object *texObj,
3804 struct gl_texture_image *texImage)
3806 /* this space intentionally left blank */
3808 (void) target; (void) level;
3809 (void) internalFormat;
3810 (void) width; (void) height; (void) depth;
3812 (void) imageSize; (void) data;
3820 * Fallback for Driver.CompressedTexSubImage1D()
3823 _mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
3825 GLint xoffset, GLsizei width,
3827 GLsizei imageSize, const GLvoid *data,
3828 struct gl_texture_object *texObj,
3829 struct gl_texture_image *texImage)
3831 /* there are no compressed 1D texture formats yet */
3833 (void) target; (void) level;
3834 (void) xoffset; (void) width;
3836 (void) imageSize; (void) data;
3843 * Fallback for Driver.CompressedTexSubImage2D()
3846 _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
3848 GLint xoffset, GLint yoffset,
3849 GLsizei width, GLsizei height,
3851 GLsizei imageSize, const GLvoid *data,
3852 struct gl_texture_object *texObj,
3853 struct gl_texture_image *texImage)
3855 GLint bytesPerRow, destRowStride, srcRowStride;
3859 const GLuint mesaFormat = texImage->TexFormat->MesaFormat;
3863 /* these should have been caught sooner */
3864 ASSERT((width & 3) == 0 || width == 2 || width == 1);
3865 ASSERT((height & 3) == 0 || height == 2 || height == 1);
3866 ASSERT((xoffset & 3) == 0);
3867 ASSERT((yoffset & 3) == 0);
3869 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3870 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
3872 "glCompressedTexSubImage2D");
3876 srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);
3877 src = (const GLubyte *) data;
3879 destRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width);
3880 dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
3881 texImage->TexFormat->MesaFormat,
3883 (GLubyte *) texImage->Data);
3885 bytesPerRow = srcRowStride;
3888 for (i = 0; i < rows; i++) {
3889 MEMCPY(dest, src, bytesPerRow);
3890 dest += destRowStride;
3891 src += srcRowStride;
3894 /* GL_SGIS_generate_mipmap */
3895 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
3896 ctx->Driver.GenerateMipmap(ctx, target, texObj);
3899 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
3904 * Fallback for Driver.CompressedTexSubImage3D()
3907 _mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
3909 GLint xoffset, GLint yoffset, GLint zoffset,
3910 GLsizei width, GLsizei height, GLsizei depth,
3912 GLsizei imageSize, const GLvoid *data,
3913 struct gl_texture_object *texObj,
3914 struct gl_texture_image *texImage)
3916 /* there are no compressed 3D texture formats yet */
3918 (void) target; (void) level;
3919 (void) xoffset; (void) yoffset; (void) zoffset;
3920 (void) width; (void) height; (void) depth;
3922 (void) imageSize; (void) data;