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, etc)
50 * These functions can handle most everything, including processing full
51 * images and sub-images.
56 #include "bufferobj.h"
61 #include "mfeatures.h"
66 #include "texcompress.h"
67 #include "texcompress_fxt1.h"
68 #include "texcompress_rgtc.h"
69 #include "texcompress_s3tc.h"
70 #include "texcompress_etc.h"
74 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
75 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
85 * Texture image storage function.
87 typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
91 * Return GL_TRUE if the given image format is one that be converted
92 * to another format by swizzling.
95 can_swizzle(GLenum logicalBaseFormat)
97 switch (logicalBaseFormat) {
100 case GL_LUMINANCE_ALPHA:
136 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO)
137 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO)
138 #define MAP3(x,y,z) MAP4(x, y, z, ZERO)
139 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
142 static const struct {
145 GLubyte from_rgba[6];
146 } mappings[MAX_IDX] =
156 MAP4(ZERO, ZERO, ZERO, 0),
186 MAP4(0, ZERO, ZERO, ONE),
192 MAP4(ZERO, 0, ZERO, ONE),
198 MAP4(ZERO, ZERO, 0, ONE),
222 MAP4(0, 1, ZERO, ONE),
230 * Convert a GL image format enum to an IDX_* value (see above).
233 get_map_idx(GLenum value)
236 case GL_LUMINANCE: return IDX_LUMINANCE;
237 case GL_ALPHA: return IDX_ALPHA;
238 case GL_INTENSITY: return IDX_INTENSITY;
239 case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
240 case GL_RGB: return IDX_RGB;
241 case GL_RGBA: return IDX_RGBA;
242 case GL_RED: return IDX_RED;
243 case GL_GREEN: return IDX_GREEN;
244 case GL_BLUE: return IDX_BLUE;
245 case GL_BGR: return IDX_BGR;
246 case GL_BGRA: return IDX_BGRA;
247 case GL_ABGR_EXT: return IDX_ABGR;
248 case GL_RG: return IDX_RG;
250 _mesa_problem(NULL, "Unexpected inFormat");
257 * When promoting texture formats (see below) we need to compute the
258 * mapping of dest components back to source components.
259 * This function does that.
260 * \param inFormat the incoming format of the texture
261 * \param outFormat the final texture format
262 * \return map[6] a full 6-component map
265 compute_component_mapping(GLenum inFormat, GLenum outFormat,
268 const int inFmt = get_map_idx(inFormat);
269 const int outFmt = get_map_idx(outFormat);
270 const GLubyte *in2rgba = mappings[inFmt].to_rgba;
271 const GLubyte *rgba2out = mappings[outFmt].from_rgba;
274 for (i = 0; i < 4; i++)
275 map[i] = in2rgba[rgba2out[i]];
281 printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
282 inFormat, _mesa_lookup_enum_by_nr(inFormat),
283 outFormat, _mesa_lookup_enum_by_nr(outFormat),
295 * Make a temporary (color) texture image with GLfloat components.
296 * Apply all needed pixel unpacking and pixel transfer operations.
297 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
298 * Suppose the user specifies GL_LUMINANCE as the internal texture format
299 * but the graphics hardware doesn't support luminance textures. So, we might
300 * use an RGB hardware format instead.
301 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
303 * \param ctx the rendering context
304 * \param dims image dimensions: 1, 2 or 3
305 * \param logicalBaseFormat basic texture derived from the user's
306 * internal texture format value
307 * \param textureBaseFormat the actual basic format of the texture
308 * \param srcWidth source image width
309 * \param srcHeight source image height
310 * \param srcDepth source image depth
311 * \param srcFormat source image format
312 * \param srcType source image type
313 * \param srcAddr source image address
314 * \param srcPacking source image pixel packing
315 * \return resulting image with format = textureBaseFormat and type = GLfloat.
318 _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
319 GLenum logicalBaseFormat,
320 GLenum textureBaseFormat,
321 GLint srcWidth, GLint srcHeight, GLint srcDepth,
322 GLenum srcFormat, GLenum srcType,
323 const GLvoid *srcAddr,
324 const struct gl_pixelstore_attrib *srcPacking,
325 GLbitfield transferOps)
328 const GLint components = _mesa_components_in_format(logicalBaseFormat);
329 const GLint srcStride =
330 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
334 ASSERT(dims >= 1 && dims <= 3);
336 ASSERT(logicalBaseFormat == GL_RGBA ||
337 logicalBaseFormat == GL_RGB ||
338 logicalBaseFormat == GL_RG ||
339 logicalBaseFormat == GL_RED ||
340 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
341 logicalBaseFormat == GL_LUMINANCE ||
342 logicalBaseFormat == GL_ALPHA ||
343 logicalBaseFormat == GL_INTENSITY ||
344 logicalBaseFormat == GL_DEPTH_COMPONENT);
346 ASSERT(textureBaseFormat == GL_RGBA ||
347 textureBaseFormat == GL_RGB ||
348 textureBaseFormat == GL_RG ||
349 textureBaseFormat == GL_RED ||
350 textureBaseFormat == GL_LUMINANCE_ALPHA ||
351 textureBaseFormat == GL_LUMINANCE ||
352 textureBaseFormat == GL_ALPHA ||
353 textureBaseFormat == GL_INTENSITY ||
354 textureBaseFormat == GL_DEPTH_COMPONENT);
356 tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
357 * components * sizeof(GLfloat));
362 for (img = 0; img < srcDepth; img++) {
364 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
368 for (row = 0; row < srcHeight; row++) {
369 _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
370 dst, srcFormat, srcType, src,
371 srcPacking, transferOps);
372 dst += srcWidth * components;
377 if (logicalBaseFormat != textureBaseFormat) {
379 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
380 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
385 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
386 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
387 textureBaseFormat == GL_LUMINANCE_ALPHA);
389 /* The actual texture format should have at least as many components
390 * as the logical texture format.
392 ASSERT(texComponents >= logComponents);
394 newImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
395 * texComponents * sizeof(GLfloat));
401 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
403 n = srcWidth * srcHeight * srcDepth;
404 for (i = 0; i < n; i++) {
406 for (k = 0; k < texComponents; k++) {
409 newImage[i * texComponents + k] = 0.0F;
411 newImage[i * texComponents + k] = 1.0F;
413 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
418 tempImage = newImage;
426 * Make temporary image with uint pixel values. Used for unsigned
427 * integer-valued textures.
430 make_temp_uint_image(struct gl_context *ctx, GLuint dims,
431 GLenum logicalBaseFormat,
432 GLenum textureBaseFormat,
433 GLint srcWidth, GLint srcHeight, GLint srcDepth,
434 GLenum srcFormat, GLenum srcType,
435 const GLvoid *srcAddr,
436 const struct gl_pixelstore_attrib *srcPacking)
439 const GLint components = _mesa_components_in_format(logicalBaseFormat);
440 const GLint srcStride =
441 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
445 ASSERT(dims >= 1 && dims <= 3);
447 ASSERT(logicalBaseFormat == GL_RGBA ||
448 logicalBaseFormat == GL_RGB ||
449 logicalBaseFormat == GL_RG ||
450 logicalBaseFormat == GL_RED ||
451 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
452 logicalBaseFormat == GL_LUMINANCE ||
453 logicalBaseFormat == GL_INTENSITY ||
454 logicalBaseFormat == GL_ALPHA);
456 ASSERT(textureBaseFormat == GL_RGBA ||
457 textureBaseFormat == GL_RGB ||
458 textureBaseFormat == GL_RG ||
459 textureBaseFormat == GL_RED ||
460 textureBaseFormat == GL_LUMINANCE_ALPHA ||
461 textureBaseFormat == GL_LUMINANCE ||
462 textureBaseFormat == GL_INTENSITY ||
463 textureBaseFormat == GL_ALPHA);
465 tempImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
466 * components * sizeof(GLuint));
471 for (img = 0; img < srcDepth; img++) {
473 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
477 for (row = 0; row < srcHeight; row++) {
478 _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat,
479 dst, srcFormat, srcType, src,
481 dst += srcWidth * components;
486 if (logicalBaseFormat != textureBaseFormat) {
488 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
489 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
494 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
495 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
496 textureBaseFormat == GL_LUMINANCE_ALPHA);
498 /* The actual texture format should have at least as many components
499 * as the logical texture format.
501 ASSERT(texComponents >= logComponents);
503 newImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
504 * texComponents * sizeof(GLuint));
510 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
512 n = srcWidth * srcHeight * srcDepth;
513 for (i = 0; i < n; i++) {
515 for (k = 0; k < texComponents; k++) {
518 newImage[i * texComponents + k] = 0.0F;
520 newImage[i * texComponents + k] = 1.0F;
522 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
527 tempImage = newImage;
536 * Make a temporary (color) texture image with GLubyte components.
537 * Apply all needed pixel unpacking and pixel transfer operations.
538 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
539 * Suppose the user specifies GL_LUMINANCE as the internal texture format
540 * but the graphics hardware doesn't support luminance textures. So, we might
541 * use an RGB hardware format instead.
542 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
544 * \param ctx the rendering context
545 * \param dims image dimensions: 1, 2 or 3
546 * \param logicalBaseFormat basic texture derived from the user's
547 * internal texture format value
548 * \param textureBaseFormat the actual basic format of the texture
549 * \param srcWidth source image width
550 * \param srcHeight source image height
551 * \param srcDepth source image depth
552 * \param srcFormat source image format
553 * \param srcType source image type
554 * \param srcAddr source image address
555 * \param srcPacking source image pixel packing
556 * \return resulting image with format = textureBaseFormat and type = GLubyte.
559 _mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims,
560 GLenum logicalBaseFormat,
561 GLenum textureBaseFormat,
562 GLint srcWidth, GLint srcHeight, GLint srcDepth,
563 GLenum srcFormat, GLenum srcType,
564 const GLvoid *srcAddr,
565 const struct gl_pixelstore_attrib *srcPacking)
567 GLuint transferOps = ctx->_ImageTransferState;
568 const GLint components = _mesa_components_in_format(logicalBaseFormat);
570 GLubyte *tempImage, *dst;
572 ASSERT(dims >= 1 && dims <= 3);
574 ASSERT(logicalBaseFormat == GL_RGBA ||
575 logicalBaseFormat == GL_RGB ||
576 logicalBaseFormat == GL_RG ||
577 logicalBaseFormat == GL_RED ||
578 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
579 logicalBaseFormat == GL_LUMINANCE ||
580 logicalBaseFormat == GL_ALPHA ||
581 logicalBaseFormat == GL_INTENSITY);
583 ASSERT(textureBaseFormat == GL_RGBA ||
584 textureBaseFormat == GL_RGB ||
585 textureBaseFormat == GL_RG ||
586 textureBaseFormat == GL_RED ||
587 textureBaseFormat == GL_LUMINANCE_ALPHA ||
588 textureBaseFormat == GL_LUMINANCE ||
589 textureBaseFormat == GL_ALPHA ||
590 textureBaseFormat == GL_INTENSITY);
592 /* unpack and transfer the source image */
593 tempImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
594 * components * sizeof(GLubyte));
600 for (img = 0; img < srcDepth; img++) {
601 const GLint srcStride =
602 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
604 (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
608 for (row = 0; row < srcHeight; row++) {
609 _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst,
610 srcFormat, srcType, src, srcPacking,
612 dst += srcWidth * components;
617 if (logicalBaseFormat != textureBaseFormat) {
618 /* one more conversion step */
619 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
620 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
625 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
626 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
627 textureBaseFormat == GL_LUMINANCE_ALPHA);
629 /* The actual texture format should have at least as many components
630 * as the logical texture format.
632 ASSERT(texComponents >= logComponents);
634 newImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
635 * texComponents * sizeof(GLubyte));
641 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
643 n = srcWidth * srcHeight * srcDepth;
644 for (i = 0; i < n; i++) {
646 for (k = 0; k < texComponents; k++) {
649 newImage[i * texComponents + k] = 0;
651 newImage[i * texComponents + k] = 255;
653 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
658 tempImage = newImage;
666 * Copy GLubyte pixels from <src> to <dst> with swizzling.
667 * \param dst destination pixels
668 * \param dstComponents number of color components in destination pixels
669 * \param src source pixels
670 * \param srcComponents number of color components in source pixels
671 * \param map the swizzle mapping. map[X] says where to find the X component
672 * in the source image's pixels. For example, if the source image
673 * is GL_BGRA and X = red, map[0] yields 2.
674 * \param count number of pixels to copy/swizzle.
677 swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
678 GLuint srcComponents, const GLubyte *map, GLuint count)
680 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
683 for (i = 0; i < count; i++) { \
685 if (srcComps == 4) { \
686 COPY_4UBV(tmp, src); \
689 for (j = 0; j < srcComps; j++) { \
694 for (j = 0; j < dstComps; j++) { \
695 dst[j] = tmp[map[j]]; \
706 ASSERT(srcComponents <= 4);
707 ASSERT(dstComponents <= 4);
709 switch (dstComponents) {
711 switch (srcComponents) {
713 SWZ_CPY(dst, src, count, 4, 4);
716 SWZ_CPY(dst, src, count, 4, 3);
719 SWZ_CPY(dst, src, count, 4, 2);
722 SWZ_CPY(dst, src, count, 4, 1);
729 switch (srcComponents) {
731 SWZ_CPY(dst, src, count, 3, 4);
734 SWZ_CPY(dst, src, count, 3, 3);
737 SWZ_CPY(dst, src, count, 3, 2);
740 SWZ_CPY(dst, src, count, 3, 1);
747 switch (srcComponents) {
749 SWZ_CPY(dst, src, count, 2, 4);
752 SWZ_CPY(dst, src, count, 2, 3);
755 SWZ_CPY(dst, src, count, 2, 2);
758 SWZ_CPY(dst, src, count, 2, 1);
765 switch (srcComponents) {
767 SWZ_CPY(dst, src, count, 1, 4);
770 SWZ_CPY(dst, src, count, 1, 3);
773 SWZ_CPY(dst, src, count, 1, 2);
776 SWZ_CPY(dst, src, count, 1, 1);
790 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
791 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
795 * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
796 * mapping array depending on endianness.
798 static const GLubyte *
799 type_mapping( GLenum srcType )
803 case GL_UNSIGNED_BYTE:
805 case GL_UNSIGNED_INT_8_8_8_8:
806 return _mesa_little_endian() ? map_3210 : map_identity;
807 case GL_UNSIGNED_INT_8_8_8_8_REV:
808 return _mesa_little_endian() ? map_identity : map_3210;
816 * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
817 * mapping array depending on pixelstore byte swapping state.
819 static const GLubyte *
820 byteswap_mapping( GLboolean swapBytes,
828 case GL_UNSIGNED_BYTE:
830 case GL_UNSIGNED_INT_8_8_8_8:
831 case GL_UNSIGNED_INT_8_8_8_8_REV:
841 * Transfer a GLubyte texture image with component swizzling.
844 _mesa_swizzle_ubyte_image(struct gl_context *ctx,
849 GLenum baseInternalFormat,
851 const GLubyte *rgba2dst,
852 GLuint dstComponents,
854 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
858 GLint srcWidth, GLint srcHeight, GLint srcDepth,
859 const GLvoid *srcAddr,
860 const struct gl_pixelstore_attrib *srcPacking )
862 GLint srcComponents = _mesa_components_in_format(srcFormat);
863 const GLubyte *srctype2ubyte, *swap;
864 GLubyte map[4], src2base[6], base2rgba[6];
866 const GLint srcRowStride =
867 _mesa_image_row_stride(srcPacking, srcWidth,
868 srcFormat, GL_UNSIGNED_BYTE);
869 const GLint srcImageStride
870 = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
872 const GLubyte *srcImage
873 = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
874 srcWidth, srcHeight, srcFormat,
875 GL_UNSIGNED_BYTE, 0, 0, 0);
879 /* Translate from src->baseInternal->GL_RGBA->dst. This will
880 * correctly deal with RGBA->RGB->RGBA conversions where the final
881 * A value must be 0xff regardless of the incoming alpha values.
883 compute_component_mapping(srcFormat, baseInternalFormat, src2base);
884 compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba);
885 swap = byteswap_mapping(srcPacking->SwapBytes, srcType);
886 srctype2ubyte = type_mapping(srcType);
889 for (i = 0; i < 4; i++)
890 map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]];
892 /* printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */
894 if (srcComponents == dstComponents &&
895 srcRowStride == dstRowStride &&
896 srcRowStride == srcWidth * srcComponents &&
898 /* 1 and 2D images only */
899 GLubyte *dstImage = dstSlices[0]
900 + dstYoffset * dstRowStride
901 + dstXoffset * dstComponents;
902 swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
903 srcWidth * srcHeight);
907 for (img = 0; img < srcDepth; img++) {
908 const GLubyte *srcRow = srcImage;
909 GLubyte *dstRow = dstSlices[dstZoffset + img]
910 + dstYoffset * dstRowStride
911 + dstXoffset * dstComponents;
912 for (row = 0; row < srcHeight; row++) {
913 swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
914 dstRow += dstRowStride;
915 srcRow += srcRowStride;
917 srcImage += srcImageStride;
924 * Teximage storage routine for when a simple memcpy will do.
925 * No pixel transfer operations or special texel encodings allowed.
926 * 1D, 2D and 3D images supported.
929 memcpy_texture(struct gl_context *ctx,
932 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
935 GLint srcWidth, GLint srcHeight, GLint srcDepth,
936 GLenum srcFormat, GLenum srcType,
937 const GLvoid *srcAddr,
938 const struct gl_pixelstore_attrib *srcPacking)
940 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
942 const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
943 srcWidth, srcHeight, srcFormat, srcType);
944 const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
945 srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
946 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
947 const GLint bytesPerRow = srcWidth * texelBytes;
949 if (dstRowStride == srcRowStride &&
950 dstRowStride == bytesPerRow) {
951 /* memcpy image by image */
953 for (img = 0; img < srcDepth; img++) {
954 GLubyte *dstImage = dstSlices[dstZoffset + img]
955 + dstYoffset * dstRowStride
956 + dstXoffset * texelBytes;
957 memcpy(dstImage, srcImage, bytesPerRow * srcHeight);
958 srcImage += srcImageStride;
962 /* memcpy row by row */
964 for (img = 0; img < srcDepth; img++) {
965 const GLubyte *srcRow = srcImage;
966 GLubyte *dstRow = dstSlices[dstZoffset + img]
967 + dstYoffset * dstRowStride
968 + dstXoffset * texelBytes;
969 for (row = 0; row < srcHeight; row++) {
970 memcpy(dstRow, srcRow, bytesPerRow);
971 dstRow += dstRowStride;
972 srcRow += srcRowStride;
974 srcImage += srcImageStride;
982 * Store a 32-bit integer or float depth component texture image.
985 _mesa_texstore_z32(TEXSTORE_PARAMS)
987 const GLuint depthScale = 0xffffffff;
988 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
991 ASSERT(dstFormat == MESA_FORMAT_Z32 ||
992 dstFormat == MESA_FORMAT_Z32_FLOAT);
993 ASSERT(texelBytes == sizeof(GLuint));
995 if (dstFormat == MESA_FORMAT_Z32)
996 dstType = GL_UNSIGNED_INT;
1000 if (ctx->Pixel.DepthScale == 1.0f &&
1001 ctx->Pixel.DepthBias == 0.0f &&
1002 !srcPacking->SwapBytes &&
1003 baseInternalFormat == GL_DEPTH_COMPONENT &&
1004 srcFormat == GL_DEPTH_COMPONENT &&
1005 srcType == dstType) {
1006 /* simple memcpy path */
1007 memcpy_texture(ctx, dims,
1008 dstFormat, dstXoffset, dstYoffset, dstZoffset,
1009 dstRowStride, dstSlices,
1010 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1011 srcAddr, srcPacking);
1016 for (img = 0; img < srcDepth; img++) {
1017 GLubyte *dstRow = dstSlices[dstZoffset + img]
1018 + dstYoffset * dstRowStride
1019 + dstXoffset * texelBytes;
1020 for (row = 0; row < srcHeight; row++) {
1021 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1022 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1023 _mesa_unpack_depth_span(ctx, srcWidth,
1025 depthScale, srcType, src, srcPacking);
1026 dstRow += dstRowStride;
1035 * Store a 24-bit integer depth component texture image.
1038 _mesa_texstore_x8_z24(TEXSTORE_PARAMS)
1040 const GLuint depthScale = 0xffffff;
1041 const GLuint texelBytes = 4;
1044 ASSERT(dstFormat == MESA_FORMAT_X8_Z24);
1049 for (img = 0; img < srcDepth; img++) {
1050 GLubyte *dstRow = dstSlices[dstZoffset + img]
1051 + dstYoffset * dstRowStride
1052 + dstXoffset * texelBytes;
1053 for (row = 0; row < srcHeight; row++) {
1054 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1055 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1056 _mesa_unpack_depth_span(ctx, srcWidth,
1057 GL_UNSIGNED_INT, (GLuint *) dstRow,
1058 depthScale, srcType, src, srcPacking);
1059 dstRow += dstRowStride;
1068 * Store a 24-bit integer depth component texture image.
1071 _mesa_texstore_z24_x8(TEXSTORE_PARAMS)
1073 const GLuint depthScale = 0xffffff;
1074 const GLuint texelBytes = 4;
1077 ASSERT(dstFormat == MESA_FORMAT_Z24_X8);
1082 for (img = 0; img < srcDepth; img++) {
1083 GLubyte *dstRow = dstSlices[dstZoffset + img]
1084 + dstYoffset * dstRowStride
1085 + dstXoffset * texelBytes;
1086 for (row = 0; row < srcHeight; row++) {
1087 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1088 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1089 GLuint *dst = (GLuint *) dstRow;
1091 _mesa_unpack_depth_span(ctx, srcWidth,
1092 GL_UNSIGNED_INT, dst,
1093 depthScale, srcType, src, srcPacking);
1094 for (i = 0; i < srcWidth; i++)
1096 dstRow += dstRowStride;
1105 * Store a 16-bit integer depth component texture image.
1108 _mesa_texstore_z16(TEXSTORE_PARAMS)
1110 const GLuint depthScale = 0xffff;
1111 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1113 ASSERT(dstFormat == MESA_FORMAT_Z16);
1114 ASSERT(texelBytes == sizeof(GLushort));
1116 if (ctx->Pixel.DepthScale == 1.0f &&
1117 ctx->Pixel.DepthBias == 0.0f &&
1118 !srcPacking->SwapBytes &&
1119 baseInternalFormat == GL_DEPTH_COMPONENT &&
1120 srcFormat == GL_DEPTH_COMPONENT &&
1121 srcType == GL_UNSIGNED_SHORT) {
1122 /* simple memcpy path */
1123 memcpy_texture(ctx, dims,
1124 dstFormat, dstXoffset, dstYoffset, dstZoffset,
1125 dstRowStride, dstSlices,
1126 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1127 srcAddr, srcPacking);
1132 for (img = 0; img < srcDepth; img++) {
1133 GLubyte *dstRow = dstSlices[dstZoffset + img]
1134 + dstYoffset * dstRowStride
1135 + dstXoffset * texelBytes;
1136 for (row = 0; row < srcHeight; row++) {
1137 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1138 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1139 GLushort *dst16 = (GLushort *) dstRow;
1140 _mesa_unpack_depth_span(ctx, srcWidth,
1141 GL_UNSIGNED_SHORT, dst16, depthScale,
1142 srcType, src, srcPacking);
1143 dstRow += dstRowStride;
1152 * Store an rgb565 or rgb565_rev texture image.
1155 _mesa_texstore_rgb565(TEXSTORE_PARAMS)
1157 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1158 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1160 ASSERT(dstFormat == MESA_FORMAT_RGB565 ||
1161 dstFormat == MESA_FORMAT_RGB565_REV);
1162 ASSERT(texelBytes == 2);
1164 if (!ctx->_ImageTransferState &&
1165 !srcPacking->SwapBytes &&
1166 dstFormat == MESA_FORMAT_RGB565 &&
1167 baseInternalFormat == GL_RGB &&
1168 srcFormat == GL_RGB &&
1169 srcType == GL_UNSIGNED_SHORT_5_6_5) {
1170 /* simple memcpy path */
1171 memcpy_texture(ctx, dims,
1172 dstFormat, dstXoffset, dstYoffset, dstZoffset,
1173 dstRowStride, dstSlices,
1174 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1175 srcAddr, srcPacking);
1177 else if (!ctx->_ImageTransferState &&
1178 !srcPacking->SwapBytes &&
1179 baseInternalFormat == GL_RGB &&
1180 srcFormat == GL_RGB &&
1181 srcType == GL_UNSIGNED_BYTE &&
1183 /* do optimized tex store */
1184 const GLint srcRowStride =
1185 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1186 const GLubyte *src = (const GLubyte *)
1187 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
1188 srcFormat, srcType, 0, 0, 0);
1189 GLubyte *dst = dstSlices[0]
1190 + dstYoffset * dstRowStride
1191 + dstXoffset * texelBytes;
1193 for (row = 0; row < srcHeight; row++) {
1194 const GLubyte *srcUB = (const GLubyte *) src;
1195 GLushort *dstUS = (GLushort *) dst;
1196 /* check for byteswapped format */
1197 if (dstFormat == MESA_FORMAT_RGB565) {
1198 for (col = 0; col < srcWidth; col++) {
1199 dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
1204 for (col = 0; col < srcWidth; col++) {
1205 dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
1209 dst += dstRowStride;
1210 src += srcRowStride;
1215 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1218 srcWidth, srcHeight, srcDepth,
1219 srcFormat, srcType, srcAddr,
1221 const GLubyte *src = tempImage;
1222 GLint img, row, col;
1225 for (img = 0; img < srcDepth; img++) {
1226 GLubyte *dstRow = dstSlices[dstZoffset + img]
1227 + dstYoffset * dstRowStride
1228 + dstXoffset * texelBytes;
1229 for (row = 0; row < srcHeight; row++) {
1230 GLushort *dstUS = (GLushort *) dstRow;
1231 /* check for byteswapped format */
1232 if (dstFormat == MESA_FORMAT_RGB565) {
1233 for (col = 0; col < srcWidth; col++) {
1234 dstUS[col] = PACK_COLOR_565( src[RCOMP],
1241 for (col = 0; col < srcWidth; col++) {
1242 dstUS[col] = PACK_COLOR_565_REV( src[RCOMP],
1248 dstRow += dstRowStride;
1251 free((void *) tempImage);
1258 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1261 _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
1263 const GLboolean littleEndian = _mesa_little_endian();
1264 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1265 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1267 ASSERT(dstFormat == MESA_FORMAT_RGBA8888 ||
1268 dstFormat == MESA_FORMAT_RGBA8888_REV ||
1269 dstFormat == MESA_FORMAT_RGBX8888 ||
1270 dstFormat == MESA_FORMAT_RGBX8888_REV);
1271 ASSERT(texelBytes == 4);
1273 if (!ctx->_ImageTransferState &&
1274 !srcPacking->SwapBytes &&
1275 (dstFormat == MESA_FORMAT_RGBA8888 ||
1276 dstFormat == MESA_FORMAT_RGBX8888) &&
1277 baseInternalFormat == GL_RGBA &&
1278 ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1279 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1280 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
1281 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian))) {
1282 /* simple memcpy path */
1283 memcpy_texture(ctx, dims,
1284 dstFormat, dstXoffset, dstYoffset, dstZoffset,
1285 dstRowStride, dstSlices,
1286 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1287 srcAddr, srcPacking);
1289 else if (!ctx->_ImageTransferState &&
1290 !srcPacking->SwapBytes &&
1291 (dstFormat == MESA_FORMAT_RGBA8888_REV ||
1292 dstFormat == MESA_FORMAT_RGBX8888_REV) &&
1293 baseInternalFormat == GL_RGBA &&
1294 ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
1295 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1296 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1297 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian))) {
1298 /* simple memcpy path */
1299 memcpy_texture(ctx, dims,
1300 dstFormat, dstXoffset, dstYoffset, dstZoffset,
1301 dstRowStride, dstSlices,
1302 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1303 srcAddr, srcPacking);
1305 else if (!ctx->_ImageTransferState &&
1306 (srcType == GL_UNSIGNED_BYTE ||
1307 srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1308 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1309 can_swizzle(baseInternalFormat) &&
1310 can_swizzle(srcFormat)) {
1314 /* dstmap - how to swizzle from RGBA to dst format:
1316 if ((littleEndian && (dstFormat == MESA_FORMAT_RGBA8888 ||
1317 dstFormat == MESA_FORMAT_RGBX8888)) ||
1318 (!littleEndian && (dstFormat == MESA_FORMAT_RGBA8888_REV ||
1319 dstFormat == MESA_FORMAT_RGBX8888_REV))) {
1332 _mesa_swizzle_ubyte_image(ctx, dims,
1337 dstXoffset, dstYoffset, dstZoffset,
1338 dstRowStride, dstSlices,
1339 srcWidth, srcHeight, srcDepth, srcAddr,
1344 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1347 srcWidth, srcHeight, srcDepth,
1348 srcFormat, srcType, srcAddr,
1350 const GLubyte *src = tempImage;
1351 GLint img, row, col;
1354 for (img = 0; img < srcDepth; img++) {
1355 GLubyte *dstRow = dstSlices[dstZoffset + img]
1356 + dstYoffset * dstRowStride
1357 + dstXoffset * texelBytes;
1358 for (row = 0; row < srcHeight; row++) {
1359 GLuint *dstUI = (GLuint *) dstRow;
1360 if (dstFormat == MESA_FORMAT_RGBA8888 ||
1361 dstFormat == MESA_FORMAT_RGBX8888) {
1362 for (col = 0; col < srcWidth; col++) {
1363 dstUI[col] = PACK_COLOR_8888( src[RCOMP],
1371 for (col = 0; col < srcWidth; col++) {
1372 dstUI[col] = PACK_COLOR_8888_REV( src[RCOMP],
1379 dstRow += dstRowStride;
1382 free((void *) tempImage);
1389 _mesa_texstore_argb8888(TEXSTORE_PARAMS)
1391 const GLboolean littleEndian = _mesa_little_endian();
1392 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1393 const GLenum baseFormat = GL_RGBA;
1395 ASSERT(dstFormat == MESA_FORMAT_ARGB8888 ||
1396 dstFormat == MESA_FORMAT_ARGB8888_REV ||
1397 dstFormat == MESA_FORMAT_XRGB8888 ||
1398 dstFormat == MESA_FORMAT_XRGB8888_REV );
1399 ASSERT(texelBytes == 4);
1401 if (!ctx->_ImageTransferState &&
1402 !srcPacking->SwapBytes &&
1403 (dstFormat == MESA_FORMAT_ARGB8888 ||
1404 dstFormat == MESA_FORMAT_XRGB8888) &&
1405 baseInternalFormat == GL_RGBA &&
1406 srcFormat == GL_BGRA &&
1407 ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1408 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
1409 /* simple memcpy path (little endian) */
1410 memcpy_texture(ctx, dims,
1411 dstFormat, dstXoffset, dstYoffset, dstZoffset,
1412 dstRowStride, dstSlices,
1413 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1414 srcAddr, srcPacking);
1416 else if (!ctx->_ImageTransferState &&
1417 !srcPacking->SwapBytes &&
1418 (dstFormat == MESA_FORMAT_ARGB8888_REV ||
1419 dstFormat == MESA_FORMAT_XRGB8888_REV) &&
1420 baseInternalFormat == GL_RGBA &&
1421 srcFormat == GL_BGRA &&
1422 ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1423 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
1424 /* simple memcpy path (big endian) */
1425 memcpy_texture(ctx, dims,
1426 dstFormat, dstXoffset, dstYoffset, dstZoffset,
1427 dstRowStride, dstSlices,
1428 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1429 srcAddr, srcPacking);
1431 else if (!ctx->_ImageTransferState &&
1432 !srcPacking->SwapBytes &&
1433 (dstFormat == MESA_FORMAT_ARGB8888 ||
1434 dstFormat == MESA_FORMAT_XRGB8888) &&
1435 srcFormat == GL_RGB &&
1436 (baseInternalFormat == GL_RGBA ||
1437 baseInternalFormat == GL_RGB) &&
1438 srcType == GL_UNSIGNED_BYTE) {
1440 for (img = 0; img < srcDepth; img++) {
1441 const GLint srcRowStride =
1442 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1443 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1444 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1445 GLubyte *dstRow = dstSlices[dstZoffset + img]
1446 + dstYoffset * dstRowStride
1447 + dstXoffset * texelBytes;
1448 for (row = 0; row < srcHeight; row++) {
1449 GLuint *d4 = (GLuint *) dstRow;
1450 for (col = 0; col < srcWidth; col++) {
1451 d4[col] = PACK_COLOR_8888(0xff,
1452 srcRow[col * 3 + RCOMP],
1453 srcRow[col * 3 + GCOMP],
1454 srcRow[col * 3 + BCOMP]);
1456 dstRow += dstRowStride;
1457 srcRow += srcRowStride;
1461 else if (!ctx->_ImageTransferState &&
1462 !srcPacking->SwapBytes &&
1463 dstFormat == MESA_FORMAT_ARGB8888 &&
1464 srcFormat == GL_RGBA &&
1465 baseInternalFormat == GL_RGBA &&
1466 srcType == GL_UNSIGNED_BYTE) {
1467 /* same as above case, but src data has alpha too */
1468 GLint img, row, col;
1469 /* For some reason, streaming copies to write-combined regions
1470 * are extremely sensitive to the characteristics of how the
1471 * source data is retrieved. By reordering the source reads to
1472 * be in-order, the speed of this operation increases by half.
1473 * Strangely the same isn't required for the RGB path, above.
1475 for (img = 0; img < srcDepth; img++) {
1476 const GLint srcRowStride =
1477 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1478 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1479 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1480 GLubyte *dstRow = dstSlices[dstZoffset + img]
1481 + dstYoffset * dstRowStride
1482 + dstXoffset * texelBytes;
1483 for (row = 0; row < srcHeight; row++) {
1484 GLuint *d4 = (GLuint *) dstRow;
1485 for (col = 0; col < srcWidth; col++) {
1486 d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
1487 srcRow[col * 4 + RCOMP],
1488 srcRow[col * 4 + GCOMP],
1489 srcRow[col * 4 + BCOMP]);
1491 dstRow += dstRowStride;
1492 srcRow += srcRowStride;
1496 else if (!ctx->_ImageTransferState &&
1497 (srcType == GL_UNSIGNED_BYTE ||
1498 srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1499 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1500 can_swizzle(baseInternalFormat) &&
1501 can_swizzle(srcFormat)) {
1505 /* dstmap - how to swizzle from RGBA to dst format:
1507 if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
1508 (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
1509 (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
1510 (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) {
1511 dstmap[3] = 3; /* alpha */
1512 dstmap[2] = 0; /* red */
1513 dstmap[1] = 1; /* green */
1514 dstmap[0] = 2; /* blue */
1517 assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
1518 (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
1519 (littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) ||
1520 (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
1527 _mesa_swizzle_ubyte_image(ctx, dims,
1532 dstXoffset, dstYoffset, dstZoffset,
1535 srcWidth, srcHeight, srcDepth, srcAddr,
1540 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1543 srcWidth, srcHeight, srcDepth,
1544 srcFormat, srcType, srcAddr,
1546 const GLubyte *src = tempImage;
1547 GLint img, row, col;
1550 for (img = 0; img < srcDepth; img++) {
1551 GLubyte *dstRow = dstSlices[dstZoffset + img]
1552 + dstYoffset * dstRowStride
1553 + dstXoffset * texelBytes;
1554 for (row = 0; row < srcHeight; row++) {
1555 GLuint *dstUI = (GLuint *) dstRow;
1556 if (dstFormat == MESA_FORMAT_ARGB8888) {
1557 for (col = 0; col < srcWidth; col++) {
1558 dstUI[col] = PACK_COLOR_8888( src[ACOMP],
1565 else if (dstFormat == MESA_FORMAT_XRGB8888) {
1566 for (col = 0; col < srcWidth; col++) {
1567 dstUI[col] = PACK_COLOR_8888( 0xff,
1575 for (col = 0; col < srcWidth; col++) {
1576 dstUI[col] = PACK_COLOR_8888_REV( src[ACOMP],
1583 dstRow += dstRowStride;
1586 free((void *) tempImage);
1593 _mesa_texstore_rgb888(TEXSTORE_PARAMS)
1595 const GLboolean littleEndian = _mesa_little_endian();
1596 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1597 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1599 ASSERT(dstFormat == MESA_FORMAT_RGB888);
1600 ASSERT(texelBytes == 3);
1602 if (!ctx->_ImageTransferState &&
1603 !srcPacking->SwapBytes &&
1604 baseInternalFormat == GL_RGB &&
1605 srcFormat == GL_BGR &&
1606 srcType == GL_UNSIGNED_BYTE &&
1608 /* simple memcpy path */
1609 memcpy_texture(ctx, dims,
1610 dstFormat, dstXoffset, dstYoffset, dstZoffset,
1611 dstRowStride, dstSlices,
1612 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1613 srcAddr, srcPacking);
1615 else if (!ctx->_ImageTransferState &&
1616 !srcPacking->SwapBytes &&
1617 srcFormat == GL_RGBA &&
1618 srcType == GL_UNSIGNED_BYTE) {
1619 /* extract RGB from RGBA */
1620 GLint img, row, col;
1621 for (img = 0; img < srcDepth; img++) {
1622 const GLint srcRowStride =
1623 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1624 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1625 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1626 GLubyte *dstRow = dstSlices[dstZoffset + img]
1627 + dstYoffset * dstRowStride
1628 + dstXoffset * texelBytes;
1629 for (row = 0; row < srcHeight; row++) {
1630 for (col = 0; col < srcWidth; col++) {
1631 dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1632 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1633 dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1635 dstRow += dstRowStride;
1636 srcRow += srcRowStride;
1640 else if (!ctx->_ImageTransferState &&
1641 srcType == GL_UNSIGNED_BYTE &&
1642 can_swizzle(baseInternalFormat) &&
1643 can_swizzle(srcFormat)) {
1647 /* dstmap - how to swizzle from RGBA to dst format:
1652 dstmap[3] = ONE; /* ? */
1654 _mesa_swizzle_ubyte_image(ctx, dims,
1659 dstXoffset, dstYoffset, dstZoffset,
1660 dstRowStride, dstSlices,
1661 srcWidth, srcHeight, srcDepth, srcAddr,
1666 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1669 srcWidth, srcHeight, srcDepth,
1670 srcFormat, srcType, srcAddr,
1672 const GLubyte *src = (const GLubyte *) tempImage;
1673 GLint img, row, col;
1676 for (img = 0; img < srcDepth; img++) {
1677 GLubyte *dstRow = dstSlices[dstZoffset + img]
1678 + dstYoffset * dstRowStride
1679 + dstXoffset * texelBytes;
1680 for (row = 0; row < srcHeight; row++) {
1683 for (col = 0; col < srcWidth; col++) {
1684 dstRow[col * 3 + 0] = src[RCOMP];
1685 dstRow[col * 3 + 1] = src[GCOMP];
1686 dstRow[col * 3 + 2] = src[BCOMP];
1691 for (col = 0; col < srcWidth; col++) {
1692 dstRow[col * 3 + 0] = srcUB[BCOMP];
1693 dstRow[col * 3 + 1] = srcUB[GCOMP];
1694 dstRow[col * 3 + 2] = srcUB[RCOMP];
1699 for (col = 0; col < srcWidth; col++) {
1700 dstRow[col * 3 + 0] = src[BCOMP];
1701 dstRow[col * 3 + 1] = src[GCOMP];
1702 dstRow[col * 3 + 2] = src[RCOMP];
1706 dstRow += dstRowStride;
1709 free((void *) tempImage);
1716 _mesa_texstore_bgr888(TEXSTORE_PARAMS)
1718 const GLboolean littleEndian = _mesa_little_endian();
1719 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1720 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1722 ASSERT(dstFormat == MESA_FORMAT_BGR888);
1723 ASSERT(texelBytes == 3);
1725 if (!ctx->_ImageTransferState &&
1726 !srcPacking->SwapBytes &&
1727 baseInternalFormat == GL_RGB &&
1728 srcFormat == GL_RGB &&
1729 srcType == GL_UNSIGNED_BYTE &&
1731 /* simple memcpy path */
1732 memcpy_texture(ctx, dims,
1733 dstFormat, dstXoffset, dstYoffset, dstZoffset,
1734 dstRowStride, dstSlices,
1735 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1736 srcAddr, srcPacking);
1738 else if (!ctx->_ImageTransferState &&
1739 !srcPacking->SwapBytes &&
1740 srcFormat == GL_RGBA &&
1741 srcType == GL_UNSIGNED_BYTE) {
1742 /* extract BGR from RGBA */
1744 for (img = 0; img < srcDepth; img++) {
1745 const GLint srcRowStride =
1746 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1747 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1748 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1749 GLubyte *dstRow = dstSlices[dstZoffset + img]
1750 + dstYoffset * dstRowStride
1751 + dstXoffset * texelBytes;
1752 for (row = 0; row < srcHeight; row++) {
1753 for (col = 0; col < srcWidth; col++) {
1754 dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1755 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1756 dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1758 dstRow += dstRowStride;
1759 srcRow += srcRowStride;
1763 else if (!ctx->_ImageTransferState &&
1764 srcType == GL_UNSIGNED_BYTE &&
1765 can_swizzle(baseInternalFormat) &&
1766 can_swizzle(srcFormat)) {
1770 /* dstmap - how to swizzle from RGBA to dst format:
1775 dstmap[3] = ONE; /* ? */
1777 _mesa_swizzle_ubyte_image(ctx, dims,
1782 dstXoffset, dstYoffset, dstZoffset,
1783 dstRowStride, dstSlices,
1784 srcWidth, srcHeight, srcDepth, srcAddr,
1789 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1792 srcWidth, srcHeight, srcDepth,
1793 srcFormat, srcType, srcAddr,
1795 const GLubyte *src = (const GLubyte *) tempImage;
1796 GLint img, row, col;
1799 for (img = 0; img < srcDepth; img++) {
1800 GLubyte *dstRow = dstSlices[dstZoffset + img]
1801 + dstYoffset * dstRowStride
1802 + dstXoffset * texelBytes;
1803 for (row = 0; row < srcHeight; row++) {
1804 for (col = 0; col < srcWidth; col++) {
1805 dstRow[col * 3 + 0] = src[RCOMP];
1806 dstRow[col * 3 + 1] = src[GCOMP];
1807 dstRow[col * 3 + 2] = src[BCOMP];
1810 dstRow += dstRowStride;
1813 free((void *) tempImage);
1820 _mesa_texstore_argb4444(TEXSTORE_PARAMS)
1822 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1823 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1825 ASSERT(dstFormat == MESA_FORMAT_ARGB4444 ||
1826 dstFormat == MESA_FORMAT_ARGB4444_REV);
1827 ASSERT(texelBytes == 2);
1829 if (!ctx->_ImageTransferState &&
1830 !srcPacking->SwapBytes &&
1831 dstFormat == MESA_FORMAT_ARGB4444 &&
1832 baseInternalFormat == GL_RGBA &&
1833 srcFormat == GL_BGRA &&
1834 srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
1835 /* simple memcpy path */
1836 memcpy_texture(ctx, dims,
1837 dstFormat, dstXoffset, dstYoffset, dstZoffset,
1838 dstRowStride, dstSlices,
1839 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1840 srcAddr, srcPacking);
1844 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1847 srcWidth, srcHeight, srcDepth,
1848 srcFormat, srcType, srcAddr,
1850 const GLubyte *src = tempImage;
1851 GLint img, row, col;
1854 for (img = 0; img < srcDepth; img++) {
1855 GLubyte *dstRow = dstSlices[dstZoffset + img]
1856 + dstYoffset * dstRowStride
1857 + dstXoffset * texelBytes;
1858 for (row = 0; row < srcHeight; row++) {
1859 GLushort *dstUS = (GLushort *) dstRow;
1860 if (dstFormat == MESA_FORMAT_ARGB4444) {
1861 for (col = 0; col < srcWidth; col++) {
1862 dstUS[col] = PACK_COLOR_4444( src[ACOMP],
1870 for (col = 0; col < srcWidth; col++) {
1871 dstUS[col] = PACK_COLOR_4444_REV( src[ACOMP],
1878 dstRow += dstRowStride;
1881 free((void *) tempImage);
1887 _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
1889 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1890 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1892 ASSERT(dstFormat == MESA_FORMAT_RGBA5551);
1893 ASSERT(texelBytes == 2);
1895 if (!ctx->_ImageTransferState &&
1896 !srcPacking->SwapBytes &&
1897 dstFormat == MESA_FORMAT_RGBA5551 &&
1898 baseInternalFormat == GL_RGBA &&
1899 srcFormat == GL_RGBA &&
1900 srcType == GL_UNSIGNED_SHORT_5_5_5_1) {
1901 /* simple memcpy path */
1902 memcpy_texture(ctx, dims,
1903 dstFormat, dstXoffset, dstYoffset, dstZoffset,
1904 dstRowStride, dstSlices,
1905 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1906 srcAddr, srcPacking);
1910 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1913 srcWidth, srcHeight, srcDepth,
1914 srcFormat, srcType, srcAddr,
1916 const GLubyte *src =tempImage;
1917 GLint img, row, col;
1920 for (img = 0; img < srcDepth; img++) {
1921 GLubyte *dstRow = dstSlices[dstZoffset + img]
1922 + dstYoffset * dstRowStride
1923 + dstXoffset * texelBytes;
1924 for (row = 0; row < srcHeight; row++) {
1925 GLushort *dstUS = (GLushort *) dstRow;
1926 for (col = 0; col < srcWidth; col++) {
1927 dstUS[col] = PACK_COLOR_5551( src[RCOMP],
1933 dstRow += dstRowStride;
1936 free((void *) tempImage);
1942 _mesa_texstore_argb1555(TEXSTORE_PARAMS)
1944 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1945 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1947 ASSERT(dstFormat == MESA_FORMAT_ARGB1555 ||
1948 dstFormat == MESA_FORMAT_ARGB1555_REV);
1949 ASSERT(texelBytes == 2);
1951 if (!ctx->_ImageTransferState &&
1952 !srcPacking->SwapBytes &&
1953 dstFormat == MESA_FORMAT_ARGB1555 &&
1954 baseInternalFormat == GL_RGBA &&
1955 srcFormat == GL_BGRA &&
1956 srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
1957 /* simple memcpy path */
1958 memcpy_texture(ctx, dims,
1959 dstFormat, dstXoffset, dstYoffset, dstZoffset,
1960 dstRowStride, dstSlices,
1961 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1962 srcAddr, srcPacking);
1966 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1969 srcWidth, srcHeight, srcDepth,
1970 srcFormat, srcType, srcAddr,
1972 const GLubyte *src =tempImage;
1973 GLint img, row, col;
1976 for (img = 0; img < srcDepth; img++) {
1977 GLubyte *dstRow = dstSlices[dstZoffset + img]
1978 + dstYoffset * dstRowStride
1979 + dstXoffset * texelBytes;
1980 for (row = 0; row < srcHeight; row++) {
1981 GLushort *dstUS = (GLushort *) dstRow;
1982 if (dstFormat == MESA_FORMAT_ARGB1555) {
1983 for (col = 0; col < srcWidth; col++) {
1984 dstUS[col] = PACK_COLOR_1555( src[ACOMP],
1992 for (col = 0; col < srcWidth; col++) {
1993 dstUS[col] = PACK_COLOR_1555_REV( src[ACOMP],
2000 dstRow += dstRowStride;
2003 free((void *) tempImage);
2010 _mesa_texstore_argb2101010(TEXSTORE_PARAMS)
2012 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2013 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2015 ASSERT(dstFormat == MESA_FORMAT_ARGB2101010);
2016 ASSERT(texelBytes == 4);
2018 if (!ctx->_ImageTransferState &&
2019 !srcPacking->SwapBytes &&
2020 dstFormat == MESA_FORMAT_ARGB2101010 &&
2021 srcFormat == GL_BGRA &&
2022 srcType == GL_UNSIGNED_INT_2_10_10_10_REV &&
2023 baseInternalFormat == GL_RGBA) {
2024 /* simple memcpy path */
2025 memcpy_texture(ctx, dims,
2026 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2027 dstRowStride, dstSlices,
2028 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2029 srcAddr, srcPacking);
2033 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2036 srcWidth, srcHeight, srcDepth,
2037 srcFormat, srcType, srcAddr,
2039 ctx->_ImageTransferState);
2040 const GLfloat *src = tempImage;
2041 GLint img, row, col;
2044 for (img = 0; img < srcDepth; img++) {
2045 GLubyte *dstRow = dstSlices[dstZoffset + img]
2046 + dstYoffset * dstRowStride
2047 + dstXoffset * texelBytes;
2048 if (baseInternalFormat == GL_RGBA) {
2049 for (row = 0; row < srcHeight; row++) {
2050 GLuint *dstUI = (GLuint *) dstRow;
2051 for (col = 0; col < srcWidth; col++) {
2054 UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
2055 UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
2056 UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
2057 UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
2058 dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b);
2061 dstRow += dstRowStride;
2063 } else if (baseInternalFormat == GL_RGB) {
2064 for (row = 0; row < srcHeight; row++) {
2065 GLuint *dstUI = (GLuint *) dstRow;
2066 for (col = 0; col < srcWidth; col++) {
2069 UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
2070 UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
2071 UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
2072 dstUI[col] = PACK_COLOR_2101010_US(0xffff, r, g, b);
2075 dstRow += dstRowStride;
2081 free((void *) tempImage);
2088 * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats.
2091 _mesa_texstore_unorm44(TEXSTORE_PARAMS)
2093 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2094 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2096 ASSERT(dstFormat == MESA_FORMAT_AL44);
2097 ASSERT(texelBytes == 1);
2101 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
2104 srcWidth, srcHeight, srcDepth,
2105 srcFormat, srcType, srcAddr,
2107 const GLubyte *src = tempImage;
2108 GLint img, row, col;
2111 for (img = 0; img < srcDepth; img++) {
2112 GLubyte *dstRow = dstSlices[dstZoffset + img]
2113 + dstYoffset * dstRowStride
2114 + dstXoffset * texelBytes;
2115 for (row = 0; row < srcHeight; row++) {
2116 GLubyte *dstUS = (GLubyte *) dstRow;
2117 for (col = 0; col < srcWidth; col++) {
2118 /* src[0] is luminance, src[1] is alpha */
2119 dstUS[col] = PACK_COLOR_44( src[1],
2123 dstRow += dstRowStride;
2126 free((void *) tempImage);
2133 * Do texstore for 2-channel, 8-bit/channel, unsigned normalized formats.
2136 _mesa_texstore_unorm88(TEXSTORE_PARAMS)
2138 const GLboolean littleEndian = _mesa_little_endian();
2139 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2140 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2142 ASSERT(dstFormat == MESA_FORMAT_AL88 ||
2143 dstFormat == MESA_FORMAT_AL88_REV ||
2144 dstFormat == MESA_FORMAT_GR88 ||
2145 dstFormat == MESA_FORMAT_RG88);
2146 ASSERT(texelBytes == 2);
2148 if (!ctx->_ImageTransferState &&
2149 !srcPacking->SwapBytes &&
2150 ((dstFormat == MESA_FORMAT_AL88 &&
2151 baseInternalFormat == GL_LUMINANCE_ALPHA &&
2152 srcFormat == GL_LUMINANCE_ALPHA) ||
2153 (dstFormat == MESA_FORMAT_GR88 &&
2154 baseInternalFormat == srcFormat)) &&
2155 srcType == GL_UNSIGNED_BYTE &&
2157 /* simple memcpy path */
2158 memcpy_texture(ctx, dims,
2159 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2160 dstRowStride, dstSlices,
2161 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2162 srcAddr, srcPacking);
2164 else if (!ctx->_ImageTransferState &&
2166 srcType == GL_UNSIGNED_BYTE &&
2167 can_swizzle(baseInternalFormat) &&
2168 can_swizzle(srcFormat)) {
2171 /* dstmap - how to swizzle from RGBA to dst format:
2173 if (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_AL88_REV) {
2174 if ((littleEndian && dstFormat == MESA_FORMAT_AL88) ||
2175 (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) {
2185 if ((littleEndian && dstFormat == MESA_FORMAT_GR88) ||
2186 (!littleEndian && dstFormat == MESA_FORMAT_RG88)) {
2195 dstmap[2] = ZERO; /* ? */
2196 dstmap[3] = ONE; /* ? */
2198 _mesa_swizzle_ubyte_image(ctx, dims,
2203 dstXoffset, dstYoffset, dstZoffset,
2204 dstRowStride, dstSlices,
2205 srcWidth, srcHeight, srcDepth, srcAddr,
2210 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
2213 srcWidth, srcHeight, srcDepth,
2214 srcFormat, srcType, srcAddr,
2216 const GLubyte *src = tempImage;
2217 GLint img, row, col;
2220 for (img = 0; img < srcDepth; img++) {
2221 GLubyte *dstRow = dstSlices[dstZoffset + img]
2222 + dstYoffset * dstRowStride
2223 + dstXoffset * texelBytes;
2224 for (row = 0; row < srcHeight; row++) {
2225 GLushort *dstUS = (GLushort *) dstRow;
2226 if (dstFormat == MESA_FORMAT_AL88 ||
2227 dstFormat == MESA_FORMAT_GR88) {
2228 for (col = 0; col < srcWidth; col++) {
2229 /* src[0] is luminance (or R), src[1] is alpha (or G) */
2230 dstUS[col] = PACK_COLOR_88( src[1],
2236 for (col = 0; col < srcWidth; col++) {
2237 /* src[0] is luminance (or R), src[1] is alpha (or G) */
2238 dstUS[col] = PACK_COLOR_88_REV( src[1],
2243 dstRow += dstRowStride;
2246 free((void *) tempImage);
2253 * Do texstore for 2-channel, 16-bit/channel, unsigned normalized formats.
2256 _mesa_texstore_unorm1616(TEXSTORE_PARAMS)
2258 const GLboolean littleEndian = _mesa_little_endian();
2259 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2260 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2262 ASSERT(dstFormat == MESA_FORMAT_AL1616 ||
2263 dstFormat == MESA_FORMAT_AL1616_REV ||
2264 dstFormat == MESA_FORMAT_RG1616 ||
2265 dstFormat == MESA_FORMAT_RG1616_REV);
2266 ASSERT(texelBytes == 4);
2268 if (!ctx->_ImageTransferState &&
2269 !srcPacking->SwapBytes &&
2270 ((dstFormat == MESA_FORMAT_AL1616 &&
2271 baseInternalFormat == GL_LUMINANCE_ALPHA &&
2272 srcFormat == GL_LUMINANCE_ALPHA) ||
2273 (dstFormat == MESA_FORMAT_RG1616 &&
2274 baseInternalFormat == srcFormat)) &&
2275 srcType == GL_UNSIGNED_SHORT &&
2277 /* simple memcpy path */
2278 memcpy_texture(ctx, dims,
2279 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2280 dstRowStride, dstSlices,
2281 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2282 srcAddr, srcPacking);
2286 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2289 srcWidth, srcHeight, srcDepth,
2290 srcFormat, srcType, srcAddr,
2292 ctx->_ImageTransferState);
2293 const GLfloat *src = tempImage;
2294 GLint img, row, col;
2297 for (img = 0; img < srcDepth; img++) {
2298 GLubyte *dstRow = dstSlices[dstZoffset + img]
2299 + dstYoffset * dstRowStride
2300 + dstXoffset * texelBytes;
2301 for (row = 0; row < srcHeight; row++) {
2302 GLuint *dstUI = (GLuint *) dstRow;
2303 if (dstFormat == MESA_FORMAT_AL1616 ||
2304 dstFormat == MESA_FORMAT_RG1616) {
2305 for (col = 0; col < srcWidth; col++) {
2308 UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
2309 UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
2310 dstUI[col] = PACK_COLOR_1616(a, l);
2315 for (col = 0; col < srcWidth; col++) {
2318 UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
2319 UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
2320 dstUI[col] = PACK_COLOR_1616_REV(a, l);
2324 dstRow += dstRowStride;
2327 free((void *) tempImage);
2333 /* Texstore for R16, A16, L16, I16. */
2335 _mesa_texstore_unorm16(TEXSTORE_PARAMS)
2337 const GLboolean littleEndian = _mesa_little_endian();
2338 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2339 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2341 ASSERT(dstFormat == MESA_FORMAT_R16 ||
2342 dstFormat == MESA_FORMAT_A16 ||
2343 dstFormat == MESA_FORMAT_L16 ||
2344 dstFormat == MESA_FORMAT_I16);
2345 ASSERT(texelBytes == 2);
2347 if (!ctx->_ImageTransferState &&
2348 !srcPacking->SwapBytes &&
2349 baseInternalFormat == srcFormat &&
2350 srcType == GL_UNSIGNED_SHORT &&
2352 /* simple memcpy path */
2353 memcpy_texture(ctx, dims,
2354 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2355 dstRowStride, dstSlices,
2356 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2357 srcAddr, srcPacking);
2361 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2364 srcWidth, srcHeight, srcDepth,
2365 srcFormat, srcType, srcAddr,
2367 ctx->_ImageTransferState);
2368 const GLfloat *src = tempImage;
2369 GLint img, row, col;
2372 for (img = 0; img < srcDepth; img++) {
2373 GLubyte *dstRow = dstSlices[dstZoffset + img]
2374 + dstYoffset * dstRowStride
2375 + dstXoffset * texelBytes;
2376 for (row = 0; row < srcHeight; row++) {
2377 GLushort *dstUS = (GLushort *) dstRow;
2378 for (col = 0; col < srcWidth; col++) {
2381 UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
2385 dstRow += dstRowStride;
2388 free((void *) tempImage);
2395 _mesa_texstore_rgba_16(TEXSTORE_PARAMS)
2397 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2398 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2400 ASSERT(dstFormat == MESA_FORMAT_RGBA_16);
2401 ASSERT(texelBytes == 8);
2403 if (!ctx->_ImageTransferState &&
2404 !srcPacking->SwapBytes &&
2405 baseInternalFormat == GL_RGBA &&
2406 srcFormat == GL_RGBA &&
2407 srcType == GL_UNSIGNED_SHORT) {
2408 /* simple memcpy path */
2409 memcpy_texture(ctx, dims,
2410 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2411 dstRowStride, dstSlices,
2412 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2413 srcAddr, srcPacking);
2417 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2420 srcWidth, srcHeight, srcDepth,
2421 srcFormat, srcType, srcAddr,
2423 ctx->_ImageTransferState);
2424 const GLfloat *src = tempImage;
2425 GLint img, row, col;
2428 for (img = 0; img < srcDepth; img++) {
2429 GLubyte *dstRow = dstSlices[dstZoffset + img]
2430 + dstYoffset * dstRowStride
2431 + dstXoffset * texelBytes;
2432 for (row = 0; row < srcHeight; row++) {
2433 GLushort *dstUS = (GLushort *) dstRow;
2434 for (col = 0; col < srcWidth; col++) {
2435 GLushort r, g, b, a;
2437 UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
2438 UNCLAMPED_FLOAT_TO_USHORT(g, src[1]);
2439 UNCLAMPED_FLOAT_TO_USHORT(b, src[2]);
2440 UNCLAMPED_FLOAT_TO_USHORT(a, src[3]);
2447 dstRow += dstRowStride;
2450 free((void *) tempImage);
2457 _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS)
2459 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2460 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2462 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGB_16 ||
2463 dstFormat == MESA_FORMAT_SIGNED_RGBA_16);
2465 if (!ctx->_ImageTransferState &&
2466 !srcPacking->SwapBytes &&
2467 baseInternalFormat == GL_RGBA &&
2468 dstFormat == MESA_FORMAT_SIGNED_RGBA_16 &&
2469 srcFormat == GL_RGBA &&
2470 srcType == GL_SHORT) {
2471 /* simple memcpy path */
2472 memcpy_texture(ctx, dims,
2473 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2474 dstRowStride, dstSlices,
2475 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2476 srcAddr, srcPacking);
2480 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2483 srcWidth, srcHeight, srcDepth,
2484 srcFormat, srcType, srcAddr,
2486 ctx->_ImageTransferState);
2487 const GLfloat *src = tempImage;
2488 const GLuint comps = _mesa_get_format_bytes(dstFormat) / 2;
2489 GLint img, row, col;
2494 /* Note: tempImage is always float[4] / RGBA. We convert to 1, 2,
2495 * 3 or 4 components/pixel here.
2497 for (img = 0; img < srcDepth; img++) {
2498 GLubyte *dstRow = dstSlices[dstZoffset + img]
2499 + dstYoffset * dstRowStride
2500 + dstXoffset * texelBytes;
2501 for (row = 0; row < srcHeight; row++) {
2502 GLshort *dstRowS = (GLshort *) dstRow;
2503 if (dstFormat == MESA_FORMAT_SIGNED_RGBA_16) {
2504 for (col = 0; col < srcWidth; col++) {
2506 for (c = 0; c < comps; c++) {
2508 UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 4 + c]);
2509 dstRowS[col * comps + c] = p;
2512 dstRow += dstRowStride;
2513 src += 4 * srcWidth;
2515 for (col = 0; col < srcWidth; col++) {
2517 for (c = 0; c < comps; c++) {
2519 UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]);
2520 dstRowS[col * comps + c] = p;
2523 dstRow += dstRowStride;
2524 src += 3 * srcWidth;
2528 free((void *) tempImage);
2535 _mesa_texstore_rgb332(TEXSTORE_PARAMS)
2537 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2538 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2540 ASSERT(dstFormat == MESA_FORMAT_RGB332);
2541 ASSERT(texelBytes == 1);
2543 if (!ctx->_ImageTransferState &&
2544 !srcPacking->SwapBytes &&
2545 baseInternalFormat == GL_RGB &&
2546 srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
2547 /* simple memcpy path */
2548 memcpy_texture(ctx, dims,
2549 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2550 dstRowStride, dstSlices,
2551 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2552 srcAddr, srcPacking);
2556 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
2559 srcWidth, srcHeight, srcDepth,
2560 srcFormat, srcType, srcAddr,
2562 const GLubyte *src = tempImage;
2563 GLint img, row, col;
2566 for (img = 0; img < srcDepth; img++) {
2567 GLubyte *dstRow = dstSlices[dstZoffset + img]
2568 + dstYoffset * dstRowStride
2569 + dstXoffset * texelBytes;
2570 for (row = 0; row < srcHeight; row++) {
2571 for (col = 0; col < srcWidth; col++) {
2572 dstRow[col] = PACK_COLOR_332( src[RCOMP],
2577 dstRow += dstRowStride;
2580 free((void *) tempImage);
2587 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2590 _mesa_texstore_unorm8(TEXSTORE_PARAMS)
2592 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2593 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2595 ASSERT(dstFormat == MESA_FORMAT_A8 ||
2596 dstFormat == MESA_FORMAT_L8 ||
2597 dstFormat == MESA_FORMAT_I8 ||
2598 dstFormat == MESA_FORMAT_R8);
2599 ASSERT(texelBytes == 1);
2601 if (!ctx->_ImageTransferState &&
2602 !srcPacking->SwapBytes &&
2603 baseInternalFormat == srcFormat &&
2604 srcType == GL_UNSIGNED_BYTE) {
2605 /* simple memcpy path */
2606 memcpy_texture(ctx, dims,
2607 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2608 dstRowStride, dstSlices,
2609 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2610 srcAddr, srcPacking);
2612 else if (!ctx->_ImageTransferState &&
2613 srcType == GL_UNSIGNED_BYTE &&
2614 can_swizzle(baseInternalFormat) &&
2615 can_swizzle(srcFormat)) {
2618 /* dstmap - how to swizzle from RGBA to dst format:
2620 if (dstFormat == MESA_FORMAT_A8) {
2626 dstmap[1] = ZERO; /* ? */
2627 dstmap[2] = ZERO; /* ? */
2628 dstmap[3] = ONE; /* ? */
2630 _mesa_swizzle_ubyte_image(ctx, dims,
2635 dstXoffset, dstYoffset, dstZoffset,
2636 dstRowStride, dstSlices,
2637 srcWidth, srcHeight, srcDepth, srcAddr,
2642 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
2645 srcWidth, srcHeight, srcDepth,
2646 srcFormat, srcType, srcAddr,
2648 const GLubyte *src = tempImage;
2649 GLint img, row, col;
2652 for (img = 0; img < srcDepth; img++) {
2653 GLubyte *dstRow = dstSlices[dstZoffset + img]
2654 + dstYoffset * dstRowStride
2655 + dstXoffset * texelBytes;
2656 for (row = 0; row < srcHeight; row++) {
2657 for (col = 0; col < srcWidth; col++) {
2658 dstRow[col] = src[col];
2660 dstRow += dstRowStride;
2664 free((void *) tempImage);
2672 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
2675 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
2677 const GLboolean littleEndian = _mesa_little_endian();
2678 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2680 (void) ctx; (void) dims; (void) baseInternalFormat;
2682 ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
2683 (dstFormat == MESA_FORMAT_YCBCR_REV));
2684 ASSERT(texelBytes == 2);
2685 ASSERT(ctx->Extensions.MESA_ycbcr_texture);
2686 ASSERT(srcFormat == GL_YCBCR_MESA);
2687 ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
2688 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
2689 ASSERT(baseInternalFormat == GL_YCBCR_MESA);
2691 /* always just memcpy since no pixel transfer ops apply */
2692 memcpy_texture(ctx, dims,
2693 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2694 dstRowStride, dstSlices,
2695 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2696 srcAddr, srcPacking);
2698 /* Check if we need byte swapping */
2699 /* XXX the logic here _might_ be wrong */
2700 if (srcPacking->SwapBytes ^
2701 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
2702 (dstFormat == MESA_FORMAT_YCBCR_REV) ^
2705 for (img = 0; img < srcDepth; img++) {
2706 GLubyte *dstRow = dstSlices[dstZoffset + img]
2707 + dstYoffset * dstRowStride
2708 + dstXoffset * texelBytes;
2709 for (row = 0; row < srcHeight; row++) {
2710 _mesa_swap2((GLushort *) dstRow, srcWidth);
2711 dstRow += dstRowStride;
2719 _mesa_texstore_dudv8(TEXSTORE_PARAMS)
2721 const GLboolean littleEndian = _mesa_little_endian();
2722 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2724 ASSERT(dstFormat == MESA_FORMAT_DUDV8);
2725 ASSERT(texelBytes == 2);
2726 ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
2727 ASSERT((srcFormat == GL_DU8DV8_ATI) ||
2728 (srcFormat == GL_DUDV_ATI));
2729 ASSERT(baseInternalFormat == GL_DUDV_ATI);
2731 if (!srcPacking->SwapBytes && srcType == GL_BYTE &&
2733 /* simple memcpy path */
2734 memcpy_texture(ctx, dims,
2735 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2736 dstRowStride, dstSlices,
2737 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2738 srcAddr, srcPacking);
2740 else if (srcType == GL_BYTE) {
2743 /* dstmap - how to swizzle from RGBA to dst format:
2753 dstmap[2] = ZERO; /* ? */
2754 dstmap[3] = ONE; /* ? */
2756 _mesa_swizzle_ubyte_image(ctx, dims,
2757 GL_LUMINANCE_ALPHA, /* hack */
2758 GL_UNSIGNED_BYTE, /* hack */
2759 GL_LUMINANCE_ALPHA, /* hack */
2761 dstXoffset, dstYoffset, dstZoffset,
2762 dstRowStride, dstSlices,
2763 srcWidth, srcHeight, srcDepth, srcAddr,
2767 /* general path - note this is defined for 2d textures only */
2768 const GLint components = _mesa_components_in_format(baseInternalFormat);
2769 const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth,
2770 srcFormat, srcType);
2771 GLbyte *tempImage, *dst, *src;
2774 tempImage = (GLbyte *) malloc(srcWidth * srcHeight * srcDepth
2775 * components * sizeof(GLbyte));
2779 src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2780 srcWidth, srcHeight,
2785 for (row = 0; row < srcHeight; row++) {
2786 _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat,
2787 dst, srcFormat, srcType, src,
2789 dst += srcWidth * components;
2794 dst = (GLbyte *) dstSlices[0]
2795 + dstYoffset * dstRowStride
2796 + dstXoffset * texelBytes;
2797 for (row = 0; row < srcHeight; row++) {
2798 memcpy(dst, src, srcWidth * texelBytes);
2799 dst += dstRowStride;
2800 src += srcWidth * texelBytes;
2802 free((void *) tempImage);
2809 * Store a texture in a signed normalized 8-bit format.
2812 _mesa_texstore_snorm8(TEXSTORE_PARAMS)
2814 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2815 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2817 ASSERT(dstFormat == MESA_FORMAT_SIGNED_A8 ||
2818 dstFormat == MESA_FORMAT_SIGNED_L8 ||
2819 dstFormat == MESA_FORMAT_SIGNED_I8 ||
2820 dstFormat == MESA_FORMAT_SIGNED_R8);
2821 ASSERT(texelBytes == 1);
2823 if (!ctx->_ImageTransferState &&
2824 !srcPacking->SwapBytes &&
2825 baseInternalFormat == srcFormat &&
2826 srcType == GL_BYTE) {
2827 /* simple memcpy path */
2828 memcpy_texture(ctx, dims,
2829 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2830 dstRowStride, dstSlices,
2831 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2832 srcAddr, srcPacking);
2836 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2839 srcWidth, srcHeight, srcDepth,
2840 srcFormat, srcType, srcAddr,
2842 ctx->_ImageTransferState);
2843 const GLfloat *src = tempImage;
2844 GLint img, row, col;
2847 for (img = 0; img < srcDepth; img++) {
2848 GLbyte *dstRow = (GLbyte *) dstSlices[dstZoffset + img]
2849 + dstYoffset * dstRowStride
2850 + dstXoffset * texelBytes;
2851 for (row = 0; row < srcHeight; row++) {
2852 for (col = 0; col < srcWidth; col++) {
2853 dstRow[col] = FLOAT_TO_BYTE_TEX(src[col]);
2855 dstRow += dstRowStride;
2859 free((void *) tempImage);
2866 * Store a texture in a signed normalized two-channel 16-bit format.
2869 _mesa_texstore_snorm88(TEXSTORE_PARAMS)
2871 const GLboolean littleEndian = _mesa_little_endian();
2872 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2873 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2875 ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL88 ||
2876 dstFormat == MESA_FORMAT_SIGNED_RG88_REV);
2877 ASSERT(texelBytes == 2);
2879 if (!ctx->_ImageTransferState &&
2880 !srcPacking->SwapBytes &&
2881 baseInternalFormat == srcFormat &&
2882 srcType == GL_BYTE &&
2884 /* simple memcpy path */
2885 memcpy_texture(ctx, dims,
2886 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2887 dstRowStride, dstSlices,
2888 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2889 srcAddr, srcPacking);
2893 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2896 srcWidth, srcHeight, srcDepth,
2897 srcFormat, srcType, srcAddr,
2899 ctx->_ImageTransferState);
2900 const GLfloat *src = tempImage;
2901 GLint img, row, col;
2904 for (img = 0; img < srcDepth; img++) {
2905 GLbyte *dstRow = (GLbyte *) dstSlices[dstZoffset + img]
2906 + dstYoffset * dstRowStride
2907 + dstXoffset * texelBytes;
2908 for (row = 0; row < srcHeight; row++) {
2909 GLbyte *dst = dstRow;
2910 for (col = 0; col < srcWidth; col++) {
2911 dst[0] = FLOAT_TO_BYTE_TEX(src[0]);
2912 dst[1] = FLOAT_TO_BYTE_TEX(src[1]);
2916 dstRow += dstRowStride;
2919 free((void *) tempImage);
2924 /* Texstore for signed R16, A16, L16, I16. */
2926 _mesa_texstore_snorm16(TEXSTORE_PARAMS)
2928 const GLboolean littleEndian = _mesa_little_endian();
2929 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2930 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2932 ASSERT(dstFormat == MESA_FORMAT_SIGNED_R16 ||
2933 dstFormat == MESA_FORMAT_SIGNED_A16 ||
2934 dstFormat == MESA_FORMAT_SIGNED_L16 ||
2935 dstFormat == MESA_FORMAT_SIGNED_I16);
2936 ASSERT(texelBytes == 2);
2938 if (!ctx->_ImageTransferState &&
2939 !srcPacking->SwapBytes &&
2940 baseInternalFormat == srcFormat &&
2941 srcType == GL_SHORT &&
2943 /* simple memcpy path */
2944 memcpy_texture(ctx, dims,
2945 dstFormat, dstXoffset, dstYoffset, dstZoffset,
2946 dstRowStride, dstSlices,
2947 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2948 srcAddr, srcPacking);
2952 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2955 srcWidth, srcHeight, srcDepth,
2956 srcFormat, srcType, srcAddr,
2958 ctx->_ImageTransferState);
2959 const GLfloat *src = tempImage;
2960 GLint img, row, col;
2963 for (img = 0; img < srcDepth; img++) {
2964 GLubyte *dstRow = dstSlices[dstZoffset + img]
2965 + dstYoffset * dstRowStride
2966 + dstXoffset * texelBytes;
2967 for (row = 0; row < srcHeight; row++) {
2968 GLshort *dstUS = (GLshort *) dstRow;
2969 for (col = 0; col < srcWidth; col++) {
2972 UNCLAMPED_FLOAT_TO_SHORT(r, src[0]);
2976 dstRow += dstRowStride;
2979 free((void *) tempImage);
2985 * Do texstore for 2-channel, 16-bit/channel, signed normalized formats.
2988 _mesa_texstore_snorm1616(TEXSTORE_PARAMS)
2990 const GLboolean littleEndian = _mesa_little_endian();
2991 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2992 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2994 ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL1616 ||
2995 dstFormat == MESA_FORMAT_SIGNED_GR1616);
2996 ASSERT(texelBytes == 4);
2998 if (!ctx->_ImageTransferState &&
2999 !srcPacking->SwapBytes &&
3000 baseInternalFormat == srcFormat &&
3001 srcType == GL_SHORT &&
3003 /* simple memcpy path */
3004 memcpy_texture(ctx, dims,
3005 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3006 dstRowStride, dstSlices,
3007 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3008 srcAddr, srcPacking);
3012 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3015 srcWidth, srcHeight, srcDepth,
3016 srcFormat, srcType, srcAddr,
3018 ctx->_ImageTransferState);
3019 const GLfloat *src = tempImage;
3020 GLint img, row, col;
3023 for (img = 0; img < srcDepth; img++) {
3024 GLubyte *dstRow = dstSlices[dstZoffset + img]
3025 + dstYoffset * dstRowStride
3026 + dstXoffset * texelBytes;
3027 for (row = 0; row < srcHeight; row++) {
3028 GLshort *dst = (GLshort *) dstRow;
3029 for (col = 0; col < srcWidth; col++) {
3032 UNCLAMPED_FLOAT_TO_SHORT(l, src[0]);
3033 UNCLAMPED_FLOAT_TO_SHORT(a, src[1]);
3039 dstRow += dstRowStride;
3042 free((void *) tempImage);
3048 * Store a texture in MESA_FORMAT_SIGNED_RGBX8888.
3051 _mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS)
3053 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3054 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3056 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBX8888);
3057 ASSERT(texelBytes == 4);
3061 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3064 srcWidth, srcHeight, srcDepth,
3065 srcFormat, srcType, srcAddr,
3067 ctx->_ImageTransferState);
3068 const GLfloat *srcRow = tempImage;
3069 GLint img, row, col;
3072 for (img = 0; img < srcDepth; img++) {
3073 GLbyte *dstRow = (GLbyte *) dstSlices[dstZoffset + img]
3074 + dstYoffset * dstRowStride
3075 + dstXoffset * texelBytes;
3076 for (row = 0; row < srcHeight; row++) {
3077 GLbyte *dst = dstRow;
3078 for (col = 0; col < srcWidth; col++) {
3079 dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
3080 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
3081 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
3086 dstRow += dstRowStride;
3089 free((void *) tempImage);
3097 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or
3098 * MESA_FORMAT_SIGNED_RGBA8888_REV
3101 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
3103 const GLboolean littleEndian = _mesa_little_endian();
3104 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3105 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3107 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBA8888 ||
3108 dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV);
3109 ASSERT(texelBytes == 4);
3111 if (!ctx->_ImageTransferState &&
3112 !srcPacking->SwapBytes &&
3113 dstFormat == MESA_FORMAT_SIGNED_RGBA8888 &&
3114 baseInternalFormat == GL_RGBA &&
3115 ((srcFormat == GL_RGBA && srcType == GL_BYTE && !littleEndian) ||
3116 (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && littleEndian))) {
3117 /* simple memcpy path */
3118 memcpy_texture(ctx, dims,
3119 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3120 dstRowStride, dstSlices,
3121 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3122 srcAddr, srcPacking);
3124 else if (!ctx->_ImageTransferState &&
3125 !srcPacking->SwapBytes &&
3126 dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV &&
3127 baseInternalFormat == GL_RGBA &&
3128 ((srcFormat == GL_RGBA && srcType == GL_BYTE && littleEndian) ||
3129 (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && !littleEndian))) {
3130 /* simple memcpy path */
3131 memcpy_texture(ctx, dims,
3132 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3133 dstRowStride, dstSlices,
3134 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3135 srcAddr, srcPacking);
3139 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3142 srcWidth, srcHeight, srcDepth,
3143 srcFormat, srcType, srcAddr,
3145 ctx->_ImageTransferState);
3146 const GLfloat *srcRow = tempImage;
3147 GLint img, row, col;
3150 for (img = 0; img < srcDepth; img++) {
3151 GLbyte *dstRow = (GLbyte *) dstSlices[dstZoffset + img]
3152 + dstYoffset * dstRowStride
3153 + dstXoffset * texelBytes;
3154 for (row = 0; row < srcHeight; row++) {
3155 GLbyte *dst = dstRow;
3156 if (dstFormat == MESA_FORMAT_SIGNED_RGBA8888) {
3157 for (col = 0; col < srcWidth; col++) {
3158 dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
3159 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
3160 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
3161 dst[0] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]);
3167 for (col = 0; col < srcWidth; col++) {
3168 dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
3169 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
3170 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
3171 dst[3] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]);
3176 dstRow += dstRowStride;
3179 free((void *) tempImage);
3186 * Store a combined depth/stencil texture image.
3189 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
3191 const GLuint depthScale = 0xffffff;
3192 const GLint srcRowStride
3193 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
3196 ASSERT(dstFormat == MESA_FORMAT_Z24_S8);
3197 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
3198 srcFormat == GL_DEPTH_COMPONENT ||
3199 srcFormat == GL_STENCIL_INDEX);
3200 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
3202 if (srcFormat == GL_DEPTH_STENCIL && ctx->Pixel.DepthScale == 1.0f &&
3203 ctx->Pixel.DepthBias == 0.0f &&
3204 !srcPacking->SwapBytes) {
3206 memcpy_texture(ctx, dims,
3207 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3208 dstRowStride, dstSlices,
3209 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3210 srcAddr, srcPacking);
3212 else if (srcFormat == GL_DEPTH_COMPONENT ||
3213 srcFormat == GL_STENCIL_INDEX) {
3214 /* In case we only upload depth we need to preserve the stencil */
3215 for (img = 0; img < srcDepth; img++) {
3216 GLuint *dstRow = (GLuint *) (dstSlices[dstZoffset + img]
3217 + dstYoffset * dstRowStride
3220 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
3221 srcWidth, srcHeight,
3224 for (row = 0; row < srcHeight; row++) {
3225 GLuint depth[MAX_WIDTH];
3226 GLubyte stencil[MAX_WIDTH];
3228 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
3230 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
3231 keepstencil = GL_TRUE;
3233 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
3234 keepdepth = GL_TRUE;
3237 if (keepdepth == GL_FALSE)
3238 /* the 24 depth bits will be in the low position: */
3239 _mesa_unpack_depth_span(ctx, srcWidth,
3240 GL_UNSIGNED_INT, /* dst type */
3241 keepstencil ? depth : dstRow, /* dst addr */
3243 srcType, src, srcPacking);
3245 if (keepstencil == GL_FALSE)
3246 /* get the 8-bit stencil values */
3247 _mesa_unpack_stencil_span(ctx, srcWidth,
3248 GL_UNSIGNED_BYTE, /* dst type */
3249 stencil, /* dst addr */
3250 srcType, src, srcPacking,
3251 ctx->_ImageTransferState);
3253 for (i = 0; i < srcWidth; i++) {
3255 dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
3257 dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF);
3260 src += srcRowStride;
3261 dstRow += dstRowStride / sizeof(GLuint);
3270 * Store a combined depth/stencil texture image.
3273 _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
3275 const GLuint depthScale = 0xffffff;
3276 const GLint srcRowStride
3277 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
3280 ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
3281 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
3282 srcFormat == GL_DEPTH_COMPONENT ||
3283 srcFormat == GL_STENCIL_INDEX);
3284 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
3285 srcType == GL_UNSIGNED_INT_24_8_EXT);
3287 for (img = 0; img < srcDepth; img++) {
3288 GLuint *dstRow = (GLuint *) (dstSlices[dstZoffset + img]
3289 + dstYoffset * dstRowStride
3292 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
3293 srcWidth, srcHeight,
3296 for (row = 0; row < srcHeight; row++) {
3297 GLuint depth[MAX_WIDTH];
3298 GLubyte stencil[MAX_WIDTH];
3300 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
3302 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
3303 keepstencil = GL_TRUE;
3305 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
3306 keepdepth = GL_TRUE;
3309 if (keepdepth == GL_FALSE)
3310 /* the 24 depth bits will be in the low position: */
3311 _mesa_unpack_depth_span(ctx, srcWidth,
3312 GL_UNSIGNED_INT, /* dst type */
3313 keepstencil ? depth : dstRow, /* dst addr */
3315 srcType, src, srcPacking);
3317 if (keepstencil == GL_FALSE)
3318 /* get the 8-bit stencil values */
3319 _mesa_unpack_stencil_span(ctx, srcWidth,
3320 GL_UNSIGNED_BYTE, /* dst type */
3321 stencil, /* dst addr */
3322 srcType, src, srcPacking,
3323 ctx->_ImageTransferState);
3325 /* merge stencil values into depth values */
3326 for (i = 0; i < srcWidth; i++) {
3328 dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
3330 dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
3333 src += srcRowStride;
3334 dstRow += dstRowStride / sizeof(GLuint);
3342 * Store simple 8-bit/value stencil texture data.
3345 _mesa_texstore_s8(TEXSTORE_PARAMS)
3347 ASSERT(dstFormat == MESA_FORMAT_S8);
3348 ASSERT(srcFormat == GL_STENCIL_INDEX);
3350 if (!ctx->_ImageTransferState &&
3351 !srcPacking->SwapBytes &&
3352 baseInternalFormat == srcFormat &&
3353 srcType == GL_UNSIGNED_BYTE) {
3354 /* simple memcpy path */
3355 memcpy_texture(ctx, dims,
3356 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3357 dstRowStride, dstSlices,
3358 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3359 srcAddr, srcPacking);
3362 const GLint srcRowStride
3363 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
3366 for (img = 0; img < srcDepth; img++) {
3367 GLubyte *dstRow = dstSlices[dstZoffset + img]
3368 + dstYoffset * dstRowStride / sizeof(GLuint)
3371 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
3372 srcWidth, srcHeight,
3375 for (row = 0; row < srcHeight; row++) {
3376 GLubyte stencil[MAX_WIDTH];
3379 /* get the 8-bit stencil values */
3380 _mesa_unpack_stencil_span(ctx, srcWidth,
3381 GL_UNSIGNED_BYTE, /* dst type */
3382 stencil, /* dst addr */
3383 srcType, src, srcPacking,
3384 ctx->_ImageTransferState);
3385 /* merge stencil values into depth values */
3386 for (i = 0; i < srcWidth; i++)
3387 dstRow[i] = stencil[i];
3389 src += srcRowStride;
3390 dstRow += dstRowStride / sizeof(GLubyte);
3401 * Store an image in any of the formats:
3402 * _mesa_texformat_rgba_float32
3403 * _mesa_texformat_rgb_float32
3404 * _mesa_texformat_alpha_float32
3405 * _mesa_texformat_luminance_float32
3406 * _mesa_texformat_luminance_alpha_float32
3407 * _mesa_texformat_intensity_float32
3410 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
3412 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3413 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3414 const GLint components = _mesa_components_in_format(baseFormat);
3416 ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 ||
3417 dstFormat == MESA_FORMAT_RGB_FLOAT32 ||
3418 dstFormat == MESA_FORMAT_ALPHA_FLOAT32 ||
3419 dstFormat == MESA_FORMAT_LUMINANCE_FLOAT32 ||
3420 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 ||
3421 dstFormat == MESA_FORMAT_INTENSITY_FLOAT32 ||
3422 dstFormat == MESA_FORMAT_R_FLOAT32 ||
3423 dstFormat == MESA_FORMAT_RG_FLOAT32);
3424 ASSERT(baseInternalFormat == GL_RGBA ||
3425 baseInternalFormat == GL_RGB ||
3426 baseInternalFormat == GL_ALPHA ||
3427 baseInternalFormat == GL_LUMINANCE ||
3428 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3429 baseInternalFormat == GL_INTENSITY ||
3430 baseInternalFormat == GL_RED ||
3431 baseInternalFormat == GL_RG);
3432 ASSERT(texelBytes == components * sizeof(GLfloat));
3434 if (!ctx->_ImageTransferState &&
3435 !srcPacking->SwapBytes &&
3436 baseInternalFormat == srcFormat &&
3437 baseInternalFormat == baseFormat &&
3438 srcType == GL_FLOAT) {
3439 /* simple memcpy path */
3440 memcpy_texture(ctx, dims,
3441 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3442 dstRowStride, dstSlices,
3443 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3444 srcAddr, srcPacking);
3448 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3451 srcWidth, srcHeight, srcDepth,
3452 srcFormat, srcType, srcAddr,
3454 ctx->_ImageTransferState);
3455 const GLfloat *srcRow = tempImage;
3460 bytesPerRow = srcWidth * components * sizeof(GLfloat);
3461 for (img = 0; img < srcDepth; img++) {
3462 GLubyte *dstRow = dstSlices[dstZoffset + img]
3463 + dstYoffset * dstRowStride
3464 + dstXoffset * texelBytes;
3465 for (row = 0; row < srcHeight; row++) {
3466 memcpy(dstRow, srcRow, bytesPerRow);
3467 dstRow += dstRowStride;
3468 srcRow += srcWidth * components;
3472 free((void *) tempImage);
3480 * As above, but store 16-bit floats.
3483 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
3485 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3486 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3487 const GLint components = _mesa_components_in_format(baseFormat);
3489 ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 ||
3490 dstFormat == MESA_FORMAT_RGB_FLOAT16 ||
3491 dstFormat == MESA_FORMAT_ALPHA_FLOAT16 ||
3492 dstFormat == MESA_FORMAT_LUMINANCE_FLOAT16 ||
3493 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 ||
3494 dstFormat == MESA_FORMAT_INTENSITY_FLOAT16 ||
3495 dstFormat == MESA_FORMAT_R_FLOAT16 ||
3496 dstFormat == MESA_FORMAT_RG_FLOAT16);
3497 ASSERT(baseInternalFormat == GL_RGBA ||
3498 baseInternalFormat == GL_RGB ||
3499 baseInternalFormat == GL_ALPHA ||
3500 baseInternalFormat == GL_LUMINANCE ||
3501 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3502 baseInternalFormat == GL_INTENSITY ||
3503 baseInternalFormat == GL_RED ||
3504 baseInternalFormat == GL_RG);
3505 ASSERT(texelBytes == components * sizeof(GLhalfARB));
3507 if (!ctx->_ImageTransferState &&
3508 !srcPacking->SwapBytes &&
3509 baseInternalFormat == srcFormat &&
3510 baseInternalFormat == baseFormat &&
3511 srcType == GL_HALF_FLOAT_ARB) {
3512 /* simple memcpy path */
3513 memcpy_texture(ctx, dims,
3514 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3515 dstRowStride, dstSlices,
3516 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3517 srcAddr, srcPacking);
3521 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3524 srcWidth, srcHeight, srcDepth,
3525 srcFormat, srcType, srcAddr,
3527 ctx->_ImageTransferState);
3528 const GLfloat *src = tempImage;
3532 for (img = 0; img < srcDepth; img++) {
3533 GLubyte *dstRow = dstSlices[dstZoffset + img]
3534 + dstYoffset * dstRowStride
3535 + dstXoffset * texelBytes;
3536 for (row = 0; row < srcHeight; row++) {
3537 GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
3539 for (i = 0; i < srcWidth * components; i++) {
3540 dstTexel[i] = _mesa_float_to_half(src[i]);
3542 dstRow += dstRowStride;
3543 src += srcWidth * components;
3547 free((void *) tempImage);
3553 /* non-normalized, signed int8 */
3555 _mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
3557 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3558 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3559 const GLint components = _mesa_components_in_format(baseFormat);
3561 ASSERT(dstFormat == MESA_FORMAT_R_INT8 ||
3562 dstFormat == MESA_FORMAT_RG_INT8 ||
3563 dstFormat == MESA_FORMAT_RGB_INT8 ||
3564 dstFormat == MESA_FORMAT_RGBA_INT8 ||
3565 dstFormat == MESA_FORMAT_ALPHA_INT8 ||
3566 dstFormat == MESA_FORMAT_INTENSITY_INT8 ||
3567 dstFormat == MESA_FORMAT_LUMINANCE_INT8 ||
3568 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT8);
3569 ASSERT(baseInternalFormat == GL_RGBA ||
3570 baseInternalFormat == GL_RGB ||
3571 baseInternalFormat == GL_RG ||
3572 baseInternalFormat == GL_RED ||
3573 baseInternalFormat == GL_ALPHA ||
3574 baseInternalFormat == GL_LUMINANCE ||
3575 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3576 baseInternalFormat == GL_INTENSITY);
3577 ASSERT(texelBytes == components * sizeof(GLbyte));
3579 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3580 * to integer formats.
3582 if (!srcPacking->SwapBytes &&
3583 baseInternalFormat == srcFormat &&
3584 srcType == GL_BYTE) {
3585 /* simple memcpy path */
3586 memcpy_texture(ctx, dims,
3587 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3588 dstRowStride, dstSlices,
3589 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3590 srcAddr, srcPacking);
3594 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3597 srcWidth, srcHeight, srcDepth,
3598 srcFormat, srcType, srcAddr,
3600 const GLfloat *src = tempImage;
3604 for (img = 0; img < srcDepth; img++) {
3605 GLubyte *dstRow = dstSlices[dstZoffset + img]
3606 + dstYoffset * dstRowStride
3607 + dstXoffset * texelBytes;
3608 for (row = 0; row < srcHeight; row++) {
3609 GLbyte *dstTexel = (GLbyte *) dstRow;
3611 for (i = 0; i < srcWidth * components; i++) {
3612 dstTexel[i] = (GLbyte) src[i];
3614 dstRow += dstRowStride;
3615 src += srcWidth * components;
3619 free((void *) tempImage);
3625 /* non-normalized, signed int16 */
3627 _mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
3629 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3630 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3631 const GLint components = _mesa_components_in_format(baseFormat);
3633 ASSERT(dstFormat == MESA_FORMAT_R_INT16 ||
3634 dstFormat == MESA_FORMAT_RG_INT16 ||
3635 dstFormat == MESA_FORMAT_RGB_INT16 ||
3636 dstFormat == MESA_FORMAT_RGBA_INT16 ||
3637 dstFormat == MESA_FORMAT_ALPHA_INT16 ||
3638 dstFormat == MESA_FORMAT_LUMINANCE_INT16 ||
3639 dstFormat == MESA_FORMAT_INTENSITY_INT16 ||
3640 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16);
3641 ASSERT(baseInternalFormat == GL_RGBA ||
3642 baseInternalFormat == GL_RGB ||
3643 baseInternalFormat == GL_RG ||
3644 baseInternalFormat == GL_RED ||
3645 baseInternalFormat == GL_ALPHA ||
3646 baseInternalFormat == GL_LUMINANCE ||
3647 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3648 baseInternalFormat == GL_INTENSITY);
3649 ASSERT(texelBytes == components * sizeof(GLshort));
3651 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3652 * to integer formats.
3654 if (!srcPacking->SwapBytes &&
3655 baseInternalFormat == srcFormat &&
3656 srcType == GL_SHORT) {
3657 /* simple memcpy path */
3658 memcpy_texture(ctx, dims,
3659 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3660 dstRowStride, dstSlices,
3661 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3662 srcAddr, srcPacking);
3666 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3669 srcWidth, srcHeight, srcDepth,
3670 srcFormat, srcType, srcAddr,
3672 const GLfloat *src = tempImage;
3676 for (img = 0; img < srcDepth; img++) {
3677 GLubyte *dstRow = dstSlices[dstZoffset + img]
3678 + dstYoffset * dstRowStride
3679 + dstXoffset * texelBytes;
3680 for (row = 0; row < srcHeight; row++) {
3681 GLshort *dstTexel = (GLshort *) dstRow;
3683 for (i = 0; i < srcWidth * components; i++) {
3684 dstTexel[i] = (GLint) src[i];
3686 dstRow += dstRowStride;
3687 src += srcWidth * components;
3691 free((void *) tempImage);
3697 /* non-normalized, signed int32 */
3699 _mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
3701 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3702 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3703 const GLint components = _mesa_components_in_format(baseFormat);
3705 ASSERT(dstFormat == MESA_FORMAT_R_INT32 ||
3706 dstFormat == MESA_FORMAT_RG_INT32 ||
3707 dstFormat == MESA_FORMAT_RGB_INT32 ||
3708 dstFormat == MESA_FORMAT_RGBA_INT32 ||
3709 dstFormat == MESA_FORMAT_ALPHA_INT32 ||
3710 dstFormat == MESA_FORMAT_INTENSITY_INT32 ||
3711 dstFormat == MESA_FORMAT_LUMINANCE_INT32 ||
3712 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32);
3713 ASSERT(baseInternalFormat == GL_RGBA ||
3714 baseInternalFormat == GL_RGB ||
3715 baseInternalFormat == GL_RG ||
3716 baseInternalFormat == GL_RED ||
3717 baseInternalFormat == GL_ALPHA ||
3718 baseInternalFormat == GL_LUMINANCE ||
3719 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3720 baseInternalFormat == GL_INTENSITY);
3721 ASSERT(texelBytes == components * sizeof(GLint));
3723 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3724 * to integer formats.
3726 if (!srcPacking->SwapBytes &&
3727 baseInternalFormat == srcFormat &&
3728 srcType == GL_INT) {
3729 /* simple memcpy path */
3730 memcpy_texture(ctx, dims,
3731 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3732 dstRowStride, dstSlices,
3733 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3734 srcAddr, srcPacking);
3738 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3741 srcWidth, srcHeight, srcDepth,
3742 srcFormat, srcType, srcAddr,
3744 const GLfloat *src = tempImage;
3748 for (img = 0; img < srcDepth; img++) {
3749 GLubyte *dstRow = dstSlices[dstZoffset + img]
3750 + dstYoffset * dstRowStride
3751 + dstXoffset * texelBytes;
3752 for (row = 0; row < srcHeight; row++) {
3753 GLint *dstTexel = (GLint *) dstRow;
3755 for (i = 0; i < srcWidth * components; i++) {
3756 dstTexel[i] = (GLint) src[i];
3758 dstRow += dstRowStride;
3759 src += srcWidth * components;
3763 free((void *) tempImage);
3769 /* non-normalized, unsigned int8 */
3771 _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
3773 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3774 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3775 const GLint components = _mesa_components_in_format(baseFormat);
3777 ASSERT(dstFormat == MESA_FORMAT_R_UINT8 ||
3778 dstFormat == MESA_FORMAT_RG_UINT8 ||
3779 dstFormat == MESA_FORMAT_RGB_UINT8 ||
3780 dstFormat == MESA_FORMAT_RGBA_UINT8 ||
3781 dstFormat == MESA_FORMAT_ALPHA_UINT8 ||
3782 dstFormat == MESA_FORMAT_INTENSITY_UINT8 ||
3783 dstFormat == MESA_FORMAT_LUMINANCE_UINT8 ||
3784 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT8);
3785 ASSERT(baseInternalFormat == GL_RGBA ||
3786 baseInternalFormat == GL_RGB ||
3787 baseInternalFormat == GL_RG ||
3788 baseInternalFormat == GL_RED ||
3789 baseInternalFormat == GL_ALPHA ||
3790 baseInternalFormat == GL_LUMINANCE ||
3791 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3792 baseInternalFormat == GL_INTENSITY);
3793 ASSERT(texelBytes == components * sizeof(GLubyte));
3795 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3796 * to integer formats.
3798 if (!srcPacking->SwapBytes &&
3799 baseInternalFormat == srcFormat &&
3800 srcType == GL_UNSIGNED_BYTE) {
3801 /* simple memcpy path */
3802 memcpy_texture(ctx, dims,
3803 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3804 dstRowStride, dstSlices,
3805 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3806 srcAddr, srcPacking);
3810 const GLuint *tempImage =
3811 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3812 srcWidth, srcHeight, srcDepth,
3813 srcFormat, srcType, srcAddr, srcPacking);
3814 const GLuint *src = tempImage;
3818 for (img = 0; img < srcDepth; img++) {
3819 GLubyte *dstRow = dstSlices[dstZoffset + img]
3820 + dstYoffset * dstRowStride
3821 + dstXoffset * texelBytes;
3822 for (row = 0; row < srcHeight; row++) {
3823 GLubyte *dstTexel = (GLubyte *) dstRow;
3825 for (i = 0; i < srcWidth * components; i++) {
3826 dstTexel[i] = (GLubyte) CLAMP(src[i], 0, 0xff);
3828 dstRow += dstRowStride;
3829 src += srcWidth * components;
3833 free((void *) tempImage);
3839 /* non-normalized, unsigned int16 */
3841 _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
3843 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3844 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3845 const GLint components = _mesa_components_in_format(baseFormat);
3847 ASSERT(dstFormat == MESA_FORMAT_R_UINT16 ||
3848 dstFormat == MESA_FORMAT_RG_UINT16 ||
3849 dstFormat == MESA_FORMAT_RGB_UINT16 ||
3850 dstFormat == MESA_FORMAT_RGBA_UINT16 ||
3851 dstFormat == MESA_FORMAT_ALPHA_UINT16 ||
3852 dstFormat == MESA_FORMAT_INTENSITY_UINT16 ||
3853 dstFormat == MESA_FORMAT_LUMINANCE_UINT16 ||
3854 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT16);
3855 ASSERT(baseInternalFormat == GL_RGBA ||
3856 baseInternalFormat == GL_RGB ||
3857 baseInternalFormat == GL_RG ||
3858 baseInternalFormat == GL_RED ||
3859 baseInternalFormat == GL_ALPHA ||
3860 baseInternalFormat == GL_LUMINANCE ||
3861 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3862 baseInternalFormat == GL_INTENSITY);
3863 ASSERT(texelBytes == components * sizeof(GLushort));
3865 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3866 * to integer formats.
3868 if (!srcPacking->SwapBytes &&
3869 baseInternalFormat == srcFormat &&
3870 srcType == GL_UNSIGNED_SHORT) {
3871 /* simple memcpy path */
3872 memcpy_texture(ctx, dims,
3873 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3874 dstRowStride, dstSlices,
3875 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3876 srcAddr, srcPacking);
3880 const GLuint *tempImage =
3881 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3882 srcWidth, srcHeight, srcDepth,
3883 srcFormat, srcType, srcAddr, srcPacking);
3884 const GLuint *src = tempImage;
3888 for (img = 0; img < srcDepth; img++) {
3889 GLubyte *dstRow = dstSlices[dstZoffset + img]
3890 + dstYoffset * dstRowStride
3891 + dstXoffset * texelBytes;
3892 for (row = 0; row < srcHeight; row++) {
3893 GLushort *dstTexel = (GLushort *) dstRow;
3895 for (i = 0; i < srcWidth * components; i++) {
3896 dstTexel[i] = (GLushort) CLAMP(src[i], 0, 0xffff);
3898 dstRow += dstRowStride;
3899 src += srcWidth * components;
3903 free((void *) tempImage);
3909 /* non-normalized, unsigned int32 */
3911 _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
3913 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3914 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3915 const GLint components = _mesa_components_in_format(baseFormat);
3917 ASSERT(dstFormat == MESA_FORMAT_R_UINT32 ||
3918 dstFormat == MESA_FORMAT_RG_UINT32 ||
3919 dstFormat == MESA_FORMAT_RGB_UINT32 ||
3920 dstFormat == MESA_FORMAT_RGBA_UINT32 ||
3921 dstFormat == MESA_FORMAT_ALPHA_UINT32 ||
3922 dstFormat == MESA_FORMAT_INTENSITY_UINT32 ||
3923 dstFormat == MESA_FORMAT_LUMINANCE_UINT32 ||
3924 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT32);
3925 ASSERT(baseInternalFormat == GL_RGBA ||
3926 baseInternalFormat == GL_RGB ||
3927 baseInternalFormat == GL_RG ||
3928 baseInternalFormat == GL_RED ||
3929 baseInternalFormat == GL_ALPHA ||
3930 baseInternalFormat == GL_LUMINANCE ||
3931 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3932 baseInternalFormat == GL_INTENSITY);
3933 ASSERT(texelBytes == components * sizeof(GLuint));
3935 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3936 * to integer formats.
3938 if (!srcPacking->SwapBytes &&
3939 baseInternalFormat == srcFormat &&
3940 srcType == GL_UNSIGNED_INT) {
3941 /* simple memcpy path */
3942 memcpy_texture(ctx, dims,
3943 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3944 dstRowStride, dstSlices,
3945 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3946 srcAddr, srcPacking);
3950 const GLuint *tempImage =
3951 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3952 srcWidth, srcHeight, srcDepth,
3953 srcFormat, srcType, srcAddr, srcPacking);
3954 const GLuint *src = tempImage;
3958 for (img = 0; img < srcDepth; img++) {
3959 GLubyte *dstRow = dstSlices[dstZoffset + img]
3960 + dstYoffset * dstRowStride
3961 + dstXoffset * texelBytes;
3962 for (row = 0; row < srcHeight; row++) {
3963 GLuint *dstTexel = (GLuint *) dstRow;
3965 for (i = 0; i < srcWidth * components; i++) {
3966 dstTexel[i] = src[i];
3968 dstRow += dstRowStride;
3969 src += srcWidth * components;
3973 free((void *) tempImage);
3981 #if FEATURE_EXT_texture_sRGB
3983 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
3985 gl_format newDstFormat;
3988 ASSERT(dstFormat == MESA_FORMAT_SRGB8);
3990 /* reuse normal rgb texstore code */
3991 newDstFormat = MESA_FORMAT_RGB888;
3993 k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
3995 dstXoffset, dstYoffset, dstZoffset,
3996 dstRowStride, dstSlices,
3997 srcWidth, srcHeight, srcDepth,
3999 srcAddr, srcPacking);
4005 _mesa_texstore_srgba8(TEXSTORE_PARAMS)
4007 gl_format newDstFormat;
4010 ASSERT(dstFormat == MESA_FORMAT_SRGBA8);
4012 /* reuse normal rgba texstore code */
4013 newDstFormat = MESA_FORMAT_RGBA8888;
4014 k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
4016 dstXoffset, dstYoffset, dstZoffset,
4017 dstRowStride, dstSlices,
4018 srcWidth, srcHeight, srcDepth,
4020 srcAddr, srcPacking);
4026 _mesa_texstore_sargb8(TEXSTORE_PARAMS)
4028 gl_format newDstFormat;
4031 ASSERT(dstFormat == MESA_FORMAT_SARGB8);
4033 /* reuse normal rgba texstore code */
4034 newDstFormat = MESA_FORMAT_ARGB8888;
4036 k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
4038 dstXoffset, dstYoffset, dstZoffset,
4039 dstRowStride, dstSlices,
4040 srcWidth, srcHeight, srcDepth,
4042 srcAddr, srcPacking);
4048 _mesa_texstore_sl8(TEXSTORE_PARAMS)
4050 gl_format newDstFormat;
4053 ASSERT(dstFormat == MESA_FORMAT_SL8);
4055 newDstFormat = MESA_FORMAT_L8;
4057 /* _mesa_textore_a8 handles luminance8 too */
4058 k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat,
4060 dstXoffset, dstYoffset, dstZoffset,
4061 dstRowStride, dstSlices,
4062 srcWidth, srcHeight, srcDepth,
4064 srcAddr, srcPacking);
4070 _mesa_texstore_sla8(TEXSTORE_PARAMS)
4072 gl_format newDstFormat;
4075 ASSERT(dstFormat == MESA_FORMAT_SLA8);
4077 /* reuse normal luminance/alpha texstore code */
4078 newDstFormat = MESA_FORMAT_AL88;
4080 k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat,
4082 dstXoffset, dstYoffset, dstZoffset,
4083 dstRowStride, dstSlices,
4084 srcWidth, srcHeight, srcDepth,
4086 srcAddr, srcPacking);
4092 /* these are used only in texstore_funcs[] below */
4093 #define _mesa_texstore_srgb8 NULL
4094 #define _mesa_texstore_srgba8 NULL
4095 #define _mesa_texstore_sargb8 NULL
4096 #define _mesa_texstore_sl8 NULL
4097 #define _mesa_texstore_sla8 NULL
4099 #endif /* FEATURE_EXT_texture_sRGB */
4102 _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)
4104 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
4106 ASSERT(dstFormat == MESA_FORMAT_RGB9_E5_FLOAT);
4107 ASSERT(baseInternalFormat == GL_RGB);
4109 if (!ctx->_ImageTransferState &&
4110 !srcPacking->SwapBytes &&
4111 srcFormat == GL_RGB &&
4112 srcType == GL_UNSIGNED_INT_5_9_9_9_REV) {
4113 /* simple memcpy path */
4114 memcpy_texture(ctx, dims,
4115 dstFormat, dstXoffset, dstYoffset, dstZoffset,
4116 dstRowStride, dstSlices,
4117 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
4118 srcAddr, srcPacking);
4122 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
4125 srcWidth, srcHeight, srcDepth,
4126 srcFormat, srcType, srcAddr,
4128 ctx->_ImageTransferState);
4129 const GLfloat *srcRow = tempImage;
4130 GLint img, row, col;
4133 for (img = 0; img < srcDepth; img++) {
4134 GLubyte *dstRow = dstSlices[dstZoffset + img]
4135 + dstYoffset * dstRowStride
4137 for (row = 0; row < srcHeight; row++) {
4138 GLuint *dstUI = (GLuint*)dstRow;
4139 for (col = 0; col < srcWidth; col++) {
4140 dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]);
4142 dstRow += dstRowStride;
4143 srcRow += srcWidth * 3;
4147 free((void *) tempImage);
4153 _mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS)
4155 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
4157 ASSERT(dstFormat == MESA_FORMAT_R11_G11_B10_FLOAT);
4158 ASSERT(baseInternalFormat == GL_RGB);
4160 if (!ctx->_ImageTransferState &&
4161 !srcPacking->SwapBytes &&
4162 srcFormat == GL_RGB &&
4163 srcType == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4164 /* simple memcpy path */
4165 memcpy_texture(ctx, dims,
4166 dstFormat, dstXoffset, dstYoffset, dstZoffset,
4167 dstRowStride, dstSlices,
4168 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
4169 srcAddr, srcPacking);
4173 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
4176 srcWidth, srcHeight, srcDepth,
4177 srcFormat, srcType, srcAddr,
4179 ctx->_ImageTransferState);
4180 const GLfloat *srcRow = tempImage;
4181 GLint img, row, col;
4184 for (img = 0; img < srcDepth; img++) {
4185 GLubyte *dstRow = dstSlices[dstZoffset + img]
4186 + dstYoffset * dstRowStride
4188 for (row = 0; row < srcHeight; row++) {
4189 GLuint *dstUI = (GLuint*)dstRow;
4190 for (col = 0; col < srcWidth; col++) {
4191 dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]);
4193 dstRow += dstRowStride;
4194 srcRow += srcWidth * 3;
4198 free((void *) tempImage);
4205 _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
4207 ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_X24S8);
4208 ASSERT(srcFormat == GL_DEPTH_STENCIL ||
4209 srcFormat == GL_DEPTH_COMPONENT ||
4210 srcFormat == GL_STENCIL_INDEX);
4211 ASSERT(srcFormat != GL_DEPTH_STENCIL ||
4212 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
4214 if (srcFormat == GL_DEPTH_STENCIL &&
4215 ctx->Pixel.DepthScale == 1.0f &&
4216 ctx->Pixel.DepthBias == 0.0f &&
4217 !srcPacking->SwapBytes) {
4219 memcpy_texture(ctx, dims,
4220 dstFormat, dstXoffset, dstYoffset, dstZoffset,
4221 dstRowStride, dstSlices,
4222 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
4223 srcAddr, srcPacking);
4225 else if (srcFormat == GL_DEPTH_COMPONENT ||
4226 srcFormat == GL_STENCIL_INDEX) {
4228 const GLint srcRowStride
4229 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
4232 /* In case we only upload depth we need to preserve the stencil */
4233 for (img = 0; img < srcDepth; img++) {
4234 uint64_t *dstRow = (uint64_t *) (dstSlices[dstZoffset + img]
4235 + dstYoffset * dstRowStride
4238 = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
4239 srcWidth, srcHeight,
4242 for (row = 0; row < srcHeight; row++) {
4243 /* The unpack functions with:
4244 * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
4245 * only write their own dword, so the other dword (stencil
4246 * or depth) is preserved. */
4247 if (srcFormat != GL_STENCIL_INDEX)
4248 _mesa_unpack_depth_span(ctx, srcWidth,
4249 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
4250 dstRow, /* dst addr */
4251 1.0f, srcType, src, srcPacking);
4253 if (srcFormat != GL_DEPTH_COMPONENT)
4254 _mesa_unpack_stencil_span(ctx, srcWidth,
4255 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
4256 dstRow, /* dst addr */
4257 srcType, src, srcPacking,
4258 ctx->_ImageTransferState);
4260 src += srcRowStride;
4261 dstRow += dstRowStride / sizeof(uint64_t);
4269 _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
4271 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
4272 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
4274 ASSERT(dstFormat == MESA_FORMAT_ARGB2101010_UINT);
4275 ASSERT(texelBytes == 4);
4277 if (!srcPacking->SwapBytes &&
4278 dstFormat == MESA_FORMAT_ARGB2101010_UINT &&
4279 srcFormat == GL_BGRA_INTEGER_EXT &&
4280 srcType == GL_UNSIGNED_INT_2_10_10_10_REV &&
4281 baseInternalFormat == GL_RGBA) {
4282 /* simple memcpy path */
4283 memcpy_texture(ctx, dims,
4284 dstFormat, dstXoffset, dstYoffset, dstZoffset,
4285 dstRowStride, dstSlices,
4286 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
4287 srcAddr, srcPacking);
4291 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
4294 srcWidth, srcHeight,
4295 srcDepth, srcFormat,
4298 const GLuint *src = tempImage;
4299 GLint img, row, col;
4302 for (img = 0; img < srcDepth; img++) {
4303 GLubyte *dstRow = dstSlices[dstZoffset + img]
4304 + dstYoffset * dstRowStride
4305 + dstXoffset * texelBytes;
4307 for (row = 0; row < srcHeight; row++) {
4308 GLuint *dstUI = (GLuint *) dstRow;
4309 for (col = 0; col < srcWidth; col++) {
4315 dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
4318 dstRow += dstRowStride;
4321 free((void *) tempImage);
4327 _mesa_texstore_null(TEXSTORE_PARAMS)
4329 (void) ctx; (void) dims;
4330 (void) baseInternalFormat;
4332 (void) dstXoffset; (void) dstYoffset; (void) dstZoffset;
4333 (void) dstRowStride; (void) dstSlices,
4334 (void) srcWidth; (void) srcHeight; (void) srcDepth;
4335 (void) srcFormat; (void) srcType;
4339 /* should never happen */
4340 _mesa_problem(NULL, "_mesa_texstore_null() is called");
4346 * Return the StoreTexImageFunc pointer to store an image in the given format.
4348 static StoreTexImageFunc
4349 _mesa_get_texstore_func(gl_format format)
4351 static StoreTexImageFunc table[MESA_FORMAT_COUNT];
4352 static GLboolean initialized = GL_FALSE;
4355 table[MESA_FORMAT_NONE] = _mesa_texstore_null;
4357 table[MESA_FORMAT_RGBA8888] = _mesa_texstore_rgba8888;
4358 table[MESA_FORMAT_RGBA8888_REV] = _mesa_texstore_rgba8888;
4359 table[MESA_FORMAT_ARGB8888] = _mesa_texstore_argb8888;
4360 table[MESA_FORMAT_ARGB8888_REV] = _mesa_texstore_argb8888;
4361 table[MESA_FORMAT_RGBX8888] = _mesa_texstore_rgba8888;
4362 table[MESA_FORMAT_RGBX8888_REV] = _mesa_texstore_rgba8888;
4363 table[MESA_FORMAT_XRGB8888] = _mesa_texstore_argb8888;
4364 table[MESA_FORMAT_XRGB8888_REV] = _mesa_texstore_argb8888;
4365 table[MESA_FORMAT_RGB888] = _mesa_texstore_rgb888;
4366 table[MESA_FORMAT_BGR888] = _mesa_texstore_bgr888;
4367 table[MESA_FORMAT_RGB565] = _mesa_texstore_rgb565;
4368 table[MESA_FORMAT_RGB565_REV] = _mesa_texstore_rgb565;
4369 table[MESA_FORMAT_ARGB4444] = _mesa_texstore_argb4444;
4370 table[MESA_FORMAT_ARGB4444_REV] = _mesa_texstore_argb4444;
4371 table[MESA_FORMAT_RGBA5551] = _mesa_texstore_rgba5551;
4372 table[MESA_FORMAT_ARGB1555] = _mesa_texstore_argb1555;
4373 table[MESA_FORMAT_ARGB1555_REV] = _mesa_texstore_argb1555;
4374 table[MESA_FORMAT_AL44] = _mesa_texstore_unorm44;
4375 table[MESA_FORMAT_AL88] = _mesa_texstore_unorm88;
4376 table[MESA_FORMAT_AL88_REV] = _mesa_texstore_unorm88;
4377 table[MESA_FORMAT_AL1616] = _mesa_texstore_unorm1616;
4378 table[MESA_FORMAT_AL1616_REV] = _mesa_texstore_unorm1616;
4379 table[MESA_FORMAT_RGB332] = _mesa_texstore_rgb332;
4380 table[MESA_FORMAT_A8] = _mesa_texstore_unorm8;
4381 table[MESA_FORMAT_A16] = _mesa_texstore_unorm16;
4382 table[MESA_FORMAT_L8] = _mesa_texstore_unorm8;
4383 table[MESA_FORMAT_L16] = _mesa_texstore_unorm16;
4384 table[MESA_FORMAT_I8] = _mesa_texstore_unorm8;
4385 table[MESA_FORMAT_I16] = _mesa_texstore_unorm16;
4386 table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;
4387 table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;
4388 table[MESA_FORMAT_R8] = _mesa_texstore_unorm8;
4389 table[MESA_FORMAT_GR88] = _mesa_texstore_unorm88;
4390 table[MESA_FORMAT_RG88] = _mesa_texstore_unorm88;
4391 table[MESA_FORMAT_R16] = _mesa_texstore_unorm16;
4392 table[MESA_FORMAT_RG1616] = _mesa_texstore_unorm1616;
4393 table[MESA_FORMAT_RG1616_REV] = _mesa_texstore_unorm1616;
4394 table[MESA_FORMAT_ARGB2101010] = _mesa_texstore_argb2101010;
4395 table[MESA_FORMAT_Z24_S8] = _mesa_texstore_z24_s8;
4396 table[MESA_FORMAT_S8_Z24] = _mesa_texstore_s8_z24;
4397 table[MESA_FORMAT_Z16] = _mesa_texstore_z16;
4398 table[MESA_FORMAT_X8_Z24] = _mesa_texstore_x8_z24;
4399 table[MESA_FORMAT_Z24_X8] = _mesa_texstore_z24_x8;
4400 table[MESA_FORMAT_Z32] = _mesa_texstore_z32;
4401 table[MESA_FORMAT_S8] = _mesa_texstore_s8;
4402 table[MESA_FORMAT_SRGB8] = _mesa_texstore_srgb8;
4403 table[MESA_FORMAT_SRGBA8] = _mesa_texstore_srgba8;
4404 table[MESA_FORMAT_SARGB8] = _mesa_texstore_sargb8;
4405 table[MESA_FORMAT_SL8] = _mesa_texstore_sl8;
4406 table[MESA_FORMAT_SLA8] = _mesa_texstore_sla8;
4407 table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1;
4408 table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1;
4409 table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3;
4410 table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5;
4411 table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1;
4412 table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1;
4413 table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1;
4414 table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1;
4415 table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3;
4416 table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5;
4417 table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32;
4418 table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16;
4419 table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32;
4420 table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16;
4421 table[MESA_FORMAT_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
4422 table[MESA_FORMAT_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
4423 table[MESA_FORMAT_LUMINANCE_FLOAT32] = _mesa_texstore_rgba_float32;
4424 table[MESA_FORMAT_LUMINANCE_FLOAT16] = _mesa_texstore_rgba_float16;
4425 table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
4426 table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
4427 table[MESA_FORMAT_INTENSITY_FLOAT32] = _mesa_texstore_rgba_float32;
4428 table[MESA_FORMAT_INTENSITY_FLOAT16] = _mesa_texstore_rgba_float16;
4429 table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32;
4430 table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16;
4431 table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32;
4432 table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16;
4433 table[MESA_FORMAT_DUDV8] = _mesa_texstore_dudv8;
4434 table[MESA_FORMAT_SIGNED_R8] = _mesa_texstore_snorm8;
4435 table[MESA_FORMAT_SIGNED_RG88_REV] = _mesa_texstore_snorm88;
4436 table[MESA_FORMAT_SIGNED_RGBX8888] = _mesa_texstore_signed_rgbx8888;
4437 table[MESA_FORMAT_SIGNED_RGBA8888] = _mesa_texstore_signed_rgba8888;
4438 table[MESA_FORMAT_SIGNED_RGBA8888_REV] = _mesa_texstore_signed_rgba8888;
4439 table[MESA_FORMAT_SIGNED_R16] = _mesa_texstore_snorm16;
4440 table[MESA_FORMAT_SIGNED_GR1616] = _mesa_texstore_snorm1616;
4441 table[MESA_FORMAT_SIGNED_RGB_16] = _mesa_texstore_signed_rgba_16;
4442 table[MESA_FORMAT_SIGNED_RGBA_16] = _mesa_texstore_signed_rgba_16;
4443 table[MESA_FORMAT_RGBA_16] = _mesa_texstore_rgba_16;
4444 table[MESA_FORMAT_RED_RGTC1] = _mesa_texstore_red_rgtc1;
4445 table[MESA_FORMAT_SIGNED_RED_RGTC1] = _mesa_texstore_signed_red_rgtc1;
4446 table[MESA_FORMAT_RG_RGTC2] = _mesa_texstore_rg_rgtc2;
4447 table[MESA_FORMAT_SIGNED_RG_RGTC2] = _mesa_texstore_signed_rg_rgtc2;
4448 table[MESA_FORMAT_L_LATC1] = _mesa_texstore_red_rgtc1;
4449 table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1;
4450 table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2;
4451 table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2;
4452 table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
4453 table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8;
4454 table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8;
4455 table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88;
4456 table[MESA_FORMAT_SIGNED_I8] = _mesa_texstore_snorm8;
4457 table[MESA_FORMAT_SIGNED_A16] = _mesa_texstore_snorm16;
4458 table[MESA_FORMAT_SIGNED_L16] = _mesa_texstore_snorm16;
4459 table[MESA_FORMAT_SIGNED_AL1616] = _mesa_texstore_snorm1616;
4460 table[MESA_FORMAT_SIGNED_I16] = _mesa_texstore_snorm16;
4461 table[MESA_FORMAT_RGB9_E5_FLOAT] = _mesa_texstore_rgb9_e5;
4462 table[MESA_FORMAT_R11_G11_B10_FLOAT] = _mesa_texstore_r11_g11_b10f;
4463 table[MESA_FORMAT_Z32_FLOAT] = _mesa_texstore_z32;
4464 table[MESA_FORMAT_Z32_FLOAT_X24S8] = _mesa_texstore_z32f_x24s8;
4466 table[MESA_FORMAT_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
4467 table[MESA_FORMAT_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
4468 table[MESA_FORMAT_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
4469 table[MESA_FORMAT_ALPHA_INT8] = _mesa_texstore_rgba_int8;
4470 table[MESA_FORMAT_ALPHA_INT16] = _mesa_texstore_rgba_int16;
4471 table[MESA_FORMAT_ALPHA_INT32] = _mesa_texstore_rgba_int32;
4473 table[MESA_FORMAT_INTENSITY_UINT8] = _mesa_texstore_rgba_uint8;
4474 table[MESA_FORMAT_INTENSITY_UINT16] = _mesa_texstore_rgba_uint16;
4475 table[MESA_FORMAT_INTENSITY_UINT32] = _mesa_texstore_rgba_uint32;
4476 table[MESA_FORMAT_INTENSITY_INT8] = _mesa_texstore_rgba_int8;
4477 table[MESA_FORMAT_INTENSITY_INT16] = _mesa_texstore_rgba_int16;
4478 table[MESA_FORMAT_INTENSITY_INT32] = _mesa_texstore_rgba_int32;
4480 table[MESA_FORMAT_LUMINANCE_UINT8] = _mesa_texstore_rgba_uint8;
4481 table[MESA_FORMAT_LUMINANCE_UINT16] = _mesa_texstore_rgba_uint16;
4482 table[MESA_FORMAT_LUMINANCE_UINT32] = _mesa_texstore_rgba_uint32;
4483 table[MESA_FORMAT_LUMINANCE_INT8] = _mesa_texstore_rgba_int8;
4484 table[MESA_FORMAT_LUMINANCE_INT16] = _mesa_texstore_rgba_int16;
4485 table[MESA_FORMAT_LUMINANCE_INT32] = _mesa_texstore_rgba_int32;
4487 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
4488 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
4489 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
4490 table[MESA_FORMAT_LUMINANCE_ALPHA_INT8] = _mesa_texstore_rgba_int8;
4491 table[MESA_FORMAT_LUMINANCE_ALPHA_INT16] = _mesa_texstore_rgba_int16;
4492 table[MESA_FORMAT_LUMINANCE_ALPHA_INT32] = _mesa_texstore_rgba_int32;
4494 table[MESA_FORMAT_R_INT8] = _mesa_texstore_rgba_int8;
4495 table[MESA_FORMAT_RG_INT8] = _mesa_texstore_rgba_int8;
4496 table[MESA_FORMAT_RGB_INT8] = _mesa_texstore_rgba_int8;
4497 table[MESA_FORMAT_RGBA_INT8] = _mesa_texstore_rgba_int8;
4498 table[MESA_FORMAT_R_INT16] = _mesa_texstore_rgba_int16;
4499 table[MESA_FORMAT_RG_INT16] = _mesa_texstore_rgba_int16;
4500 table[MESA_FORMAT_RGB_INT16] = _mesa_texstore_rgba_int16;
4501 table[MESA_FORMAT_RGBA_INT16] = _mesa_texstore_rgba_int16;
4502 table[MESA_FORMAT_R_INT32] = _mesa_texstore_rgba_int32;
4503 table[MESA_FORMAT_RG_INT32] = _mesa_texstore_rgba_int32;
4504 table[MESA_FORMAT_RGB_INT32] = _mesa_texstore_rgba_int32;
4505 table[MESA_FORMAT_RGBA_INT32] = _mesa_texstore_rgba_int32;
4507 table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8;
4508 table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8;
4509 table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8;
4510 table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8;
4511 table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16;
4512 table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16;
4513 table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16;
4514 table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16;
4515 table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32;
4516 table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32;
4517 table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32;
4518 table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32;
4520 table[MESA_FORMAT_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint;
4521 initialized = GL_TRUE;
4524 ASSERT(table[format]);
4525 return table[format];
4530 * Store user data into texture memory.
4531 * Called via glTex[Sub]Image1/2/3D()
4534 _mesa_texstore(TEXSTORE_PARAMS)
4536 StoreTexImageFunc storeImage;
4539 storeImage = _mesa_get_texstore_func(dstFormat);
4541 success = storeImage(ctx, dims, baseInternalFormat,
4542 dstFormat, dstXoffset, dstYoffset, dstZoffset,
4543 dstRowStride, dstSlices,
4544 srcWidth, srcHeight, srcDepth,
4545 srcFormat, srcType, srcAddr, srcPacking);
4551 * Normally, we'll only _write_ texel data to a texture when we map it.
4552 * But if the user is providing depth or stencil values and the texture
4553 * image is a combined depth/stencil format, we'll actually read from
4554 * the texture buffer too (in order to insert the depth or stencil values.
4555 * \param userFormat the user-provided image format
4556 * \param texFormat the destination texture format
4559 get_read_write_mode(GLenum userFormat, gl_format texFormat)
4561 if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
4562 && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
4563 return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
4565 return GL_MAP_WRITE_BIT;
4569 * This is the software fallback for Driver.TexImage1D().
4570 * \sa _mesa_store_teximage2d()
4573 _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
4574 GLint internalFormat,
4575 GLint width, GLint border,
4576 GLenum format, GLenum type, const GLvoid *pixels,
4577 const struct gl_pixelstore_attrib *packing,
4578 struct gl_texture_object *texObj,
4579 struct gl_texture_image *texImage)
4581 const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
4591 /* allocate storage for texture data */
4592 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
4594 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
4598 pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
4599 pixels, packing, "glTexImage1D");
4601 /* Note: we check for a NULL image pointer here, _after_ we allocated
4602 * memory for the texture. That's what the GL spec calls for.
4607 /* Map dest texture buffer (write to whole region) */
4608 ctx->Driver.MapTextureImage(ctx, texImage, 0,
4611 &dstMap, &dstRowStride);
4613 success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
4614 texImage->TexFormat,
4615 0, 0, 0, /* dstX/Y/Zoffset */
4616 0, /* dstRowStride */
4619 format, type, pixels, packing);
4621 ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
4628 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
4630 _mesa_unmap_teximage_pbo(ctx, packing);
4635 * This is the software fallback for Driver.TexImage2D().
4637 * This function is oriented toward storing images in main memory, rather
4638 * than VRAM. Device driver's can easily plug in their own replacement.
4641 _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
4642 GLint internalFormat,
4643 GLint width, GLint height, GLint border,
4644 GLenum format, GLenum type, const void *pixels,
4645 const struct gl_pixelstore_attrib *packing,
4646 struct gl_texture_object *texObj,
4647 struct gl_texture_image *texImage)
4649 const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
4656 if (width == 0 || height == 0)
4659 /* allocate storage for texture data */
4660 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
4661 width, height, 1)) {
4662 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
4666 pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
4667 pixels, packing, "glTexImage2D");
4669 /* Note: we check for a NULL image pointer here, _after_ we allocated
4670 * memory for the texture. That's what the GL spec calls for.
4675 if (target == GL_TEXTURE_1D_ARRAY) {
4676 const GLint srcStride =
4677 _mesa_image_row_stride(packing, width, format, type);
4682 for (y = 0; y < height; y++) {
4683 /* Map dest texture buffer (write to whole region) */
4684 ctx->Driver.MapTextureImage(ctx, texImage, y,
4687 &dstMap, &dstRowStride);
4689 success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
4690 texImage->TexFormat,
4691 0, 0, 0, /* dstX/Y/Zoffset */
4695 format, type, pixels, packing);
4696 ctx->Driver.UnmapTextureImage(ctx, texImage, y);
4705 pixels = (const GLubyte *) pixels + srcStride;
4708 /* Map dest texture buffer (write to whole region) */
4709 ctx->Driver.MapTextureImage(ctx, texImage, 0,
4710 0, 0, width, height,
4712 &dstMap, &dstRowStride);
4714 success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
4715 texImage->TexFormat,
4716 0, 0, 0, /* dstX/Y/Zoffset */
4720 format, type, pixels, packing);
4722 ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
4730 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
4732 _mesa_unmap_teximage_pbo(ctx, packing);
4738 * This is the software fallback for Driver.TexImage3D().
4739 * \sa _mesa_store_teximage2d()
4742 _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
4743 GLint internalFormat,
4744 GLint width, GLint height, GLint depth, GLint border,
4745 GLenum format, GLenum type, const void *pixels,
4746 const struct gl_pixelstore_attrib *packing,
4747 struct gl_texture_object *texObj,
4748 struct gl_texture_image *texImage)
4750 const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
4751 GLboolean success = GL_TRUE;
4753 GLubyte **sliceMaps;
4758 if (width == 0 || height == 0 || depth == 0)
4761 /* allocate storage for texture data */
4762 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
4763 width, height, depth)) {
4764 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
4768 pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth,
4770 pixels, packing, "glTexImage3D");
4772 /* Note: we check for a NULL image pointer here, _after_ we allocated
4773 * memory for the texture. That's what the GL spec calls for.
4778 if (target == GL_TEXTURE_1D_ARRAY) {
4783 sliceMaps = (GLubyte **) calloc(depth, sizeof(GLubyte *));
4785 /* Map dest texture buffer slices */
4786 for (slice = 0; slice < depth; slice++) {
4787 ctx->Driver.MapTextureImage(ctx, texImage, slice,
4788 0, 0, width, height,
4790 &sliceMaps[slice], &dstRowStride);
4791 if (!sliceMaps[slice]) {
4798 success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
4799 texImage->TexFormat,
4800 0, 0, 0, /* dstX/Y/Zoffset */
4803 width, height, depth,
4804 format, type, pixels, packing);
4807 /* Unmap dest texture buffer slices */
4808 for (slice = 0; slice < depth; slice++) {
4809 if (sliceMaps[slice]) {
4810 ctx->Driver.UnmapTextureImage(ctx, texImage, slice);
4815 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
4817 _mesa_unmap_teximage_pbo(ctx, packing);
4826 * This is the software fallback for Driver.TexSubImage1D()
4827 * and Driver.CopyTexSubImage1D().
4830 _mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level,
4831 GLint xoffset, GLint width,
4832 GLenum format, GLenum type, const void *pixels,
4833 const struct gl_pixelstore_attrib *packing,
4834 struct gl_texture_object *texObj,
4835 struct gl_texture_image *texImage)
4837 const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
4842 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4843 pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
4844 pixels, packing, "glTexSubImage1D");
4848 /* Map dest texture buffer */
4849 ctx->Driver.MapTextureImage(ctx, texImage, 0,
4850 xoffset, 0, width, 1,
4852 &dstMap, &dstRowStride);
4855 success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
4856 texImage->TexFormat,
4857 0, 0, 0, /* dstX/Y/Zoffset */
4861 format, type, pixels, packing);
4863 ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
4870 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
4872 _mesa_unmap_teximage_pbo(ctx, packing);
4878 * This is the software fallback for Driver.TexSubImage2D()
4879 * and Driver.CopyTexSubImage2D().
4882 _mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level,
4883 GLint xoffset, GLint yoffset,
4884 GLint width, GLint height,
4885 GLenum format, GLenum type, const void *pixels,
4886 const struct gl_pixelstore_attrib *packing,
4887 struct gl_texture_object *texObj,
4888 struct gl_texture_image *texImage)
4890 const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
4895 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4896 pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
4897 pixels, packing, "glTexSubImage2D");
4901 /* Map dest texture buffer */
4902 ctx->Driver.MapTextureImage(ctx, texImage, 0,
4903 xoffset, yoffset, width, height,
4905 &dstMap, &dstRowStride);
4908 success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
4909 texImage->TexFormat,
4910 0, 0, 0, /* dstX/Y/Zoffset */
4914 format, type, pixels, packing);
4916 ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
4923 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
4925 _mesa_unmap_teximage_pbo(ctx, packing);
4930 * This is the software fallback for Driver.TexSubImage3D().
4931 * and Driver.CopyTexSubImage3D().
4934 _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
4935 GLint xoffset, GLint yoffset, GLint zoffset,
4936 GLint width, GLint height, GLint depth,
4937 GLenum format, GLenum type, const void *pixels,
4938 const struct gl_pixelstore_attrib *packing,
4939 struct gl_texture_object *texObj,
4940 struct gl_texture_image *texImage)
4942 const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
4943 GLboolean success = GL_TRUE;
4945 GLubyte **sliceMaps;
4948 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4949 pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
4950 type, pixels, packing,
4955 sliceMaps = (GLubyte **) calloc(depth, sizeof(GLubyte *));
4957 /* Map dest texture buffer slices */
4958 for (slice = 0; slice < depth; slice++) {
4959 ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice,
4960 xoffset, yoffset, width, height,
4962 &sliceMaps[slice], &dstRowStride);
4963 if (!sliceMaps[slice]) {
4970 success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
4971 texImage->TexFormat,
4975 width, height, depth,
4976 format, type, pixels, packing);
4979 /* Unmap dest texture buffer slices */
4980 for (slice = 0; slice < depth; slice++) {
4981 if (sliceMaps[slice]) {
4982 ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + slice);
4987 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
4989 _mesa_unmap_teximage_pbo(ctx, packing);
4996 * Fallback for Driver.CompressedTexImage1D()
4999 _mesa_store_compressed_teximage1d(struct gl_context *ctx,
5000 GLenum target, GLint level,
5001 GLint internalFormat,
5002 GLint width, GLint border,
5003 GLsizei imageSize, const GLvoid *data,
5004 struct gl_texture_object *texObj,
5005 struct gl_texture_image *texImage)
5007 /* this space intentionally left blank */
5009 (void) target; (void) level;
5010 (void) internalFormat;
5011 (void) width; (void) border;
5012 (void) imageSize; (void) data;
5020 * Fallback for Driver.CompressedTexImage2D()
5023 _mesa_store_compressed_teximage2d(struct gl_context *ctx,
5024 GLenum target, GLint level,
5025 GLint internalFormat,
5026 GLint width, GLint height, GLint border,
5027 GLsizei imageSize, const GLvoid *data,
5028 struct gl_texture_object *texObj,
5029 struct gl_texture_image *texImage)
5031 /* This is pretty simple, because unlike the general texstore path we don't
5032 * have to worry about the usual image unpacking or image transfer
5037 ASSERT(texImage->Width > 0);
5038 ASSERT(texImage->Height > 0);
5039 ASSERT(texImage->Depth == 1);
5041 /* allocate storage for texture data */
5042 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
5043 width, height, 1)) {
5044 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
5048 _mesa_store_compressed_texsubimage2d(ctx, target, level,
5051 texImage->TexFormat,
5059 * Fallback for Driver.CompressedTexImage3D()
5062 _mesa_store_compressed_teximage3d(struct gl_context *ctx,
5063 GLenum target, GLint level,
5064 GLint internalFormat,
5065 GLint width, GLint height, GLint depth,
5067 GLsizei imageSize, const GLvoid *data,
5068 struct gl_texture_object *texObj,
5069 struct gl_texture_image *texImage)
5071 /* this space intentionally left blank */
5073 (void) target; (void) level;
5074 (void) internalFormat;
5075 (void) width; (void) height; (void) depth;
5077 (void) imageSize; (void) data;
5085 * Fallback for Driver.CompressedTexSubImage1D()
5088 _mesa_store_compressed_texsubimage1d(struct gl_context *ctx, GLenum target,
5090 GLint xoffset, GLsizei width,
5092 GLsizei imageSize, const GLvoid *data,
5093 struct gl_texture_object *texObj,
5094 struct gl_texture_image *texImage)
5096 /* there are no compressed 1D texture formats yet */
5098 (void) target; (void) level;
5099 (void) xoffset; (void) width;
5101 (void) imageSize; (void) data;
5108 * Fallback for Driver.CompressedTexSubImage2D()
5111 _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
5113 GLint xoffset, GLint yoffset,
5114 GLsizei width, GLsizei height,
5116 GLsizei imageSize, const GLvoid *data,
5117 struct gl_texture_object *texObj,
5118 struct gl_texture_image *texImage)
5120 GLint bytesPerRow, dstRowStride, srcRowStride;
5124 const gl_format texFormat = texImage->TexFormat;
5127 _mesa_get_format_block_size(texFormat, &bw, &bh);
5129 /* these should have been caught sooner */
5130 ASSERT((width % bw) == 0 || width < bw);
5131 ASSERT((height % bh) == 0 || height < bh);
5132 ASSERT((xoffset % bw) == 0);
5133 ASSERT((yoffset % bh) == 0);
5135 /* get pointer to src pixels (may be in a pbo which we'll map here) */
5136 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
5138 "glCompressedTexSubImage2D");
5142 srcRowStride = _mesa_format_row_stride(texFormat, width);
5143 src = (const GLubyte *) data;
5145 /* Map dest texture buffer */
5146 ctx->Driver.MapTextureImage(ctx, texImage, 0,
5147 xoffset, yoffset, width, height,
5149 &dstMap, &dstRowStride);
5152 bytesPerRow = srcRowStride; /* bytes per row of blocks */
5153 rows = (height + bh - 1) / bh; /* rows in blocks */
5155 /* copy rows of blocks */
5156 for (i = 0; i < rows; i++) {
5157 memcpy(dstMap, src, bytesPerRow);
5158 dstMap += dstRowStride;
5159 src += srcRowStride;
5162 ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
5165 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D");
5168 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
5173 * Fallback for Driver.CompressedTexSubImage3D()
5176 _mesa_store_compressed_texsubimage3d(struct gl_context *ctx, GLenum target,
5178 GLint xoffset, GLint yoffset, GLint zoffset,
5179 GLsizei width, GLsizei height, GLsizei depth,
5181 GLsizei imageSize, const GLvoid *data,
5182 struct gl_texture_object *texObj,
5183 struct gl_texture_image *texImage)
5185 /* there are no compressed 3D texture formats yet */
5187 (void) target; (void) level;
5188 (void) xoffset; (void) yoffset; (void) zoffset;
5189 (void) width; (void) height; (void) depth;
5191 (void) imageSize; (void) data;