2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (c) 2008 VMware, Inc.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 * The GL texture image functions in teximage.c basically just do
33 * error checking and data structure allocation. They in turn call
34 * device driver functions which actually copy/convert/store the user's
37 * However, most device drivers will be able to use the fallback functions
38 * in this file. That is, most drivers will have the following bit of
40 * ctx->Driver.TexImage1D = _mesa_store_teximage1d;
41 * ctx->Driver.TexImage2D = _mesa_store_teximage2d;
42 * ctx->Driver.TexImage3D = _mesa_store_teximage3d;
45 * Texture image processing is actually kind of complicated. We have to do:
46 * Format/type conversions
48 * pixel transfer (scale, bais, lookup, convolution!, etc)
50 * These functions can handle most everything, including processing full
51 * images and sub-images.
56 #include "bufferobj.h"
66 #include "texcompress.h"
67 #include "texformat.h"
80 * Return GL_TRUE if the given image format is one that be converted
81 * to another format by swizzling.
84 can_swizzle(GLenum logicalBaseFormat
)
86 switch (logicalBaseFormat
) {
89 case GL_LUMINANCE_ALPHA
:
123 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO)
124 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO)
125 #define MAP3(x,y,z) MAP4(x, y, z, ZERO)
126 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
129 static const struct {
132 GLubyte from_rgba
[6];
133 } mappings
[MAX_IDX
] =
143 MAP4(ZERO
, ZERO
, ZERO
, 0),
174 MAP4(0, ZERO
, ZERO
, ONE
),
180 MAP4(ZERO
, 0, ZERO
, ONE
),
186 MAP4(ZERO
, ZERO
, 0, ONE
),
212 * Convert a GL image format enum to an IDX_* value (see above).
215 get_map_idx(GLenum value
)
218 case GL_LUMINANCE
: return IDX_LUMINANCE
;
219 case GL_ALPHA
: return IDX_ALPHA
;
220 case GL_INTENSITY
: return IDX_INTENSITY
;
221 case GL_LUMINANCE_ALPHA
: return IDX_LUMINANCE_ALPHA
;
222 case GL_RGB
: return IDX_RGB
;
223 case GL_RGBA
: return IDX_RGBA
;
224 case GL_RED
: return IDX_RED
;
225 case GL_GREEN
: return IDX_GREEN
;
226 case GL_BLUE
: return IDX_BLUE
;
227 case GL_BGR
: return IDX_BGR
;
228 case GL_BGRA
: return IDX_BGRA
;
229 case GL_ABGR_EXT
: return IDX_ABGR
;
231 _mesa_problem(NULL
, "Unexpected inFormat");
238 * When promoting texture formats (see below) we need to compute the
239 * mapping of dest components back to source components.
240 * This function does that.
241 * \param inFormat the incoming format of the texture
242 * \param outFormat the final texture format
243 * \return map[6] a full 6-component map
246 compute_component_mapping(GLenum inFormat
, GLenum outFormat
,
249 const int inFmt
= get_map_idx(inFormat
);
250 const int outFmt
= get_map_idx(outFormat
);
251 const GLubyte
*in2rgba
= mappings
[inFmt
].to_rgba
;
252 const GLubyte
*rgba2out
= mappings
[outFmt
].from_rgba
;
255 for (i
= 0; i
< 4; i
++)
256 map
[i
] = in2rgba
[rgba2out
[i
]];
262 _mesa_printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
263 inFormat, _mesa_lookup_enum_by_nr(inFormat),
264 outFormat, _mesa_lookup_enum_by_nr(outFormat),
275 #if !FEATURE_convolve
277 _mesa_adjust_image_for_convolution(GLcontext
*ctx
, GLuint dims
,
278 GLsizei
*srcWidth
, GLsizei
*srcHeight
)
286 * Make a temporary (color) texture image with GLfloat components.
287 * Apply all needed pixel unpacking and pixel transfer operations.
288 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
289 * Suppose the user specifies GL_LUMINANCE as the internal texture format
290 * but the graphics hardware doesn't support luminance textures. So, might
291 * use an RGB hardware format instead.
292 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
294 * \param ctx the rendering context
295 * \param dims image dimensions: 1, 2 or 3
296 * \param logicalBaseFormat basic texture derived from the user's
297 * internal texture format value
298 * \param textureBaseFormat the actual basic format of the texture
299 * \param srcWidth source image width
300 * \param srcHeight source image height
301 * \param srcDepth source image depth
302 * \param srcFormat source image format
303 * \param srcType source image type
304 * \param srcAddr source image address
305 * \param srcPacking source image pixel packing
306 * \return resulting image with format = textureBaseFormat and type = GLfloat.
309 make_temp_float_image(GLcontext
*ctx
, GLuint dims
,
310 GLenum logicalBaseFormat
,
311 GLenum textureBaseFormat
,
312 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
313 GLenum srcFormat
, GLenum srcType
,
314 const GLvoid
*srcAddr
,
315 const struct gl_pixelstore_attrib
*srcPacking
)
317 GLuint transferOps
= ctx
->_ImageTransferState
;
320 ASSERT(dims
>= 1 && dims
<= 3);
322 ASSERT(logicalBaseFormat
== GL_RGBA
||
323 logicalBaseFormat
== GL_RGB
||
324 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
325 logicalBaseFormat
== GL_LUMINANCE
||
326 logicalBaseFormat
== GL_ALPHA
||
327 logicalBaseFormat
== GL_INTENSITY
||
328 logicalBaseFormat
== GL_COLOR_INDEX
||
329 logicalBaseFormat
== GL_DEPTH_COMPONENT
);
331 ASSERT(textureBaseFormat
== GL_RGBA
||
332 textureBaseFormat
== GL_RGB
||
333 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
334 textureBaseFormat
== GL_LUMINANCE
||
335 textureBaseFormat
== GL_ALPHA
||
336 textureBaseFormat
== GL_INTENSITY
||
337 textureBaseFormat
== GL_COLOR_INDEX
||
338 textureBaseFormat
== GL_DEPTH_COMPONENT
);
340 /* conventional color image */
342 if ((dims
== 1 && ctx
->Pixel
.Convolution1DEnabled
) ||
343 (dims
>= 2 && ctx
->Pixel
.Convolution2DEnabled
) ||
344 (dims
>= 2 && ctx
->Pixel
.Separable2DEnabled
)) {
345 /* need image convolution */
346 const GLuint preConvTransferOps
347 = (transferOps
& IMAGE_PRE_CONVOLUTION_BITS
) | IMAGE_CLAMP_BIT
;
348 const GLuint postConvTransferOps
349 = (transferOps
& IMAGE_POST_CONVOLUTION_BITS
) | IMAGE_CLAMP_BIT
;
351 GLint convWidth
, convHeight
;
354 /* pre-convolution image buffer (3D) */
355 tempImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
356 * 4 * sizeof(GLfloat
));
360 /* post-convolution image buffer (2D) */
361 convImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
362 * 4 * sizeof(GLfloat
));
364 _mesa_free(tempImage
);
368 /* loop over 3D image slices */
369 for (img
= 0; img
< srcDepth
; img
++) {
370 GLfloat
*dst
= tempImage
+ img
* (srcWidth
* srcHeight
* 4);
372 /* unpack and do transfer ops up to convolution */
373 for (row
= 0; row
< srcHeight
; row
++) {
374 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
375 srcAddr
, srcWidth
, srcHeight
,
376 srcFormat
, srcType
, img
, row
, 0);
377 _mesa_unpack_color_span_float(ctx
, srcWidth
, GL_RGBA
, dst
,
378 srcFormat
, srcType
, src
,
384 /* size after optional convolution */
385 convWidth
= srcWidth
;
386 convHeight
= srcHeight
;
391 GLfloat
*src
= tempImage
+ img
* (srcWidth
* srcHeight
* 4);
393 ASSERT(ctx
->Pixel
.Convolution1DEnabled
);
394 _mesa_convolve_1d_image(ctx
, &convWidth
, src
, convImage
);
397 if (ctx
->Pixel
.Convolution2DEnabled
) {
398 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
402 ASSERT(ctx
->Pixel
.Separable2DEnabled
);
403 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
409 /* do post-convolution transfer and pack into tempImage */
411 const GLint logComponents
412 = _mesa_components_in_format(logicalBaseFormat
);
413 const GLfloat
*src
= convImage
;
414 GLfloat
*dst
= tempImage
+ img
* (convWidth
* convHeight
* 4);
415 for (row
= 0; row
< convHeight
; row
++) {
416 _mesa_pack_rgba_span_float(ctx
, convWidth
,
417 (GLfloat (*)[4]) src
,
418 logicalBaseFormat
, GL_FLOAT
,
419 dst
, &ctx
->DefaultPacking
,
420 postConvTransferOps
);
421 src
+= convWidth
* 4;
422 dst
+= convWidth
* logComponents
;
425 } /* loop over 3D image slices */
427 _mesa_free(convImage
);
429 /* might need these below */
430 srcWidth
= convWidth
;
431 srcHeight
= convHeight
;
435 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
436 const GLint srcStride
= _mesa_image_row_stride(srcPacking
,
437 srcWidth
, srcFormat
, srcType
);
441 tempImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
442 * components
* sizeof(GLfloat
));
447 for (img
= 0; img
< srcDepth
; img
++) {
449 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
453 for (row
= 0; row
< srcHeight
; row
++) {
454 _mesa_unpack_color_span_float(ctx
, srcWidth
, logicalBaseFormat
,
455 dst
, srcFormat
, srcType
, src
,
456 srcPacking
, transferOps
);
457 dst
+= srcWidth
* components
;
463 if (logicalBaseFormat
!= textureBaseFormat
) {
465 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
466 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
471 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
472 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
473 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
475 /* The actual texture format should have at least as many components
476 * as the logical texture format.
478 ASSERT(texComponents
>= logComponents
);
480 newImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
481 * texComponents
* sizeof(GLfloat
));
483 _mesa_free(tempImage
);
487 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
489 n
= srcWidth
* srcHeight
* srcDepth
;
490 for (i
= 0; i
< n
; i
++) {
492 for (k
= 0; k
< texComponents
; k
++) {
495 newImage
[i
* texComponents
+ k
] = 0.0F
;
497 newImage
[i
* texComponents
+ k
] = 1.0F
;
499 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
503 _mesa_free(tempImage
);
504 tempImage
= newImage
;
512 * Make a temporary (color) texture image with GLchan components.
513 * Apply all needed pixel unpacking and pixel transfer operations.
514 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
515 * Suppose the user specifies GL_LUMINANCE as the internal texture format
516 * but the graphics hardware doesn't support luminance textures. So, might
517 * use an RGB hardware format instead.
518 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
520 * \param ctx the rendering context
521 * \param dims image dimensions: 1, 2 or 3
522 * \param logicalBaseFormat basic texture derived from the user's
523 * internal texture format value
524 * \param textureBaseFormat the actual basic format of the texture
525 * \param srcWidth source image width
526 * \param srcHeight source image height
527 * \param srcDepth source image depth
528 * \param srcFormat source image format
529 * \param srcType source image type
530 * \param srcAddr source image address
531 * \param srcPacking source image pixel packing
532 * \return resulting image with format = textureBaseFormat and type = GLchan.
535 _mesa_make_temp_chan_image(GLcontext
*ctx
, GLuint dims
,
536 GLenum logicalBaseFormat
,
537 GLenum textureBaseFormat
,
538 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
539 GLenum srcFormat
, GLenum srcType
,
540 const GLvoid
*srcAddr
,
541 const struct gl_pixelstore_attrib
*srcPacking
)
543 GLuint transferOps
= ctx
->_ImageTransferState
;
544 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
545 GLboolean freeSrcImage
= GL_FALSE
;
547 GLchan
*tempImage
, *dst
;
549 ASSERT(dims
>= 1 && dims
<= 3);
551 ASSERT(logicalBaseFormat
== GL_RGBA
||
552 logicalBaseFormat
== GL_RGB
||
553 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
554 logicalBaseFormat
== GL_LUMINANCE
||
555 logicalBaseFormat
== GL_ALPHA
||
556 logicalBaseFormat
== GL_INTENSITY
);
558 ASSERT(textureBaseFormat
== GL_RGBA
||
559 textureBaseFormat
== GL_RGB
||
560 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
561 textureBaseFormat
== GL_LUMINANCE
||
562 textureBaseFormat
== GL_ALPHA
||
563 textureBaseFormat
== GL_INTENSITY
);
566 if ((dims
== 1 && ctx
->Pixel
.Convolution1DEnabled
) ||
567 (dims
>= 2 && ctx
->Pixel
.Convolution2DEnabled
) ||
568 (dims
>= 2 && ctx
->Pixel
.Separable2DEnabled
)) {
569 /* get convolved image */
570 GLfloat
*convImage
= make_temp_float_image(ctx
, dims
,
573 srcWidth
, srcHeight
, srcDepth
,
575 srcAddr
, srcPacking
);
578 /* the convolved image is our new source image */
580 srcFormat
= logicalBaseFormat
;
582 srcPacking
= &ctx
->DefaultPacking
;
583 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
585 freeSrcImage
= GL_TRUE
;
589 /* unpack and transfer the source image */
590 tempImage
= (GLchan
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
591 * components
* sizeof(GLchan
));
596 for (img
= 0; img
< srcDepth
; img
++) {
597 const GLint srcStride
= _mesa_image_row_stride(srcPacking
,
601 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
605 for (row
= 0; row
< srcHeight
; row
++) {
606 _mesa_unpack_color_span_chan(ctx
, srcWidth
, logicalBaseFormat
, dst
,
607 srcFormat
, srcType
, src
, srcPacking
,
609 dst
+= srcWidth
* components
;
614 /* If we made a temporary image for convolution, free it here */
616 _mesa_free((void *) srcAddr
);
619 if (logicalBaseFormat
!= textureBaseFormat
) {
620 /* one more conversion step */
621 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
622 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
627 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
628 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
629 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
631 /* The actual texture format should have at least as many components
632 * as the logical texture format.
634 ASSERT(texComponents
>= logComponents
);
636 newImage
= (GLchan
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
637 * texComponents
* sizeof(GLchan
));
639 _mesa_free(tempImage
);
643 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
645 n
= srcWidth
* srcHeight
* srcDepth
;
646 for (i
= 0; i
< n
; i
++) {
648 for (k
= 0; k
< texComponents
; k
++) {
651 newImage
[i
* texComponents
+ k
] = 0;
653 newImage
[i
* texComponents
+ k
] = CHAN_MAX
;
655 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
659 _mesa_free(tempImage
);
660 tempImage
= newImage
;
668 * Copy GLubyte pixels from <src> to <dst> with swizzling.
669 * \param dst destination pixels
670 * \param dstComponents number of color components in destination pixels
671 * \param src source pixels
672 * \param srcComponents number of color components in source pixels
673 * \param map the swizzle mapping. map[X] says where to find the X component
674 * in the source image's pixels. For example, if the source image
675 * is GL_BGRA and X = red, map[0] yields 2.
676 * \param count number of pixels to copy/swizzle.
679 swizzle_copy(GLubyte
*dst
, GLuint dstComponents
, const GLubyte
*src
,
680 GLuint srcComponents
, const GLubyte
*map
, GLuint count
)
682 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
685 for (i = 0; i < count; i++) { \
687 if (srcComps == 4) { \
688 COPY_4UBV(tmp, src); \
691 for (j = 0; j < srcComps; j++) { \
696 for (j = 0; j < dstComps; j++) { \
697 dst[j] = tmp[map[j]]; \
708 ASSERT(srcComponents
<= 4);
709 ASSERT(dstComponents
<= 4);
711 switch (dstComponents
) {
713 switch (srcComponents
) {
715 SWZ_CPY(dst
, src
, count
, 4, 4);
718 SWZ_CPY(dst
, src
, count
, 4, 3);
721 SWZ_CPY(dst
, src
, count
, 4, 2);
724 SWZ_CPY(dst
, src
, count
, 4, 1);
731 switch (srcComponents
) {
733 SWZ_CPY(dst
, src
, count
, 3, 4);
736 SWZ_CPY(dst
, src
, count
, 3, 3);
739 SWZ_CPY(dst
, src
, count
, 3, 2);
742 SWZ_CPY(dst
, src
, count
, 3, 1);
749 switch (srcComponents
) {
751 SWZ_CPY(dst
, src
, count
, 2, 4);
754 SWZ_CPY(dst
, src
, count
, 2, 3);
757 SWZ_CPY(dst
, src
, count
, 2, 2);
760 SWZ_CPY(dst
, src
, count
, 2, 1);
767 switch (srcComponents
) {
769 SWZ_CPY(dst
, src
, count
, 1, 4);
772 SWZ_CPY(dst
, src
, count
, 1, 3);
775 SWZ_CPY(dst
, src
, count
, 1, 2);
778 SWZ_CPY(dst
, src
, count
, 1, 1);
792 static const GLubyte map_identity
[6] = { 0, 1, 2, 3, ZERO
, ONE
};
793 static const GLubyte map_3210
[6] = { 3, 2, 1, 0, ZERO
, ONE
};
795 /* Deal with the _REV input types:
797 static const GLubyte
*
798 type_mapping( GLenum srcType
)
802 case GL_UNSIGNED_BYTE
:
804 case GL_UNSIGNED_INT_8_8_8_8
:
805 return _mesa_little_endian() ? map_3210
: map_identity
;
806 case GL_UNSIGNED_INT_8_8_8_8_REV
:
807 return _mesa_little_endian() ? map_identity
: map_3210
;
813 /* Mapping required if input type is
815 static const GLubyte
*
816 byteswap_mapping( GLboolean swapBytes
,
824 case GL_UNSIGNED_BYTE
:
826 case GL_UNSIGNED_INT_8_8_8_8
:
827 case GL_UNSIGNED_INT_8_8_8_8_REV
:
837 * Transfer a GLubyte texture image with component swizzling.
840 _mesa_swizzle_ubyte_image(GLcontext
*ctx
,
845 GLenum baseInternalFormat
,
847 const GLubyte
*rgba2dst
,
848 GLuint dstComponents
,
851 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
853 const GLuint
*dstImageOffsets
,
855 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
856 const GLvoid
*srcAddr
,
857 const struct gl_pixelstore_attrib
*srcPacking
)
859 GLint srcComponents
= _mesa_components_in_format(srcFormat
);
860 const GLubyte
*srctype2ubyte
, *swap
;
861 GLubyte map
[4], src2base
[6], base2rgba
[6];
863 const GLint srcRowStride
=
864 _mesa_image_row_stride(srcPacking
, srcWidth
,
865 srcFormat
, GL_UNSIGNED_BYTE
);
866 const GLint srcImageStride
867 = _mesa_image_image_stride(srcPacking
, srcWidth
, srcHeight
, srcFormat
,
869 const GLubyte
*srcImage
870 = (const GLubyte
*) _mesa_image_address(dimensions
, srcPacking
, srcAddr
,
871 srcWidth
, srcHeight
, srcFormat
,
872 GL_UNSIGNED_BYTE
, 0, 0, 0);
876 /* Translate from src->baseInternal->GL_RGBA->dst. This will
877 * correctly deal with RGBA->RGB->RGBA conversions where the final
878 * A value must be 0xff regardless of the incoming alpha values.
880 compute_component_mapping(srcFormat
, baseInternalFormat
, src2base
);
881 compute_component_mapping(baseInternalFormat
, GL_RGBA
, base2rgba
);
882 swap
= byteswap_mapping(srcPacking
->SwapBytes
, srcType
);
883 srctype2ubyte
= type_mapping(srcType
);
886 for (i
= 0; i
< 4; i
++)
887 map
[i
] = srctype2ubyte
[swap
[src2base
[base2rgba
[rgba2dst
[i
]]]]];
889 /* _mesa_printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */
891 if (srcComponents
== dstComponents
&&
892 srcRowStride
== dstRowStride
&&
893 srcRowStride
== srcWidth
* srcComponents
&&
895 /* 1 and 2D images only */
896 GLubyte
*dstImage
= (GLubyte
*) dstAddr
897 + dstYoffset
* dstRowStride
898 + dstXoffset
* dstComponents
;
899 swizzle_copy(dstImage
, dstComponents
, srcImage
, srcComponents
, map
,
900 srcWidth
* srcHeight
);
904 for (img
= 0; img
< srcDepth
; img
++) {
905 const GLubyte
*srcRow
= srcImage
;
906 GLubyte
*dstRow
= (GLubyte
*) dstAddr
907 + dstImageOffsets
[dstZoffset
+ img
] * dstComponents
908 + dstYoffset
* dstRowStride
909 + dstXoffset
* dstComponents
;
910 for (row
= 0; row
< srcHeight
; row
++) {
911 swizzle_copy(dstRow
, dstComponents
, srcRow
, srcComponents
, map
, srcWidth
);
912 dstRow
+= dstRowStride
;
913 srcRow
+= srcRowStride
;
915 srcImage
+= srcImageStride
;
922 * Teximage storage routine for when a simple memcpy will do.
923 * No pixel transfer operations or special texel encodings allowed.
924 * 1D, 2D and 3D images supported.
927 memcpy_texture(GLcontext
*ctx
,
929 const struct gl_texture_format
*dstFormat
,
931 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
933 const GLuint
*dstImageOffsets
,
934 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
935 GLenum srcFormat
, GLenum srcType
,
936 const GLvoid
*srcAddr
,
937 const struct gl_pixelstore_attrib
*srcPacking
)
939 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
941 const GLint srcImageStride
= _mesa_image_image_stride(srcPacking
,
942 srcWidth
, srcHeight
, srcFormat
, srcType
);
943 const GLubyte
*srcImage
= (const GLubyte
*) _mesa_image_address(dimensions
,
944 srcPacking
, srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, 0, 0, 0);
945 const GLint bytesPerRow
= srcWidth
* dstFormat
->TexelBytes
;
948 /* XXX update/re-enable for dstImageOffsets array */
949 const GLint bytesPerImage
= srcHeight
* bytesPerRow
;
950 const GLint bytesPerTexture
= srcDepth
* bytesPerImage
;
951 GLubyte
*dstImage
= (GLubyte
*) dstAddr
952 + dstZoffset
* dstImageStride
953 + dstYoffset
* dstRowStride
954 + dstXoffset
* dstFormat
->TexelBytes
;
956 if (dstRowStride
== srcRowStride
&&
957 dstRowStride
== bytesPerRow
&&
958 ((dstImageStride
== srcImageStride
&&
959 dstImageStride
== bytesPerImage
) ||
962 ctx
->Driver
.TextureMemCpy(dstImage
, srcImage
, bytesPerTexture
);
967 for (img
= 0; img
< srcDepth
; img
++) {
968 const GLubyte
*srcRow
= srcImage
;
969 GLubyte
*dstRow
= dstImage
;
970 for (row
= 0; row
< srcHeight
; row
++) {
971 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
972 dstRow
+= dstRowStride
;
973 srcRow
+= srcRowStride
;
975 srcImage
+= srcImageStride
;
976 dstImage
+= dstImageStride
;
982 for (img
= 0; img
< srcDepth
; img
++) {
983 const GLubyte
*srcRow
= srcImage
;
984 GLubyte
*dstRow
= (GLubyte
*) dstAddr
985 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
986 + dstYoffset
* dstRowStride
987 + dstXoffset
* dstFormat
->TexelBytes
;
988 for (row
= 0; row
< srcHeight
; row
++) {
989 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
990 dstRow
+= dstRowStride
;
991 srcRow
+= srcRowStride
;
993 srcImage
+= srcImageStride
;
1000 * Store an image in any of the formats:
1001 * _mesa_texformat_rgba
1002 * _mesa_texformat_rgb
1003 * _mesa_texformat_alpha
1004 * _mesa_texformat_luminance
1005 * _mesa_texformat_luminance_alpha
1006 * _mesa_texformat_intensity
1010 _mesa_texstore_rgba(TEXSTORE_PARAMS
)
1012 const GLint components
= _mesa_components_in_format(baseInternalFormat
);
1014 ASSERT(dstFormat
== &_mesa_texformat_rgba
||
1015 dstFormat
== &_mesa_texformat_rgb
||
1016 dstFormat
== &_mesa_texformat_alpha
||
1017 dstFormat
== &_mesa_texformat_luminance
||
1018 dstFormat
== &_mesa_texformat_luminance_alpha
||
1019 dstFormat
== &_mesa_texformat_intensity
);
1020 ASSERT(baseInternalFormat
== GL_RGBA
||
1021 baseInternalFormat
== GL_RGB
||
1022 baseInternalFormat
== GL_ALPHA
||
1023 baseInternalFormat
== GL_LUMINANCE
||
1024 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
1025 baseInternalFormat
== GL_INTENSITY
);
1026 ASSERT(dstFormat
->TexelBytes
== components
* sizeof(GLchan
));
1028 if (!ctx
->_ImageTransferState
&&
1029 !srcPacking
->SwapBytes
&&
1030 baseInternalFormat
== srcFormat
&&
1031 srcType
== CHAN_TYPE
) {
1032 /* simple memcpy path */
1033 memcpy_texture(ctx
, dims
,
1034 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1037 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1038 srcAddr
, srcPacking
);
1040 else if (!ctx
->_ImageTransferState
&&
1041 !srcPacking
->SwapBytes
&&
1042 dstFormat
== &_mesa_texformat_rgb
&&
1043 srcFormat
== GL_RGBA
&&
1044 srcType
== CHAN_TYPE
) {
1045 /* extract RGB from RGBA */
1046 GLint img
, row
, col
;
1047 for (img
= 0; img
< srcDepth
; img
++) {
1048 GLchan
*dstImage
= (GLchan
*)
1049 ((GLubyte
*) dstAddr
1050 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1051 + dstYoffset
* dstRowStride
1052 + dstXoffset
* dstFormat
->TexelBytes
);
1054 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1055 srcWidth
, srcFormat
, srcType
);
1056 GLchan
*srcRow
= (GLchan
*) _mesa_image_address(dims
, srcPacking
,
1057 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1058 GLchan
*dstRow
= dstImage
;
1059 for (row
= 0; row
< srcHeight
; row
++) {
1060 for (col
= 0; col
< srcWidth
; col
++) {
1061 dstRow
[col
* 3 + RCOMP
] = srcRow
[col
* 4 + RCOMP
];
1062 dstRow
[col
* 3 + GCOMP
] = srcRow
[col
* 4 + GCOMP
];
1063 dstRow
[col
* 3 + BCOMP
] = srcRow
[col
* 4 + BCOMP
];
1065 dstRow
+= dstRowStride
/ sizeof(GLchan
);
1066 srcRow
= (GLchan
*) ((GLubyte
*) srcRow
+ srcRowStride
);
1070 else if (!ctx
->_ImageTransferState
&&
1071 CHAN_TYPE
== GL_UNSIGNED_BYTE
&&
1072 (srcType
== GL_UNSIGNED_BYTE
||
1073 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1074 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1075 can_swizzle(baseInternalFormat
) &&
1076 can_swizzle(srcFormat
)) {
1078 const GLubyte
*dstmap
;
1081 /* dstmap - how to swizzle from RGBA to dst format:
1083 if (dstFormat
== &_mesa_texformat_rgba
) {
1084 dstmap
= mappings
[IDX_RGBA
].from_rgba
;
1087 else if (dstFormat
== &_mesa_texformat_rgb
) {
1088 dstmap
= mappings
[IDX_RGB
].from_rgba
;
1091 else if (dstFormat
== &_mesa_texformat_alpha
) {
1092 dstmap
= mappings
[IDX_ALPHA
].from_rgba
;
1095 else if (dstFormat
== &_mesa_texformat_luminance
) {
1096 dstmap
= mappings
[IDX_LUMINANCE
].from_rgba
;
1099 else if (dstFormat
== &_mesa_texformat_luminance_alpha
) {
1100 dstmap
= mappings
[IDX_LUMINANCE_ALPHA
].from_rgba
;
1103 else if (dstFormat
== &_mesa_texformat_intensity
) {
1104 dstmap
= mappings
[IDX_INTENSITY
].from_rgba
;
1108 _mesa_problem(ctx
, "Unexpected dstFormat in _mesa_texstore_rgba");
1112 _mesa_swizzle_ubyte_image(ctx
, dims
,
1117 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1118 dstRowStride
, dstImageOffsets
,
1119 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1124 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1126 dstFormat
->BaseFormat
,
1127 srcWidth
, srcHeight
, srcDepth
,
1128 srcFormat
, srcType
, srcAddr
,
1130 const GLchan
*src
= tempImage
;
1135 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1136 bytesPerRow
= srcWidth
* components
* sizeof(GLchan
);
1137 for (img
= 0; img
< srcDepth
; img
++) {
1138 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1139 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1140 + dstYoffset
* dstRowStride
1141 + dstXoffset
* dstFormat
->TexelBytes
;
1142 for (row
= 0; row
< srcHeight
; row
++) {
1143 _mesa_memcpy(dstRow
, src
, bytesPerRow
);
1144 dstRow
+= dstRowStride
;
1145 src
+= srcWidth
* components
;
1149 _mesa_free((void *) tempImage
);
1156 * Store a 32-bit integer depth component texture image.
1159 _mesa_texstore_z32(TEXSTORE_PARAMS
)
1161 const GLuint depthScale
= 0xffffffff;
1163 ASSERT(dstFormat
== &_mesa_texformat_z32
);
1164 ASSERT(dstFormat
->TexelBytes
== sizeof(GLuint
));
1166 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1167 ctx
->Pixel
.DepthBias
== 0.0f
&&
1168 !srcPacking
->SwapBytes
&&
1169 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1170 srcFormat
== GL_DEPTH_COMPONENT
&&
1171 srcType
== GL_UNSIGNED_INT
) {
1172 /* simple memcpy path */
1173 memcpy_texture(ctx
, dims
,
1174 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1177 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1178 srcAddr
, srcPacking
);
1183 for (img
= 0; img
< srcDepth
; img
++) {
1184 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1185 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1186 + dstYoffset
* dstRowStride
1187 + dstXoffset
* dstFormat
->TexelBytes
;
1188 for (row
= 0; row
< srcHeight
; row
++) {
1189 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1190 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1191 _mesa_unpack_depth_span(ctx
, srcWidth
,
1192 GL_UNSIGNED_INT
, (GLuint
*) dstRow
,
1193 depthScale
, srcType
, src
, srcPacking
);
1194 dstRow
+= dstRowStride
;
1204 * Store a 16-bit integer depth component texture image.
1207 _mesa_texstore_z16(TEXSTORE_PARAMS
)
1209 const GLuint depthScale
= 0xffff;
1211 ASSERT(dstFormat
== &_mesa_texformat_z16
);
1212 ASSERT(dstFormat
->TexelBytes
== sizeof(GLushort
));
1214 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1215 ctx
->Pixel
.DepthBias
== 0.0f
&&
1216 !srcPacking
->SwapBytes
&&
1217 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1218 srcFormat
== GL_DEPTH_COMPONENT
&&
1219 srcType
== GL_UNSIGNED_SHORT
) {
1220 /* simple memcpy path */
1221 memcpy_texture(ctx
, dims
,
1222 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1225 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1226 srcAddr
, srcPacking
);
1231 for (img
= 0; img
< srcDepth
; img
++) {
1232 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1233 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1234 + dstYoffset
* dstRowStride
1235 + dstXoffset
* dstFormat
->TexelBytes
;
1236 for (row
= 0; row
< srcHeight
; row
++) {
1237 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1238 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1239 GLushort
*dst16
= (GLushort
*) dstRow
;
1240 _mesa_unpack_depth_span(ctx
, srcWidth
,
1241 GL_UNSIGNED_SHORT
, dst16
, depthScale
,
1242 srcType
, src
, srcPacking
);
1243 dstRow
+= dstRowStride
;
1252 * Store an rgb565 or rgb565_rev texture image.
1255 _mesa_texstore_rgb565(TEXSTORE_PARAMS
)
1257 ASSERT(dstFormat
== &_mesa_texformat_rgb565
||
1258 dstFormat
== &_mesa_texformat_rgb565_rev
);
1259 ASSERT(dstFormat
->TexelBytes
== 2);
1261 if (!ctx
->_ImageTransferState
&&
1262 !srcPacking
->SwapBytes
&&
1263 dstFormat
== &_mesa_texformat_rgb565
&&
1264 baseInternalFormat
== GL_RGB
&&
1265 srcFormat
== GL_RGB
&&
1266 srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1267 /* simple memcpy path */
1268 memcpy_texture(ctx
, dims
,
1269 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1272 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1273 srcAddr
, srcPacking
);
1275 else if (!ctx
->_ImageTransferState
&&
1276 !srcPacking
->SwapBytes
&&
1277 baseInternalFormat
== GL_RGB
&&
1278 srcFormat
== GL_RGB
&&
1279 srcType
== GL_UNSIGNED_BYTE
&&
1281 /* do optimized tex store */
1282 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
1283 srcFormat
, srcType
);
1284 const GLubyte
*src
= (const GLubyte
*)
1285 _mesa_image_address(dims
, srcPacking
, srcAddr
, srcWidth
, srcHeight
,
1286 srcFormat
, srcType
, 0, 0, 0);
1287 GLubyte
*dst
= (GLubyte
*) dstAddr
1288 + dstYoffset
* dstRowStride
1289 + dstXoffset
* dstFormat
->TexelBytes
;
1291 for (row
= 0; row
< srcHeight
; row
++) {
1292 const GLubyte
*srcUB
= (const GLubyte
*) src
;
1293 GLushort
*dstUS
= (GLushort
*) dst
;
1294 /* check for byteswapped format */
1295 if (dstFormat
== &_mesa_texformat_rgb565
) {
1296 for (col
= 0; col
< srcWidth
; col
++) {
1297 dstUS
[col
] = PACK_COLOR_565( srcUB
[0], srcUB
[1], srcUB
[2] );
1302 for (col
= 0; col
< srcWidth
; col
++) {
1303 dstUS
[col
] = PACK_COLOR_565_REV( srcUB
[0], srcUB
[1], srcUB
[2] );
1307 dst
+= dstRowStride
;
1308 src
+= srcRowStride
;
1313 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1315 dstFormat
->BaseFormat
,
1316 srcWidth
, srcHeight
, srcDepth
,
1317 srcFormat
, srcType
, srcAddr
,
1319 const GLchan
*src
= tempImage
;
1320 GLint img
, row
, col
;
1323 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1324 for (img
= 0; img
< srcDepth
; img
++) {
1325 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1326 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1327 + dstYoffset
* dstRowStride
1328 + dstXoffset
* dstFormat
->TexelBytes
;
1329 for (row
= 0; row
< srcHeight
; row
++) {
1330 GLushort
*dstUS
= (GLushort
*) dstRow
;
1331 /* check for byteswapped format */
1332 if (dstFormat
== &_mesa_texformat_rgb565
) {
1333 for (col
= 0; col
< srcWidth
; col
++) {
1334 dstUS
[col
] = PACK_COLOR_565( CHAN_TO_UBYTE(src
[RCOMP
]),
1335 CHAN_TO_UBYTE(src
[GCOMP
]),
1336 CHAN_TO_UBYTE(src
[BCOMP
]) );
1341 for (col
= 0; col
< srcWidth
; col
++) {
1342 dstUS
[col
] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1343 CHAN_TO_UBYTE(src
[GCOMP
]),
1344 CHAN_TO_UBYTE(src
[BCOMP
]) );
1348 dstRow
+= dstRowStride
;
1351 _mesa_free((void *) tempImage
);
1358 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1361 _mesa_texstore_rgba8888(TEXSTORE_PARAMS
)
1363 const GLboolean littleEndian
= _mesa_little_endian();
1365 ASSERT(dstFormat
== &_mesa_texformat_rgba8888
||
1366 dstFormat
== &_mesa_texformat_rgba8888_rev
);
1367 ASSERT(dstFormat
->TexelBytes
== 4);
1369 if (!ctx
->_ImageTransferState
&&
1370 !srcPacking
->SwapBytes
&&
1371 dstFormat
== &_mesa_texformat_rgba8888
&&
1372 baseInternalFormat
== GL_RGBA
&&
1373 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1374 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1375 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1376 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
))) {
1377 /* simple memcpy path */
1378 memcpy_texture(ctx
, dims
,
1379 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1382 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1383 srcAddr
, srcPacking
);
1385 else if (!ctx
->_ImageTransferState
&&
1386 !srcPacking
->SwapBytes
&&
1387 dstFormat
== &_mesa_texformat_rgba8888_rev
&&
1388 baseInternalFormat
== GL_RGBA
&&
1389 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1390 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1391 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1392 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
))) {
1393 /* simple memcpy path */
1394 memcpy_texture(ctx
, dims
,
1395 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1398 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1399 srcAddr
, srcPacking
);
1401 else if (!ctx
->_ImageTransferState
&&
1402 (srcType
== GL_UNSIGNED_BYTE
||
1403 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1404 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1405 can_swizzle(baseInternalFormat
) &&
1406 can_swizzle(srcFormat
)) {
1410 /* dstmap - how to swizzle from RGBA to dst format:
1412 if ((littleEndian
&& dstFormat
== &_mesa_texformat_rgba8888
) ||
1413 (!littleEndian
&& dstFormat
== &_mesa_texformat_rgba8888_rev
)) {
1426 _mesa_swizzle_ubyte_image(ctx
, dims
,
1431 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1432 dstRowStride
, dstImageOffsets
,
1433 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1438 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1440 dstFormat
->BaseFormat
,
1441 srcWidth
, srcHeight
, srcDepth
,
1442 srcFormat
, srcType
, srcAddr
,
1444 const GLchan
*src
= tempImage
;
1445 GLint img
, row
, col
;
1448 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1449 for (img
= 0; img
< srcDepth
; img
++) {
1450 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1451 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1452 + dstYoffset
* dstRowStride
1453 + dstXoffset
* dstFormat
->TexelBytes
;
1454 for (row
= 0; row
< srcHeight
; row
++) {
1455 GLuint
*dstUI
= (GLuint
*) dstRow
;
1456 if (dstFormat
== &_mesa_texformat_rgba8888
) {
1457 for (col
= 0; col
< srcWidth
; col
++) {
1458 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[RCOMP
]),
1459 CHAN_TO_UBYTE(src
[GCOMP
]),
1460 CHAN_TO_UBYTE(src
[BCOMP
]),
1461 CHAN_TO_UBYTE(src
[ACOMP
]) );
1466 for (col
= 0; col
< srcWidth
; col
++) {
1467 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1468 CHAN_TO_UBYTE(src
[GCOMP
]),
1469 CHAN_TO_UBYTE(src
[BCOMP
]),
1470 CHAN_TO_UBYTE(src
[ACOMP
]) );
1474 dstRow
+= dstRowStride
;
1477 _mesa_free((void *) tempImage
);
1484 _mesa_texstore_argb8888(TEXSTORE_PARAMS
)
1486 const GLboolean littleEndian
= _mesa_little_endian();
1488 ASSERT(dstFormat
== &_mesa_texformat_argb8888
||
1489 dstFormat
== &_mesa_texformat_argb8888_rev
);
1490 ASSERT(dstFormat
->TexelBytes
== 4);
1492 if (!ctx
->_ImageTransferState
&&
1493 !srcPacking
->SwapBytes
&&
1494 dstFormat
== &_mesa_texformat_argb8888
&&
1495 baseInternalFormat
== GL_RGBA
&&
1496 srcFormat
== GL_BGRA
&&
1497 ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1498 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
1499 /* simple memcpy path (little endian) */
1500 memcpy_texture(ctx
, dims
,
1501 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1504 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1505 srcAddr
, srcPacking
);
1507 else if (!ctx
->_ImageTransferState
&&
1508 !srcPacking
->SwapBytes
&&
1509 dstFormat
== &_mesa_texformat_argb8888_rev
&&
1510 baseInternalFormat
== GL_RGBA
&&
1511 srcFormat
== GL_BGRA
&&
1512 ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1513 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
1514 /* simple memcpy path (big endian) */
1515 memcpy_texture(ctx
, dims
,
1516 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1519 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1520 srcAddr
, srcPacking
);
1522 else if (!ctx
->_ImageTransferState
&&
1523 !srcPacking
->SwapBytes
&&
1524 dstFormat
== &_mesa_texformat_argb8888
&&
1525 srcFormat
== GL_RGB
&&
1526 (baseInternalFormat
== GL_RGBA
||
1527 baseInternalFormat
== GL_RGB
) &&
1528 srcType
== GL_UNSIGNED_BYTE
) {
1530 for (img
= 0; img
< srcDepth
; img
++) {
1531 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1532 srcWidth
, srcFormat
, srcType
);
1533 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1534 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1535 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1536 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1537 + dstYoffset
* dstRowStride
1538 + dstXoffset
* dstFormat
->TexelBytes
;
1539 for (row
= 0; row
< srcHeight
; row
++) {
1540 GLuint
*d4
= (GLuint
*) dstRow
;
1541 for (col
= 0; col
< srcWidth
; col
++) {
1542 d4
[col
] = PACK_COLOR_8888(0xff,
1543 srcRow
[col
* 3 + RCOMP
],
1544 srcRow
[col
* 3 + GCOMP
],
1545 srcRow
[col
* 3 + BCOMP
]);
1547 dstRow
+= dstRowStride
;
1548 srcRow
+= srcRowStride
;
1552 else if (!ctx
->_ImageTransferState
&&
1553 !srcPacking
->SwapBytes
&&
1554 dstFormat
== &_mesa_texformat_argb8888
&&
1555 srcFormat
== GL_RGBA
&&
1556 baseInternalFormat
== GL_RGBA
&&
1557 srcType
== GL_UNSIGNED_BYTE
) {
1558 /* same as above case, but src data has alpha too */
1559 GLint img
, row
, col
;
1560 /* For some reason, streaming copies to write-combined regions
1561 * are extremely sensitive to the characteristics of how the
1562 * source data is retrieved. By reordering the source reads to
1563 * be in-order, the speed of this operation increases by half.
1564 * Strangely the same isn't required for the RGB path, above.
1566 for (img
= 0; img
< srcDepth
; img
++) {
1567 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1568 srcWidth
, srcFormat
, srcType
);
1569 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1570 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1571 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1572 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1573 + dstYoffset
* dstRowStride
1574 + dstXoffset
* dstFormat
->TexelBytes
;
1575 for (row
= 0; row
< srcHeight
; row
++) {
1576 GLuint
*d4
= (GLuint
*) dstRow
;
1577 for (col
= 0; col
< srcWidth
; col
++) {
1578 d4
[col
] = PACK_COLOR_8888(srcRow
[col
* 4 + ACOMP
],
1579 srcRow
[col
* 4 + RCOMP
],
1580 srcRow
[col
* 4 + GCOMP
],
1581 srcRow
[col
* 4 + BCOMP
]);
1583 dstRow
+= dstRowStride
;
1584 srcRow
+= srcRowStride
;
1588 else if (!ctx
->_ImageTransferState
&&
1589 (srcType
== GL_UNSIGNED_BYTE
||
1590 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1591 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1592 can_swizzle(baseInternalFormat
) &&
1593 can_swizzle(srcFormat
)) {
1597 /* dstmap - how to swizzle from RGBA to dst format:
1599 if ((littleEndian
&& dstFormat
== &_mesa_texformat_argb8888
) ||
1600 (!littleEndian
&& dstFormat
== &_mesa_texformat_argb8888_rev
)) {
1601 dstmap
[3] = 3; /* alpha */
1602 dstmap
[2] = 0; /* red */
1603 dstmap
[1] = 1; /* green */
1604 dstmap
[0] = 2; /* blue */
1607 assert((littleEndian
&& dstFormat
== &_mesa_texformat_argb8888_rev
) ||
1608 (!littleEndian
&& dstFormat
== &_mesa_texformat_argb8888
));
1615 _mesa_swizzle_ubyte_image(ctx
, dims
,
1621 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1624 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1629 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1631 dstFormat
->BaseFormat
,
1632 srcWidth
, srcHeight
, srcDepth
,
1633 srcFormat
, srcType
, srcAddr
,
1635 const GLchan
*src
= tempImage
;
1636 GLint img
, row
, col
;
1639 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1640 for (img
= 0; img
< srcDepth
; img
++) {
1641 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1642 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1643 + dstYoffset
* dstRowStride
1644 + dstXoffset
* dstFormat
->TexelBytes
;
1645 for (row
= 0; row
< srcHeight
; row
++) {
1646 GLuint
*dstUI
= (GLuint
*) dstRow
;
1647 if (dstFormat
== &_mesa_texformat_argb8888
) {
1648 for (col
= 0; col
< srcWidth
; col
++) {
1649 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[ACOMP
]),
1650 CHAN_TO_UBYTE(src
[RCOMP
]),
1651 CHAN_TO_UBYTE(src
[GCOMP
]),
1652 CHAN_TO_UBYTE(src
[BCOMP
]) );
1657 for (col
= 0; col
< srcWidth
; col
++) {
1658 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1659 CHAN_TO_UBYTE(src
[RCOMP
]),
1660 CHAN_TO_UBYTE(src
[GCOMP
]),
1661 CHAN_TO_UBYTE(src
[BCOMP
]) );
1665 dstRow
+= dstRowStride
;
1668 _mesa_free((void *) tempImage
);
1675 _mesa_texstore_rgb888(TEXSTORE_PARAMS
)
1677 const GLboolean littleEndian
= _mesa_little_endian();
1679 ASSERT(dstFormat
== &_mesa_texformat_rgb888
);
1680 ASSERT(dstFormat
->TexelBytes
== 3);
1682 if (!ctx
->_ImageTransferState
&&
1683 !srcPacking
->SwapBytes
&&
1684 baseInternalFormat
== GL_RGB
&&
1685 srcFormat
== GL_BGR
&&
1686 srcType
== GL_UNSIGNED_BYTE
&&
1688 /* simple memcpy path */
1689 memcpy_texture(ctx
, dims
,
1690 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1693 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1694 srcAddr
, srcPacking
);
1696 else if (!ctx
->_ImageTransferState
&&
1697 !srcPacking
->SwapBytes
&&
1698 srcFormat
== GL_RGBA
&&
1699 srcType
== GL_UNSIGNED_BYTE
) {
1700 /* extract RGB from RGBA */
1701 GLint img
, row
, col
;
1702 for (img
= 0; img
< srcDepth
; img
++) {
1703 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1704 srcWidth
, srcFormat
, srcType
);
1705 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1706 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1707 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1708 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1709 + dstYoffset
* dstRowStride
1710 + dstXoffset
* dstFormat
->TexelBytes
;
1711 for (row
= 0; row
< srcHeight
; row
++) {
1712 for (col
= 0; col
< srcWidth
; col
++) {
1713 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + BCOMP
];
1714 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1715 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + RCOMP
];
1717 dstRow
+= dstRowStride
;
1718 srcRow
+= srcRowStride
;
1722 else if (!ctx
->_ImageTransferState
&&
1723 srcType
== GL_UNSIGNED_BYTE
&&
1724 can_swizzle(baseInternalFormat
) &&
1725 can_swizzle(srcFormat
)) {
1729 /* dstmap - how to swizzle from RGBA to dst format:
1734 dstmap
[3] = ONE
; /* ? */
1736 _mesa_swizzle_ubyte_image(ctx
, dims
,
1741 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1742 dstRowStride
, dstImageOffsets
,
1743 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1748 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1750 dstFormat
->BaseFormat
,
1751 srcWidth
, srcHeight
, srcDepth
,
1752 srcFormat
, srcType
, srcAddr
,
1754 const GLchan
*src
= (const GLchan
*) tempImage
;
1755 GLint img
, row
, col
;
1758 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1759 for (img
= 0; img
< srcDepth
; img
++) {
1760 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1761 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1762 + dstYoffset
* dstRowStride
1763 + dstXoffset
* dstFormat
->TexelBytes
;
1764 for (row
= 0; row
< srcHeight
; row
++) {
1767 for (col
= 0; col
< srcWidth
; col
++) {
1768 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1769 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1770 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1775 for (col
= 0; col
< srcWidth
; col
++) {
1776 dstRow
[col
* 3 + 0] = srcUB
[BCOMP
];
1777 dstRow
[col
* 3 + 1] = srcUB
[GCOMP
];
1778 dstRow
[col
* 3 + 2] = srcUB
[RCOMP
];
1783 for (col
= 0; col
< srcWidth
; col
++) {
1784 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[BCOMP
]);
1785 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1786 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[RCOMP
]);
1790 dstRow
+= dstRowStride
;
1793 _mesa_free((void *) tempImage
);
1800 _mesa_texstore_bgr888(TEXSTORE_PARAMS
)
1802 const GLboolean littleEndian
= _mesa_little_endian();
1804 ASSERT(dstFormat
== &_mesa_texformat_bgr888
);
1805 ASSERT(dstFormat
->TexelBytes
== 3);
1807 if (!ctx
->_ImageTransferState
&&
1808 !srcPacking
->SwapBytes
&&
1809 baseInternalFormat
== GL_RGB
&&
1810 srcFormat
== GL_RGB
&&
1811 srcType
== GL_UNSIGNED_BYTE
&&
1813 /* simple memcpy path */
1814 memcpy_texture(ctx
, dims
,
1815 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1818 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1819 srcAddr
, srcPacking
);
1821 else if (!ctx
->_ImageTransferState
&&
1822 !srcPacking
->SwapBytes
&&
1823 srcFormat
== GL_RGBA
&&
1824 srcType
== GL_UNSIGNED_BYTE
) {
1825 /* extract BGR from RGBA */
1827 for (img
= 0; img
< srcDepth
; img
++) {
1828 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1829 srcWidth
, srcFormat
, srcType
);
1830 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1831 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1832 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1833 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1834 + dstYoffset
* dstRowStride
1835 + dstXoffset
* dstFormat
->TexelBytes
;
1836 for (row
= 0; row
< srcHeight
; row
++) {
1837 for (col
= 0; col
< srcWidth
; col
++) {
1838 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + RCOMP
];
1839 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1840 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + BCOMP
];
1842 dstRow
+= dstRowStride
;
1843 srcRow
+= srcRowStride
;
1847 else if (!ctx
->_ImageTransferState
&&
1848 srcType
== GL_UNSIGNED_BYTE
&&
1849 can_swizzle(baseInternalFormat
) &&
1850 can_swizzle(srcFormat
)) {
1854 /* dstmap - how to swizzle from RGBA to dst format:
1859 dstmap
[3] = ONE
; /* ? */
1861 _mesa_swizzle_ubyte_image(ctx
, dims
,
1866 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1867 dstRowStride
, dstImageOffsets
,
1868 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1873 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1875 dstFormat
->BaseFormat
,
1876 srcWidth
, srcHeight
, srcDepth
,
1877 srcFormat
, srcType
, srcAddr
,
1879 const GLchan
*src
= (const GLchan
*) tempImage
;
1880 GLint img
, row
, col
;
1883 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1884 for (img
= 0; img
< srcDepth
; img
++) {
1885 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1886 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1887 + dstYoffset
* dstRowStride
1888 + dstXoffset
* dstFormat
->TexelBytes
;
1889 for (row
= 0; row
< srcHeight
; row
++) {
1890 for (col
= 0; col
< srcWidth
; col
++) {
1891 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1892 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1893 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1896 dstRow
+= dstRowStride
;
1899 _mesa_free((void *) tempImage
);
1905 _mesa_texstore_rgba4444(TEXSTORE_PARAMS
)
1907 ASSERT(dstFormat
== &_mesa_texformat_rgba4444
);
1908 ASSERT(dstFormat
->TexelBytes
== 2);
1910 if (!ctx
->_ImageTransferState
&&
1911 !srcPacking
->SwapBytes
&&
1912 dstFormat
== &_mesa_texformat_rgba4444
&&
1913 baseInternalFormat
== GL_RGBA
&&
1914 srcFormat
== GL_RGBA
&&
1915 srcType
== GL_UNSIGNED_SHORT_4_4_4_4
){
1916 /* simple memcpy path */
1917 memcpy_texture(ctx
, dims
,
1918 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1921 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1922 srcAddr
, srcPacking
);
1926 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1928 dstFormat
->BaseFormat
,
1929 srcWidth
, srcHeight
, srcDepth
,
1930 srcFormat
, srcType
, srcAddr
,
1932 const GLchan
*src
= tempImage
;
1933 GLint img
, row
, col
;
1936 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1937 for (img
= 0; img
< srcDepth
; img
++) {
1938 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1939 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1940 + dstYoffset
* dstRowStride
1941 + dstXoffset
* dstFormat
->TexelBytes
;
1942 for (row
= 0; row
< srcHeight
; row
++) {
1943 GLushort
*dstUS
= (GLushort
*) dstRow
;
1944 for (col
= 0; col
< srcWidth
; col
++) {
1945 dstUS
[col
] = PACK_COLOR_4444( CHAN_TO_UBYTE(src
[RCOMP
]),
1946 CHAN_TO_UBYTE(src
[GCOMP
]),
1947 CHAN_TO_UBYTE(src
[BCOMP
]),
1948 CHAN_TO_UBYTE(src
[ACOMP
]) );
1951 dstRow
+= dstRowStride
;
1954 _mesa_free((void *) tempImage
);
1960 _mesa_texstore_argb4444(TEXSTORE_PARAMS
)
1962 ASSERT(dstFormat
== &_mesa_texformat_argb4444
||
1963 dstFormat
== &_mesa_texformat_argb4444_rev
);
1964 ASSERT(dstFormat
->TexelBytes
== 2);
1966 if (!ctx
->_ImageTransferState
&&
1967 !srcPacking
->SwapBytes
&&
1968 dstFormat
== &_mesa_texformat_argb4444
&&
1969 baseInternalFormat
== GL_RGBA
&&
1970 srcFormat
== GL_BGRA
&&
1971 srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1972 /* simple memcpy path */
1973 memcpy_texture(ctx
, dims
,
1974 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1977 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1978 srcAddr
, srcPacking
);
1982 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1984 dstFormat
->BaseFormat
,
1985 srcWidth
, srcHeight
, srcDepth
,
1986 srcFormat
, srcType
, srcAddr
,
1988 const GLchan
*src
= tempImage
;
1989 GLint img
, row
, col
;
1992 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1993 for (img
= 0; img
< srcDepth
; img
++) {
1994 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1995 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1996 + dstYoffset
* dstRowStride
1997 + dstXoffset
* dstFormat
->TexelBytes
;
1998 for (row
= 0; row
< srcHeight
; row
++) {
1999 GLushort
*dstUS
= (GLushort
*) dstRow
;
2000 if (dstFormat
== &_mesa_texformat_argb4444
) {
2001 for (col
= 0; col
< srcWidth
; col
++) {
2002 dstUS
[col
] = PACK_COLOR_4444( CHAN_TO_UBYTE(src
[ACOMP
]),
2003 CHAN_TO_UBYTE(src
[RCOMP
]),
2004 CHAN_TO_UBYTE(src
[GCOMP
]),
2005 CHAN_TO_UBYTE(src
[BCOMP
]) );
2010 for (col
= 0; col
< srcWidth
; col
++) {
2011 dstUS
[col
] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
2012 CHAN_TO_UBYTE(src
[RCOMP
]),
2013 CHAN_TO_UBYTE(src
[GCOMP
]),
2014 CHAN_TO_UBYTE(src
[BCOMP
]) );
2018 dstRow
+= dstRowStride
;
2021 _mesa_free((void *) tempImage
);
2027 _mesa_texstore_rgba5551(TEXSTORE_PARAMS
)
2029 ASSERT(dstFormat
== &_mesa_texformat_rgba5551
);
2030 ASSERT(dstFormat
->TexelBytes
== 2);
2032 if (!ctx
->_ImageTransferState
&&
2033 !srcPacking
->SwapBytes
&&
2034 dstFormat
== &_mesa_texformat_rgba5551
&&
2035 baseInternalFormat
== GL_RGBA
&&
2036 srcFormat
== GL_RGBA
&&
2037 srcType
== GL_UNSIGNED_SHORT_5_5_5_1
) {
2038 /* simple memcpy path */
2039 memcpy_texture(ctx
, dims
,
2040 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2043 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2044 srcAddr
, srcPacking
);
2048 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2050 dstFormat
->BaseFormat
,
2051 srcWidth
, srcHeight
, srcDepth
,
2052 srcFormat
, srcType
, srcAddr
,
2054 const GLchan
*src
=tempImage
;
2055 GLint img
, row
, col
;
2058 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2059 for (img
= 0; img
< srcDepth
; img
++) {
2060 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2061 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2062 + dstYoffset
* dstRowStride
2063 + dstXoffset
* dstFormat
->TexelBytes
;
2064 for (row
= 0; row
< srcHeight
; row
++) {
2065 GLushort
*dstUS
= (GLushort
*) dstRow
;
2066 for (col
= 0; col
< srcWidth
; col
++) {
2067 dstUS
[col
] = PACK_COLOR_5551( CHAN_TO_UBYTE(src
[RCOMP
]),
2068 CHAN_TO_UBYTE(src
[GCOMP
]),
2069 CHAN_TO_UBYTE(src
[BCOMP
]),
2070 CHAN_TO_UBYTE(src
[ACOMP
]) );
2073 dstRow
+= dstRowStride
;
2076 _mesa_free((void *) tempImage
);
2082 _mesa_texstore_argb1555(TEXSTORE_PARAMS
)
2084 ASSERT(dstFormat
== &_mesa_texformat_argb1555
||
2085 dstFormat
== &_mesa_texformat_argb1555_rev
);
2086 ASSERT(dstFormat
->TexelBytes
== 2);
2088 if (!ctx
->_ImageTransferState
&&
2089 !srcPacking
->SwapBytes
&&
2090 dstFormat
== &_mesa_texformat_argb1555
&&
2091 baseInternalFormat
== GL_RGBA
&&
2092 srcFormat
== GL_BGRA
&&
2093 srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
2094 /* simple memcpy path */
2095 memcpy_texture(ctx
, dims
,
2096 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2099 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2100 srcAddr
, srcPacking
);
2104 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2106 dstFormat
->BaseFormat
,
2107 srcWidth
, srcHeight
, srcDepth
,
2108 srcFormat
, srcType
, srcAddr
,
2110 const GLchan
*src
=tempImage
;
2111 GLint img
, row
, col
;
2114 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2115 for (img
= 0; img
< srcDepth
; img
++) {
2116 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2117 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2118 + dstYoffset
* dstRowStride
2119 + dstXoffset
* dstFormat
->TexelBytes
;
2120 for (row
= 0; row
< srcHeight
; row
++) {
2121 GLushort
*dstUS
= (GLushort
*) dstRow
;
2122 if (dstFormat
== &_mesa_texformat_argb1555
) {
2123 for (col
= 0; col
< srcWidth
; col
++) {
2124 dstUS
[col
] = PACK_COLOR_1555( CHAN_TO_UBYTE(src
[ACOMP
]),
2125 CHAN_TO_UBYTE(src
[RCOMP
]),
2126 CHAN_TO_UBYTE(src
[GCOMP
]),
2127 CHAN_TO_UBYTE(src
[BCOMP
]) );
2132 for (col
= 0; col
< srcWidth
; col
++) {
2133 dstUS
[col
] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
2134 CHAN_TO_UBYTE(src
[RCOMP
]),
2135 CHAN_TO_UBYTE(src
[GCOMP
]),
2136 CHAN_TO_UBYTE(src
[BCOMP
]) );
2140 dstRow
+= dstRowStride
;
2143 _mesa_free((void *) tempImage
);
2150 _mesa_texstore_al88(TEXSTORE_PARAMS
)
2152 const GLboolean littleEndian
= _mesa_little_endian();
2154 ASSERT(dstFormat
== &_mesa_texformat_al88
||
2155 dstFormat
== &_mesa_texformat_al88_rev
);
2156 ASSERT(dstFormat
->TexelBytes
== 2);
2158 if (!ctx
->_ImageTransferState
&&
2159 !srcPacking
->SwapBytes
&&
2160 dstFormat
== &_mesa_texformat_al88
&&
2161 baseInternalFormat
== GL_LUMINANCE_ALPHA
&&
2162 srcFormat
== GL_LUMINANCE_ALPHA
&&
2163 srcType
== GL_UNSIGNED_BYTE
&&
2165 /* simple memcpy path */
2166 memcpy_texture(ctx
, dims
,
2167 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2170 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2171 srcAddr
, srcPacking
);
2173 else if (!ctx
->_ImageTransferState
&&
2175 srcType
== GL_UNSIGNED_BYTE
&&
2176 can_swizzle(baseInternalFormat
) &&
2177 can_swizzle(srcFormat
)) {
2181 /* dstmap - how to swizzle from RGBA to dst format:
2183 if ((littleEndian
&& dstFormat
== &_mesa_texformat_al88
) ||
2184 (!littleEndian
&& dstFormat
== &_mesa_texformat_al88_rev
)) {
2192 dstmap
[2] = ZERO
; /* ? */
2193 dstmap
[3] = ONE
; /* ? */
2195 _mesa_swizzle_ubyte_image(ctx
, dims
,
2200 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2201 dstRowStride
, dstImageOffsets
,
2202 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2207 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2209 dstFormat
->BaseFormat
,
2210 srcWidth
, srcHeight
, srcDepth
,
2211 srcFormat
, srcType
, srcAddr
,
2213 const GLchan
*src
= tempImage
;
2214 GLint img
, row
, col
;
2217 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2218 for (img
= 0; img
< srcDepth
; img
++) {
2219 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2220 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2221 + dstYoffset
* dstRowStride
2222 + dstXoffset
* dstFormat
->TexelBytes
;
2223 for (row
= 0; row
< srcHeight
; row
++) {
2224 GLushort
*dstUS
= (GLushort
*) dstRow
;
2225 if (dstFormat
== &_mesa_texformat_al88
) {
2226 for (col
= 0; col
< srcWidth
; col
++) {
2227 /* src[0] is luminance, src[1] is alpha */
2228 dstUS
[col
] = PACK_COLOR_88( CHAN_TO_UBYTE(src
[1]),
2229 CHAN_TO_UBYTE(src
[0]) );
2234 for (col
= 0; col
< srcWidth
; col
++) {
2235 /* src[0] is luminance, src[1] is alpha */
2236 dstUS
[col
] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src
[1]),
2237 CHAN_TO_UBYTE(src
[0]) );
2241 dstRow
+= dstRowStride
;
2244 _mesa_free((void *) tempImage
);
2251 _mesa_texstore_rgb332(TEXSTORE_PARAMS
)
2253 ASSERT(dstFormat
== &_mesa_texformat_rgb332
);
2254 ASSERT(dstFormat
->TexelBytes
== 1);
2256 if (!ctx
->_ImageTransferState
&&
2257 !srcPacking
->SwapBytes
&&
2258 baseInternalFormat
== GL_RGB
&&
2259 srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_BYTE_3_3_2
) {
2260 /* simple memcpy path */
2261 memcpy_texture(ctx
, dims
,
2262 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2265 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2266 srcAddr
, srcPacking
);
2270 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2272 dstFormat
->BaseFormat
,
2273 srcWidth
, srcHeight
, srcDepth
,
2274 srcFormat
, srcType
, srcAddr
,
2276 const GLchan
*src
= tempImage
;
2277 GLint img
, row
, col
;
2280 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2281 for (img
= 0; img
< srcDepth
; img
++) {
2282 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2283 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2284 + dstYoffset
* dstRowStride
2285 + dstXoffset
* dstFormat
->TexelBytes
;
2286 for (row
= 0; row
< srcHeight
; row
++) {
2287 for (col
= 0; col
< srcWidth
; col
++) {
2288 dstRow
[col
] = PACK_COLOR_332( CHAN_TO_UBYTE(src
[RCOMP
]),
2289 CHAN_TO_UBYTE(src
[GCOMP
]),
2290 CHAN_TO_UBYTE(src
[BCOMP
]) );
2293 dstRow
+= dstRowStride
;
2296 _mesa_free((void *) tempImage
);
2303 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2306 _mesa_texstore_a8(TEXSTORE_PARAMS
)
2308 ASSERT(dstFormat
== &_mesa_texformat_a8
||
2309 dstFormat
== &_mesa_texformat_l8
||
2310 dstFormat
== &_mesa_texformat_i8
);
2311 ASSERT(dstFormat
->TexelBytes
== 1);
2313 if (!ctx
->_ImageTransferState
&&
2314 !srcPacking
->SwapBytes
&&
2315 baseInternalFormat
== srcFormat
&&
2316 srcType
== GL_UNSIGNED_BYTE
) {
2317 /* simple memcpy path */
2318 memcpy_texture(ctx
, dims
,
2319 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2322 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2323 srcAddr
, srcPacking
);
2325 else if (!ctx
->_ImageTransferState
&&
2326 srcType
== GL_UNSIGNED_BYTE
&&
2327 can_swizzle(baseInternalFormat
) &&
2328 can_swizzle(srcFormat
)) {
2332 /* dstmap - how to swizzle from RGBA to dst format:
2334 if (dstFormat
== &_mesa_texformat_a8
) {
2340 dstmap
[1] = ZERO
; /* ? */
2341 dstmap
[2] = ZERO
; /* ? */
2342 dstmap
[3] = ONE
; /* ? */
2344 _mesa_swizzle_ubyte_image(ctx
, dims
,
2349 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2350 dstRowStride
, dstImageOffsets
,
2351 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2356 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2358 dstFormat
->BaseFormat
,
2359 srcWidth
, srcHeight
, srcDepth
,
2360 srcFormat
, srcType
, srcAddr
,
2362 const GLchan
*src
= tempImage
;
2363 GLint img
, row
, col
;
2366 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2367 for (img
= 0; img
< srcDepth
; img
++) {
2368 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2369 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2370 + dstYoffset
* dstRowStride
2371 + dstXoffset
* dstFormat
->TexelBytes
;
2372 for (row
= 0; row
< srcHeight
; row
++) {
2373 for (col
= 0; col
< srcWidth
; col
++) {
2374 dstRow
[col
] = CHAN_TO_UBYTE(src
[col
]);
2376 dstRow
+= dstRowStride
;
2380 _mesa_free((void *) tempImage
);
2388 _mesa_texstore_ci8(TEXSTORE_PARAMS
)
2390 (void) dims
; (void) baseInternalFormat
;
2391 ASSERT(dstFormat
== &_mesa_texformat_ci8
);
2392 ASSERT(dstFormat
->TexelBytes
== 1);
2393 ASSERT(baseInternalFormat
== GL_COLOR_INDEX
);
2395 if (!ctx
->_ImageTransferState
&&
2396 !srcPacking
->SwapBytes
&&
2397 srcFormat
== GL_COLOR_INDEX
&&
2398 srcType
== GL_UNSIGNED_BYTE
) {
2399 /* simple memcpy path */
2400 memcpy_texture(ctx
, dims
,
2401 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2404 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2405 srcAddr
, srcPacking
);
2410 for (img
= 0; img
< srcDepth
; img
++) {
2411 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2412 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2413 + dstYoffset
* dstRowStride
2414 + dstXoffset
* dstFormat
->TexelBytes
;
2415 for (row
= 0; row
< srcHeight
; row
++) {
2416 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
2417 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
2418 _mesa_unpack_index_span(ctx
, srcWidth
, GL_UNSIGNED_BYTE
, dstRow
,
2419 srcType
, src
, srcPacking
,
2420 ctx
->_ImageTransferState
);
2421 dstRow
+= dstRowStride
;
2430 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
2433 _mesa_texstore_ycbcr(TEXSTORE_PARAMS
)
2435 const GLboolean littleEndian
= _mesa_little_endian();
2436 (void) ctx
; (void) dims
; (void) baseInternalFormat
;
2438 ASSERT((dstFormat
== &_mesa_texformat_ycbcr
) ||
2439 (dstFormat
== &_mesa_texformat_ycbcr_rev
));
2440 ASSERT(dstFormat
->TexelBytes
== 2);
2441 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
2442 ASSERT(srcFormat
== GL_YCBCR_MESA
);
2443 ASSERT((srcType
== GL_UNSIGNED_SHORT_8_8_MESA
) ||
2444 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
));
2445 ASSERT(baseInternalFormat
== GL_YCBCR_MESA
);
2447 /* always just memcpy since no pixel transfer ops apply */
2448 memcpy_texture(ctx
, dims
,
2449 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2452 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2453 srcAddr
, srcPacking
);
2455 /* Check if we need byte swapping */
2456 /* XXX the logic here _might_ be wrong */
2457 if (srcPacking
->SwapBytes
^
2458 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ^
2459 (dstFormat
== &_mesa_texformat_ycbcr_rev
) ^
2462 for (img
= 0; img
< srcDepth
; img
++) {
2463 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2464 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2465 + dstYoffset
* dstRowStride
2466 + dstXoffset
* dstFormat
->TexelBytes
;
2467 for (row
= 0; row
< srcHeight
; row
++) {
2468 _mesa_swap2((GLushort
*) dstRow
, srcWidth
);
2469 dstRow
+= dstRowStride
;
2477 _mesa_texstore_dudv8(TEXSTORE_PARAMS
)
2479 const GLboolean littleEndian
= _mesa_little_endian();
2481 ASSERT(dstFormat
== &_mesa_texformat_dudv8
);
2482 ASSERT(dstFormat
->TexelBytes
== 2);
2483 ASSERT(ctx
->Extensions
.ATI_envmap_bumpmap
);
2484 ASSERT((srcFormat
== GL_DU8DV8_ATI
) ||
2485 (srcFormat
== GL_DUDV_ATI
));
2486 ASSERT(baseInternalFormat
== GL_DUDV_ATI
);
2488 if (!srcPacking
->SwapBytes
&& srcType
== GL_BYTE
&&
2490 /* simple memcpy path */
2491 memcpy_texture(ctx
, dims
,
2492 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2495 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2496 srcAddr
, srcPacking
);
2498 else if (srcType
== GL_BYTE
) {
2502 /* dstmap - how to swizzle from RGBA to dst format:
2512 dstmap
[2] = ZERO
; /* ? */
2513 dstmap
[3] = ONE
; /* ? */
2515 _mesa_swizzle_ubyte_image(ctx
, dims
,
2516 GL_LUMINANCE_ALPHA
, /* hack */
2517 GL_UNSIGNED_BYTE
, /* hack */
2518 GL_LUMINANCE_ALPHA
, /* hack */
2520 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2521 dstRowStride
, dstImageOffsets
,
2522 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2526 /* general path - note this is defined for 2d textures only */
2527 const GLint components
= _mesa_components_in_format(baseInternalFormat
);
2528 const GLint srcStride
= _mesa_image_row_stride(srcPacking
,
2529 srcWidth
, srcFormat
, srcType
);
2530 GLbyte
*tempImage
, *dst
, *src
;
2533 tempImage
= (GLbyte
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
2534 * components
* sizeof(GLbyte
));
2538 src
= (GLbyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2539 srcWidth
, srcHeight
,
2544 for (row
= 0; row
< srcHeight
; row
++) {
2545 _mesa_unpack_dudv_span_byte(ctx
, srcWidth
, baseInternalFormat
,
2546 dst
, srcFormat
, srcType
, src
,
2548 dst
+= srcWidth
* components
;
2553 dst
= (GLbyte
*) dstAddr
2554 + dstYoffset
* dstRowStride
2555 + dstXoffset
* dstFormat
->TexelBytes
;
2556 for (row
= 0; row
< srcHeight
; row
++) {
2557 memcpy(dst
, src
, srcWidth
* dstFormat
->TexelBytes
);
2558 dst
+= dstRowStride
;
2559 src
+= srcWidth
* dstFormat
->TexelBytes
;
2561 _mesa_free((void *) tempImage
);
2567 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or MESA_FORMAT_SIGNED_RGBA8888_REV
2570 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS
)
2572 const GLboolean littleEndian
= _mesa_little_endian();
2574 ASSERT(dstFormat
== &_mesa_texformat_signed_rgba8888
||
2575 dstFormat
== &_mesa_texformat_signed_rgba8888_rev
);
2576 ASSERT(dstFormat
->TexelBytes
== 4);
2578 if (!ctx
->_ImageTransferState
&&
2579 !srcPacking
->SwapBytes
&&
2580 dstFormat
== &_mesa_texformat_signed_rgba8888
&&
2581 baseInternalFormat
== GL_RGBA
&&
2582 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& !littleEndian
) ||
2583 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& littleEndian
))) {
2584 /* simple memcpy path */
2585 memcpy_texture(ctx
, dims
,
2586 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2589 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2590 srcAddr
, srcPacking
);
2592 else if (!ctx
->_ImageTransferState
&&
2593 !srcPacking
->SwapBytes
&&
2594 dstFormat
== &_mesa_texformat_signed_rgba8888_rev
&&
2595 baseInternalFormat
== GL_RGBA
&&
2596 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& littleEndian
) ||
2597 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& !littleEndian
))) {
2598 /* simple memcpy path */
2599 memcpy_texture(ctx
, dims
,
2600 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2603 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2604 srcAddr
, srcPacking
);
2606 else if (!ctx
->_ImageTransferState
&&
2607 (srcType
== GL_BYTE
) &&
2608 can_swizzle(baseInternalFormat
) &&
2609 can_swizzle(srcFormat
)) {
2613 /* dstmap - how to swizzle from RGBA to dst format:
2615 if ((littleEndian
&& dstFormat
== &_mesa_texformat_signed_rgba8888
) ||
2616 (!littleEndian
&& dstFormat
== &_mesa_texformat_signed_rgba8888_rev
)) {
2629 _mesa_swizzle_ubyte_image(ctx
, dims
,
2634 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2635 dstRowStride
, dstImageOffsets
,
2636 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2641 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2643 dstFormat
->BaseFormat
,
2644 srcWidth
, srcHeight
, srcDepth
,
2645 srcFormat
, srcType
, srcAddr
,
2647 const GLfloat
*srcRow
= tempImage
;
2648 GLint img
, row
, col
;
2651 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2652 for (img
= 0; img
< srcDepth
; img
++) {
2653 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2654 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2655 + dstYoffset
* dstRowStride
2656 + dstXoffset
* dstFormat
->TexelBytes
;
2657 for (row
= 0; row
< srcHeight
; row
++) {
2658 GLuint
*dstUI
= (GLuint
*) dstRow
;
2659 if (dstFormat
== &_mesa_texformat_signed_rgba8888
) {
2660 for (col
= 0; col
< srcWidth
; col
++) {
2661 dstUI
[col
] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2662 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2663 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2664 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2669 for (col
= 0; col
< srcWidth
; col
++) {
2670 dstUI
[col
] = PACK_COLOR_8888_REV( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2671 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2672 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2673 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2677 dstRow
+= dstRowStride
;
2680 _mesa_free((void *) tempImage
);
2686 * Store a combined depth/stencil texture image.
2689 _mesa_texstore_z24_s8(TEXSTORE_PARAMS
)
2691 const GLfloat depthScale
= (GLfloat
) 0xffffff;
2693 ASSERT(dstFormat
== &_mesa_texformat_z24_s8
);
2694 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
);
2695 ASSERT(srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2697 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
2698 ctx
->Pixel
.DepthBias
== 0.0f
&&
2699 !srcPacking
->SwapBytes
) {
2701 memcpy_texture(ctx
, dims
,
2702 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2705 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2706 srcAddr
, srcPacking
);
2710 const GLint srcRowStride
2711 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2715 for (img
= 0; img
< srcDepth
; img
++) {
2716 GLuint
*dstRow
= (GLuint
*) dstAddr
2717 + dstImageOffsets
[dstZoffset
+ img
]
2718 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2721 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2722 srcWidth
, srcHeight
,
2725 for (row
= 0; row
< srcHeight
; row
++) {
2726 GLubyte stencil
[MAX_WIDTH
];
2728 /* the 24 depth bits will be in the high position: */
2729 _mesa_unpack_depth_span(ctx
, srcWidth
,
2730 GL_UNSIGNED_INT_24_8_EXT
, /* dst type */
2731 dstRow
, /* dst addr */
2732 (GLuint
) depthScale
,
2733 srcType
, src
, srcPacking
);
2734 /* get the 8-bit stencil values */
2735 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2736 GL_UNSIGNED_BYTE
, /* dst type */
2737 stencil
, /* dst addr */
2738 srcType
, src
, srcPacking
,
2739 ctx
->_ImageTransferState
);
2740 /* merge stencil values into depth values */
2741 for (i
= 0; i
< srcWidth
; i
++)
2742 dstRow
[i
] |= stencil
[i
];
2744 src
+= srcRowStride
;
2745 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2754 * Store a combined depth/stencil texture image.
2757 _mesa_texstore_s8_z24(TEXSTORE_PARAMS
)
2759 const GLuint depthScale
= 0xffffff;
2760 const GLint srcRowStride
2761 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2765 ASSERT(dstFormat
== &_mesa_texformat_s8_z24
);
2766 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
);
2767 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2769 /* In case we only upload depth we need to preserve the stencil */
2770 if (srcFormat
== GL_DEPTH_COMPONENT
) {
2771 for (img
= 0; img
< srcDepth
; img
++) {
2772 GLuint
*dstRow
= (GLuint
*) dstAddr
2773 + dstImageOffsets
[dstZoffset
+ img
]
2774 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2777 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2778 srcWidth
, srcHeight
,
2781 for (row
= 0; row
< srcHeight
; row
++) {
2782 GLuint depth
[MAX_WIDTH
];
2784 _mesa_unpack_depth_span(ctx
, srcWidth
,
2785 GL_UNSIGNED_INT
, /* dst type */
2786 depth
, /* dst addr */
2788 srcType
, src
, srcPacking
);
2790 for (i
= 0; i
< srcWidth
; i
++)
2791 dstRow
[i
] = depth
[i
] | (dstRow
[i
] & 0xFF000000);
2793 src
+= srcRowStride
;
2794 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2799 for (img
= 0; img
< srcDepth
; img
++) {
2800 GLuint
*dstRow
= (GLuint
*) dstAddr
2801 + dstImageOffsets
[dstZoffset
+ img
]
2802 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2805 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2806 srcWidth
, srcHeight
,
2809 for (row
= 0; row
< srcHeight
; row
++) {
2810 GLubyte stencil
[MAX_WIDTH
];
2812 /* the 24 depth bits will be in the low position: */
2813 _mesa_unpack_depth_span(ctx
, srcWidth
,
2814 GL_UNSIGNED_INT
, /* dst type */
2815 dstRow
, /* dst addr */
2817 srcType
, src
, srcPacking
);
2818 /* get the 8-bit stencil values */
2819 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2820 GL_UNSIGNED_BYTE
, /* dst type */
2821 stencil
, /* dst addr */
2822 srcType
, src
, srcPacking
,
2823 ctx
->_ImageTransferState
);
2824 /* merge stencil values into depth values */
2825 for (i
= 0; i
< srcWidth
; i
++)
2826 dstRow
[i
] |= stencil
[i
] << 24;
2828 src
+= srcRowStride
;
2829 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2837 * Store an image in any of the formats:
2838 * _mesa_texformat_rgba_float32
2839 * _mesa_texformat_rgb_float32
2840 * _mesa_texformat_alpha_float32
2841 * _mesa_texformat_luminance_float32
2842 * _mesa_texformat_luminance_alpha_float32
2843 * _mesa_texformat_intensity_float32
2846 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS
)
2848 const GLint components
= _mesa_components_in_format(dstFormat
->BaseFormat
);
2850 ASSERT(dstFormat
== &_mesa_texformat_rgba_float32
||
2851 dstFormat
== &_mesa_texformat_rgb_float32
||
2852 dstFormat
== &_mesa_texformat_alpha_float32
||
2853 dstFormat
== &_mesa_texformat_luminance_float32
||
2854 dstFormat
== &_mesa_texformat_luminance_alpha_float32
||
2855 dstFormat
== &_mesa_texformat_intensity_float32
);
2856 ASSERT(baseInternalFormat
== GL_RGBA
||
2857 baseInternalFormat
== GL_RGB
||
2858 baseInternalFormat
== GL_ALPHA
||
2859 baseInternalFormat
== GL_LUMINANCE
||
2860 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
2861 baseInternalFormat
== GL_INTENSITY
);
2862 ASSERT(dstFormat
->TexelBytes
== components
* sizeof(GLfloat
));
2864 if (!ctx
->_ImageTransferState
&&
2865 !srcPacking
->SwapBytes
&&
2866 baseInternalFormat
== srcFormat
&&
2867 srcType
== GL_FLOAT
) {
2868 /* simple memcpy path */
2869 memcpy_texture(ctx
, dims
,
2870 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2873 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2874 srcAddr
, srcPacking
);
2878 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2880 dstFormat
->BaseFormat
,
2881 srcWidth
, srcHeight
, srcDepth
,
2882 srcFormat
, srcType
, srcAddr
,
2884 const GLfloat
*srcRow
= tempImage
;
2889 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2890 bytesPerRow
= srcWidth
* components
* sizeof(GLfloat
);
2891 for (img
= 0; img
< srcDepth
; img
++) {
2892 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2893 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2894 + dstYoffset
* dstRowStride
2895 + dstXoffset
* dstFormat
->TexelBytes
;
2896 for (row
= 0; row
< srcHeight
; row
++) {
2897 _mesa_memcpy(dstRow
, srcRow
, bytesPerRow
);
2898 dstRow
+= dstRowStride
;
2899 srcRow
+= srcWidth
* components
;
2903 _mesa_free((void *) tempImage
);
2910 * As above, but store 16-bit floats.
2913 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS
)
2915 const GLint components
= _mesa_components_in_format(dstFormat
->BaseFormat
);
2917 ASSERT(dstFormat
== &_mesa_texformat_rgba_float16
||
2918 dstFormat
== &_mesa_texformat_rgb_float16
||
2919 dstFormat
== &_mesa_texformat_alpha_float16
||
2920 dstFormat
== &_mesa_texformat_luminance_float16
||
2921 dstFormat
== &_mesa_texformat_luminance_alpha_float16
||
2922 dstFormat
== &_mesa_texformat_intensity_float16
);
2923 ASSERT(baseInternalFormat
== GL_RGBA
||
2924 baseInternalFormat
== GL_RGB
||
2925 baseInternalFormat
== GL_ALPHA
||
2926 baseInternalFormat
== GL_LUMINANCE
||
2927 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
2928 baseInternalFormat
== GL_INTENSITY
);
2929 ASSERT(dstFormat
->TexelBytes
== components
* sizeof(GLhalfARB
));
2931 if (!ctx
->_ImageTransferState
&&
2932 !srcPacking
->SwapBytes
&&
2933 baseInternalFormat
== srcFormat
&&
2934 srcType
== GL_HALF_FLOAT_ARB
) {
2935 /* simple memcpy path */
2936 memcpy_texture(ctx
, dims
,
2937 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2940 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2941 srcAddr
, srcPacking
);
2945 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2947 dstFormat
->BaseFormat
,
2948 srcWidth
, srcHeight
, srcDepth
,
2949 srcFormat
, srcType
, srcAddr
,
2951 const GLfloat
*src
= tempImage
;
2955 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2956 for (img
= 0; img
< srcDepth
; img
++) {
2957 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2958 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2959 + dstYoffset
* dstRowStride
2960 + dstXoffset
* dstFormat
->TexelBytes
;
2961 for (row
= 0; row
< srcHeight
; row
++) {
2962 GLhalfARB
*dstTexel
= (GLhalfARB
*) dstRow
;
2964 for (i
= 0; i
< srcWidth
* components
; i
++) {
2965 dstTexel
[i
] = _mesa_float_to_half(src
[i
]);
2967 dstRow
+= dstRowStride
;
2968 src
+= srcWidth
* components
;
2972 _mesa_free((void *) tempImage
);
2978 #if FEATURE_EXT_texture_sRGB
2980 _mesa_texstore_srgb8(TEXSTORE_PARAMS
)
2982 const struct gl_texture_format
*newDstFormat
;
2983 StoreTexImageFunc store
;
2986 ASSERT(dstFormat
== &_mesa_texformat_srgb8
);
2988 /* reuse normal rgb texstore code */
2989 newDstFormat
= &_mesa_texformat_rgb888
;
2990 store
= _mesa_texstore_rgb888
;
2992 k
= store(ctx
, dims
, baseInternalFormat
,
2993 newDstFormat
, dstAddr
,
2994 dstXoffset
, dstYoffset
, dstZoffset
,
2995 dstRowStride
, dstImageOffsets
,
2996 srcWidth
, srcHeight
, srcDepth
,
2998 srcAddr
, srcPacking
);
3004 _mesa_texstore_srgba8(TEXSTORE_PARAMS
)
3006 const struct gl_texture_format
*newDstFormat
;
3009 ASSERT(dstFormat
== &_mesa_texformat_srgba8
);
3011 /* reuse normal rgba texstore code */
3012 newDstFormat
= &_mesa_texformat_rgba8888
;
3014 k
= _mesa_texstore_rgba8888(ctx
, dims
, baseInternalFormat
,
3015 newDstFormat
, dstAddr
,
3016 dstXoffset
, dstYoffset
, dstZoffset
,
3017 dstRowStride
, dstImageOffsets
,
3018 srcWidth
, srcHeight
, srcDepth
,
3020 srcAddr
, srcPacking
);
3026 _mesa_texstore_sargb8(TEXSTORE_PARAMS
)
3028 const struct gl_texture_format
*newDstFormat
;
3031 ASSERT(dstFormat
== &_mesa_texformat_sargb8
);
3033 /* reuse normal rgba texstore code */
3034 newDstFormat
= &_mesa_texformat_argb8888
;
3036 k
= _mesa_texstore_argb8888(ctx
, dims
, baseInternalFormat
,
3037 newDstFormat
, dstAddr
,
3038 dstXoffset
, dstYoffset
, dstZoffset
,
3039 dstRowStride
, dstImageOffsets
,
3040 srcWidth
, srcHeight
, srcDepth
,
3042 srcAddr
, srcPacking
);
3048 _mesa_texstore_sl8(TEXSTORE_PARAMS
)
3050 const struct gl_texture_format
*newDstFormat
;
3053 ASSERT(dstFormat
== &_mesa_texformat_sl8
);
3055 newDstFormat
= &_mesa_texformat_l8
;
3057 /* _mesa_textore_a8 handles luminance8 too */
3058 k
= _mesa_texstore_a8(ctx
, dims
, baseInternalFormat
,
3059 newDstFormat
, dstAddr
,
3060 dstXoffset
, dstYoffset
, dstZoffset
,
3061 dstRowStride
, dstImageOffsets
,
3062 srcWidth
, srcHeight
, srcDepth
,
3064 srcAddr
, srcPacking
);
3070 _mesa_texstore_sla8(TEXSTORE_PARAMS
)
3072 const struct gl_texture_format
*newDstFormat
;
3075 ASSERT(dstFormat
== &_mesa_texformat_sla8
);
3077 /* reuse normal luminance/alpha texstore code */
3078 newDstFormat
= &_mesa_texformat_al88
;
3080 k
= _mesa_texstore_al88(ctx
, dims
, baseInternalFormat
,
3081 newDstFormat
, dstAddr
,
3082 dstXoffset
, dstYoffset
, dstZoffset
,
3083 dstRowStride
, dstImageOffsets
,
3084 srcWidth
, srcHeight
, srcDepth
,
3086 srcAddr
, srcPacking
);
3090 #endif /* FEATURE_EXT_texture_sRGB */
3094 * Check if an unpack PBO is active prior to fetching a texture image.
3095 * If so, do bounds checking and map the buffer into main memory.
3096 * Any errors detected will be recorded.
3097 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3100 _mesa_validate_pbo_teximage(GLcontext
*ctx
, GLuint dimensions
,
3101 GLsizei width
, GLsizei height
, GLsizei depth
,
3102 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3103 const struct gl_pixelstore_attrib
*unpack
,
3104 const char *funcName
)
3108 if (unpack
->BufferObj
->Name
== 0) {
3112 if (!_mesa_validate_pbo_access(dimensions
, unpack
, width
, height
, depth
,
3113 format
, type
, pixels
)) {
3114 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3118 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3119 GL_READ_ONLY_ARB
, unpack
->BufferObj
);
3121 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3125 return ADD_POINTERS(buf
, pixels
);
3130 * Check if an unpack PBO is active prior to fetching a compressed texture
3132 * If so, do bounds checking and map the buffer into main memory.
3133 * Any errors detected will be recorded.
3134 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3137 _mesa_validate_pbo_compressed_teximage(GLcontext
*ctx
,
3138 GLsizei imageSize
, const GLvoid
*pixels
,
3139 const struct gl_pixelstore_attrib
*packing
,
3140 const char *funcName
)
3144 if (packing
->BufferObj
->Name
== 0) {
3145 /* not using a PBO - return pointer unchanged */
3148 if ((const GLubyte
*) pixels
+ imageSize
>
3149 ((const GLubyte
*) 0) + packing
->BufferObj
->Size
) {
3150 /* out of bounds read! */
3151 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3155 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3156 GL_READ_ONLY_ARB
, packing
->BufferObj
);
3158 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3162 return ADD_POINTERS(buf
, pixels
);
3167 * This function must be called after either of the validate_pbo_*_teximage()
3168 * functions. It unmaps the PBO buffer if it was mapped earlier.
3171 _mesa_unmap_teximage_pbo(GLcontext
*ctx
,
3172 const struct gl_pixelstore_attrib
*unpack
)
3174 if (unpack
->BufferObj
->Name
) {
3175 ctx
->Driver
.UnmapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3183 * Adaptor for fetching a GLchan texel from a float-valued texture.
3186 fetch_texel_float_to_chan(const struct gl_texture_image
*texImage
,
3187 GLint i
, GLint j
, GLint k
, GLchan
*texelOut
)
3190 ASSERT(texImage
->FetchTexelf
);
3191 texImage
->FetchTexelf(texImage
, i
, j
, k
, temp
);
3192 if (texImage
->TexFormat
->BaseFormat
== GL_DEPTH_COMPONENT
||
3193 texImage
->TexFormat
->BaseFormat
== GL_DEPTH_STENCIL_EXT
) {
3194 /* just one channel */
3195 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[0], temp
[0]);
3199 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[0], temp
[0]);
3200 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[1], temp
[1]);
3201 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[2], temp
[2]);
3202 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[3], temp
[3]);
3208 * Adaptor for fetching a float texel from a GLchan-valued texture.
3211 fetch_texel_chan_to_float(const struct gl_texture_image
*texImage
,
3212 GLint i
, GLint j
, GLint k
, GLfloat
*texelOut
)
3215 ASSERT(texImage
->FetchTexelc
);
3216 texImage
->FetchTexelc(texImage
, i
, j
, k
, temp
);
3217 if (texImage
->TexFormat
->BaseFormat
== GL_DEPTH_COMPONENT
||
3218 texImage
->TexFormat
->BaseFormat
== GL_DEPTH_STENCIL_EXT
) {
3219 /* just one channel */
3220 texelOut
[0] = CHAN_TO_FLOAT(temp
[0]);
3224 texelOut
[0] = CHAN_TO_FLOAT(temp
[0]);
3225 texelOut
[1] = CHAN_TO_FLOAT(temp
[1]);
3226 texelOut
[2] = CHAN_TO_FLOAT(temp
[2]);
3227 texelOut
[3] = CHAN_TO_FLOAT(temp
[3]);
3233 * Initialize the texture image's FetchTexelc and FetchTexelf methods.
3236 _mesa_set_fetch_functions(struct gl_texture_image
*texImage
, GLuint dims
)
3238 ASSERT(dims
== 1 || dims
== 2 || dims
== 3);
3239 ASSERT(texImage
->TexFormat
);
3243 texImage
->FetchTexelc
= texImage
->TexFormat
->FetchTexel1D
;
3244 texImage
->FetchTexelf
= texImage
->TexFormat
->FetchTexel1Df
;
3247 texImage
->FetchTexelc
= texImage
->TexFormat
->FetchTexel2D
;
3248 texImage
->FetchTexelf
= texImage
->TexFormat
->FetchTexel2Df
;
3251 texImage
->FetchTexelc
= texImage
->TexFormat
->FetchTexel3D
;
3252 texImage
->FetchTexelf
= texImage
->TexFormat
->FetchTexel3Df
;
3258 /* now check if we need to use a float/chan adaptor */
3259 if (!texImage
->FetchTexelc
) {
3260 texImage
->FetchTexelc
= fetch_texel_float_to_chan
;
3262 else if (!texImage
->FetchTexelf
) {
3263 texImage
->FetchTexelf
= fetch_texel_chan_to_float
;
3267 ASSERT(texImage
->FetchTexelc
);
3268 ASSERT(texImage
->FetchTexelf
);
3273 * Choose the actual storage format for a new texture image.
3274 * Mainly, this is a wrapper for the driver's ChooseTextureFormat() function.
3275 * Also set some other texImage fields related to texture compression, etc.
3276 * \param ctx rendering context
3277 * \param texImage the gl_texture_image
3278 * \param dims texture dimensions (1, 2 or 3)
3279 * \param format the user-specified format parameter
3280 * \param type the user-specified type parameter
3281 * \param internalFormat the user-specified internal format hint
3284 choose_texture_format(GLcontext
*ctx
, struct gl_texture_image
*texImage
,
3286 GLenum format
, GLenum type
, GLint internalFormat
)
3288 ASSERT(dims
== 1 || dims
== 2 || dims
== 3);
3289 ASSERT(ctx
->Driver
.ChooseTextureFormat
);
3292 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3294 ASSERT(texImage
->TexFormat
);
3296 _mesa_set_fetch_functions(texImage
, dims
);
3298 if (texImage
->TexFormat
->TexelBytes
== 0) {
3299 /* must be a compressed format */
3300 texImage
->IsCompressed
= GL_TRUE
;
3301 texImage
->CompressedSize
=
3302 ctx
->Driver
.CompressedTextureSize(ctx
, texImage
->Width
,
3303 texImage
->Height
, texImage
->Depth
,
3304 texImage
->TexFormat
->MesaFormat
);
3307 /* non-compressed format */
3308 texImage
->IsCompressed
= GL_FALSE
;
3309 texImage
->CompressedSize
= 0;
3316 * This is the software fallback for Driver.TexImage1D()
3317 * and Driver.CopyTexImage1D().
3318 * \sa _mesa_store_teximage2d()
3319 * Note that the width may not be the actual texture width since it may
3320 * be changed by convolution w/ GL_REDUCE. The texImage->Width field will
3321 * have the actual texture size.
3324 _mesa_store_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3325 GLint internalFormat
,
3326 GLint width
, GLint border
,
3327 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3328 const struct gl_pixelstore_attrib
*packing
,
3329 struct gl_texture_object
*texObj
,
3330 struct gl_texture_image
*texImage
)
3335 choose_texture_format(ctx
, texImage
, 1, format
, type
, internalFormat
);
3337 /* allocate memory */
3338 if (texImage
->IsCompressed
)
3339 sizeInBytes
= texImage
->CompressedSize
;
3341 sizeInBytes
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
3342 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3343 if (!texImage
->Data
) {
3344 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
3348 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
3349 pixels
, packing
, "glTexImage1D");
3351 /* Note: we check for a NULL image pointer here, _after_ we allocated
3352 * memory for the texture. That's what the GL spec calls for.
3357 const GLint dstRowStride
= 0;
3359 ASSERT(texImage
->TexFormat
->StoreImage
);
3360 success
= texImage
->TexFormat
->StoreImage(ctx
, 1, texImage
->_BaseFormat
,
3361 texImage
->TexFormat
,
3363 0, 0, 0, /* dstX/Y/Zoffset */
3365 texImage
->ImageOffsets
,
3367 format
, type
, pixels
, packing
);
3369 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
3373 /* GL_SGIS_generate_mipmap */
3374 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
3375 ctx
->Driver
.GenerateMipmap(ctx
, target
, texObj
);
3378 _mesa_unmap_teximage_pbo(ctx
, packing
);
3383 * This is the software fallback for Driver.TexImage2D()
3384 * and Driver.CopyTexImage2D().
3386 * This function is oriented toward storing images in main memory, rather
3387 * than VRAM. Device driver's can easily plug in their own replacement.
3389 * Note: width and height may be pre-convolved dimensions, but
3390 * texImage->Width and texImage->Height will be post-convolved dimensions.
3393 _mesa_store_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3394 GLint internalFormat
,
3395 GLint width
, GLint height
, GLint border
,
3396 GLenum format
, GLenum type
, const void *pixels
,
3397 const struct gl_pixelstore_attrib
*packing
,
3398 struct gl_texture_object
*texObj
,
3399 struct gl_texture_image
*texImage
)
3401 GLint texelBytes
, sizeInBytes
;
3404 choose_texture_format(ctx
, texImage
, 2, format
, type
, internalFormat
);
3406 texelBytes
= texImage
->TexFormat
->TexelBytes
;
3408 /* allocate memory */
3409 if (texImage
->IsCompressed
)
3410 sizeInBytes
= texImage
->CompressedSize
;
3412 sizeInBytes
= texImage
->Width
* texImage
->Height
* texelBytes
;
3413 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3414 if (!texImage
->Data
) {
3415 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
3419 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
3420 pixels
, packing
, "glTexImage2D");
3422 /* Note: we check for a NULL image pointer here, _after_ we allocated
3423 * memory for the texture. That's what the GL spec calls for.
3430 if (texImage
->IsCompressed
) {
3432 = _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, width
);
3435 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
3437 ASSERT(texImage
->TexFormat
->StoreImage
);
3438 success
= texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->_BaseFormat
,
3439 texImage
->TexFormat
,
3441 0, 0, 0, /* dstX/Y/Zoffset */
3443 texImage
->ImageOffsets
,
3445 format
, type
, pixels
, packing
);
3447 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
3451 /* GL_SGIS_generate_mipmap */
3452 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
3453 ctx
->Driver
.GenerateMipmap(ctx
, target
, texObj
);
3456 _mesa_unmap_teximage_pbo(ctx
, packing
);
3462 * This is the software fallback for Driver.TexImage3D()
3463 * and Driver.CopyTexImage3D().
3464 * \sa _mesa_store_teximage2d()
3467 _mesa_store_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3468 GLint internalFormat
,
3469 GLint width
, GLint height
, GLint depth
, GLint border
,
3470 GLenum format
, GLenum type
, const void *pixels
,
3471 const struct gl_pixelstore_attrib
*packing
,
3472 struct gl_texture_object
*texObj
,
3473 struct gl_texture_image
*texImage
)
3475 GLint texelBytes
, sizeInBytes
;
3478 choose_texture_format(ctx
, texImage
, 3, format
, type
, internalFormat
);
3480 texelBytes
= texImage
->TexFormat
->TexelBytes
;
3482 /* allocate memory */
3483 if (texImage
->IsCompressed
)
3484 sizeInBytes
= texImage
->CompressedSize
;
3486 sizeInBytes
= width
* height
* depth
* texelBytes
;
3487 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3488 if (!texImage
->Data
) {
3489 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
3493 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
3494 type
, pixels
, packing
, "glTexImage3D");
3496 /* Note: we check for a NULL image pointer here, _after_ we allocated
3497 * memory for the texture. That's what the GL spec calls for.
3504 if (texImage
->IsCompressed
) {
3506 = _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, width
);
3509 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
3511 ASSERT(texImage
->TexFormat
->StoreImage
);
3512 success
= texImage
->TexFormat
->StoreImage(ctx
, 3, texImage
->_BaseFormat
,
3513 texImage
->TexFormat
,
3515 0, 0, 0, /* dstX/Y/Zoffset */
3517 texImage
->ImageOffsets
,
3518 width
, height
, depth
,
3519 format
, type
, pixels
, packing
);
3521 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
3525 /* GL_SGIS_generate_mipmap */
3526 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
3527 ctx
->Driver
.GenerateMipmap(ctx
, target
, texObj
);
3530 _mesa_unmap_teximage_pbo(ctx
, packing
);
3537 * This is the software fallback for Driver.TexSubImage1D()
3538 * and Driver.CopyTexSubImage1D().
3541 _mesa_store_texsubimage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3542 GLint xoffset
, GLint width
,
3543 GLenum format
, GLenum type
, const void *pixels
,
3544 const struct gl_pixelstore_attrib
*packing
,
3545 struct gl_texture_object
*texObj
,
3546 struct gl_texture_image
*texImage
)
3548 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3549 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
3550 pixels
, packing
, "glTexSubImage1D");
3555 const GLint dstRowStride
= 0;
3557 ASSERT(texImage
->TexFormat
->StoreImage
);
3558 success
= texImage
->TexFormat
->StoreImage(ctx
, 1, texImage
->_BaseFormat
,
3559 texImage
->TexFormat
,
3561 xoffset
, 0, 0, /* offsets */
3563 texImage
->ImageOffsets
,
3565 format
, type
, pixels
, packing
);
3567 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
3571 /* GL_SGIS_generate_mipmap */
3572 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
3573 ctx
->Driver
.GenerateMipmap(ctx
, target
, texObj
);
3576 _mesa_unmap_teximage_pbo(ctx
, packing
);
3582 * This is the software fallback for Driver.TexSubImage2D()
3583 * and Driver.CopyTexSubImage2D().
3586 _mesa_store_texsubimage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3587 GLint xoffset
, GLint yoffset
,
3588 GLint width
, GLint height
,
3589 GLenum format
, GLenum type
, const void *pixels
,
3590 const struct gl_pixelstore_attrib
*packing
,
3591 struct gl_texture_object
*texObj
,
3592 struct gl_texture_image
*texImage
)
3594 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3595 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
3596 pixels
, packing
, "glTexSubImage2D");
3601 GLint dstRowStride
= 0;
3603 if (texImage
->IsCompressed
) {
3604 dstRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
,
3608 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
3610 ASSERT(texImage
->TexFormat
->StoreImage
);
3611 success
= texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->_BaseFormat
,
3612 texImage
->TexFormat
,
3614 xoffset
, yoffset
, 0,
3616 texImage
->ImageOffsets
,
3618 format
, type
, pixels
, packing
);
3620 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
3624 /* GL_SGIS_generate_mipmap */
3625 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
3626 ctx
->Driver
.GenerateMipmap(ctx
, target
, texObj
);
3629 _mesa_unmap_teximage_pbo(ctx
, packing
);
3634 * This is the software fallback for Driver.TexSubImage3D().
3635 * and Driver.CopyTexSubImage3D().
3638 _mesa_store_texsubimage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3639 GLint xoffset
, GLint yoffset
, GLint zoffset
,
3640 GLint width
, GLint height
, GLint depth
,
3641 GLenum format
, GLenum type
, const void *pixels
,
3642 const struct gl_pixelstore_attrib
*packing
,
3643 struct gl_texture_object
*texObj
,
3644 struct gl_texture_image
*texImage
)
3646 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3647 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
3648 type
, pixels
, packing
,
3656 if (texImage
->IsCompressed
) {
3657 dstRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
,
3661 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
3663 ASSERT(texImage
->TexFormat
->StoreImage
);
3664 success
= texImage
->TexFormat
->StoreImage(ctx
, 3, texImage
->_BaseFormat
,
3665 texImage
->TexFormat
,
3667 xoffset
, yoffset
, zoffset
,
3669 texImage
->ImageOffsets
,
3670 width
, height
, depth
,
3671 format
, type
, pixels
, packing
);
3673 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3D");
3677 /* GL_SGIS_generate_mipmap */
3678 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
3679 ctx
->Driver
.GenerateMipmap(ctx
, target
, texObj
);
3682 _mesa_unmap_teximage_pbo(ctx
, packing
);
3687 * Fallback for Driver.CompressedTexImage1D()
3690 _mesa_store_compressed_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3691 GLint internalFormat
,
3692 GLint width
, GLint border
,
3693 GLsizei imageSize
, const GLvoid
*data
,
3694 struct gl_texture_object
*texObj
,
3695 struct gl_texture_image
*texImage
)
3697 /* this space intentionally left blank */
3699 (void) target
; (void) level
;
3700 (void) internalFormat
;
3701 (void) width
; (void) border
;
3702 (void) imageSize
; (void) data
;
3710 * Fallback for Driver.CompressedTexImage2D()
3713 _mesa_store_compressed_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3714 GLint internalFormat
,
3715 GLint width
, GLint height
, GLint border
,
3716 GLsizei imageSize
, const GLvoid
*data
,
3717 struct gl_texture_object
*texObj
,
3718 struct gl_texture_image
*texImage
)
3720 (void) width
; (void) height
; (void) border
;
3722 /* This is pretty simple, basically just do a memcpy without worrying
3723 * about the usual image unpacking or image transfer operations.
3727 ASSERT(texImage
->Width
> 0);
3728 ASSERT(texImage
->Height
> 0);
3729 ASSERT(texImage
->Depth
== 1);
3730 ASSERT(texImage
->Data
== NULL
); /* was freed in glCompressedTexImage2DARB */
3732 choose_texture_format(ctx
, texImage
, 2, 0, 0, internalFormat
);
3734 /* allocate storage */
3735 texImage
->Data
= _mesa_alloc_texmemory(imageSize
);
3736 if (!texImage
->Data
) {
3737 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
3741 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
3743 "glCompressedTexImage2D");
3748 ASSERT(texImage
->CompressedSize
== (GLuint
) imageSize
);
3749 MEMCPY(texImage
->Data
, data
, imageSize
);
3751 /* GL_SGIS_generate_mipmap */
3752 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
3753 ctx
->Driver
.GenerateMipmap(ctx
, target
, texObj
);
3756 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
3762 * Fallback for Driver.CompressedTexImage3D()
3765 _mesa_store_compressed_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3766 GLint internalFormat
,
3767 GLint width
, GLint height
, GLint depth
,
3769 GLsizei imageSize
, const GLvoid
*data
,
3770 struct gl_texture_object
*texObj
,
3771 struct gl_texture_image
*texImage
)
3773 /* this space intentionally left blank */
3775 (void) target
; (void) level
;
3776 (void) internalFormat
;
3777 (void) width
; (void) height
; (void) depth
;
3779 (void) imageSize
; (void) data
;
3787 * Fallback for Driver.CompressedTexSubImage1D()
3790 _mesa_store_compressed_texsubimage1d(GLcontext
*ctx
, GLenum target
,
3792 GLint xoffset
, GLsizei width
,
3794 GLsizei imageSize
, const GLvoid
*data
,
3795 struct gl_texture_object
*texObj
,
3796 struct gl_texture_image
*texImage
)
3798 /* there are no compressed 1D texture formats yet */
3800 (void) target
; (void) level
;
3801 (void) xoffset
; (void) width
;
3803 (void) imageSize
; (void) data
;
3810 * Fallback for Driver.CompressedTexSubImage2D()
3813 _mesa_store_compressed_texsubimage2d(GLcontext
*ctx
, GLenum target
,
3815 GLint xoffset
, GLint yoffset
,
3816 GLsizei width
, GLsizei height
,
3818 GLsizei imageSize
, const GLvoid
*data
,
3819 struct gl_texture_object
*texObj
,
3820 struct gl_texture_image
*texImage
)
3822 GLint bytesPerRow
, destRowStride
, srcRowStride
;
3826 const GLuint mesaFormat
= texImage
->TexFormat
->MesaFormat
;
3830 /* these should have been caught sooner */
3831 ASSERT((width
& 3) == 0 || width
== 2 || width
== 1);
3832 ASSERT((height
& 3) == 0 || height
== 2 || height
== 1);
3833 ASSERT((xoffset
& 3) == 0);
3834 ASSERT((yoffset
& 3) == 0);
3836 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3837 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
3839 "glCompressedTexSubImage2D");
3843 srcRowStride
= _mesa_compressed_row_stride(mesaFormat
, width
);
3844 src
= (const GLubyte
*) data
;
3846 destRowStride
= _mesa_compressed_row_stride(mesaFormat
, texImage
->Width
);
3847 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
3848 texImage
->TexFormat
->MesaFormat
,
3850 (GLubyte
*) texImage
->Data
);
3852 bytesPerRow
= srcRowStride
;
3855 for (i
= 0; i
< rows
; i
++) {
3856 MEMCPY(dest
, src
, bytesPerRow
);
3857 dest
+= destRowStride
;
3858 src
+= srcRowStride
;
3861 /* GL_SGIS_generate_mipmap */
3862 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
3863 ctx
->Driver
.GenerateMipmap(ctx
, target
, texObj
);
3866 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
3871 * Fallback for Driver.CompressedTexSubImage3D()
3874 _mesa_store_compressed_texsubimage3d(GLcontext
*ctx
, GLenum target
,
3876 GLint xoffset
, GLint yoffset
, GLint zoffset
,
3877 GLsizei width
, GLsizei height
, GLsizei depth
,
3879 GLsizei imageSize
, const GLvoid
*data
,
3880 struct gl_texture_object
*texObj
,
3881 struct gl_texture_image
*texImage
)
3883 /* there are no compressed 3D texture formats yet */
3885 (void) target
; (void) level
;
3886 (void) xoffset
; (void) yoffset
; (void) zoffset
;
3887 (void) width
; (void) height
; (void) depth
;
3889 (void) imageSize
; (void) data
;
3897 #if FEATURE_EXT_texture_sRGB
3900 * Test if given texture image is an sRGB format.
3903 is_srgb_teximage(const struct gl_texture_image
*texImage
)
3905 switch (texImage
->TexFormat
->MesaFormat
) {
3906 case MESA_FORMAT_SRGB8
:
3907 case MESA_FORMAT_SRGBA8
:
3908 case MESA_FORMAT_SARGB8
:
3909 case MESA_FORMAT_SL8
:
3910 case MESA_FORMAT_SLA8
:
3911 case MESA_FORMAT_SRGB_DXT1
:
3912 case MESA_FORMAT_SRGBA_DXT1
:
3913 case MESA_FORMAT_SRGBA_DXT3
:
3914 case MESA_FORMAT_SRGBA_DXT5
:
3923 * Convert a float value from linear space to a
3924 * non-linear sRGB value in [0, 255].
3925 * Not terribly efficient.
3927 static INLINE GLfloat
3928 linear_to_nonlinear(GLfloat cl
)
3930 /* can't have values outside [0, 1] */
3932 if (cl
< 0.0031308) {
3936 cs
= 1.055 * _mesa_pow(cl
, 0.41666) - 0.055;
3941 #endif /* FEATURE_EXT_texture_sRGB */
3945 * Can the given type represent negative values?
3947 static INLINE GLboolean
3948 type_with_negative_values(GLenum type
)
3955 case GL_HALF_FLOAT_ARB
:
3964 * This is the software fallback for Driver.GetTexImage().
3965 * All error checking will have been done before this routine is called.
3968 _mesa_get_teximage(GLcontext
*ctx
, GLenum target
, GLint level
,
3969 GLenum format
, GLenum type
, GLvoid
*pixels
,
3970 struct gl_texture_object
*texObj
,
3971 struct gl_texture_image
*texImage
)
3973 const GLuint dimensions
= (target
== GL_TEXTURE_3D
) ? 3 : 2;
3975 if (ctx
->Pack
.BufferObj
->Name
) {
3976 /* Packing texture image into a PBO.
3977 * Map the (potentially) VRAM-based buffer into our process space so
3978 * we can write into it with the code below.
3979 * A hardware driver might use a sophisticated blit to move the
3980 * texture data to the PBO if the PBO is in VRAM along with the texture.
3982 GLubyte
*buf
= (GLubyte
*)
3983 ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_PACK_BUFFER_EXT
,
3984 GL_WRITE_ONLY_ARB
, ctx
->Pack
.BufferObj
);
3986 /* buffer is already mapped - that's an error */
3987 _mesa_error(ctx
, GL_INVALID_OPERATION
,"glGetTexImage(PBO is mapped)");
3990 /* <pixels> was an offset into the PBO.
3991 * Now make it a real, client-side pointer inside the mapped region.
3993 pixels
= ADD_POINTERS(buf
, pixels
);
4001 const GLint width
= texImage
->Width
;
4002 const GLint height
= texImage
->Height
;
4003 const GLint depth
= texImage
->Depth
;
4005 for (img
= 0; img
< depth
; img
++) {
4006 for (row
= 0; row
< height
; row
++) {
4007 /* compute destination address in client memory */
4008 GLvoid
*dest
= _mesa_image_address( dimensions
, &ctx
->Pack
, pixels
,
4009 width
, height
, format
, type
,
4013 if (format
== GL_COLOR_INDEX
) {
4014 GLuint indexRow
[MAX_WIDTH
];
4016 /* Can't use FetchTexel here because that returns RGBA */
4017 if (texImage
->TexFormat
->IndexBits
== 8) {
4018 const GLubyte
*src
= (const GLubyte
*) texImage
->Data
;
4019 src
+= width
* (img
* texImage
->Height
+ row
);
4020 for (col
= 0; col
< width
; col
++) {
4021 indexRow
[col
] = src
[col
];
4024 else if (texImage
->TexFormat
->IndexBits
== 16) {
4025 const GLushort
*src
= (const GLushort
*) texImage
->Data
;
4026 src
+= width
* (img
* texImage
->Height
+ row
);
4027 for (col
= 0; col
< width
; col
++) {
4028 indexRow
[col
] = src
[col
];
4033 "Color index problem in _mesa_GetTexImage");
4035 _mesa_pack_index_span(ctx
, width
, type
, dest
,
4036 indexRow
, &ctx
->Pack
,
4037 0 /* no image transfer */);
4039 else if (format
== GL_DEPTH_COMPONENT
) {
4040 GLfloat depthRow
[MAX_WIDTH
];
4042 for (col
= 0; col
< width
; col
++) {
4043 (*texImage
->FetchTexelf
)(texImage
, col
, row
, img
,
4046 _mesa_pack_depth_span(ctx
, width
, dest
, type
,
4047 depthRow
, &ctx
->Pack
);
4049 else if (format
== GL_DEPTH_STENCIL_EXT
) {
4050 /* XXX Note: we're bypassing texImage->FetchTexel()! */
4051 const GLuint
*src
= (const GLuint
*) texImage
->Data
;
4052 src
+= width
* row
+ width
* height
* img
;
4053 _mesa_memcpy(dest
, src
, width
* sizeof(GLuint
));
4054 if (ctx
->Pack
.SwapBytes
) {
4055 _mesa_swap4((GLuint
*) dest
, width
);
4058 else if (format
== GL_YCBCR_MESA
) {
4059 /* No pixel transfer */
4060 const GLint rowstride
= texImage
->RowStride
;
4062 (const GLushort
*) texImage
->Data
+ row
* rowstride
,
4063 width
* sizeof(GLushort
));
4064 /* check for byte swapping */
4065 if ((texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_YCBCR
4066 && type
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ||
4067 (texImage
->TexFormat
->MesaFormat
== MESA_FORMAT_YCBCR_REV
4068 && type
== GL_UNSIGNED_SHORT_8_8_MESA
)) {
4069 if (!ctx
->Pack
.SwapBytes
)
4070 _mesa_swap2((GLushort
*) dest
, width
);
4072 else if (ctx
->Pack
.SwapBytes
) {
4073 _mesa_swap2((GLushort
*) dest
, width
);
4076 #if FEATURE_EXT_texture_sRGB
4077 else if (is_srgb_teximage(texImage
)) {
4078 /* special case this since need to backconvert values */
4079 /* convert row to RGBA format */
4080 GLfloat rgba
[MAX_WIDTH
][4];
4082 GLbitfield transferOps
= 0x0;
4084 for (col
= 0; col
< width
; col
++) {
4085 (*texImage
->FetchTexelf
)(texImage
, col
, row
, img
, rgba
[col
]);
4086 if (texImage
->_BaseFormat
== GL_LUMINANCE
) {
4087 rgba
[col
][RCOMP
] = linear_to_nonlinear(rgba
[col
][RCOMP
]);
4088 rgba
[col
][GCOMP
] = 0.0;
4089 rgba
[col
][BCOMP
] = 0.0;
4091 else if (texImage
->_BaseFormat
== GL_LUMINANCE_ALPHA
) {
4092 rgba
[col
][RCOMP
] = linear_to_nonlinear(rgba
[col
][RCOMP
]);
4093 rgba
[col
][GCOMP
] = 0.0;
4094 rgba
[col
][BCOMP
] = 0.0;
4096 else if (texImage
->_BaseFormat
== GL_RGB
||
4097 texImage
->_BaseFormat
== GL_RGBA
) {
4098 rgba
[col
][RCOMP
] = linear_to_nonlinear(rgba
[col
][RCOMP
]);
4099 rgba
[col
][GCOMP
] = linear_to_nonlinear(rgba
[col
][GCOMP
]);
4100 rgba
[col
][BCOMP
] = linear_to_nonlinear(rgba
[col
][BCOMP
]);
4103 _mesa_pack_rgba_span_float(ctx
, width
, (GLfloat (*)[4]) rgba
,
4105 &ctx
->Pack
, transferOps
);
4107 #endif /* FEATURE_EXT_texture_sRGB */
4109 /* general case: convert row to RGBA format */
4110 GLfloat rgba
[MAX_WIDTH
][4];
4112 GLbitfield transferOps
= 0x0;
4114 /* clamp does not apply to GetTexImage (final conversion)?
4115 * Looks like we need clamp though when going from format
4116 * containing negative values to unsigned format.
4118 if (format
== GL_LUMINANCE
|| format
== GL_LUMINANCE_ALPHA
)
4119 transferOps
|= IMAGE_CLAMP_BIT
;
4120 else if (!type_with_negative_values(type
) &&
4121 (texImage
->TexFormat
->DataType
== GL_FLOAT
||
4122 texImage
->TexFormat
->DataType
== GL_SIGNED_NORMALIZED
))
4123 transferOps
|= IMAGE_CLAMP_BIT
;
4125 for (col
= 0; col
< width
; col
++) {
4126 (*texImage
->FetchTexelf
)(texImage
, col
, row
, img
, rgba
[col
]);
4127 if (texImage
->_BaseFormat
== GL_ALPHA
) {
4128 rgba
[col
][RCOMP
] = 0.0;
4129 rgba
[col
][GCOMP
] = 0.0;
4130 rgba
[col
][BCOMP
] = 0.0;
4132 else if (texImage
->_BaseFormat
== GL_LUMINANCE
) {
4133 rgba
[col
][GCOMP
] = 0.0;
4134 rgba
[col
][BCOMP
] = 0.0;
4135 rgba
[col
][ACOMP
] = 1.0;
4137 else if (texImage
->_BaseFormat
== GL_LUMINANCE_ALPHA
) {
4138 rgba
[col
][GCOMP
] = 0.0;
4139 rgba
[col
][BCOMP
] = 0.0;
4141 else if (texImage
->_BaseFormat
== GL_INTENSITY
) {
4142 rgba
[col
][GCOMP
] = 0.0;
4143 rgba
[col
][BCOMP
] = 0.0;
4144 rgba
[col
][ACOMP
] = 1.0;
4147 _mesa_pack_rgba_span_float(ctx
, width
, (GLfloat (*)[4]) rgba
,
4149 &ctx
->Pack
, transferOps
);
4155 if (ctx
->Pack
.BufferObj
->Name
) {
4156 ctx
->Driver
.UnmapBuffer(ctx
, GL_PIXEL_PACK_BUFFER_EXT
,
4157 ctx
->Pack
.BufferObj
);
4164 * This is the software fallback for Driver.GetCompressedTexImage().
4165 * All error checking will have been done before this routine is called.
4168 _mesa_get_compressed_teximage(GLcontext
*ctx
, GLenum target
, GLint level
,
4170 struct gl_texture_object
*texObj
,
4171 struct gl_texture_image
*texImage
)
4175 if (ctx
->Pack
.BufferObj
->Name
) {
4176 /* pack texture image into a PBO */
4178 if ((const GLubyte
*) img
+ texImage
->CompressedSize
>
4179 (const GLubyte
*) ctx
->Pack
.BufferObj
->Size
) {
4180 _mesa_error(ctx
, GL_INVALID_OPERATION
,
4181 "glGetCompressedTexImage(invalid PBO access)");
4184 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_PACK_BUFFER_EXT
,
4186 ctx
->Pack
.BufferObj
);
4188 /* buffer is already mapped - that's an error */
4189 _mesa_error(ctx
, GL_INVALID_OPERATION
,
4190 "glGetCompressedTexImage(PBO is mapped)");
4193 img
= ADD_POINTERS(buf
, img
);
4200 /* don't use texImage->CompressedSize since that may be padded out */
4201 size
= _mesa_compressed_texture_size(ctx
, texImage
->Width
, texImage
->Height
,
4203 texImage
->TexFormat
->MesaFormat
);
4205 /* just memcpy, no pixelstore or pixel transfer */
4206 _mesa_memcpy(img
, texImage
->Data
, size
);
4208 if (ctx
->Pack
.BufferObj
->Name
) {
4209 ctx
->Driver
.UnmapBuffer(ctx
, GL_PIXEL_PACK_BUFFER_EXT
,
4210 ctx
->Pack
.BufferObj
);