2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (c) 2008-2009 VMware, Inc.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 * The GL texture image functions in teximage.c basically just do
33 * error checking and data structure allocation. They in turn call
34 * device driver functions which actually copy/convert/store the user's
37 * However, most device drivers will be able to use the fallback functions
38 * in this file. That is, most drivers will have the following bit of
40 * ctx->Driver.TexImage1D = _mesa_store_teximage1d;
41 * ctx->Driver.TexImage2D = _mesa_store_teximage2d;
42 * ctx->Driver.TexImage3D = _mesa_store_teximage3d;
45 * Texture image processing is actually kind of complicated. We have to do:
46 * Format/type conversions
48 * pixel transfer (scale, bais, lookup, convolution!, etc)
50 * These functions can handle most everything, including processing full
51 * images and sub-images.
56 #include "bufferobj.h"
64 #include "texcompress.h"
65 #include "texcompress_fxt1.h"
66 #include "texcompress_s3tc.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 GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
946 const GLint bytesPerRow
= srcWidth
* texelBytes
;
949 /* XXX update/re-enable for dstImageOffsets array */
950 const GLint bytesPerImage
= srcHeight
* bytesPerRow
;
951 const GLint bytesPerTexture
= srcDepth
* bytesPerImage
;
952 GLubyte
*dstImage
= (GLubyte
*) dstAddr
953 + dstZoffset
* dstImageStride
954 + dstYoffset
* dstRowStride
955 + dstXoffset
* texelBytes
;
957 if (dstRowStride
== srcRowStride
&&
958 dstRowStride
== bytesPerRow
&&
959 ((dstImageStride
== srcImageStride
&&
960 dstImageStride
== bytesPerImage
) ||
963 ctx
->Driver
.TextureMemCpy(dstImage
, srcImage
, bytesPerTexture
);
968 for (img
= 0; img
< srcDepth
; img
++) {
969 const GLubyte
*srcRow
= srcImage
;
970 GLubyte
*dstRow
= dstImage
;
971 for (row
= 0; row
< srcHeight
; row
++) {
972 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
973 dstRow
+= dstRowStride
;
974 srcRow
+= srcRowStride
;
976 srcImage
+= srcImageStride
;
977 dstImage
+= dstImageStride
;
983 for (img
= 0; img
< srcDepth
; img
++) {
984 const GLubyte
*srcRow
= srcImage
;
985 GLubyte
*dstRow
= (GLubyte
*) dstAddr
986 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
987 + dstYoffset
* dstRowStride
988 + dstXoffset
* texelBytes
;
989 for (row
= 0; row
< srcHeight
; row
++) {
990 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
991 dstRow
+= dstRowStride
;
992 srcRow
+= srcRowStride
;
994 srcImage
+= srcImageStride
;
1001 * Store an image in any of the formats:
1002 * _mesa_texformat_rgba
1003 * _mesa_texformat_rgb
1004 * _mesa_texformat_alpha
1005 * _mesa_texformat_luminance
1006 * _mesa_texformat_luminance_alpha
1007 * _mesa_texformat_intensity
1011 _mesa_texstore_rgba(TEXSTORE_PARAMS
)
1013 const GLint components
= _mesa_components_in_format(baseInternalFormat
);
1014 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
1015 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
1017 ASSERT(dstFormat
== &_mesa_texformat_rgba
||
1018 dstFormat
== &_mesa_texformat_rgb
||
1019 dstFormat
== &_mesa_texformat_alpha
||
1020 dstFormat
== &_mesa_texformat_luminance
||
1021 dstFormat
== &_mesa_texformat_luminance_alpha
||
1022 dstFormat
== &_mesa_texformat_intensity
);
1023 ASSERT(baseInternalFormat
== GL_RGBA
||
1024 baseInternalFormat
== GL_RGB
||
1025 baseInternalFormat
== GL_ALPHA
||
1026 baseInternalFormat
== GL_LUMINANCE
||
1027 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
1028 baseInternalFormat
== GL_INTENSITY
);
1029 ASSERT(texelBytes
== components
* sizeof(GLchan
));
1031 if (!ctx
->_ImageTransferState
&&
1032 !srcPacking
->SwapBytes
&&
1033 baseInternalFormat
== srcFormat
&&
1034 srcType
== CHAN_TYPE
) {
1035 /* simple memcpy path */
1036 memcpy_texture(ctx
, dims
,
1037 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1040 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1041 srcAddr
, srcPacking
);
1043 else if (!ctx
->_ImageTransferState
&&
1044 !srcPacking
->SwapBytes
&&
1045 dstFormat
== &_mesa_texformat_rgb
&&
1046 srcFormat
== GL_RGBA
&&
1047 srcType
== CHAN_TYPE
) {
1048 /* extract RGB from RGBA */
1049 GLint img
, row
, col
;
1050 for (img
= 0; img
< srcDepth
; img
++) {
1051 GLchan
*dstImage
= (GLchan
*)
1052 ((GLubyte
*) dstAddr
1053 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1054 + dstYoffset
* dstRowStride
1055 + dstXoffset
* texelBytes
);
1057 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1058 srcWidth
, srcFormat
, srcType
);
1059 GLchan
*srcRow
= (GLchan
*) _mesa_image_address(dims
, srcPacking
,
1060 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1061 GLchan
*dstRow
= dstImage
;
1062 for (row
= 0; row
< srcHeight
; row
++) {
1063 for (col
= 0; col
< srcWidth
; col
++) {
1064 dstRow
[col
* 3 + RCOMP
] = srcRow
[col
* 4 + RCOMP
];
1065 dstRow
[col
* 3 + GCOMP
] = srcRow
[col
* 4 + GCOMP
];
1066 dstRow
[col
* 3 + BCOMP
] = srcRow
[col
* 4 + BCOMP
];
1068 dstRow
+= dstRowStride
/ sizeof(GLchan
);
1069 srcRow
= (GLchan
*) ((GLubyte
*) srcRow
+ srcRowStride
);
1073 else if (!ctx
->_ImageTransferState
&&
1074 CHAN_TYPE
== GL_UNSIGNED_BYTE
&&
1075 (srcType
== GL_UNSIGNED_BYTE
||
1076 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1077 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1078 can_swizzle(baseInternalFormat
) &&
1079 can_swizzle(srcFormat
)) {
1081 const GLubyte
*dstmap
;
1084 /* dstmap - how to swizzle from RGBA to dst format:
1086 if (dstFormat
== &_mesa_texformat_rgba
) {
1087 dstmap
= mappings
[IDX_RGBA
].from_rgba
;
1090 else if (dstFormat
== &_mesa_texformat_rgb
) {
1091 dstmap
= mappings
[IDX_RGB
].from_rgba
;
1094 else if (dstFormat
== &_mesa_texformat_alpha
) {
1095 dstmap
= mappings
[IDX_ALPHA
].from_rgba
;
1098 else if (dstFormat
== &_mesa_texformat_luminance
) {
1099 dstmap
= mappings
[IDX_LUMINANCE
].from_rgba
;
1102 else if (dstFormat
== &_mesa_texformat_luminance_alpha
) {
1103 dstmap
= mappings
[IDX_LUMINANCE_ALPHA
].from_rgba
;
1106 else if (dstFormat
== &_mesa_texformat_intensity
) {
1107 dstmap
= mappings
[IDX_INTENSITY
].from_rgba
;
1111 _mesa_problem(ctx
, "Unexpected dstFormat in _mesa_texstore_rgba");
1115 _mesa_swizzle_ubyte_image(ctx
, dims
,
1120 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1121 dstRowStride
, dstImageOffsets
,
1122 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1127 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1130 srcWidth
, srcHeight
, srcDepth
,
1131 srcFormat
, srcType
, srcAddr
,
1133 const GLchan
*src
= tempImage
;
1138 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1139 bytesPerRow
= srcWidth
* components
* sizeof(GLchan
);
1140 for (img
= 0; img
< srcDepth
; img
++) {
1141 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1142 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1143 + dstYoffset
* dstRowStride
1144 + dstXoffset
* texelBytes
;
1145 for (row
= 0; row
< srcHeight
; row
++) {
1146 _mesa_memcpy(dstRow
, src
, bytesPerRow
);
1147 dstRow
+= dstRowStride
;
1148 src
+= srcWidth
* components
;
1152 _mesa_free((void *) tempImage
);
1159 * Store a 32-bit integer depth component texture image.
1162 _mesa_texstore_z32(TEXSTORE_PARAMS
)
1164 const GLuint depthScale
= 0xffffffff;
1165 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
1167 ASSERT(dstFormat
== &_mesa_texformat_z32
);
1168 ASSERT(texelBytes
== sizeof(GLuint
));
1170 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1171 ctx
->Pixel
.DepthBias
== 0.0f
&&
1172 !srcPacking
->SwapBytes
&&
1173 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1174 srcFormat
== GL_DEPTH_COMPONENT
&&
1175 srcType
== GL_UNSIGNED_INT
) {
1176 /* simple memcpy path */
1177 memcpy_texture(ctx
, dims
,
1178 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1181 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1182 srcAddr
, srcPacking
);
1187 for (img
= 0; img
< srcDepth
; img
++) {
1188 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1189 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1190 + dstYoffset
* dstRowStride
1191 + dstXoffset
* texelBytes
;
1192 for (row
= 0; row
< srcHeight
; row
++) {
1193 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1194 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1195 _mesa_unpack_depth_span(ctx
, srcWidth
,
1196 GL_UNSIGNED_INT
, (GLuint
*) dstRow
,
1197 depthScale
, srcType
, src
, srcPacking
);
1198 dstRow
+= dstRowStride
;
1208 * Store a 16-bit integer depth component texture image.
1211 _mesa_texstore_z16(TEXSTORE_PARAMS
)
1213 const GLuint depthScale
= 0xffff;
1214 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
1216 ASSERT(dstFormat
== &_mesa_texformat_z16
);
1217 ASSERT(texelBytes
== sizeof(GLushort
));
1219 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1220 ctx
->Pixel
.DepthBias
== 0.0f
&&
1221 !srcPacking
->SwapBytes
&&
1222 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1223 srcFormat
== GL_DEPTH_COMPONENT
&&
1224 srcType
== GL_UNSIGNED_SHORT
) {
1225 /* simple memcpy path */
1226 memcpy_texture(ctx
, dims
,
1227 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1230 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1231 srcAddr
, srcPacking
);
1236 for (img
= 0; img
< srcDepth
; img
++) {
1237 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1238 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1239 + dstYoffset
* dstRowStride
1240 + dstXoffset
* texelBytes
;
1241 for (row
= 0; row
< srcHeight
; row
++) {
1242 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1243 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1244 GLushort
*dst16
= (GLushort
*) dstRow
;
1245 _mesa_unpack_depth_span(ctx
, srcWidth
,
1246 GL_UNSIGNED_SHORT
, dst16
, depthScale
,
1247 srcType
, src
, srcPacking
);
1248 dstRow
+= dstRowStride
;
1257 * Store an rgb565 or rgb565_rev texture image.
1260 _mesa_texstore_rgb565(TEXSTORE_PARAMS
)
1262 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
1263 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
1265 ASSERT(dstFormat
== &_mesa_texformat_rgb565
||
1266 dstFormat
== &_mesa_texformat_rgb565_rev
);
1267 ASSERT(texelBytes
== 2);
1269 if (!ctx
->_ImageTransferState
&&
1270 !srcPacking
->SwapBytes
&&
1271 dstFormat
== &_mesa_texformat_rgb565
&&
1272 baseInternalFormat
== GL_RGB
&&
1273 srcFormat
== GL_RGB
&&
1274 srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1275 /* simple memcpy path */
1276 memcpy_texture(ctx
, dims
,
1277 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1280 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1281 srcAddr
, srcPacking
);
1283 else if (!ctx
->_ImageTransferState
&&
1284 !srcPacking
->SwapBytes
&&
1285 baseInternalFormat
== GL_RGB
&&
1286 srcFormat
== GL_RGB
&&
1287 srcType
== GL_UNSIGNED_BYTE
&&
1289 /* do optimized tex store */
1290 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
1291 srcFormat
, srcType
);
1292 const GLubyte
*src
= (const GLubyte
*)
1293 _mesa_image_address(dims
, srcPacking
, srcAddr
, srcWidth
, srcHeight
,
1294 srcFormat
, srcType
, 0, 0, 0);
1295 GLubyte
*dst
= (GLubyte
*) dstAddr
1296 + dstYoffset
* dstRowStride
1297 + dstXoffset
* texelBytes
;
1299 for (row
= 0; row
< srcHeight
; row
++) {
1300 const GLubyte
*srcUB
= (const GLubyte
*) src
;
1301 GLushort
*dstUS
= (GLushort
*) dst
;
1302 /* check for byteswapped format */
1303 if (dstFormat
== &_mesa_texformat_rgb565
) {
1304 for (col
= 0; col
< srcWidth
; col
++) {
1305 dstUS
[col
] = PACK_COLOR_565( srcUB
[0], srcUB
[1], srcUB
[2] );
1310 for (col
= 0; col
< srcWidth
; col
++) {
1311 dstUS
[col
] = PACK_COLOR_565_REV( srcUB
[0], srcUB
[1], srcUB
[2] );
1315 dst
+= dstRowStride
;
1316 src
+= srcRowStride
;
1321 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1324 srcWidth
, srcHeight
, srcDepth
,
1325 srcFormat
, srcType
, srcAddr
,
1327 const GLchan
*src
= tempImage
;
1328 GLint img
, row
, col
;
1331 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1332 for (img
= 0; img
< srcDepth
; img
++) {
1333 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1334 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1335 + dstYoffset
* dstRowStride
1336 + dstXoffset
* texelBytes
;
1337 for (row
= 0; row
< srcHeight
; row
++) {
1338 GLushort
*dstUS
= (GLushort
*) dstRow
;
1339 /* check for byteswapped format */
1340 if (dstFormat
== &_mesa_texformat_rgb565
) {
1341 for (col
= 0; col
< srcWidth
; col
++) {
1342 dstUS
[col
] = PACK_COLOR_565( CHAN_TO_UBYTE(src
[RCOMP
]),
1343 CHAN_TO_UBYTE(src
[GCOMP
]),
1344 CHAN_TO_UBYTE(src
[BCOMP
]) );
1349 for (col
= 0; col
< srcWidth
; col
++) {
1350 dstUS
[col
] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1351 CHAN_TO_UBYTE(src
[GCOMP
]),
1352 CHAN_TO_UBYTE(src
[BCOMP
]) );
1356 dstRow
+= dstRowStride
;
1359 _mesa_free((void *) tempImage
);
1366 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1369 _mesa_texstore_rgba8888(TEXSTORE_PARAMS
)
1371 const GLboolean littleEndian
= _mesa_little_endian();
1372 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
1373 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
1375 ASSERT(dstFormat
== &_mesa_texformat_rgba8888
||
1376 dstFormat
== &_mesa_texformat_rgba8888_rev
);
1377 ASSERT(texelBytes
== 4);
1379 if (!ctx
->_ImageTransferState
&&
1380 !srcPacking
->SwapBytes
&&
1381 dstFormat
== &_mesa_texformat_rgba8888
&&
1382 baseInternalFormat
== GL_RGBA
&&
1383 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1384 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1385 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1386 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
))) {
1387 /* simple memcpy path */
1388 memcpy_texture(ctx
, dims
,
1389 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1392 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1393 srcAddr
, srcPacking
);
1395 else if (!ctx
->_ImageTransferState
&&
1396 !srcPacking
->SwapBytes
&&
1397 dstFormat
== &_mesa_texformat_rgba8888_rev
&&
1398 baseInternalFormat
== GL_RGBA
&&
1399 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1400 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1401 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1402 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
))) {
1403 /* simple memcpy path */
1404 memcpy_texture(ctx
, dims
,
1405 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1408 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1409 srcAddr
, srcPacking
);
1411 else if (!ctx
->_ImageTransferState
&&
1412 (srcType
== GL_UNSIGNED_BYTE
||
1413 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1414 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1415 can_swizzle(baseInternalFormat
) &&
1416 can_swizzle(srcFormat
)) {
1420 /* dstmap - how to swizzle from RGBA to dst format:
1422 if ((littleEndian
&& dstFormat
== &_mesa_texformat_rgba8888
) ||
1423 (!littleEndian
&& dstFormat
== &_mesa_texformat_rgba8888_rev
)) {
1436 _mesa_swizzle_ubyte_image(ctx
, dims
,
1441 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1442 dstRowStride
, dstImageOffsets
,
1443 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1448 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1451 srcWidth
, srcHeight
, srcDepth
,
1452 srcFormat
, srcType
, srcAddr
,
1454 const GLchan
*src
= tempImage
;
1455 GLint img
, row
, col
;
1458 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1459 for (img
= 0; img
< srcDepth
; img
++) {
1460 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1461 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1462 + dstYoffset
* dstRowStride
1463 + dstXoffset
* texelBytes
;
1464 for (row
= 0; row
< srcHeight
; row
++) {
1465 GLuint
*dstUI
= (GLuint
*) dstRow
;
1466 if (dstFormat
== &_mesa_texformat_rgba8888
) {
1467 for (col
= 0; col
< srcWidth
; col
++) {
1468 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[RCOMP
]),
1469 CHAN_TO_UBYTE(src
[GCOMP
]),
1470 CHAN_TO_UBYTE(src
[BCOMP
]),
1471 CHAN_TO_UBYTE(src
[ACOMP
]) );
1476 for (col
= 0; col
< srcWidth
; col
++) {
1477 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1478 CHAN_TO_UBYTE(src
[GCOMP
]),
1479 CHAN_TO_UBYTE(src
[BCOMP
]),
1480 CHAN_TO_UBYTE(src
[ACOMP
]) );
1484 dstRow
+= dstRowStride
;
1487 _mesa_free((void *) tempImage
);
1494 _mesa_texstore_argb8888(TEXSTORE_PARAMS
)
1496 const GLboolean littleEndian
= _mesa_little_endian();
1497 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
1498 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
1500 ASSERT(dstFormat
== &_mesa_texformat_argb8888
||
1501 dstFormat
== &_mesa_texformat_argb8888_rev
);
1502 ASSERT(texelBytes
== 4);
1504 if (!ctx
->_ImageTransferState
&&
1505 !srcPacking
->SwapBytes
&&
1506 dstFormat
== &_mesa_texformat_argb8888
&&
1507 baseInternalFormat
== GL_RGBA
&&
1508 srcFormat
== GL_BGRA
&&
1509 ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1510 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
1511 /* simple memcpy path (little endian) */
1512 memcpy_texture(ctx
, dims
,
1513 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1516 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1517 srcAddr
, srcPacking
);
1519 else if (!ctx
->_ImageTransferState
&&
1520 !srcPacking
->SwapBytes
&&
1521 dstFormat
== &_mesa_texformat_argb8888_rev
&&
1522 baseInternalFormat
== GL_RGBA
&&
1523 srcFormat
== GL_BGRA
&&
1524 ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1525 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
1526 /* simple memcpy path (big endian) */
1527 memcpy_texture(ctx
, dims
,
1528 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1531 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1532 srcAddr
, srcPacking
);
1534 else if (!ctx
->_ImageTransferState
&&
1535 !srcPacking
->SwapBytes
&&
1536 dstFormat
== &_mesa_texformat_argb8888
&&
1537 srcFormat
== GL_RGB
&&
1538 (baseInternalFormat
== GL_RGBA
||
1539 baseInternalFormat
== GL_RGB
) &&
1540 srcType
== GL_UNSIGNED_BYTE
) {
1542 for (img
= 0; img
< srcDepth
; img
++) {
1543 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1544 srcWidth
, srcFormat
, srcType
);
1545 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1546 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1547 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1548 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1549 + dstYoffset
* dstRowStride
1550 + dstXoffset
* texelBytes
;
1551 for (row
= 0; row
< srcHeight
; row
++) {
1552 GLuint
*d4
= (GLuint
*) dstRow
;
1553 for (col
= 0; col
< srcWidth
; col
++) {
1554 d4
[col
] = PACK_COLOR_8888(0xff,
1555 srcRow
[col
* 3 + RCOMP
],
1556 srcRow
[col
* 3 + GCOMP
],
1557 srcRow
[col
* 3 + BCOMP
]);
1559 dstRow
+= dstRowStride
;
1560 srcRow
+= srcRowStride
;
1564 else if (!ctx
->_ImageTransferState
&&
1565 !srcPacking
->SwapBytes
&&
1566 dstFormat
== &_mesa_texformat_argb8888
&&
1567 srcFormat
== GL_RGBA
&&
1568 baseInternalFormat
== GL_RGBA
&&
1569 srcType
== GL_UNSIGNED_BYTE
) {
1570 /* same as above case, but src data has alpha too */
1571 GLint img
, row
, col
;
1572 /* For some reason, streaming copies to write-combined regions
1573 * are extremely sensitive to the characteristics of how the
1574 * source data is retrieved. By reordering the source reads to
1575 * be in-order, the speed of this operation increases by half.
1576 * Strangely the same isn't required for the RGB path, above.
1578 for (img
= 0; img
< srcDepth
; img
++) {
1579 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1580 srcWidth
, srcFormat
, srcType
);
1581 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1582 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1583 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1584 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1585 + dstYoffset
* dstRowStride
1586 + dstXoffset
* texelBytes
;
1587 for (row
= 0; row
< srcHeight
; row
++) {
1588 GLuint
*d4
= (GLuint
*) dstRow
;
1589 for (col
= 0; col
< srcWidth
; col
++) {
1590 d4
[col
] = PACK_COLOR_8888(srcRow
[col
* 4 + ACOMP
],
1591 srcRow
[col
* 4 + RCOMP
],
1592 srcRow
[col
* 4 + GCOMP
],
1593 srcRow
[col
* 4 + BCOMP
]);
1595 dstRow
+= dstRowStride
;
1596 srcRow
+= srcRowStride
;
1600 else if (!ctx
->_ImageTransferState
&&
1601 (srcType
== GL_UNSIGNED_BYTE
||
1602 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1603 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1604 can_swizzle(baseInternalFormat
) &&
1605 can_swizzle(srcFormat
)) {
1609 /* dstmap - how to swizzle from RGBA to dst format:
1611 if ((littleEndian
&& dstFormat
== &_mesa_texformat_argb8888
) ||
1612 (!littleEndian
&& dstFormat
== &_mesa_texformat_argb8888_rev
)) {
1613 dstmap
[3] = 3; /* alpha */
1614 dstmap
[2] = 0; /* red */
1615 dstmap
[1] = 1; /* green */
1616 dstmap
[0] = 2; /* blue */
1619 assert((littleEndian
&& dstFormat
== &_mesa_texformat_argb8888_rev
) ||
1620 (!littleEndian
&& dstFormat
== &_mesa_texformat_argb8888
));
1627 _mesa_swizzle_ubyte_image(ctx
, dims
,
1633 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1636 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1641 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1644 srcWidth
, srcHeight
, srcDepth
,
1645 srcFormat
, srcType
, srcAddr
,
1647 const GLchan
*src
= tempImage
;
1648 GLint img
, row
, col
;
1651 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1652 for (img
= 0; img
< srcDepth
; img
++) {
1653 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1654 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1655 + dstYoffset
* dstRowStride
1656 + dstXoffset
* texelBytes
;
1657 for (row
= 0; row
< srcHeight
; row
++) {
1658 GLuint
*dstUI
= (GLuint
*) dstRow
;
1659 if (dstFormat
== &_mesa_texformat_argb8888
) {
1660 for (col
= 0; col
< srcWidth
; col
++) {
1661 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[ACOMP
]),
1662 CHAN_TO_UBYTE(src
[RCOMP
]),
1663 CHAN_TO_UBYTE(src
[GCOMP
]),
1664 CHAN_TO_UBYTE(src
[BCOMP
]) );
1669 for (col
= 0; col
< srcWidth
; col
++) {
1670 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1671 CHAN_TO_UBYTE(src
[RCOMP
]),
1672 CHAN_TO_UBYTE(src
[GCOMP
]),
1673 CHAN_TO_UBYTE(src
[BCOMP
]) );
1677 dstRow
+= dstRowStride
;
1680 _mesa_free((void *) tempImage
);
1687 _mesa_texstore_rgb888(TEXSTORE_PARAMS
)
1689 const GLboolean littleEndian
= _mesa_little_endian();
1690 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
1691 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
1693 ASSERT(dstFormat
== &_mesa_texformat_rgb888
);
1694 ASSERT(texelBytes
== 3);
1696 if (!ctx
->_ImageTransferState
&&
1697 !srcPacking
->SwapBytes
&&
1698 baseInternalFormat
== GL_RGB
&&
1699 srcFormat
== GL_BGR
&&
1700 srcType
== GL_UNSIGNED_BYTE
&&
1702 /* simple memcpy path */
1703 memcpy_texture(ctx
, dims
,
1704 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1707 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1708 srcAddr
, srcPacking
);
1710 else if (!ctx
->_ImageTransferState
&&
1711 !srcPacking
->SwapBytes
&&
1712 srcFormat
== GL_RGBA
&&
1713 srcType
== GL_UNSIGNED_BYTE
) {
1714 /* extract RGB from RGBA */
1715 GLint img
, row
, col
;
1716 for (img
= 0; img
< srcDepth
; img
++) {
1717 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1718 srcWidth
, srcFormat
, srcType
);
1719 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1720 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1721 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1722 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1723 + dstYoffset
* dstRowStride
1724 + dstXoffset
* texelBytes
;
1725 for (row
= 0; row
< srcHeight
; row
++) {
1726 for (col
= 0; col
< srcWidth
; col
++) {
1727 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + BCOMP
];
1728 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1729 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + RCOMP
];
1731 dstRow
+= dstRowStride
;
1732 srcRow
+= srcRowStride
;
1736 else if (!ctx
->_ImageTransferState
&&
1737 srcType
== GL_UNSIGNED_BYTE
&&
1738 can_swizzle(baseInternalFormat
) &&
1739 can_swizzle(srcFormat
)) {
1743 /* dstmap - how to swizzle from RGBA to dst format:
1748 dstmap
[3] = ONE
; /* ? */
1750 _mesa_swizzle_ubyte_image(ctx
, dims
,
1755 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1756 dstRowStride
, dstImageOffsets
,
1757 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1762 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1765 srcWidth
, srcHeight
, srcDepth
,
1766 srcFormat
, srcType
, srcAddr
,
1768 const GLchan
*src
= (const GLchan
*) tempImage
;
1769 GLint img
, row
, col
;
1772 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1773 for (img
= 0; img
< srcDepth
; img
++) {
1774 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1775 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1776 + dstYoffset
* dstRowStride
1777 + dstXoffset
* texelBytes
;
1778 for (row
= 0; row
< srcHeight
; row
++) {
1781 for (col
= 0; col
< srcWidth
; col
++) {
1782 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1783 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1784 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1789 for (col
= 0; col
< srcWidth
; col
++) {
1790 dstRow
[col
* 3 + 0] = srcUB
[BCOMP
];
1791 dstRow
[col
* 3 + 1] = srcUB
[GCOMP
];
1792 dstRow
[col
* 3 + 2] = srcUB
[RCOMP
];
1797 for (col
= 0; col
< srcWidth
; col
++) {
1798 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[BCOMP
]);
1799 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1800 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[RCOMP
]);
1804 dstRow
+= dstRowStride
;
1807 _mesa_free((void *) tempImage
);
1814 _mesa_texstore_bgr888(TEXSTORE_PARAMS
)
1816 const GLboolean littleEndian
= _mesa_little_endian();
1817 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
1818 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
1820 ASSERT(dstFormat
== &_mesa_texformat_bgr888
);
1821 ASSERT(texelBytes
== 3);
1823 if (!ctx
->_ImageTransferState
&&
1824 !srcPacking
->SwapBytes
&&
1825 baseInternalFormat
== GL_RGB
&&
1826 srcFormat
== GL_RGB
&&
1827 srcType
== GL_UNSIGNED_BYTE
&&
1829 /* simple memcpy path */
1830 memcpy_texture(ctx
, dims
,
1831 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1834 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1835 srcAddr
, srcPacking
);
1837 else if (!ctx
->_ImageTransferState
&&
1838 !srcPacking
->SwapBytes
&&
1839 srcFormat
== GL_RGBA
&&
1840 srcType
== GL_UNSIGNED_BYTE
) {
1841 /* extract BGR from RGBA */
1843 for (img
= 0; img
< srcDepth
; img
++) {
1844 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1845 srcWidth
, srcFormat
, srcType
);
1846 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1847 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1848 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1849 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1850 + dstYoffset
* dstRowStride
1851 + dstXoffset
* texelBytes
;
1852 for (row
= 0; row
< srcHeight
; row
++) {
1853 for (col
= 0; col
< srcWidth
; col
++) {
1854 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + RCOMP
];
1855 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1856 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + BCOMP
];
1858 dstRow
+= dstRowStride
;
1859 srcRow
+= srcRowStride
;
1863 else if (!ctx
->_ImageTransferState
&&
1864 srcType
== GL_UNSIGNED_BYTE
&&
1865 can_swizzle(baseInternalFormat
) &&
1866 can_swizzle(srcFormat
)) {
1870 /* dstmap - how to swizzle from RGBA to dst format:
1875 dstmap
[3] = ONE
; /* ? */
1877 _mesa_swizzle_ubyte_image(ctx
, dims
,
1882 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1883 dstRowStride
, dstImageOffsets
,
1884 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1889 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1892 srcWidth
, srcHeight
, srcDepth
,
1893 srcFormat
, srcType
, srcAddr
,
1895 const GLchan
*src
= (const GLchan
*) tempImage
;
1896 GLint img
, row
, col
;
1899 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1900 for (img
= 0; img
< srcDepth
; img
++) {
1901 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1902 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1903 + dstYoffset
* dstRowStride
1904 + dstXoffset
* texelBytes
;
1905 for (row
= 0; row
< srcHeight
; row
++) {
1906 for (col
= 0; col
< srcWidth
; col
++) {
1907 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1908 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1909 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1912 dstRow
+= dstRowStride
;
1915 _mesa_free((void *) tempImage
);
1921 _mesa_texstore_rgba4444(TEXSTORE_PARAMS
)
1923 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
1924 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
1926 ASSERT(dstFormat
== &_mesa_texformat_rgba4444
);
1927 ASSERT(texelBytes
== 2);
1929 if (!ctx
->_ImageTransferState
&&
1930 !srcPacking
->SwapBytes
&&
1931 dstFormat
== &_mesa_texformat_rgba4444
&&
1932 baseInternalFormat
== GL_RGBA
&&
1933 srcFormat
== GL_RGBA
&&
1934 srcType
== GL_UNSIGNED_SHORT_4_4_4_4
){
1935 /* simple memcpy path */
1936 memcpy_texture(ctx
, dims
,
1937 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1940 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1941 srcAddr
, srcPacking
);
1945 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1948 srcWidth
, srcHeight
, srcDepth
,
1949 srcFormat
, srcType
, srcAddr
,
1951 const GLchan
*src
= tempImage
;
1952 GLint img
, row
, col
;
1955 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1956 for (img
= 0; img
< srcDepth
; img
++) {
1957 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1958 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1959 + dstYoffset
* dstRowStride
1960 + dstXoffset
* texelBytes
;
1961 for (row
= 0; row
< srcHeight
; row
++) {
1962 GLushort
*dstUS
= (GLushort
*) dstRow
;
1963 for (col
= 0; col
< srcWidth
; col
++) {
1964 dstUS
[col
] = PACK_COLOR_4444( CHAN_TO_UBYTE(src
[RCOMP
]),
1965 CHAN_TO_UBYTE(src
[GCOMP
]),
1966 CHAN_TO_UBYTE(src
[BCOMP
]),
1967 CHAN_TO_UBYTE(src
[ACOMP
]) );
1970 dstRow
+= dstRowStride
;
1973 _mesa_free((void *) tempImage
);
1979 _mesa_texstore_argb4444(TEXSTORE_PARAMS
)
1981 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
1982 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
1984 ASSERT(dstFormat
== &_mesa_texformat_argb4444
||
1985 dstFormat
== &_mesa_texformat_argb4444_rev
);
1986 ASSERT(texelBytes
== 2);
1988 if (!ctx
->_ImageTransferState
&&
1989 !srcPacking
->SwapBytes
&&
1990 dstFormat
== &_mesa_texformat_argb4444
&&
1991 baseInternalFormat
== GL_RGBA
&&
1992 srcFormat
== GL_BGRA
&&
1993 srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1994 /* simple memcpy path */
1995 memcpy_texture(ctx
, dims
,
1996 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1999 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2000 srcAddr
, srcPacking
);
2004 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2007 srcWidth
, srcHeight
, srcDepth
,
2008 srcFormat
, srcType
, srcAddr
,
2010 const GLchan
*src
= tempImage
;
2011 GLint img
, row
, col
;
2014 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2015 for (img
= 0; img
< srcDepth
; img
++) {
2016 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2017 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2018 + dstYoffset
* dstRowStride
2019 + dstXoffset
* texelBytes
;
2020 for (row
= 0; row
< srcHeight
; row
++) {
2021 GLushort
*dstUS
= (GLushort
*) dstRow
;
2022 if (dstFormat
== &_mesa_texformat_argb4444
) {
2023 for (col
= 0; col
< srcWidth
; col
++) {
2024 dstUS
[col
] = PACK_COLOR_4444( CHAN_TO_UBYTE(src
[ACOMP
]),
2025 CHAN_TO_UBYTE(src
[RCOMP
]),
2026 CHAN_TO_UBYTE(src
[GCOMP
]),
2027 CHAN_TO_UBYTE(src
[BCOMP
]) );
2032 for (col
= 0; col
< srcWidth
; col
++) {
2033 dstUS
[col
] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
2034 CHAN_TO_UBYTE(src
[RCOMP
]),
2035 CHAN_TO_UBYTE(src
[GCOMP
]),
2036 CHAN_TO_UBYTE(src
[BCOMP
]) );
2040 dstRow
+= dstRowStride
;
2043 _mesa_free((void *) tempImage
);
2049 _mesa_texstore_rgba5551(TEXSTORE_PARAMS
)
2051 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
2052 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
2054 ASSERT(dstFormat
== &_mesa_texformat_rgba5551
);
2055 ASSERT(texelBytes
== 2);
2057 if (!ctx
->_ImageTransferState
&&
2058 !srcPacking
->SwapBytes
&&
2059 dstFormat
== &_mesa_texformat_rgba5551
&&
2060 baseInternalFormat
== GL_RGBA
&&
2061 srcFormat
== GL_RGBA
&&
2062 srcType
== GL_UNSIGNED_SHORT_5_5_5_1
) {
2063 /* simple memcpy path */
2064 memcpy_texture(ctx
, dims
,
2065 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2068 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2069 srcAddr
, srcPacking
);
2073 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2076 srcWidth
, srcHeight
, srcDepth
,
2077 srcFormat
, srcType
, srcAddr
,
2079 const GLchan
*src
=tempImage
;
2080 GLint img
, row
, col
;
2083 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2084 for (img
= 0; img
< srcDepth
; img
++) {
2085 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2086 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2087 + dstYoffset
* dstRowStride
2088 + dstXoffset
* texelBytes
;
2089 for (row
= 0; row
< srcHeight
; row
++) {
2090 GLushort
*dstUS
= (GLushort
*) dstRow
;
2091 for (col
= 0; col
< srcWidth
; col
++) {
2092 dstUS
[col
] = PACK_COLOR_5551( CHAN_TO_UBYTE(src
[RCOMP
]),
2093 CHAN_TO_UBYTE(src
[GCOMP
]),
2094 CHAN_TO_UBYTE(src
[BCOMP
]),
2095 CHAN_TO_UBYTE(src
[ACOMP
]) );
2098 dstRow
+= dstRowStride
;
2101 _mesa_free((void *) tempImage
);
2107 _mesa_texstore_argb1555(TEXSTORE_PARAMS
)
2109 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
2110 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
2112 ASSERT(dstFormat
== &_mesa_texformat_argb1555
||
2113 dstFormat
== &_mesa_texformat_argb1555_rev
);
2114 ASSERT(texelBytes
== 2);
2116 if (!ctx
->_ImageTransferState
&&
2117 !srcPacking
->SwapBytes
&&
2118 dstFormat
== &_mesa_texformat_argb1555
&&
2119 baseInternalFormat
== GL_RGBA
&&
2120 srcFormat
== GL_BGRA
&&
2121 srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
2122 /* simple memcpy path */
2123 memcpy_texture(ctx
, dims
,
2124 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2127 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2128 srcAddr
, srcPacking
);
2132 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2135 srcWidth
, srcHeight
, srcDepth
,
2136 srcFormat
, srcType
, srcAddr
,
2138 const GLchan
*src
=tempImage
;
2139 GLint img
, row
, col
;
2142 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2143 for (img
= 0; img
< srcDepth
; img
++) {
2144 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2145 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2146 + dstYoffset
* dstRowStride
2147 + dstXoffset
* texelBytes
;
2148 for (row
= 0; row
< srcHeight
; row
++) {
2149 GLushort
*dstUS
= (GLushort
*) dstRow
;
2150 if (dstFormat
== &_mesa_texformat_argb1555
) {
2151 for (col
= 0; col
< srcWidth
; col
++) {
2152 dstUS
[col
] = PACK_COLOR_1555( CHAN_TO_UBYTE(src
[ACOMP
]),
2153 CHAN_TO_UBYTE(src
[RCOMP
]),
2154 CHAN_TO_UBYTE(src
[GCOMP
]),
2155 CHAN_TO_UBYTE(src
[BCOMP
]) );
2160 for (col
= 0; col
< srcWidth
; col
++) {
2161 dstUS
[col
] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
2162 CHAN_TO_UBYTE(src
[RCOMP
]),
2163 CHAN_TO_UBYTE(src
[GCOMP
]),
2164 CHAN_TO_UBYTE(src
[BCOMP
]) );
2168 dstRow
+= dstRowStride
;
2171 _mesa_free((void *) tempImage
);
2178 _mesa_texstore_al88(TEXSTORE_PARAMS
)
2180 const GLboolean littleEndian
= _mesa_little_endian();
2181 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
2182 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
2184 ASSERT(dstFormat
== &_mesa_texformat_al88
||
2185 dstFormat
== &_mesa_texformat_al88_rev
);
2186 ASSERT(texelBytes
== 2);
2188 if (!ctx
->_ImageTransferState
&&
2189 !srcPacking
->SwapBytes
&&
2190 dstFormat
== &_mesa_texformat_al88
&&
2191 baseInternalFormat
== GL_LUMINANCE_ALPHA
&&
2192 srcFormat
== GL_LUMINANCE_ALPHA
&&
2193 srcType
== GL_UNSIGNED_BYTE
&&
2195 /* simple memcpy path */
2196 memcpy_texture(ctx
, dims
,
2197 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2200 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2201 srcAddr
, srcPacking
);
2203 else if (!ctx
->_ImageTransferState
&&
2205 srcType
== GL_UNSIGNED_BYTE
&&
2206 can_swizzle(baseInternalFormat
) &&
2207 can_swizzle(srcFormat
)) {
2211 /* dstmap - how to swizzle from RGBA to dst format:
2213 if ((littleEndian
&& dstFormat
== &_mesa_texformat_al88
) ||
2214 (!littleEndian
&& dstFormat
== &_mesa_texformat_al88_rev
)) {
2222 dstmap
[2] = ZERO
; /* ? */
2223 dstmap
[3] = ONE
; /* ? */
2225 _mesa_swizzle_ubyte_image(ctx
, dims
,
2230 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2231 dstRowStride
, dstImageOffsets
,
2232 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2237 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2240 srcWidth
, srcHeight
, srcDepth
,
2241 srcFormat
, srcType
, srcAddr
,
2243 const GLchan
*src
= tempImage
;
2244 GLint img
, row
, col
;
2247 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2248 for (img
= 0; img
< srcDepth
; img
++) {
2249 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2250 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2251 + dstYoffset
* dstRowStride
2252 + dstXoffset
* texelBytes
;
2253 for (row
= 0; row
< srcHeight
; row
++) {
2254 GLushort
*dstUS
= (GLushort
*) dstRow
;
2255 if (dstFormat
== &_mesa_texformat_al88
) {
2256 for (col
= 0; col
< srcWidth
; col
++) {
2257 /* src[0] is luminance, src[1] is alpha */
2258 dstUS
[col
] = PACK_COLOR_88( CHAN_TO_UBYTE(src
[1]),
2259 CHAN_TO_UBYTE(src
[0]) );
2264 for (col
= 0; col
< srcWidth
; col
++) {
2265 /* src[0] is luminance, src[1] is alpha */
2266 dstUS
[col
] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src
[1]),
2267 CHAN_TO_UBYTE(src
[0]) );
2271 dstRow
+= dstRowStride
;
2274 _mesa_free((void *) tempImage
);
2281 _mesa_texstore_rgb332(TEXSTORE_PARAMS
)
2283 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
2284 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
2286 ASSERT(dstFormat
== &_mesa_texformat_rgb332
);
2287 ASSERT(texelBytes
== 1);
2289 if (!ctx
->_ImageTransferState
&&
2290 !srcPacking
->SwapBytes
&&
2291 baseInternalFormat
== GL_RGB
&&
2292 srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_BYTE_3_3_2
) {
2293 /* simple memcpy path */
2294 memcpy_texture(ctx
, dims
,
2295 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2298 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2299 srcAddr
, srcPacking
);
2303 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2306 srcWidth
, srcHeight
, srcDepth
,
2307 srcFormat
, srcType
, srcAddr
,
2309 const GLchan
*src
= tempImage
;
2310 GLint img
, row
, col
;
2313 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2314 for (img
= 0; img
< srcDepth
; img
++) {
2315 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2316 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2317 + dstYoffset
* dstRowStride
2318 + dstXoffset
* texelBytes
;
2319 for (row
= 0; row
< srcHeight
; row
++) {
2320 for (col
= 0; col
< srcWidth
; col
++) {
2321 dstRow
[col
] = PACK_COLOR_332( CHAN_TO_UBYTE(src
[RCOMP
]),
2322 CHAN_TO_UBYTE(src
[GCOMP
]),
2323 CHAN_TO_UBYTE(src
[BCOMP
]) );
2326 dstRow
+= dstRowStride
;
2329 _mesa_free((void *) tempImage
);
2336 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2339 _mesa_texstore_a8(TEXSTORE_PARAMS
)
2341 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
2342 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
2344 ASSERT(dstFormat
== &_mesa_texformat_a8
||
2345 dstFormat
== &_mesa_texformat_l8
||
2346 dstFormat
== &_mesa_texformat_i8
);
2347 ASSERT(texelBytes
== 1);
2349 if (!ctx
->_ImageTransferState
&&
2350 !srcPacking
->SwapBytes
&&
2351 baseInternalFormat
== srcFormat
&&
2352 srcType
== GL_UNSIGNED_BYTE
) {
2353 /* simple memcpy path */
2354 memcpy_texture(ctx
, dims
,
2355 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2358 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2359 srcAddr
, srcPacking
);
2361 else if (!ctx
->_ImageTransferState
&&
2362 srcType
== GL_UNSIGNED_BYTE
&&
2363 can_swizzle(baseInternalFormat
) &&
2364 can_swizzle(srcFormat
)) {
2368 /* dstmap - how to swizzle from RGBA to dst format:
2370 if (dstFormat
== &_mesa_texformat_a8
) {
2376 dstmap
[1] = ZERO
; /* ? */
2377 dstmap
[2] = ZERO
; /* ? */
2378 dstmap
[3] = ONE
; /* ? */
2380 _mesa_swizzle_ubyte_image(ctx
, dims
,
2385 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2386 dstRowStride
, dstImageOffsets
,
2387 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2392 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2395 srcWidth
, srcHeight
, srcDepth
,
2396 srcFormat
, srcType
, srcAddr
,
2398 const GLchan
*src
= tempImage
;
2399 GLint img
, row
, col
;
2402 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2403 for (img
= 0; img
< srcDepth
; img
++) {
2404 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2405 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2406 + dstYoffset
* dstRowStride
2407 + dstXoffset
* texelBytes
;
2408 for (row
= 0; row
< srcHeight
; row
++) {
2409 for (col
= 0; col
< srcWidth
; col
++) {
2410 dstRow
[col
] = CHAN_TO_UBYTE(src
[col
]);
2412 dstRow
+= dstRowStride
;
2416 _mesa_free((void *) tempImage
);
2424 _mesa_texstore_ci8(TEXSTORE_PARAMS
)
2426 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
2428 (void) dims
; (void) baseInternalFormat
;
2429 ASSERT(dstFormat
== &_mesa_texformat_ci8
);
2430 ASSERT(texelBytes
== 1);
2431 ASSERT(baseInternalFormat
== GL_COLOR_INDEX
);
2433 if (!ctx
->_ImageTransferState
&&
2434 !srcPacking
->SwapBytes
&&
2435 srcFormat
== GL_COLOR_INDEX
&&
2436 srcType
== GL_UNSIGNED_BYTE
) {
2437 /* simple memcpy path */
2438 memcpy_texture(ctx
, dims
,
2439 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2442 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2443 srcAddr
, srcPacking
);
2448 for (img
= 0; img
< srcDepth
; img
++) {
2449 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2450 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2451 + dstYoffset
* dstRowStride
2452 + dstXoffset
* texelBytes
;
2453 for (row
= 0; row
< srcHeight
; row
++) {
2454 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
2455 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
2456 _mesa_unpack_index_span(ctx
, srcWidth
, GL_UNSIGNED_BYTE
, dstRow
,
2457 srcType
, src
, srcPacking
,
2458 ctx
->_ImageTransferState
);
2459 dstRow
+= dstRowStride
;
2468 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
2471 _mesa_texstore_ycbcr(TEXSTORE_PARAMS
)
2473 const GLboolean littleEndian
= _mesa_little_endian();
2474 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
2476 (void) ctx
; (void) dims
; (void) baseInternalFormat
;
2478 ASSERT((dstFormat
== &_mesa_texformat_ycbcr
) ||
2479 (dstFormat
== &_mesa_texformat_ycbcr_rev
));
2480 ASSERT(texelBytes
== 2);
2481 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
2482 ASSERT(srcFormat
== GL_YCBCR_MESA
);
2483 ASSERT((srcType
== GL_UNSIGNED_SHORT_8_8_MESA
) ||
2484 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
));
2485 ASSERT(baseInternalFormat
== GL_YCBCR_MESA
);
2487 /* always just memcpy since no pixel transfer ops apply */
2488 memcpy_texture(ctx
, dims
,
2489 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2492 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2493 srcAddr
, srcPacking
);
2495 /* Check if we need byte swapping */
2496 /* XXX the logic here _might_ be wrong */
2497 if (srcPacking
->SwapBytes
^
2498 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ^
2499 (dstFormat
== &_mesa_texformat_ycbcr_rev
) ^
2502 for (img
= 0; img
< srcDepth
; img
++) {
2503 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2504 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2505 + dstYoffset
* dstRowStride
2506 + dstXoffset
* texelBytes
;
2507 for (row
= 0; row
< srcHeight
; row
++) {
2508 _mesa_swap2((GLushort
*) dstRow
, srcWidth
);
2509 dstRow
+= dstRowStride
;
2517 _mesa_texstore_dudv8(TEXSTORE_PARAMS
)
2519 const GLboolean littleEndian
= _mesa_little_endian();
2520 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
2522 ASSERT(dstFormat
== &_mesa_texformat_dudv8
);
2523 ASSERT(texelBytes
== 2);
2524 ASSERT(ctx
->Extensions
.ATI_envmap_bumpmap
);
2525 ASSERT((srcFormat
== GL_DU8DV8_ATI
) ||
2526 (srcFormat
== GL_DUDV_ATI
));
2527 ASSERT(baseInternalFormat
== GL_DUDV_ATI
);
2529 if (!srcPacking
->SwapBytes
&& srcType
== GL_BYTE
&&
2531 /* simple memcpy path */
2532 memcpy_texture(ctx
, dims
,
2533 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2536 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2537 srcAddr
, srcPacking
);
2539 else if (srcType
== GL_BYTE
) {
2543 /* dstmap - how to swizzle from RGBA to dst format:
2553 dstmap
[2] = ZERO
; /* ? */
2554 dstmap
[3] = ONE
; /* ? */
2556 _mesa_swizzle_ubyte_image(ctx
, dims
,
2557 GL_LUMINANCE_ALPHA
, /* hack */
2558 GL_UNSIGNED_BYTE
, /* hack */
2559 GL_LUMINANCE_ALPHA
, /* hack */
2561 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2562 dstRowStride
, dstImageOffsets
,
2563 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2567 /* general path - note this is defined for 2d textures only */
2568 const GLint components
= _mesa_components_in_format(baseInternalFormat
);
2569 const GLint srcStride
= _mesa_image_row_stride(srcPacking
,
2570 srcWidth
, srcFormat
, srcType
);
2571 GLbyte
*tempImage
, *dst
, *src
;
2574 tempImage
= (GLbyte
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
2575 * components
* sizeof(GLbyte
));
2579 src
= (GLbyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2580 srcWidth
, srcHeight
,
2585 for (row
= 0; row
< srcHeight
; row
++) {
2586 _mesa_unpack_dudv_span_byte(ctx
, srcWidth
, baseInternalFormat
,
2587 dst
, srcFormat
, srcType
, src
,
2589 dst
+= srcWidth
* components
;
2594 dst
= (GLbyte
*) dstAddr
2595 + dstYoffset
* dstRowStride
2596 + dstXoffset
* texelBytes
;
2597 for (row
= 0; row
< srcHeight
; row
++) {
2598 memcpy(dst
, src
, srcWidth
* texelBytes
);
2599 dst
+= dstRowStride
;
2600 src
+= srcWidth
* texelBytes
;
2602 _mesa_free((void *) tempImage
);
2608 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or MESA_FORMAT_SIGNED_RGBA8888_REV
2611 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS
)
2613 const GLboolean littleEndian
= _mesa_little_endian();
2614 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
2615 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
2617 ASSERT(dstFormat
== &_mesa_texformat_signed_rgba8888
||
2618 dstFormat
== &_mesa_texformat_signed_rgba8888_rev
);
2619 ASSERT(texelBytes
== 4);
2621 if (!ctx
->_ImageTransferState
&&
2622 !srcPacking
->SwapBytes
&&
2623 dstFormat
== &_mesa_texformat_signed_rgba8888
&&
2624 baseInternalFormat
== GL_RGBA
&&
2625 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& !littleEndian
) ||
2626 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& littleEndian
))) {
2627 /* simple memcpy path */
2628 memcpy_texture(ctx
, dims
,
2629 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2632 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2633 srcAddr
, srcPacking
);
2635 else if (!ctx
->_ImageTransferState
&&
2636 !srcPacking
->SwapBytes
&&
2637 dstFormat
== &_mesa_texformat_signed_rgba8888_rev
&&
2638 baseInternalFormat
== GL_RGBA
&&
2639 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& littleEndian
) ||
2640 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& !littleEndian
))) {
2641 /* simple memcpy path */
2642 memcpy_texture(ctx
, dims
,
2643 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2646 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2647 srcAddr
, srcPacking
);
2649 else if (!ctx
->_ImageTransferState
&&
2650 (srcType
== GL_BYTE
) &&
2651 can_swizzle(baseInternalFormat
) &&
2652 can_swizzle(srcFormat
)) {
2656 /* dstmap - how to swizzle from RGBA to dst format:
2658 if ((littleEndian
&& dstFormat
== &_mesa_texformat_signed_rgba8888
) ||
2659 (!littleEndian
&& dstFormat
== &_mesa_texformat_signed_rgba8888_rev
)) {
2672 _mesa_swizzle_ubyte_image(ctx
, dims
,
2677 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2678 dstRowStride
, dstImageOffsets
,
2679 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2684 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2687 srcWidth
, srcHeight
, srcDepth
,
2688 srcFormat
, srcType
, srcAddr
,
2690 const GLfloat
*srcRow
= tempImage
;
2691 GLint img
, row
, col
;
2694 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2695 for (img
= 0; img
< srcDepth
; img
++) {
2696 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2697 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2698 + dstYoffset
* dstRowStride
2699 + dstXoffset
* texelBytes
;
2700 for (row
= 0; row
< srcHeight
; row
++) {
2701 GLuint
*dstUI
= (GLuint
*) dstRow
;
2702 if (dstFormat
== &_mesa_texformat_signed_rgba8888
) {
2703 for (col
= 0; col
< srcWidth
; col
++) {
2704 dstUI
[col
] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2705 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2706 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2707 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2712 for (col
= 0; col
< srcWidth
; col
++) {
2713 dstUI
[col
] = PACK_COLOR_8888_REV( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2714 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2715 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2716 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2720 dstRow
+= dstRowStride
;
2723 _mesa_free((void *) tempImage
);
2729 * Store a combined depth/stencil texture image.
2732 _mesa_texstore_z24_s8(TEXSTORE_PARAMS
)
2734 const GLfloat depthScale
= (GLfloat
) 0xffffff;
2735 const GLint srcRowStride
2736 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2740 ASSERT(dstFormat
== &_mesa_texformat_z24_s8
);
2741 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
);
2742 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2744 /* In case we only upload depth we need to preserve the stencil */
2745 if (srcFormat
== GL_DEPTH_COMPONENT
) {
2746 for (img
= 0; img
< srcDepth
; img
++) {
2747 GLuint
*dstRow
= (GLuint
*) dstAddr
2748 + dstImageOffsets
[dstZoffset
+ img
]
2749 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2752 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2753 srcWidth
, srcHeight
,
2756 for (row
= 0; row
< srcHeight
; row
++) {
2757 GLuint depth
[MAX_WIDTH
];
2759 _mesa_unpack_depth_span(ctx
, srcWidth
,
2760 GL_UNSIGNED_INT
, /* dst type */
2761 depth
, /* dst addr */
2763 srcType
, src
, srcPacking
);
2765 for (i
= 0; i
< srcWidth
; i
++)
2766 dstRow
[i
] = depth
[i
] << 8 | (dstRow
[i
] & 0x000000FF);
2768 src
+= srcRowStride
;
2769 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2773 else if (ctx
->Pixel
.DepthScale
== 1.0f
&&
2774 ctx
->Pixel
.DepthBias
== 0.0f
&&
2775 !srcPacking
->SwapBytes
) {
2777 memcpy_texture(ctx
, dims
,
2778 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2781 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2782 srcAddr
, srcPacking
);
2786 const GLint srcRowStride
2787 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2791 for (img
= 0; img
< srcDepth
; img
++) {
2792 GLuint
*dstRow
= (GLuint
*) dstAddr
2793 + dstImageOffsets
[dstZoffset
+ img
]
2794 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2797 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2798 srcWidth
, srcHeight
,
2801 for (row
= 0; row
< srcHeight
; row
++) {
2802 GLubyte stencil
[MAX_WIDTH
];
2804 /* the 24 depth bits will be in the high position: */
2805 _mesa_unpack_depth_span(ctx
, srcWidth
,
2806 GL_UNSIGNED_INT_24_8_EXT
, /* dst type */
2807 dstRow
, /* dst addr */
2808 (GLuint
) depthScale
,
2809 srcType
, src
, srcPacking
);
2810 /* get the 8-bit stencil values */
2811 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2812 GL_UNSIGNED_BYTE
, /* dst type */
2813 stencil
, /* dst addr */
2814 srcType
, src
, srcPacking
,
2815 ctx
->_ImageTransferState
);
2816 /* merge stencil values into depth values */
2817 for (i
= 0; i
< srcWidth
; i
++)
2818 dstRow
[i
] |= stencil
[i
];
2820 src
+= srcRowStride
;
2821 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2830 * Store a combined depth/stencil texture image.
2833 _mesa_texstore_s8_z24(TEXSTORE_PARAMS
)
2835 const GLuint depthScale
= 0xffffff;
2836 const GLint srcRowStride
2837 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2841 ASSERT(dstFormat
== &_mesa_texformat_s8_z24
);
2842 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
);
2843 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2845 /* In case we only upload depth we need to preserve the stencil */
2846 if (srcFormat
== GL_DEPTH_COMPONENT
) {
2847 for (img
= 0; img
< srcDepth
; img
++) {
2848 GLuint
*dstRow
= (GLuint
*) dstAddr
2849 + dstImageOffsets
[dstZoffset
+ img
]
2850 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2853 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2854 srcWidth
, srcHeight
,
2857 for (row
= 0; row
< srcHeight
; row
++) {
2858 GLuint depth
[MAX_WIDTH
];
2860 _mesa_unpack_depth_span(ctx
, srcWidth
,
2861 GL_UNSIGNED_INT
, /* dst type */
2862 depth
, /* dst addr */
2864 srcType
, src
, srcPacking
);
2866 for (i
= 0; i
< srcWidth
; i
++)
2867 dstRow
[i
] = depth
[i
] | (dstRow
[i
] & 0xFF000000);
2869 src
+= srcRowStride
;
2870 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2875 for (img
= 0; img
< srcDepth
; img
++) {
2876 GLuint
*dstRow
= (GLuint
*) dstAddr
2877 + dstImageOffsets
[dstZoffset
+ img
]
2878 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2881 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2882 srcWidth
, srcHeight
,
2885 for (row
= 0; row
< srcHeight
; row
++) {
2886 GLubyte stencil
[MAX_WIDTH
];
2888 /* the 24 depth bits will be in the low position: */
2889 _mesa_unpack_depth_span(ctx
, srcWidth
,
2890 GL_UNSIGNED_INT
, /* dst type */
2891 dstRow
, /* dst addr */
2893 srcType
, src
, srcPacking
);
2894 /* get the 8-bit stencil values */
2895 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2896 GL_UNSIGNED_BYTE
, /* dst type */
2897 stencil
, /* dst addr */
2898 srcType
, src
, srcPacking
,
2899 ctx
->_ImageTransferState
);
2900 /* merge stencil values into depth values */
2901 for (i
= 0; i
< srcWidth
; i
++)
2902 dstRow
[i
] |= stencil
[i
] << 24;
2904 src
+= srcRowStride
;
2905 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2913 * Store an image in any of the formats:
2914 * _mesa_texformat_rgba_float32
2915 * _mesa_texformat_rgb_float32
2916 * _mesa_texformat_alpha_float32
2917 * _mesa_texformat_luminance_float32
2918 * _mesa_texformat_luminance_alpha_float32
2919 * _mesa_texformat_intensity_float32
2922 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS
)
2924 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
2925 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
2926 const GLint components
= _mesa_components_in_format(baseFormat
);
2928 ASSERT(dstFormat
== &_mesa_texformat_rgba_float32
||
2929 dstFormat
== &_mesa_texformat_rgb_float32
||
2930 dstFormat
== &_mesa_texformat_alpha_float32
||
2931 dstFormat
== &_mesa_texformat_luminance_float32
||
2932 dstFormat
== &_mesa_texformat_luminance_alpha_float32
||
2933 dstFormat
== &_mesa_texformat_intensity_float32
);
2934 ASSERT(baseInternalFormat
== GL_RGBA
||
2935 baseInternalFormat
== GL_RGB
||
2936 baseInternalFormat
== GL_ALPHA
||
2937 baseInternalFormat
== GL_LUMINANCE
||
2938 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
2939 baseInternalFormat
== GL_INTENSITY
);
2940 ASSERT(texelBytes
== components
* sizeof(GLfloat
));
2942 if (!ctx
->_ImageTransferState
&&
2943 !srcPacking
->SwapBytes
&&
2944 baseInternalFormat
== srcFormat
&&
2945 srcType
== GL_FLOAT
) {
2946 /* simple memcpy path */
2947 memcpy_texture(ctx
, dims
,
2948 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2951 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2952 srcAddr
, srcPacking
);
2956 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2959 srcWidth
, srcHeight
, srcDepth
,
2960 srcFormat
, srcType
, srcAddr
,
2962 const GLfloat
*srcRow
= tempImage
;
2967 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2968 bytesPerRow
= srcWidth
* components
* sizeof(GLfloat
);
2969 for (img
= 0; img
< srcDepth
; img
++) {
2970 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2971 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2972 + dstYoffset
* dstRowStride
2973 + dstXoffset
* texelBytes
;
2974 for (row
= 0; row
< srcHeight
; row
++) {
2975 _mesa_memcpy(dstRow
, srcRow
, bytesPerRow
);
2976 dstRow
+= dstRowStride
;
2977 srcRow
+= srcWidth
* components
;
2981 _mesa_free((void *) tempImage
);
2988 * As above, but store 16-bit floats.
2991 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS
)
2993 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
->MesaFormat
);
2994 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
->MesaFormat
);
2995 const GLint components
= _mesa_components_in_format(baseFormat
);
2997 ASSERT(dstFormat
== &_mesa_texformat_rgba_float16
||
2998 dstFormat
== &_mesa_texformat_rgb_float16
||
2999 dstFormat
== &_mesa_texformat_alpha_float16
||
3000 dstFormat
== &_mesa_texformat_luminance_float16
||
3001 dstFormat
== &_mesa_texformat_luminance_alpha_float16
||
3002 dstFormat
== &_mesa_texformat_intensity_float16
);
3003 ASSERT(baseInternalFormat
== GL_RGBA
||
3004 baseInternalFormat
== GL_RGB
||
3005 baseInternalFormat
== GL_ALPHA
||
3006 baseInternalFormat
== GL_LUMINANCE
||
3007 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
3008 baseInternalFormat
== GL_INTENSITY
);
3009 ASSERT(texelBytes
== components
* sizeof(GLhalfARB
));
3011 if (!ctx
->_ImageTransferState
&&
3012 !srcPacking
->SwapBytes
&&
3013 baseInternalFormat
== srcFormat
&&
3014 srcType
== GL_HALF_FLOAT_ARB
) {
3015 /* simple memcpy path */
3016 memcpy_texture(ctx
, dims
,
3017 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3020 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
3021 srcAddr
, srcPacking
);
3025 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
3028 srcWidth
, srcHeight
, srcDepth
,
3029 srcFormat
, srcType
, srcAddr
,
3031 const GLfloat
*src
= tempImage
;
3035 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
3036 for (img
= 0; img
< srcDepth
; img
++) {
3037 GLubyte
*dstRow
= (GLubyte
*) dstAddr
3038 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
3039 + dstYoffset
* dstRowStride
3040 + dstXoffset
* texelBytes
;
3041 for (row
= 0; row
< srcHeight
; row
++) {
3042 GLhalfARB
*dstTexel
= (GLhalfARB
*) dstRow
;
3044 for (i
= 0; i
< srcWidth
* components
; i
++) {
3045 dstTexel
[i
] = _mesa_float_to_half(src
[i
]);
3047 dstRow
+= dstRowStride
;
3048 src
+= srcWidth
* components
;
3052 _mesa_free((void *) tempImage
);
3058 #if FEATURE_EXT_texture_sRGB
3060 _mesa_texstore_srgb8(TEXSTORE_PARAMS
)
3062 const struct gl_texture_format
*newDstFormat
;
3065 ASSERT(dstFormat
== &_mesa_texformat_srgb8
);
3067 /* reuse normal rgb texstore code */
3068 newDstFormat
= &_mesa_texformat_rgb888
;
3070 k
= _mesa_texstore_rgb888(ctx
, dims
, baseInternalFormat
,
3071 newDstFormat
, dstAddr
,
3072 dstXoffset
, dstYoffset
, dstZoffset
,
3073 dstRowStride
, dstImageOffsets
,
3074 srcWidth
, srcHeight
, srcDepth
,
3076 srcAddr
, srcPacking
);
3082 _mesa_texstore_srgba8(TEXSTORE_PARAMS
)
3084 const struct gl_texture_format
*newDstFormat
;
3087 ASSERT(dstFormat
== &_mesa_texformat_srgba8
);
3089 /* reuse normal rgba texstore code */
3090 newDstFormat
= &_mesa_texformat_rgba8888
;
3092 k
= _mesa_texstore_rgba8888(ctx
, dims
, baseInternalFormat
,
3093 newDstFormat
, dstAddr
,
3094 dstXoffset
, dstYoffset
, dstZoffset
,
3095 dstRowStride
, dstImageOffsets
,
3096 srcWidth
, srcHeight
, srcDepth
,
3098 srcAddr
, srcPacking
);
3104 _mesa_texstore_sargb8(TEXSTORE_PARAMS
)
3106 const struct gl_texture_format
*newDstFormat
;
3109 ASSERT(dstFormat
== &_mesa_texformat_sargb8
);
3111 /* reuse normal rgba texstore code */
3112 newDstFormat
= &_mesa_texformat_argb8888
;
3114 k
= _mesa_texstore_argb8888(ctx
, dims
, baseInternalFormat
,
3115 newDstFormat
, dstAddr
,
3116 dstXoffset
, dstYoffset
, dstZoffset
,
3117 dstRowStride
, dstImageOffsets
,
3118 srcWidth
, srcHeight
, srcDepth
,
3120 srcAddr
, srcPacking
);
3126 _mesa_texstore_sl8(TEXSTORE_PARAMS
)
3128 const struct gl_texture_format
*newDstFormat
;
3131 ASSERT(dstFormat
== &_mesa_texformat_sl8
);
3133 newDstFormat
= &_mesa_texformat_l8
;
3135 /* _mesa_textore_a8 handles luminance8 too */
3136 k
= _mesa_texstore_a8(ctx
, dims
, baseInternalFormat
,
3137 newDstFormat
, dstAddr
,
3138 dstXoffset
, dstYoffset
, dstZoffset
,
3139 dstRowStride
, dstImageOffsets
,
3140 srcWidth
, srcHeight
, srcDepth
,
3142 srcAddr
, srcPacking
);
3148 _mesa_texstore_sla8(TEXSTORE_PARAMS
)
3150 const struct gl_texture_format
*newDstFormat
;
3153 ASSERT(dstFormat
== &_mesa_texformat_sla8
);
3155 /* reuse normal luminance/alpha texstore code */
3156 newDstFormat
= &_mesa_texformat_al88
;
3158 k
= _mesa_texstore_al88(ctx
, dims
, baseInternalFormat
,
3159 newDstFormat
, dstAddr
,
3160 dstXoffset
, dstYoffset
, dstZoffset
,
3161 dstRowStride
, dstImageOffsets
,
3162 srcWidth
, srcHeight
, srcDepth
,
3164 srcAddr
, srcPacking
);
3168 #endif /* FEATURE_EXT_texture_sRGB */
3174 * Table mapping MESA_FORMAT_8 to _mesa_texstore_*()
3175 * XXX this is somewhat temporary.
3179 StoreTexImageFunc Store
;
3181 texstore_funcs
[MESA_FORMAT_COUNT
] =
3183 { MESA_FORMAT_NONE
, NULL
},
3184 { MESA_FORMAT_RGBA8888
, _mesa_texstore_rgba8888
},
3185 { MESA_FORMAT_RGBA8888_REV
, _mesa_texstore_rgba8888
},
3186 { MESA_FORMAT_ARGB8888
, _mesa_texstore_argb8888
},
3187 { MESA_FORMAT_ARGB8888_REV
, _mesa_texstore_argb8888
},
3188 { MESA_FORMAT_RGB888
, _mesa_texstore_rgb888
},
3189 { MESA_FORMAT_BGR888
, _mesa_texstore_bgr888
},
3190 { MESA_FORMAT_RGB565
, _mesa_texstore_rgb565
},
3191 { MESA_FORMAT_RGB565_REV
, _mesa_texstore_rgb565
},
3192 { MESA_FORMAT_RGBA4444
, _mesa_texstore_rgba4444
},
3193 { MESA_FORMAT_ARGB4444
, _mesa_texstore_argb4444
},
3194 { MESA_FORMAT_ARGB4444_REV
, _mesa_texstore_argb4444
},
3195 { MESA_FORMAT_RGBA5551
, _mesa_texstore_rgba5551
},
3196 { MESA_FORMAT_ARGB1555
, _mesa_texstore_argb1555
},
3197 { MESA_FORMAT_ARGB1555_REV
, _mesa_texstore_argb1555
},
3198 { MESA_FORMAT_AL88
, _mesa_texstore_al88
},
3199 { MESA_FORMAT_AL88_REV
, _mesa_texstore_al88
},
3200 { MESA_FORMAT_RGB332
, _mesa_texstore_rgb332
},
3201 { MESA_FORMAT_A8
, _mesa_texstore_a8
},
3202 { MESA_FORMAT_L8
, _mesa_texstore_a8
},
3203 { MESA_FORMAT_I8
, _mesa_texstore_a8
},
3204 { MESA_FORMAT_CI8
, _mesa_texstore_ci8
},
3205 { MESA_FORMAT_YCBCR
, _mesa_texstore_ycbcr
},
3206 { MESA_FORMAT_YCBCR_REV
, _mesa_texstore_ycbcr
},
3207 { MESA_FORMAT_Z24_S8
, _mesa_texstore_z24_s8
},
3208 { MESA_FORMAT_S8_Z24
, _mesa_texstore_s8_z24
},
3209 { MESA_FORMAT_Z16
, _mesa_texstore_z16
},
3210 { MESA_FORMAT_Z32
, _mesa_texstore_z32
},
3211 { MESA_FORMAT_S8
, NULL
/*_mesa_texstore_s8*/ },
3212 { MESA_FORMAT_SRGB8
, _mesa_texstore_srgb8
},
3213 { MESA_FORMAT_SRGBA8
, _mesa_texstore_srgba8
},
3214 { MESA_FORMAT_SARGB8
, _mesa_texstore_sargb8
},
3215 { MESA_FORMAT_SL8
, _mesa_texstore_sl8
},
3216 { MESA_FORMAT_SLA8
, _mesa_texstore_sla8
},
3217 { MESA_FORMAT_SRGB_DXT1
, _mesa_texstore_rgb_dxt1
},
3218 { MESA_FORMAT_SRGBA_DXT1
, _mesa_texstore_rgba_dxt1
},
3219 { MESA_FORMAT_SRGBA_DXT3
, _mesa_texstore_rgba_dxt3
},
3220 { MESA_FORMAT_SRGBA_DXT5
, _mesa_texstore_rgba_dxt5
},
3221 { MESA_FORMAT_RGB_FXT1
, _mesa_texstore_rgb_fxt1
},
3222 { MESA_FORMAT_RGBA_FXT1
, _mesa_texstore_rgba_fxt1
},
3223 { MESA_FORMAT_RGB_DXT1
, _mesa_texstore_rgb_dxt1
},
3224 { MESA_FORMAT_RGBA_DXT1
, _mesa_texstore_rgba_dxt1
},
3225 { MESA_FORMAT_RGBA_DXT3
, _mesa_texstore_rgba_dxt3
},
3226 { MESA_FORMAT_RGBA_DXT5
, _mesa_texstore_rgba_dxt5
},
3227 { MESA_FORMAT_RGBA
, _mesa_texstore_rgba
},
3228 { MESA_FORMAT_RGB
, _mesa_texstore_rgba
},
3229 { MESA_FORMAT_ALPHA
, _mesa_texstore_rgba
},
3230 { MESA_FORMAT_LUMINANCE
, _mesa_texstore_rgba
},
3231 { MESA_FORMAT_LUMINANCE_ALPHA
, _mesa_texstore_rgba
},
3232 { MESA_FORMAT_INTENSITY
, _mesa_texstore_rgba
},
3233 { MESA_FORMAT_RGBA_FLOAT32
, _mesa_texstore_rgba_float32
},
3234 { MESA_FORMAT_RGBA_FLOAT16
, _mesa_texstore_rgba_float16
},
3235 { MESA_FORMAT_RGB_FLOAT32
, _mesa_texstore_rgba_float32
},
3236 { MESA_FORMAT_RGB_FLOAT16
, _mesa_texstore_rgba_float16
},
3237 { MESA_FORMAT_ALPHA_FLOAT32
, _mesa_texstore_rgba_float32
},
3238 { MESA_FORMAT_ALPHA_FLOAT16
, _mesa_texstore_rgba_float16
},
3239 { MESA_FORMAT_LUMINANCE_FLOAT32
, _mesa_texstore_rgba_float32
},
3240 { MESA_FORMAT_LUMINANCE_FLOAT16
, _mesa_texstore_rgba_float16
},
3241 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32
, _mesa_texstore_rgba_float32
},
3242 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16
, _mesa_texstore_rgba_float16
},
3243 { MESA_FORMAT_INTENSITY_FLOAT32
, _mesa_texstore_rgba_float32
},
3244 { MESA_FORMAT_INTENSITY_FLOAT16
, _mesa_texstore_rgba_float16
},
3245 { MESA_FORMAT_DUDV8
, _mesa_texstore_dudv8
},
3246 { MESA_FORMAT_SIGNED_RGBA8888
, _mesa_texstore_signed_rgba8888
},
3247 { MESA_FORMAT_SIGNED_RGBA8888_REV
, _mesa_texstore_signed_rgba8888
},
3252 * Return the StoreTexImageFunc pointer to store an image in the given format.
3255 _mesa_get_texstore_func(gl_format format
)
3259 for (i
= 0; i
< MESA_FORMAT_COUNT
; i
++) {
3260 ASSERT(texstore_funcs
[i
].Name
== i
);
3263 ASSERT(texstore_funcs
[format
].Name
== format
);
3264 return texstore_funcs
[format
].Store
;
3269 * Store user data into texture memory.
3270 * Called via glTex[Sub]Image1/2/3D()
3273 _mesa_texstore(TEXSTORE_PARAMS
)
3275 StoreTexImageFunc storeImage
;
3278 storeImage
= _mesa_get_texstore_func(dstFormat
->MesaFormat
);
3282 success
= storeImage(ctx
, dims
, baseInternalFormat
,
3283 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3284 dstRowStride
, dstImageOffsets
,
3285 srcWidth
, srcHeight
, srcDepth
,
3286 srcFormat
, srcType
, srcAddr
, srcPacking
);
3292 * Check if an unpack PBO is active prior to fetching a texture image.
3293 * If so, do bounds checking and map the buffer into main memory.
3294 * Any errors detected will be recorded.
3295 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3298 _mesa_validate_pbo_teximage(GLcontext
*ctx
, GLuint dimensions
,
3299 GLsizei width
, GLsizei height
, GLsizei depth
,
3300 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3301 const struct gl_pixelstore_attrib
*unpack
,
3302 const char *funcName
)
3306 if (!_mesa_is_bufferobj(unpack
->BufferObj
)) {
3310 if (!_mesa_validate_pbo_access(dimensions
, unpack
, width
, height
, depth
,
3311 format
, type
, pixels
)) {
3312 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3316 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3317 GL_READ_ONLY_ARB
, unpack
->BufferObj
);
3319 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3323 return ADD_POINTERS(buf
, pixels
);
3328 * Check if an unpack PBO is active prior to fetching a compressed texture
3330 * If so, do bounds checking and map the buffer into main memory.
3331 * Any errors detected will be recorded.
3332 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3335 _mesa_validate_pbo_compressed_teximage(GLcontext
*ctx
,
3336 GLsizei imageSize
, const GLvoid
*pixels
,
3337 const struct gl_pixelstore_attrib
*packing
,
3338 const char *funcName
)
3342 if (!_mesa_is_bufferobj(packing
->BufferObj
)) {
3343 /* not using a PBO - return pointer unchanged */
3346 if ((const GLubyte
*) pixels
+ imageSize
>
3347 ((const GLubyte
*) 0) + packing
->BufferObj
->Size
) {
3348 /* out of bounds read! */
3349 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3353 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3354 GL_READ_ONLY_ARB
, packing
->BufferObj
);
3356 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3360 return ADD_POINTERS(buf
, pixels
);
3365 * This function must be called after either of the validate_pbo_*_teximage()
3366 * functions. It unmaps the PBO buffer if it was mapped earlier.
3369 _mesa_unmap_teximage_pbo(GLcontext
*ctx
,
3370 const struct gl_pixelstore_attrib
*unpack
)
3372 if (_mesa_is_bufferobj(unpack
->BufferObj
)) {
3373 ctx
->Driver
.UnmapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3381 * Adaptor for fetching a GLchan texel from a float-valued texture.
3384 fetch_texel_float_to_chan(const struct gl_texture_image
*texImage
,
3385 GLint i
, GLint j
, GLint k
, GLchan
*texelOut
)
3388 GLenum baseFormat
= _mesa_get_format_base_format(texImage
->TexFormat
->MesaFormat
);
3390 ASSERT(texImage
->FetchTexelf
);
3391 texImage
->FetchTexelf(texImage
, i
, j
, k
, temp
);
3392 if (baseFormat
== GL_DEPTH_COMPONENT
||
3393 baseFormat
== GL_DEPTH_STENCIL_EXT
) {
3394 /* just one channel */
3395 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[0], temp
[0]);
3399 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[0], temp
[0]);
3400 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[1], temp
[1]);
3401 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[2], temp
[2]);
3402 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[3], temp
[3]);
3408 * Adaptor for fetching a float texel from a GLchan-valued texture.
3411 fetch_texel_chan_to_float(const struct gl_texture_image
*texImage
,
3412 GLint i
, GLint j
, GLint k
, GLfloat
*texelOut
)
3415 GLenum baseFormat
= _mesa_get_format_base_format(texImage
->TexFormat
->MesaFormat
);
3417 ASSERT(texImage
->FetchTexelc
);
3418 texImage
->FetchTexelc(texImage
, i
, j
, k
, temp
);
3419 if (baseFormat
== GL_DEPTH_COMPONENT
||
3420 baseFormat
== GL_DEPTH_STENCIL_EXT
) {
3421 /* just one channel */
3422 texelOut
[0] = CHAN_TO_FLOAT(temp
[0]);
3426 texelOut
[0] = CHAN_TO_FLOAT(temp
[0]);
3427 texelOut
[1] = CHAN_TO_FLOAT(temp
[1]);
3428 texelOut
[2] = CHAN_TO_FLOAT(temp
[2]);
3429 texelOut
[3] = CHAN_TO_FLOAT(temp
[3]);
3435 * Initialize the texture image's FetchTexelc and FetchTexelf methods.
3438 _mesa_set_fetch_functions(struct gl_texture_image
*texImage
, GLuint dims
)
3440 ASSERT(dims
== 1 || dims
== 2 || dims
== 3);
3441 ASSERT(texImage
->TexFormat
);
3443 texImage
->FetchTexelf
=
3444 _mesa_get_texel_fetch_func(texImage
->TexFormat
->MesaFormat
, dims
);
3446 /* now check if we need to use a float/chan adaptor */
3447 if (!texImage
->FetchTexelc
) {
3448 texImage
->FetchTexelc
= fetch_texel_float_to_chan
;
3450 else if (!texImage
->FetchTexelf
) {
3451 texImage
->FetchTexelf
= fetch_texel_chan_to_float
;
3455 ASSERT(texImage
->FetchTexelc
);
3456 ASSERT(texImage
->FetchTexelf
);
3461 compute_texture_size(GLcontext
*ctx
, struct gl_texture_image
*texImage
)
3463 texImage
->IsCompressed
=
3464 _mesa_is_format_compressed(texImage
->TexFormat
->MesaFormat
);
3466 if (texImage
->IsCompressed
) {
3467 texImage
->CompressedSize
=
3468 ctx
->Driver
.CompressedTextureSize(ctx
, texImage
->Width
,
3469 texImage
->Height
, texImage
->Depth
,
3470 texImage
->TexFormat
->MesaFormat
);
3473 /* non-compressed format */
3474 texImage
->CompressedSize
= 0;
3481 * This is the software fallback for Driver.TexImage1D()
3482 * and Driver.CopyTexImage1D().
3483 * \sa _mesa_store_teximage2d()
3484 * Note that the width may not be the actual texture width since it may
3485 * be changed by convolution w/ GL_REDUCE. The texImage->Width field will
3486 * have the actual texture size.
3489 _mesa_store_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3490 GLint internalFormat
,
3491 GLint width
, GLint border
,
3492 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3493 const struct gl_pixelstore_attrib
*packing
,
3494 struct gl_texture_object
*texObj
,
3495 struct gl_texture_image
*texImage
)
3501 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3502 ASSERT(texImage
->TexFormat
);
3504 _mesa_set_fetch_functions(texImage
, 1);
3505 compute_texture_size(ctx
, texImage
);
3507 /* allocate memory */
3508 if (texImage
->IsCompressed
)
3509 sizeInBytes
= texImage
->CompressedSize
;
3511 sizeInBytes
= texImage
->Width
* _mesa_get_format_bytes(texImage
->TexFormat
->MesaFormat
);
3512 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3513 if (!texImage
->Data
) {
3514 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
3518 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
3519 pixels
, packing
, "glTexImage1D");
3521 /* Note: we check for a NULL image pointer here, _after_ we allocated
3522 * memory for the texture. That's what the GL spec calls for.
3527 const GLint dstRowStride
= 0;
3530 success
= _mesa_texstore(ctx
, 1, texImage
->_BaseFormat
,
3531 texImage
->TexFormat
,
3533 0, 0, 0, /* dstX/Y/Zoffset */
3535 texImage
->ImageOffsets
,
3537 format
, type
, pixels
, packing
);
3539 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
3543 _mesa_unmap_teximage_pbo(ctx
, packing
);
3548 * This is the software fallback for Driver.TexImage2D()
3549 * and Driver.CopyTexImage2D().
3551 * This function is oriented toward storing images in main memory, rather
3552 * than VRAM. Device driver's can easily plug in their own replacement.
3554 * Note: width and height may be pre-convolved dimensions, but
3555 * texImage->Width and texImage->Height will be post-convolved dimensions.
3558 _mesa_store_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3559 GLint internalFormat
,
3560 GLint width
, GLint height
, GLint border
,
3561 GLenum format
, GLenum type
, const void *pixels
,
3562 const struct gl_pixelstore_attrib
*packing
,
3563 struct gl_texture_object
*texObj
,
3564 struct gl_texture_image
*texImage
)
3566 GLint texelBytes
, sizeInBytes
;
3570 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3571 ASSERT(texImage
->TexFormat
);
3573 _mesa_set_fetch_functions(texImage
, 2);
3574 compute_texture_size(ctx
, texImage
);
3576 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
->MesaFormat
);
3578 /* allocate memory */
3579 if (texImage
->IsCompressed
)
3580 sizeInBytes
= texImage
->CompressedSize
;
3582 sizeInBytes
= texImage
->Width
* texImage
->Height
* texelBytes
;
3583 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3584 if (!texImage
->Data
) {
3585 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
3589 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
3590 pixels
, packing
, "glTexImage2D");
3592 /* Note: we check for a NULL image pointer here, _after_ we allocated
3593 * memory for the texture. That's what the GL spec calls for.
3601 if (texImage
->IsCompressed
) {
3603 = _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, width
);
3606 dstRowStride
= texImage
->RowStride
* texelBytes
;
3609 success
= _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
3610 texImage
->TexFormat
,
3612 0, 0, 0, /* dstX/Y/Zoffset */
3614 texImage
->ImageOffsets
,
3616 format
, type
, pixels
, packing
);
3619 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
3623 _mesa_unmap_teximage_pbo(ctx
, packing
);
3629 * This is the software fallback for Driver.TexImage3D()
3630 * and Driver.CopyTexImage3D().
3631 * \sa _mesa_store_teximage2d()
3634 _mesa_store_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3635 GLint internalFormat
,
3636 GLint width
, GLint height
, GLint depth
, GLint border
,
3637 GLenum format
, GLenum type
, const void *pixels
,
3638 const struct gl_pixelstore_attrib
*packing
,
3639 struct gl_texture_object
*texObj
,
3640 struct gl_texture_image
*texImage
)
3642 GLint texelBytes
, sizeInBytes
;
3646 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3647 ASSERT(texImage
->TexFormat
);
3649 _mesa_set_fetch_functions(texImage
, 3);
3650 compute_texture_size(ctx
, texImage
);
3652 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
->MesaFormat
);
3654 /* allocate memory */
3655 if (texImage
->IsCompressed
)
3656 sizeInBytes
= texImage
->CompressedSize
;
3658 sizeInBytes
= width
* height
* depth
* texelBytes
;
3659 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3660 if (!texImage
->Data
) {
3661 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
3665 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
3666 type
, pixels
, packing
, "glTexImage3D");
3668 /* Note: we check for a NULL image pointer here, _after_ we allocated
3669 * memory for the texture. That's what the GL spec calls for.
3677 if (texImage
->IsCompressed
) {
3679 = _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, width
);
3682 dstRowStride
= texImage
->RowStride
* texelBytes
;
3685 success
= _mesa_texstore(ctx
, 3, texImage
->_BaseFormat
,
3686 texImage
->TexFormat
,
3688 0, 0, 0, /* dstX/Y/Zoffset */
3690 texImage
->ImageOffsets
,
3691 width
, height
, depth
,
3692 format
, type
, pixels
, packing
);
3694 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
3698 _mesa_unmap_teximage_pbo(ctx
, packing
);
3705 * This is the software fallback for Driver.TexSubImage1D()
3706 * and Driver.CopyTexSubImage1D().
3709 _mesa_store_texsubimage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3710 GLint xoffset
, GLint width
,
3711 GLenum format
, GLenum type
, const void *pixels
,
3712 const struct gl_pixelstore_attrib
*packing
,
3713 struct gl_texture_object
*texObj
,
3714 struct gl_texture_image
*texImage
)
3716 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3717 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
3718 pixels
, packing
, "glTexSubImage1D");
3723 const GLint dstRowStride
= 0;
3726 success
= _mesa_texstore(ctx
, 1, texImage
->_BaseFormat
,
3727 texImage
->TexFormat
,
3729 xoffset
, 0, 0, /* offsets */
3731 texImage
->ImageOffsets
,
3733 format
, type
, pixels
, packing
);
3735 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
3739 _mesa_unmap_teximage_pbo(ctx
, packing
);
3745 * This is the software fallback for Driver.TexSubImage2D()
3746 * and Driver.CopyTexSubImage2D().
3749 _mesa_store_texsubimage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3750 GLint xoffset
, GLint yoffset
,
3751 GLint width
, GLint height
,
3752 GLenum format
, GLenum type
, const void *pixels
,
3753 const struct gl_pixelstore_attrib
*packing
,
3754 struct gl_texture_object
*texObj
,
3755 struct gl_texture_image
*texImage
)
3757 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3758 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
3759 pixels
, packing
, "glTexSubImage2D");
3764 GLint dstRowStride
= 0;
3767 if (texImage
->IsCompressed
) {
3768 dstRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
,
3772 dstRowStride
= texImage
->RowStride
*
3773 _mesa_get_format_bytes(texImage
->TexFormat
->MesaFormat
);
3776 success
= _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
3777 texImage
->TexFormat
,
3779 xoffset
, yoffset
, 0,
3781 texImage
->ImageOffsets
,
3783 format
, type
, pixels
, packing
);
3785 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
3789 _mesa_unmap_teximage_pbo(ctx
, packing
);
3794 * This is the software fallback for Driver.TexSubImage3D().
3795 * and Driver.CopyTexSubImage3D().
3798 _mesa_store_texsubimage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3799 GLint xoffset
, GLint yoffset
, GLint zoffset
,
3800 GLint width
, GLint height
, GLint depth
,
3801 GLenum format
, GLenum type
, const void *pixels
,
3802 const struct gl_pixelstore_attrib
*packing
,
3803 struct gl_texture_object
*texObj
,
3804 struct gl_texture_image
*texImage
)
3806 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3807 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
3808 type
, pixels
, packing
,
3817 if (texImage
->IsCompressed
) {
3818 dstRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
,
3822 dstRowStride
= texImage
->RowStride
*
3823 _mesa_get_format_bytes(texImage
->TexFormat
->MesaFormat
);
3826 success
= _mesa_texstore(ctx
, 3, texImage
->_BaseFormat
,
3827 texImage
->TexFormat
,
3829 xoffset
, yoffset
, zoffset
,
3831 texImage
->ImageOffsets
,
3832 width
, height
, depth
,
3833 format
, type
, pixels
, packing
);
3835 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3D");
3839 _mesa_unmap_teximage_pbo(ctx
, packing
);
3844 * Fallback for Driver.CompressedTexImage1D()
3847 _mesa_store_compressed_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3848 GLint internalFormat
,
3849 GLint width
, GLint border
,
3850 GLsizei imageSize
, const GLvoid
*data
,
3851 struct gl_texture_object
*texObj
,
3852 struct gl_texture_image
*texImage
)
3854 /* this space intentionally left blank */
3856 (void) target
; (void) level
;
3857 (void) internalFormat
;
3858 (void) width
; (void) border
;
3859 (void) imageSize
; (void) data
;
3867 * Fallback for Driver.CompressedTexImage2D()
3870 _mesa_store_compressed_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3871 GLint internalFormat
,
3872 GLint width
, GLint height
, GLint border
,
3873 GLsizei imageSize
, const GLvoid
*data
,
3874 struct gl_texture_object
*texObj
,
3875 struct gl_texture_image
*texImage
)
3877 (void) width
; (void) height
; (void) border
;
3879 /* This is pretty simple, basically just do a memcpy without worrying
3880 * about the usual image unpacking or image transfer operations.
3884 ASSERT(texImage
->Width
> 0);
3885 ASSERT(texImage
->Height
> 0);
3886 ASSERT(texImage
->Depth
== 1);
3887 ASSERT(texImage
->Data
== NULL
); /* was freed in glCompressedTexImage2DARB */
3890 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, 0, 0);
3891 ASSERT(texImage
->TexFormat
);
3893 _mesa_set_fetch_functions(texImage
, 2);
3894 compute_texture_size(ctx
, texImage
);
3896 /* allocate storage */
3897 texImage
->Data
= _mesa_alloc_texmemory(imageSize
);
3898 if (!texImage
->Data
) {
3899 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
3903 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
3905 "glCompressedTexImage2D");
3910 ASSERT(texImage
->CompressedSize
== (GLuint
) imageSize
);
3911 MEMCPY(texImage
->Data
, data
, imageSize
);
3913 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
3919 * Fallback for Driver.CompressedTexImage3D()
3922 _mesa_store_compressed_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3923 GLint internalFormat
,
3924 GLint width
, GLint height
, GLint depth
,
3926 GLsizei imageSize
, const GLvoid
*data
,
3927 struct gl_texture_object
*texObj
,
3928 struct gl_texture_image
*texImage
)
3930 /* this space intentionally left blank */
3932 (void) target
; (void) level
;
3933 (void) internalFormat
;
3934 (void) width
; (void) height
; (void) depth
;
3936 (void) imageSize
; (void) data
;
3944 * Fallback for Driver.CompressedTexSubImage1D()
3947 _mesa_store_compressed_texsubimage1d(GLcontext
*ctx
, GLenum target
,
3949 GLint xoffset
, GLsizei width
,
3951 GLsizei imageSize
, const GLvoid
*data
,
3952 struct gl_texture_object
*texObj
,
3953 struct gl_texture_image
*texImage
)
3955 /* there are no compressed 1D texture formats yet */
3957 (void) target
; (void) level
;
3958 (void) xoffset
; (void) width
;
3960 (void) imageSize
; (void) data
;
3967 * Fallback for Driver.CompressedTexSubImage2D()
3970 _mesa_store_compressed_texsubimage2d(GLcontext
*ctx
, GLenum target
,
3972 GLint xoffset
, GLint yoffset
,
3973 GLsizei width
, GLsizei height
,
3975 GLsizei imageSize
, const GLvoid
*data
,
3976 struct gl_texture_object
*texObj
,
3977 struct gl_texture_image
*texImage
)
3979 GLint bytesPerRow
, destRowStride
, srcRowStride
;
3983 const gl_format texFormat
= texImage
->TexFormat
->MesaFormat
;
3987 /* these should have been caught sooner */
3988 ASSERT((width
& 3) == 0 || width
== 2 || width
== 1);
3989 ASSERT((height
& 3) == 0 || height
== 2 || height
== 1);
3990 ASSERT((xoffset
& 3) == 0);
3991 ASSERT((yoffset
& 3) == 0);
3993 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3994 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
3996 "glCompressedTexSubImage2D");
4000 srcRowStride
= _mesa_compressed_row_stride(texFormat
, width
);
4001 src
= (const GLubyte
*) data
;
4003 destRowStride
= _mesa_compressed_row_stride(texFormat
, texImage
->Width
);
4004 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
4007 (GLubyte
*) texImage
->Data
);
4009 bytesPerRow
= srcRowStride
;
4012 for (i
= 0; i
< rows
; i
++) {
4013 MEMCPY(dest
, src
, bytesPerRow
);
4014 dest
+= destRowStride
;
4015 src
+= srcRowStride
;
4018 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
4023 * Fallback for Driver.CompressedTexSubImage3D()
4026 _mesa_store_compressed_texsubimage3d(GLcontext
*ctx
, GLenum target
,
4028 GLint xoffset
, GLint yoffset
, GLint zoffset
,
4029 GLsizei width
, GLsizei height
, GLsizei depth
,
4031 GLsizei imageSize
, const GLvoid
*data
,
4032 struct gl_texture_object
*texObj
,
4033 struct gl_texture_image
*texImage
)
4035 /* there are no compressed 3D texture formats yet */
4037 (void) target
; (void) level
;
4038 (void) xoffset
; (void) yoffset
; (void) zoffset
;
4039 (void) width
; (void) height
; (void) depth
;
4041 (void) imageSize
; (void) data
;