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"
68 #include "texformat.h"
81 * Texture image storage function.
83 typedef GLboolean (*StoreTexImageFunc
)(TEXSTORE_PARAMS
);
87 * Return GL_TRUE if the given image format is one that be converted
88 * to another format by swizzling.
91 can_swizzle(GLenum logicalBaseFormat
)
93 switch (logicalBaseFormat
) {
96 case GL_LUMINANCE_ALPHA
:
130 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO)
131 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO)
132 #define MAP3(x,y,z) MAP4(x, y, z, ZERO)
133 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
136 static const struct {
139 GLubyte from_rgba
[6];
140 } mappings
[MAX_IDX
] =
150 MAP4(ZERO
, ZERO
, ZERO
, 0),
181 MAP4(0, ZERO
, ZERO
, ONE
),
187 MAP4(ZERO
, 0, ZERO
, ONE
),
193 MAP4(ZERO
, ZERO
, 0, ONE
),
219 * Convert a GL image format enum to an IDX_* value (see above).
222 get_map_idx(GLenum value
)
225 case GL_LUMINANCE
: return IDX_LUMINANCE
;
226 case GL_ALPHA
: return IDX_ALPHA
;
227 case GL_INTENSITY
: return IDX_INTENSITY
;
228 case GL_LUMINANCE_ALPHA
: return IDX_LUMINANCE_ALPHA
;
229 case GL_RGB
: return IDX_RGB
;
230 case GL_RGBA
: return IDX_RGBA
;
231 case GL_RED
: return IDX_RED
;
232 case GL_GREEN
: return IDX_GREEN
;
233 case GL_BLUE
: return IDX_BLUE
;
234 case GL_BGR
: return IDX_BGR
;
235 case GL_BGRA
: return IDX_BGRA
;
236 case GL_ABGR_EXT
: return IDX_ABGR
;
238 _mesa_problem(NULL
, "Unexpected inFormat");
245 * When promoting texture formats (see below) we need to compute the
246 * mapping of dest components back to source components.
247 * This function does that.
248 * \param inFormat the incoming format of the texture
249 * \param outFormat the final texture format
250 * \return map[6] a full 6-component map
253 compute_component_mapping(GLenum inFormat
, GLenum outFormat
,
256 const int inFmt
= get_map_idx(inFormat
);
257 const int outFmt
= get_map_idx(outFormat
);
258 const GLubyte
*in2rgba
= mappings
[inFmt
].to_rgba
;
259 const GLubyte
*rgba2out
= mappings
[outFmt
].from_rgba
;
262 for (i
= 0; i
< 4; i
++)
263 map
[i
] = in2rgba
[rgba2out
[i
]];
269 _mesa_printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
270 inFormat, _mesa_lookup_enum_by_nr(inFormat),
271 outFormat, _mesa_lookup_enum_by_nr(outFormat),
282 #if !FEATURE_convolve
284 _mesa_adjust_image_for_convolution(GLcontext
*ctx
, GLuint dims
,
285 GLsizei
*srcWidth
, GLsizei
*srcHeight
)
293 * Make a temporary (color) texture image with GLfloat components.
294 * Apply all needed pixel unpacking and pixel transfer operations.
295 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
296 * Suppose the user specifies GL_LUMINANCE as the internal texture format
297 * but the graphics hardware doesn't support luminance textures. So, might
298 * use an RGB hardware format instead.
299 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
301 * \param ctx the rendering context
302 * \param dims image dimensions: 1, 2 or 3
303 * \param logicalBaseFormat basic texture derived from the user's
304 * internal texture format value
305 * \param textureBaseFormat the actual basic format of the texture
306 * \param srcWidth source image width
307 * \param srcHeight source image height
308 * \param srcDepth source image depth
309 * \param srcFormat source image format
310 * \param srcType source image type
311 * \param srcAddr source image address
312 * \param srcPacking source image pixel packing
313 * \return resulting image with format = textureBaseFormat and type = GLfloat.
316 make_temp_float_image(GLcontext
*ctx
, GLuint dims
,
317 GLenum logicalBaseFormat
,
318 GLenum textureBaseFormat
,
319 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
320 GLenum srcFormat
, GLenum srcType
,
321 const GLvoid
*srcAddr
,
322 const struct gl_pixelstore_attrib
*srcPacking
)
324 GLuint transferOps
= ctx
->_ImageTransferState
;
327 ASSERT(dims
>= 1 && dims
<= 3);
329 ASSERT(logicalBaseFormat
== GL_RGBA
||
330 logicalBaseFormat
== GL_RGB
||
331 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
332 logicalBaseFormat
== GL_LUMINANCE
||
333 logicalBaseFormat
== GL_ALPHA
||
334 logicalBaseFormat
== GL_INTENSITY
||
335 logicalBaseFormat
== GL_COLOR_INDEX
||
336 logicalBaseFormat
== GL_DEPTH_COMPONENT
);
338 ASSERT(textureBaseFormat
== GL_RGBA
||
339 textureBaseFormat
== GL_RGB
||
340 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
341 textureBaseFormat
== GL_LUMINANCE
||
342 textureBaseFormat
== GL_ALPHA
||
343 textureBaseFormat
== GL_INTENSITY
||
344 textureBaseFormat
== GL_COLOR_INDEX
||
345 textureBaseFormat
== GL_DEPTH_COMPONENT
);
347 /* conventional color image */
349 if ((dims
== 1 && ctx
->Pixel
.Convolution1DEnabled
) ||
350 (dims
>= 2 && ctx
->Pixel
.Convolution2DEnabled
) ||
351 (dims
>= 2 && ctx
->Pixel
.Separable2DEnabled
)) {
352 /* need image convolution */
353 const GLuint preConvTransferOps
354 = (transferOps
& IMAGE_PRE_CONVOLUTION_BITS
) | IMAGE_CLAMP_BIT
;
355 const GLuint postConvTransferOps
356 = (transferOps
& IMAGE_POST_CONVOLUTION_BITS
) | IMAGE_CLAMP_BIT
;
358 GLint convWidth
, convHeight
;
361 /* pre-convolution image buffer (3D) */
362 tempImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
363 * 4 * sizeof(GLfloat
));
367 /* post-convolution image buffer (2D) */
368 convImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
369 * 4 * sizeof(GLfloat
));
371 _mesa_free(tempImage
);
375 /* loop over 3D image slices */
376 for (img
= 0; img
< srcDepth
; img
++) {
377 GLfloat
*dst
= tempImage
+ img
* (srcWidth
* srcHeight
* 4);
379 /* unpack and do transfer ops up to convolution */
380 for (row
= 0; row
< srcHeight
; row
++) {
381 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
382 srcAddr
, srcWidth
, srcHeight
,
383 srcFormat
, srcType
, img
, row
, 0);
384 _mesa_unpack_color_span_float(ctx
, srcWidth
, GL_RGBA
, dst
,
385 srcFormat
, srcType
, src
,
391 /* size after optional convolution */
392 convWidth
= srcWidth
;
393 convHeight
= srcHeight
;
398 GLfloat
*src
= tempImage
+ img
* (srcWidth
* srcHeight
* 4);
400 ASSERT(ctx
->Pixel
.Convolution1DEnabled
);
401 _mesa_convolve_1d_image(ctx
, &convWidth
, src
, convImage
);
404 if (ctx
->Pixel
.Convolution2DEnabled
) {
405 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
409 ASSERT(ctx
->Pixel
.Separable2DEnabled
);
410 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
416 /* do post-convolution transfer and pack into tempImage */
418 const GLint logComponents
419 = _mesa_components_in_format(logicalBaseFormat
);
420 const GLfloat
*src
= convImage
;
421 GLfloat
*dst
= tempImage
+ img
* (convWidth
* convHeight
* 4);
422 for (row
= 0; row
< convHeight
; row
++) {
423 _mesa_pack_rgba_span_float(ctx
, convWidth
,
424 (GLfloat (*)[4]) src
,
425 logicalBaseFormat
, GL_FLOAT
,
426 dst
, &ctx
->DefaultPacking
,
427 postConvTransferOps
);
428 src
+= convWidth
* 4;
429 dst
+= convWidth
* logComponents
;
432 } /* loop over 3D image slices */
434 _mesa_free(convImage
);
436 /* might need these below */
437 srcWidth
= convWidth
;
438 srcHeight
= convHeight
;
442 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
443 const GLint srcStride
=
444 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
448 tempImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
449 * components
* sizeof(GLfloat
));
454 for (img
= 0; img
< srcDepth
; img
++) {
456 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
460 for (row
= 0; row
< srcHeight
; row
++) {
461 _mesa_unpack_color_span_float(ctx
, srcWidth
, logicalBaseFormat
,
462 dst
, srcFormat
, srcType
, src
,
463 srcPacking
, transferOps
);
464 dst
+= srcWidth
* components
;
470 if (logicalBaseFormat
!= textureBaseFormat
) {
472 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
473 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
478 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
479 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
480 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
482 /* The actual texture format should have at least as many components
483 * as the logical texture format.
485 ASSERT(texComponents
>= logComponents
);
487 newImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
488 * texComponents
* sizeof(GLfloat
));
490 _mesa_free(tempImage
);
494 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
496 n
= srcWidth
* srcHeight
* srcDepth
;
497 for (i
= 0; i
< n
; i
++) {
499 for (k
= 0; k
< texComponents
; k
++) {
502 newImage
[i
* texComponents
+ k
] = 0.0F
;
504 newImage
[i
* texComponents
+ k
] = 1.0F
;
506 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
510 _mesa_free(tempImage
);
511 tempImage
= newImage
;
519 * Make a temporary (color) texture image with GLchan components.
520 * Apply all needed pixel unpacking and pixel transfer operations.
521 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
522 * Suppose the user specifies GL_LUMINANCE as the internal texture format
523 * but the graphics hardware doesn't support luminance textures. So, might
524 * use an RGB hardware format instead.
525 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
527 * \param ctx the rendering context
528 * \param dims image dimensions: 1, 2 or 3
529 * \param logicalBaseFormat basic texture derived from the user's
530 * internal texture format value
531 * \param textureBaseFormat the actual basic format of the texture
532 * \param srcWidth source image width
533 * \param srcHeight source image height
534 * \param srcDepth source image depth
535 * \param srcFormat source image format
536 * \param srcType source image type
537 * \param srcAddr source image address
538 * \param srcPacking source image pixel packing
539 * \return resulting image with format = textureBaseFormat and type = GLchan.
542 _mesa_make_temp_chan_image(GLcontext
*ctx
, GLuint dims
,
543 GLenum logicalBaseFormat
,
544 GLenum textureBaseFormat
,
545 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
546 GLenum srcFormat
, GLenum srcType
,
547 const GLvoid
*srcAddr
,
548 const struct gl_pixelstore_attrib
*srcPacking
)
550 GLuint transferOps
= ctx
->_ImageTransferState
;
551 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
552 GLboolean freeSrcImage
= GL_FALSE
;
554 GLchan
*tempImage
, *dst
;
556 ASSERT(dims
>= 1 && dims
<= 3);
558 ASSERT(logicalBaseFormat
== GL_RGBA
||
559 logicalBaseFormat
== GL_RGB
||
560 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
561 logicalBaseFormat
== GL_LUMINANCE
||
562 logicalBaseFormat
== GL_ALPHA
||
563 logicalBaseFormat
== GL_INTENSITY
);
565 ASSERT(textureBaseFormat
== GL_RGBA
||
566 textureBaseFormat
== GL_RGB
||
567 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
568 textureBaseFormat
== GL_LUMINANCE
||
569 textureBaseFormat
== GL_ALPHA
||
570 textureBaseFormat
== GL_INTENSITY
);
573 if ((dims
== 1 && ctx
->Pixel
.Convolution1DEnabled
) ||
574 (dims
>= 2 && ctx
->Pixel
.Convolution2DEnabled
) ||
575 (dims
>= 2 && ctx
->Pixel
.Separable2DEnabled
)) {
576 /* get convolved image */
577 GLfloat
*convImage
= make_temp_float_image(ctx
, dims
,
580 srcWidth
, srcHeight
, srcDepth
,
582 srcAddr
, srcPacking
);
585 /* the convolved image is our new source image */
587 srcFormat
= logicalBaseFormat
;
589 srcPacking
= &ctx
->DefaultPacking
;
590 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
592 freeSrcImage
= GL_TRUE
;
596 /* unpack and transfer the source image */
597 tempImage
= (GLchan
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
598 * components
* sizeof(GLchan
));
603 for (img
= 0; img
< srcDepth
; img
++) {
604 const GLint srcStride
=
605 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
607 (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
611 for (row
= 0; row
< srcHeight
; row
++) {
612 _mesa_unpack_color_span_chan(ctx
, srcWidth
, logicalBaseFormat
, dst
,
613 srcFormat
, srcType
, src
, srcPacking
,
615 dst
+= srcWidth
* components
;
620 /* If we made a temporary image for convolution, free it here */
622 _mesa_free((void *) srcAddr
);
625 if (logicalBaseFormat
!= textureBaseFormat
) {
626 /* one more conversion step */
627 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
628 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
633 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
634 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
635 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
637 /* The actual texture format should have at least as many components
638 * as the logical texture format.
640 ASSERT(texComponents
>= logComponents
);
642 newImage
= (GLchan
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
643 * texComponents
* sizeof(GLchan
));
645 _mesa_free(tempImage
);
649 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
651 n
= srcWidth
* srcHeight
* srcDepth
;
652 for (i
= 0; i
< n
; i
++) {
654 for (k
= 0; k
< texComponents
; k
++) {
657 newImage
[i
* texComponents
+ k
] = 0;
659 newImage
[i
* texComponents
+ k
] = CHAN_MAX
;
661 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
665 _mesa_free(tempImage
);
666 tempImage
= newImage
;
674 * Copy GLubyte pixels from <src> to <dst> with swizzling.
675 * \param dst destination pixels
676 * \param dstComponents number of color components in destination pixels
677 * \param src source pixels
678 * \param srcComponents number of color components in source pixels
679 * \param map the swizzle mapping. map[X] says where to find the X component
680 * in the source image's pixels. For example, if the source image
681 * is GL_BGRA and X = red, map[0] yields 2.
682 * \param count number of pixels to copy/swizzle.
685 swizzle_copy(GLubyte
*dst
, GLuint dstComponents
, const GLubyte
*src
,
686 GLuint srcComponents
, const GLubyte
*map
, GLuint count
)
688 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
691 for (i = 0; i < count; i++) { \
693 if (srcComps == 4) { \
694 COPY_4UBV(tmp, src); \
697 for (j = 0; j < srcComps; j++) { \
702 for (j = 0; j < dstComps; j++) { \
703 dst[j] = tmp[map[j]]; \
714 ASSERT(srcComponents
<= 4);
715 ASSERT(dstComponents
<= 4);
717 switch (dstComponents
) {
719 switch (srcComponents
) {
721 SWZ_CPY(dst
, src
, count
, 4, 4);
724 SWZ_CPY(dst
, src
, count
, 4, 3);
727 SWZ_CPY(dst
, src
, count
, 4, 2);
730 SWZ_CPY(dst
, src
, count
, 4, 1);
737 switch (srcComponents
) {
739 SWZ_CPY(dst
, src
, count
, 3, 4);
742 SWZ_CPY(dst
, src
, count
, 3, 3);
745 SWZ_CPY(dst
, src
, count
, 3, 2);
748 SWZ_CPY(dst
, src
, count
, 3, 1);
755 switch (srcComponents
) {
757 SWZ_CPY(dst
, src
, count
, 2, 4);
760 SWZ_CPY(dst
, src
, count
, 2, 3);
763 SWZ_CPY(dst
, src
, count
, 2, 2);
766 SWZ_CPY(dst
, src
, count
, 2, 1);
773 switch (srcComponents
) {
775 SWZ_CPY(dst
, src
, count
, 1, 4);
778 SWZ_CPY(dst
, src
, count
, 1, 3);
781 SWZ_CPY(dst
, src
, count
, 1, 2);
784 SWZ_CPY(dst
, src
, count
, 1, 1);
798 static const GLubyte map_identity
[6] = { 0, 1, 2, 3, ZERO
, ONE
};
799 static const GLubyte map_3210
[6] = { 3, 2, 1, 0, ZERO
, ONE
};
801 /* Deal with the _REV input types:
803 static const GLubyte
*
804 type_mapping( GLenum srcType
)
808 case GL_UNSIGNED_BYTE
:
810 case GL_UNSIGNED_INT_8_8_8_8
:
811 return _mesa_little_endian() ? map_3210
: map_identity
;
812 case GL_UNSIGNED_INT_8_8_8_8_REV
:
813 return _mesa_little_endian() ? map_identity
: map_3210
;
819 /* Mapping required if input type is
821 static const GLubyte
*
822 byteswap_mapping( GLboolean swapBytes
,
830 case GL_UNSIGNED_BYTE
:
832 case GL_UNSIGNED_INT_8_8_8_8
:
833 case GL_UNSIGNED_INT_8_8_8_8_REV
:
843 * Transfer a GLubyte texture image with component swizzling.
846 _mesa_swizzle_ubyte_image(GLcontext
*ctx
,
851 GLenum baseInternalFormat
,
853 const GLubyte
*rgba2dst
,
854 GLuint dstComponents
,
857 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
859 const GLuint
*dstImageOffsets
,
861 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
862 const GLvoid
*srcAddr
,
863 const struct gl_pixelstore_attrib
*srcPacking
)
865 GLint srcComponents
= _mesa_components_in_format(srcFormat
);
866 const GLubyte
*srctype2ubyte
, *swap
;
867 GLubyte map
[4], src2base
[6], base2rgba
[6];
869 const GLint srcRowStride
=
870 _mesa_image_row_stride(srcPacking
, srcWidth
,
871 srcFormat
, GL_UNSIGNED_BYTE
);
872 const GLint srcImageStride
873 = _mesa_image_image_stride(srcPacking
, srcWidth
, srcHeight
, srcFormat
,
875 const GLubyte
*srcImage
876 = (const GLubyte
*) _mesa_image_address(dimensions
, srcPacking
, srcAddr
,
877 srcWidth
, srcHeight
, srcFormat
,
878 GL_UNSIGNED_BYTE
, 0, 0, 0);
882 /* Translate from src->baseInternal->GL_RGBA->dst. This will
883 * correctly deal with RGBA->RGB->RGBA conversions where the final
884 * A value must be 0xff regardless of the incoming alpha values.
886 compute_component_mapping(srcFormat
, baseInternalFormat
, src2base
);
887 compute_component_mapping(baseInternalFormat
, GL_RGBA
, base2rgba
);
888 swap
= byteswap_mapping(srcPacking
->SwapBytes
, srcType
);
889 srctype2ubyte
= type_mapping(srcType
);
892 for (i
= 0; i
< 4; i
++)
893 map
[i
] = srctype2ubyte
[swap
[src2base
[base2rgba
[rgba2dst
[i
]]]]];
895 /* _mesa_printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */
897 if (srcComponents
== dstComponents
&&
898 srcRowStride
== dstRowStride
&&
899 srcRowStride
== srcWidth
* srcComponents
&&
901 /* 1 and 2D images only */
902 GLubyte
*dstImage
= (GLubyte
*) dstAddr
903 + dstYoffset
* dstRowStride
904 + dstXoffset
* dstComponents
;
905 swizzle_copy(dstImage
, dstComponents
, srcImage
, srcComponents
, map
,
906 srcWidth
* srcHeight
);
910 for (img
= 0; img
< srcDepth
; img
++) {
911 const GLubyte
*srcRow
= srcImage
;
912 GLubyte
*dstRow
= (GLubyte
*) dstAddr
913 + dstImageOffsets
[dstZoffset
+ img
] * dstComponents
914 + dstYoffset
* dstRowStride
915 + dstXoffset
* dstComponents
;
916 for (row
= 0; row
< srcHeight
; row
++) {
917 swizzle_copy(dstRow
, dstComponents
, srcRow
, srcComponents
, map
, srcWidth
);
918 dstRow
+= dstRowStride
;
919 srcRow
+= srcRowStride
;
921 srcImage
+= srcImageStride
;
928 * Teximage storage routine for when a simple memcpy will do.
929 * No pixel transfer operations or special texel encodings allowed.
930 * 1D, 2D and 3D images supported.
933 memcpy_texture(GLcontext
*ctx
,
937 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
939 const GLuint
*dstImageOffsets
,
940 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
941 GLenum srcFormat
, GLenum srcType
,
942 const GLvoid
*srcAddr
,
943 const struct gl_pixelstore_attrib
*srcPacking
)
945 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
947 const GLint srcImageStride
= _mesa_image_image_stride(srcPacking
,
948 srcWidth
, srcHeight
, srcFormat
, srcType
);
949 const GLubyte
*srcImage
= (const GLubyte
*) _mesa_image_address(dimensions
,
950 srcPacking
, srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, 0, 0, 0);
951 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
952 const GLint bytesPerRow
= srcWidth
* texelBytes
;
955 /* XXX update/re-enable for dstImageOffsets array */
956 const GLint bytesPerImage
= srcHeight
* bytesPerRow
;
957 const GLint bytesPerTexture
= srcDepth
* bytesPerImage
;
958 GLubyte
*dstImage
= (GLubyte
*) dstAddr
959 + dstZoffset
* dstImageStride
960 + dstYoffset
* dstRowStride
961 + dstXoffset
* texelBytes
;
963 if (dstRowStride
== srcRowStride
&&
964 dstRowStride
== bytesPerRow
&&
965 ((dstImageStride
== srcImageStride
&&
966 dstImageStride
== bytesPerImage
) ||
969 ctx
->Driver
.TextureMemCpy(dstImage
, srcImage
, bytesPerTexture
);
974 for (img
= 0; img
< srcDepth
; img
++) {
975 const GLubyte
*srcRow
= srcImage
;
976 GLubyte
*dstRow
= dstImage
;
977 for (row
= 0; row
< srcHeight
; row
++) {
978 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
979 dstRow
+= dstRowStride
;
980 srcRow
+= srcRowStride
;
982 srcImage
+= srcImageStride
;
983 dstImage
+= dstImageStride
;
989 for (img
= 0; img
< srcDepth
; img
++) {
990 const GLubyte
*srcRow
= srcImage
;
991 GLubyte
*dstRow
= (GLubyte
*) dstAddr
992 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
993 + dstYoffset
* dstRowStride
994 + dstXoffset
* texelBytes
;
995 for (row
= 0; row
< srcHeight
; row
++) {
996 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
997 dstRow
+= dstRowStride
;
998 srcRow
+= srcRowStride
;
1000 srcImage
+= srcImageStride
;
1007 * Store a 32-bit integer depth component texture image.
1010 _mesa_texstore_z32(TEXSTORE_PARAMS
)
1012 const GLuint depthScale
= 0xffffffff;
1013 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1015 ASSERT(dstFormat
== MESA_FORMAT_Z32
);
1016 ASSERT(texelBytes
== sizeof(GLuint
));
1018 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1019 ctx
->Pixel
.DepthBias
== 0.0f
&&
1020 !srcPacking
->SwapBytes
&&
1021 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1022 srcFormat
== GL_DEPTH_COMPONENT
&&
1023 srcType
== GL_UNSIGNED_INT
) {
1024 /* simple memcpy path */
1025 memcpy_texture(ctx
, dims
,
1026 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1029 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1030 srcAddr
, srcPacking
);
1035 for (img
= 0; img
< srcDepth
; img
++) {
1036 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1037 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1038 + dstYoffset
* dstRowStride
1039 + dstXoffset
* texelBytes
;
1040 for (row
= 0; row
< srcHeight
; row
++) {
1041 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1042 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1043 _mesa_unpack_depth_span(ctx
, srcWidth
,
1044 GL_UNSIGNED_INT
, (GLuint
*) dstRow
,
1045 depthScale
, srcType
, src
, srcPacking
);
1046 dstRow
+= dstRowStride
;
1056 * Store a 16-bit integer depth component texture image.
1059 _mesa_texstore_z16(TEXSTORE_PARAMS
)
1061 const GLuint depthScale
= 0xffff;
1062 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1064 ASSERT(dstFormat
== MESA_FORMAT_Z16
);
1065 ASSERT(texelBytes
== sizeof(GLushort
));
1067 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1068 ctx
->Pixel
.DepthBias
== 0.0f
&&
1069 !srcPacking
->SwapBytes
&&
1070 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1071 srcFormat
== GL_DEPTH_COMPONENT
&&
1072 srcType
== GL_UNSIGNED_SHORT
) {
1073 /* simple memcpy path */
1074 memcpy_texture(ctx
, dims
,
1075 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1078 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1079 srcAddr
, srcPacking
);
1084 for (img
= 0; img
< srcDepth
; img
++) {
1085 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1086 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1087 + dstYoffset
* dstRowStride
1088 + dstXoffset
* texelBytes
;
1089 for (row
= 0; row
< srcHeight
; row
++) {
1090 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1091 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1092 GLushort
*dst16
= (GLushort
*) dstRow
;
1093 _mesa_unpack_depth_span(ctx
, srcWidth
,
1094 GL_UNSIGNED_SHORT
, dst16
, depthScale
,
1095 srcType
, src
, srcPacking
);
1096 dstRow
+= dstRowStride
;
1105 * Store an rgb565 or rgb565_rev texture image.
1108 _mesa_texstore_rgb565(TEXSTORE_PARAMS
)
1110 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1111 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1113 ASSERT(dstFormat
== MESA_FORMAT_RGB565
||
1114 dstFormat
== MESA_FORMAT_RGB565_REV
);
1115 ASSERT(texelBytes
== 2);
1117 if (!ctx
->_ImageTransferState
&&
1118 !srcPacking
->SwapBytes
&&
1119 dstFormat
== MESA_FORMAT_RGB565
&&
1120 baseInternalFormat
== GL_RGB
&&
1121 srcFormat
== GL_RGB
&&
1122 srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1123 /* simple memcpy path */
1124 memcpy_texture(ctx
, dims
,
1125 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1128 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1129 srcAddr
, srcPacking
);
1131 else if (!ctx
->_ImageTransferState
&&
1132 !srcPacking
->SwapBytes
&&
1133 baseInternalFormat
== GL_RGB
&&
1134 srcFormat
== GL_RGB
&&
1135 srcType
== GL_UNSIGNED_BYTE
&&
1137 /* do optimized tex store */
1138 const GLint srcRowStride
=
1139 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1140 const GLubyte
*src
= (const GLubyte
*)
1141 _mesa_image_address(dims
, srcPacking
, srcAddr
, srcWidth
, srcHeight
,
1142 srcFormat
, srcType
, 0, 0, 0);
1143 GLubyte
*dst
= (GLubyte
*) dstAddr
1144 + dstYoffset
* dstRowStride
1145 + dstXoffset
* texelBytes
;
1147 for (row
= 0; row
< srcHeight
; row
++) {
1148 const GLubyte
*srcUB
= (const GLubyte
*) src
;
1149 GLushort
*dstUS
= (GLushort
*) dst
;
1150 /* check for byteswapped format */
1151 if (dstFormat
== MESA_FORMAT_RGB565
) {
1152 for (col
= 0; col
< srcWidth
; col
++) {
1153 dstUS
[col
] = PACK_COLOR_565( srcUB
[0], srcUB
[1], srcUB
[2] );
1158 for (col
= 0; col
< srcWidth
; col
++) {
1159 dstUS
[col
] = PACK_COLOR_565_REV( srcUB
[0], srcUB
[1], srcUB
[2] );
1163 dst
+= dstRowStride
;
1164 src
+= srcRowStride
;
1169 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1172 srcWidth
, srcHeight
, srcDepth
,
1173 srcFormat
, srcType
, srcAddr
,
1175 const GLchan
*src
= tempImage
;
1176 GLint img
, row
, col
;
1179 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1180 for (img
= 0; img
< srcDepth
; img
++) {
1181 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1182 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1183 + dstYoffset
* dstRowStride
1184 + dstXoffset
* texelBytes
;
1185 for (row
= 0; row
< srcHeight
; row
++) {
1186 GLushort
*dstUS
= (GLushort
*) dstRow
;
1187 /* check for byteswapped format */
1188 if (dstFormat
== MESA_FORMAT_RGB565
) {
1189 for (col
= 0; col
< srcWidth
; col
++) {
1190 dstUS
[col
] = PACK_COLOR_565( CHAN_TO_UBYTE(src
[RCOMP
]),
1191 CHAN_TO_UBYTE(src
[GCOMP
]),
1192 CHAN_TO_UBYTE(src
[BCOMP
]) );
1197 for (col
= 0; col
< srcWidth
; col
++) {
1198 dstUS
[col
] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1199 CHAN_TO_UBYTE(src
[GCOMP
]),
1200 CHAN_TO_UBYTE(src
[BCOMP
]) );
1204 dstRow
+= dstRowStride
;
1207 _mesa_free((void *) tempImage
);
1214 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1217 _mesa_texstore_rgba8888(TEXSTORE_PARAMS
)
1219 const GLboolean littleEndian
= _mesa_little_endian();
1220 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1221 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1223 ASSERT(dstFormat
== MESA_FORMAT_RGBA8888
||
1224 dstFormat
== MESA_FORMAT_RGBA8888_REV
);
1225 ASSERT(texelBytes
== 4);
1227 if (!ctx
->_ImageTransferState
&&
1228 !srcPacking
->SwapBytes
&&
1229 dstFormat
== MESA_FORMAT_RGBA8888
&&
1230 baseInternalFormat
== GL_RGBA
&&
1231 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1232 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1233 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1234 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
))) {
1235 /* simple memcpy path */
1236 memcpy_texture(ctx
, dims
,
1237 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1240 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1241 srcAddr
, srcPacking
);
1243 else if (!ctx
->_ImageTransferState
&&
1244 !srcPacking
->SwapBytes
&&
1245 dstFormat
== MESA_FORMAT_RGBA8888_REV
&&
1246 baseInternalFormat
== GL_RGBA
&&
1247 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1248 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1249 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1250 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
))) {
1251 /* simple memcpy path */
1252 memcpy_texture(ctx
, dims
,
1253 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1256 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1257 srcAddr
, srcPacking
);
1259 else if (!ctx
->_ImageTransferState
&&
1260 (srcType
== GL_UNSIGNED_BYTE
||
1261 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1262 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1263 can_swizzle(baseInternalFormat
) &&
1264 can_swizzle(srcFormat
)) {
1268 /* dstmap - how to swizzle from RGBA to dst format:
1270 if ((littleEndian
&& dstFormat
== MESA_FORMAT_RGBA8888
) ||
1271 (!littleEndian
&& dstFormat
== MESA_FORMAT_RGBA8888_REV
)) {
1284 _mesa_swizzle_ubyte_image(ctx
, dims
,
1289 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1290 dstRowStride
, dstImageOffsets
,
1291 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1296 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1299 srcWidth
, srcHeight
, srcDepth
,
1300 srcFormat
, srcType
, srcAddr
,
1302 const GLchan
*src
= tempImage
;
1303 GLint img
, row
, col
;
1306 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1307 for (img
= 0; img
< srcDepth
; img
++) {
1308 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1309 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1310 + dstYoffset
* dstRowStride
1311 + dstXoffset
* texelBytes
;
1312 for (row
= 0; row
< srcHeight
; row
++) {
1313 GLuint
*dstUI
= (GLuint
*) dstRow
;
1314 if (dstFormat
== MESA_FORMAT_RGBA8888
) {
1315 for (col
= 0; col
< srcWidth
; col
++) {
1316 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[RCOMP
]),
1317 CHAN_TO_UBYTE(src
[GCOMP
]),
1318 CHAN_TO_UBYTE(src
[BCOMP
]),
1319 CHAN_TO_UBYTE(src
[ACOMP
]) );
1324 for (col
= 0; col
< srcWidth
; col
++) {
1325 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1326 CHAN_TO_UBYTE(src
[GCOMP
]),
1327 CHAN_TO_UBYTE(src
[BCOMP
]),
1328 CHAN_TO_UBYTE(src
[ACOMP
]) );
1332 dstRow
+= dstRowStride
;
1335 _mesa_free((void *) tempImage
);
1342 _mesa_texstore_argb8888(TEXSTORE_PARAMS
)
1344 const GLboolean littleEndian
= _mesa_little_endian();
1345 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1346 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1348 ASSERT(dstFormat
== MESA_FORMAT_ARGB8888
||
1349 dstFormat
== MESA_FORMAT_ARGB8888_REV
);
1350 ASSERT(texelBytes
== 4);
1352 if (!ctx
->_ImageTransferState
&&
1353 !srcPacking
->SwapBytes
&&
1354 dstFormat
== MESA_FORMAT_ARGB8888
&&
1355 baseInternalFormat
== GL_RGBA
&&
1356 srcFormat
== GL_BGRA
&&
1357 ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1358 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
1359 /* simple memcpy path (little endian) */
1360 memcpy_texture(ctx
, dims
,
1361 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1364 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1365 srcAddr
, srcPacking
);
1367 else if (!ctx
->_ImageTransferState
&&
1368 !srcPacking
->SwapBytes
&&
1369 dstFormat
== MESA_FORMAT_ARGB8888_REV
&&
1370 baseInternalFormat
== GL_RGBA
&&
1371 srcFormat
== GL_BGRA
&&
1372 ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1373 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
1374 /* simple memcpy path (big endian) */
1375 memcpy_texture(ctx
, dims
,
1376 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1379 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1380 srcAddr
, srcPacking
);
1382 else if (!ctx
->_ImageTransferState
&&
1383 !srcPacking
->SwapBytes
&&
1384 dstFormat
== MESA_FORMAT_ARGB8888
&&
1385 srcFormat
== GL_RGB
&&
1386 (baseInternalFormat
== GL_RGBA
||
1387 baseInternalFormat
== GL_RGB
) &&
1388 srcType
== GL_UNSIGNED_BYTE
) {
1390 for (img
= 0; img
< srcDepth
; img
++) {
1391 const GLint srcRowStride
=
1392 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1393 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1394 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1395 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1396 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1397 + dstYoffset
* dstRowStride
1398 + dstXoffset
* texelBytes
;
1399 for (row
= 0; row
< srcHeight
; row
++) {
1400 GLuint
*d4
= (GLuint
*) dstRow
;
1401 for (col
= 0; col
< srcWidth
; col
++) {
1402 d4
[col
] = PACK_COLOR_8888(0xff,
1403 srcRow
[col
* 3 + RCOMP
],
1404 srcRow
[col
* 3 + GCOMP
],
1405 srcRow
[col
* 3 + BCOMP
]);
1407 dstRow
+= dstRowStride
;
1408 srcRow
+= srcRowStride
;
1412 else if (!ctx
->_ImageTransferState
&&
1413 !srcPacking
->SwapBytes
&&
1414 dstFormat
== MESA_FORMAT_ARGB8888
&&
1415 srcFormat
== GL_RGBA
&&
1416 baseInternalFormat
== GL_RGBA
&&
1417 srcType
== GL_UNSIGNED_BYTE
) {
1418 /* same as above case, but src data has alpha too */
1419 GLint img
, row
, col
;
1420 /* For some reason, streaming copies to write-combined regions
1421 * are extremely sensitive to the characteristics of how the
1422 * source data is retrieved. By reordering the source reads to
1423 * be in-order, the speed of this operation increases by half.
1424 * Strangely the same isn't required for the RGB path, above.
1426 for (img
= 0; img
< srcDepth
; img
++) {
1427 const GLint srcRowStride
=
1428 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1429 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1430 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1431 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1432 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1433 + dstYoffset
* dstRowStride
1434 + dstXoffset
* texelBytes
;
1435 for (row
= 0; row
< srcHeight
; row
++) {
1436 GLuint
*d4
= (GLuint
*) dstRow
;
1437 for (col
= 0; col
< srcWidth
; col
++) {
1438 d4
[col
] = PACK_COLOR_8888(srcRow
[col
* 4 + ACOMP
],
1439 srcRow
[col
* 4 + RCOMP
],
1440 srcRow
[col
* 4 + GCOMP
],
1441 srcRow
[col
* 4 + BCOMP
]);
1443 dstRow
+= dstRowStride
;
1444 srcRow
+= srcRowStride
;
1448 else if (!ctx
->_ImageTransferState
&&
1449 (srcType
== GL_UNSIGNED_BYTE
||
1450 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1451 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1452 can_swizzle(baseInternalFormat
) &&
1453 can_swizzle(srcFormat
)) {
1457 /* dstmap - how to swizzle from RGBA to dst format:
1459 if ((littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888
) ||
1460 (!littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888_REV
)) {
1461 dstmap
[3] = 3; /* alpha */
1462 dstmap
[2] = 0; /* red */
1463 dstmap
[1] = 1; /* green */
1464 dstmap
[0] = 2; /* blue */
1467 assert((littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888_REV
) ||
1468 (!littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888
));
1475 _mesa_swizzle_ubyte_image(ctx
, dims
,
1481 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1484 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1489 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1492 srcWidth
, srcHeight
, srcDepth
,
1493 srcFormat
, srcType
, srcAddr
,
1495 const GLchan
*src
= tempImage
;
1496 GLint img
, row
, col
;
1499 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1500 for (img
= 0; img
< srcDepth
; img
++) {
1501 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1502 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1503 + dstYoffset
* dstRowStride
1504 + dstXoffset
* texelBytes
;
1505 for (row
= 0; row
< srcHeight
; row
++) {
1506 GLuint
*dstUI
= (GLuint
*) dstRow
;
1507 if (dstFormat
== MESA_FORMAT_ARGB8888
) {
1508 for (col
= 0; col
< srcWidth
; col
++) {
1509 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[ACOMP
]),
1510 CHAN_TO_UBYTE(src
[RCOMP
]),
1511 CHAN_TO_UBYTE(src
[GCOMP
]),
1512 CHAN_TO_UBYTE(src
[BCOMP
]) );
1517 for (col
= 0; col
< srcWidth
; col
++) {
1518 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1519 CHAN_TO_UBYTE(src
[RCOMP
]),
1520 CHAN_TO_UBYTE(src
[GCOMP
]),
1521 CHAN_TO_UBYTE(src
[BCOMP
]) );
1525 dstRow
+= dstRowStride
;
1528 _mesa_free((void *) tempImage
);
1535 _mesa_texstore_rgb888(TEXSTORE_PARAMS
)
1537 const GLboolean littleEndian
= _mesa_little_endian();
1538 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1539 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1541 ASSERT(dstFormat
== MESA_FORMAT_RGB888
);
1542 ASSERT(texelBytes
== 3);
1544 if (!ctx
->_ImageTransferState
&&
1545 !srcPacking
->SwapBytes
&&
1546 baseInternalFormat
== GL_RGB
&&
1547 srcFormat
== GL_BGR
&&
1548 srcType
== GL_UNSIGNED_BYTE
&&
1550 /* simple memcpy path */
1551 memcpy_texture(ctx
, dims
,
1552 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1555 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1556 srcAddr
, srcPacking
);
1558 else if (!ctx
->_ImageTransferState
&&
1559 !srcPacking
->SwapBytes
&&
1560 srcFormat
== GL_RGBA
&&
1561 srcType
== GL_UNSIGNED_BYTE
) {
1562 /* extract RGB from RGBA */
1563 GLint img
, row
, col
;
1564 for (img
= 0; img
< srcDepth
; img
++) {
1565 const GLint srcRowStride
=
1566 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1567 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1568 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1569 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1570 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1571 + dstYoffset
* dstRowStride
1572 + dstXoffset
* texelBytes
;
1573 for (row
= 0; row
< srcHeight
; row
++) {
1574 for (col
= 0; col
< srcWidth
; col
++) {
1575 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + BCOMP
];
1576 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1577 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + RCOMP
];
1579 dstRow
+= dstRowStride
;
1580 srcRow
+= srcRowStride
;
1584 else if (!ctx
->_ImageTransferState
&&
1585 srcType
== GL_UNSIGNED_BYTE
&&
1586 can_swizzle(baseInternalFormat
) &&
1587 can_swizzle(srcFormat
)) {
1591 /* dstmap - how to swizzle from RGBA to dst format:
1596 dstmap
[3] = ONE
; /* ? */
1598 _mesa_swizzle_ubyte_image(ctx
, dims
,
1603 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1604 dstRowStride
, dstImageOffsets
,
1605 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1610 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1613 srcWidth
, srcHeight
, srcDepth
,
1614 srcFormat
, srcType
, srcAddr
,
1616 const GLchan
*src
= (const GLchan
*) tempImage
;
1617 GLint img
, row
, col
;
1620 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1621 for (img
= 0; img
< srcDepth
; img
++) {
1622 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1623 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1624 + dstYoffset
* dstRowStride
1625 + dstXoffset
* texelBytes
;
1626 for (row
= 0; row
< srcHeight
; row
++) {
1629 for (col
= 0; col
< srcWidth
; col
++) {
1630 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1631 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1632 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1637 for (col
= 0; col
< srcWidth
; col
++) {
1638 dstRow
[col
* 3 + 0] = srcUB
[BCOMP
];
1639 dstRow
[col
* 3 + 1] = srcUB
[GCOMP
];
1640 dstRow
[col
* 3 + 2] = srcUB
[RCOMP
];
1645 for (col
= 0; col
< srcWidth
; col
++) {
1646 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[BCOMP
]);
1647 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1648 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[RCOMP
]);
1652 dstRow
+= dstRowStride
;
1655 _mesa_free((void *) tempImage
);
1662 _mesa_texstore_bgr888(TEXSTORE_PARAMS
)
1664 const GLboolean littleEndian
= _mesa_little_endian();
1665 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1666 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1668 ASSERT(dstFormat
== MESA_FORMAT_BGR888
);
1669 ASSERT(texelBytes
== 3);
1671 if (!ctx
->_ImageTransferState
&&
1672 !srcPacking
->SwapBytes
&&
1673 baseInternalFormat
== GL_RGB
&&
1674 srcFormat
== GL_RGB
&&
1675 srcType
== GL_UNSIGNED_BYTE
&&
1677 /* simple memcpy path */
1678 memcpy_texture(ctx
, dims
,
1679 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1682 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1683 srcAddr
, srcPacking
);
1685 else if (!ctx
->_ImageTransferState
&&
1686 !srcPacking
->SwapBytes
&&
1687 srcFormat
== GL_RGBA
&&
1688 srcType
== GL_UNSIGNED_BYTE
) {
1689 /* extract BGR from RGBA */
1691 for (img
= 0; img
< srcDepth
; img
++) {
1692 const GLint srcRowStride
=
1693 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1694 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1695 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1696 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1697 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1698 + dstYoffset
* dstRowStride
1699 + dstXoffset
* texelBytes
;
1700 for (row
= 0; row
< srcHeight
; row
++) {
1701 for (col
= 0; col
< srcWidth
; col
++) {
1702 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + RCOMP
];
1703 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1704 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + BCOMP
];
1706 dstRow
+= dstRowStride
;
1707 srcRow
+= srcRowStride
;
1711 else if (!ctx
->_ImageTransferState
&&
1712 srcType
== GL_UNSIGNED_BYTE
&&
1713 can_swizzle(baseInternalFormat
) &&
1714 can_swizzle(srcFormat
)) {
1718 /* dstmap - how to swizzle from RGBA to dst format:
1723 dstmap
[3] = ONE
; /* ? */
1725 _mesa_swizzle_ubyte_image(ctx
, dims
,
1730 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1731 dstRowStride
, dstImageOffsets
,
1732 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1737 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1740 srcWidth
, srcHeight
, srcDepth
,
1741 srcFormat
, srcType
, srcAddr
,
1743 const GLchan
*src
= (const GLchan
*) tempImage
;
1744 GLint img
, row
, col
;
1747 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1748 for (img
= 0; img
< srcDepth
; img
++) {
1749 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1750 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1751 + dstYoffset
* dstRowStride
1752 + dstXoffset
* texelBytes
;
1753 for (row
= 0; row
< srcHeight
; row
++) {
1754 for (col
= 0; col
< srcWidth
; col
++) {
1755 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1756 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1757 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1760 dstRow
+= dstRowStride
;
1763 _mesa_free((void *) tempImage
);
1770 _mesa_texstore_argb4444(TEXSTORE_PARAMS
)
1772 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1773 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1775 ASSERT(dstFormat
== MESA_FORMAT_ARGB4444
||
1776 dstFormat
== MESA_FORMAT_ARGB4444_REV
);
1777 ASSERT(texelBytes
== 2);
1779 if (!ctx
->_ImageTransferState
&&
1780 !srcPacking
->SwapBytes
&&
1781 dstFormat
== MESA_FORMAT_ARGB4444
&&
1782 baseInternalFormat
== GL_RGBA
&&
1783 srcFormat
== GL_BGRA
&&
1784 srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1785 /* simple memcpy path */
1786 memcpy_texture(ctx
, dims
,
1787 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1790 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1791 srcAddr
, srcPacking
);
1795 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1798 srcWidth
, srcHeight
, srcDepth
,
1799 srcFormat
, srcType
, srcAddr
,
1801 const GLchan
*src
= tempImage
;
1802 GLint img
, row
, col
;
1805 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1806 for (img
= 0; img
< srcDepth
; img
++) {
1807 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1808 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1809 + dstYoffset
* dstRowStride
1810 + dstXoffset
* texelBytes
;
1811 for (row
= 0; row
< srcHeight
; row
++) {
1812 GLushort
*dstUS
= (GLushort
*) dstRow
;
1813 if (dstFormat
== MESA_FORMAT_ARGB4444
) {
1814 for (col
= 0; col
< srcWidth
; col
++) {
1815 dstUS
[col
] = PACK_COLOR_4444( CHAN_TO_UBYTE(src
[ACOMP
]),
1816 CHAN_TO_UBYTE(src
[RCOMP
]),
1817 CHAN_TO_UBYTE(src
[GCOMP
]),
1818 CHAN_TO_UBYTE(src
[BCOMP
]) );
1823 for (col
= 0; col
< srcWidth
; col
++) {
1824 dstUS
[col
] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1825 CHAN_TO_UBYTE(src
[RCOMP
]),
1826 CHAN_TO_UBYTE(src
[GCOMP
]),
1827 CHAN_TO_UBYTE(src
[BCOMP
]) );
1831 dstRow
+= dstRowStride
;
1834 _mesa_free((void *) tempImage
);
1840 _mesa_texstore_rgba5551(TEXSTORE_PARAMS
)
1842 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1843 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1845 ASSERT(dstFormat
== MESA_FORMAT_RGBA5551
);
1846 ASSERT(texelBytes
== 2);
1848 if (!ctx
->_ImageTransferState
&&
1849 !srcPacking
->SwapBytes
&&
1850 dstFormat
== MESA_FORMAT_RGBA5551
&&
1851 baseInternalFormat
== GL_RGBA
&&
1852 srcFormat
== GL_RGBA
&&
1853 srcType
== GL_UNSIGNED_SHORT_5_5_5_1
) {
1854 /* simple memcpy path */
1855 memcpy_texture(ctx
, dims
,
1856 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1859 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1860 srcAddr
, srcPacking
);
1864 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1867 srcWidth
, srcHeight
, srcDepth
,
1868 srcFormat
, srcType
, srcAddr
,
1870 const GLchan
*src
=tempImage
;
1871 GLint img
, row
, col
;
1874 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1875 for (img
= 0; img
< srcDepth
; img
++) {
1876 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1877 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1878 + dstYoffset
* dstRowStride
1879 + dstXoffset
* texelBytes
;
1880 for (row
= 0; row
< srcHeight
; row
++) {
1881 GLushort
*dstUS
= (GLushort
*) dstRow
;
1882 for (col
= 0; col
< srcWidth
; col
++) {
1883 dstUS
[col
] = PACK_COLOR_5551( CHAN_TO_UBYTE(src
[RCOMP
]),
1884 CHAN_TO_UBYTE(src
[GCOMP
]),
1885 CHAN_TO_UBYTE(src
[BCOMP
]),
1886 CHAN_TO_UBYTE(src
[ACOMP
]) );
1889 dstRow
+= dstRowStride
;
1892 _mesa_free((void *) tempImage
);
1898 _mesa_texstore_argb1555(TEXSTORE_PARAMS
)
1900 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1901 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1903 ASSERT(dstFormat
== MESA_FORMAT_ARGB1555
||
1904 dstFormat
== MESA_FORMAT_ARGB1555_REV
);
1905 ASSERT(texelBytes
== 2);
1907 if (!ctx
->_ImageTransferState
&&
1908 !srcPacking
->SwapBytes
&&
1909 dstFormat
== MESA_FORMAT_ARGB1555
&&
1910 baseInternalFormat
== GL_RGBA
&&
1911 srcFormat
== GL_BGRA
&&
1912 srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
1913 /* simple memcpy path */
1914 memcpy_texture(ctx
, dims
,
1915 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1918 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1919 srcAddr
, srcPacking
);
1923 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1926 srcWidth
, srcHeight
, srcDepth
,
1927 srcFormat
, srcType
, srcAddr
,
1929 const GLchan
*src
=tempImage
;
1930 GLint img
, row
, col
;
1933 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1934 for (img
= 0; img
< srcDepth
; img
++) {
1935 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1936 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1937 + dstYoffset
* dstRowStride
1938 + dstXoffset
* texelBytes
;
1939 for (row
= 0; row
< srcHeight
; row
++) {
1940 GLushort
*dstUS
= (GLushort
*) dstRow
;
1941 if (dstFormat
== MESA_FORMAT_ARGB1555
) {
1942 for (col
= 0; col
< srcWidth
; col
++) {
1943 dstUS
[col
] = PACK_COLOR_1555( CHAN_TO_UBYTE(src
[ACOMP
]),
1944 CHAN_TO_UBYTE(src
[RCOMP
]),
1945 CHAN_TO_UBYTE(src
[GCOMP
]),
1946 CHAN_TO_UBYTE(src
[BCOMP
]) );
1951 for (col
= 0; col
< srcWidth
; col
++) {
1952 dstUS
[col
] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1953 CHAN_TO_UBYTE(src
[RCOMP
]),
1954 CHAN_TO_UBYTE(src
[GCOMP
]),
1955 CHAN_TO_UBYTE(src
[BCOMP
]) );
1959 dstRow
+= dstRowStride
;
1962 _mesa_free((void *) tempImage
);
1969 _mesa_texstore_al88(TEXSTORE_PARAMS
)
1971 const GLboolean littleEndian
= _mesa_little_endian();
1972 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1973 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1975 ASSERT(dstFormat
== MESA_FORMAT_AL88
||
1976 dstFormat
== MESA_FORMAT_AL88_REV
);
1977 ASSERT(texelBytes
== 2);
1979 if (!ctx
->_ImageTransferState
&&
1980 !srcPacking
->SwapBytes
&&
1981 dstFormat
== MESA_FORMAT_AL88
&&
1982 baseInternalFormat
== GL_LUMINANCE_ALPHA
&&
1983 srcFormat
== GL_LUMINANCE_ALPHA
&&
1984 srcType
== GL_UNSIGNED_BYTE
&&
1986 /* simple memcpy path */
1987 memcpy_texture(ctx
, dims
,
1988 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1991 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1992 srcAddr
, srcPacking
);
1994 else if (!ctx
->_ImageTransferState
&&
1996 srcType
== GL_UNSIGNED_BYTE
&&
1997 can_swizzle(baseInternalFormat
) &&
1998 can_swizzle(srcFormat
)) {
2002 /* dstmap - how to swizzle from RGBA to dst format:
2004 if ((littleEndian
&& dstFormat
== MESA_FORMAT_AL88
) ||
2005 (!littleEndian
&& dstFormat
== MESA_FORMAT_AL88_REV
)) {
2013 dstmap
[2] = ZERO
; /* ? */
2014 dstmap
[3] = ONE
; /* ? */
2016 _mesa_swizzle_ubyte_image(ctx
, dims
,
2021 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2022 dstRowStride
, dstImageOffsets
,
2023 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2028 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2031 srcWidth
, srcHeight
, srcDepth
,
2032 srcFormat
, srcType
, srcAddr
,
2034 const GLchan
*src
= tempImage
;
2035 GLint img
, row
, col
;
2038 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2039 for (img
= 0; img
< srcDepth
; img
++) {
2040 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2041 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2042 + dstYoffset
* dstRowStride
2043 + dstXoffset
* texelBytes
;
2044 for (row
= 0; row
< srcHeight
; row
++) {
2045 GLushort
*dstUS
= (GLushort
*) dstRow
;
2046 if (dstFormat
== MESA_FORMAT_AL88
) {
2047 for (col
= 0; col
< srcWidth
; col
++) {
2048 /* src[0] is luminance, src[1] is alpha */
2049 dstUS
[col
] = PACK_COLOR_88( CHAN_TO_UBYTE(src
[1]),
2050 CHAN_TO_UBYTE(src
[0]) );
2055 for (col
= 0; col
< srcWidth
; col
++) {
2056 /* src[0] is luminance, src[1] is alpha */
2057 dstUS
[col
] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src
[1]),
2058 CHAN_TO_UBYTE(src
[0]) );
2062 dstRow
+= dstRowStride
;
2065 _mesa_free((void *) tempImage
);
2072 _mesa_texstore_rgb332(TEXSTORE_PARAMS
)
2074 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2075 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2077 ASSERT(dstFormat
== MESA_FORMAT_RGB332
);
2078 ASSERT(texelBytes
== 1);
2080 if (!ctx
->_ImageTransferState
&&
2081 !srcPacking
->SwapBytes
&&
2082 baseInternalFormat
== GL_RGB
&&
2083 srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_BYTE_3_3_2
) {
2084 /* simple memcpy path */
2085 memcpy_texture(ctx
, dims
,
2086 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2089 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2090 srcAddr
, srcPacking
);
2094 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2097 srcWidth
, srcHeight
, srcDepth
,
2098 srcFormat
, srcType
, srcAddr
,
2100 const GLchan
*src
= tempImage
;
2101 GLint img
, row
, col
;
2104 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2105 for (img
= 0; img
< srcDepth
; img
++) {
2106 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2107 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2108 + dstYoffset
* dstRowStride
2109 + dstXoffset
* texelBytes
;
2110 for (row
= 0; row
< srcHeight
; row
++) {
2111 for (col
= 0; col
< srcWidth
; col
++) {
2112 dstRow
[col
] = PACK_COLOR_332( CHAN_TO_UBYTE(src
[RCOMP
]),
2113 CHAN_TO_UBYTE(src
[GCOMP
]),
2114 CHAN_TO_UBYTE(src
[BCOMP
]) );
2117 dstRow
+= dstRowStride
;
2120 _mesa_free((void *) tempImage
);
2127 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2130 _mesa_texstore_a8(TEXSTORE_PARAMS
)
2132 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2133 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2135 ASSERT(dstFormat
== MESA_FORMAT_A8
||
2136 dstFormat
== MESA_FORMAT_L8
||
2137 dstFormat
== MESA_FORMAT_I8
);
2138 ASSERT(texelBytes
== 1);
2140 if (!ctx
->_ImageTransferState
&&
2141 !srcPacking
->SwapBytes
&&
2142 baseInternalFormat
== srcFormat
&&
2143 srcType
== GL_UNSIGNED_BYTE
) {
2144 /* simple memcpy path */
2145 memcpy_texture(ctx
, dims
,
2146 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2149 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2150 srcAddr
, srcPacking
);
2152 else if (!ctx
->_ImageTransferState
&&
2153 srcType
== GL_UNSIGNED_BYTE
&&
2154 can_swizzle(baseInternalFormat
) &&
2155 can_swizzle(srcFormat
)) {
2159 /* dstmap - how to swizzle from RGBA to dst format:
2161 if (dstFormat
== MESA_FORMAT_A8
) {
2167 dstmap
[1] = ZERO
; /* ? */
2168 dstmap
[2] = ZERO
; /* ? */
2169 dstmap
[3] = ONE
; /* ? */
2171 _mesa_swizzle_ubyte_image(ctx
, dims
,
2176 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2177 dstRowStride
, dstImageOffsets
,
2178 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2183 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2186 srcWidth
, srcHeight
, srcDepth
,
2187 srcFormat
, srcType
, srcAddr
,
2189 const GLchan
*src
= tempImage
;
2190 GLint img
, row
, col
;
2193 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2194 for (img
= 0; img
< srcDepth
; img
++) {
2195 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2196 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2197 + dstYoffset
* dstRowStride
2198 + dstXoffset
* texelBytes
;
2199 for (row
= 0; row
< srcHeight
; row
++) {
2200 for (col
= 0; col
< srcWidth
; col
++) {
2201 dstRow
[col
] = CHAN_TO_UBYTE(src
[col
]);
2203 dstRow
+= dstRowStride
;
2207 _mesa_free((void *) tempImage
);
2215 _mesa_texstore_ci8(TEXSTORE_PARAMS
)
2217 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2219 (void) dims
; (void) baseInternalFormat
;
2220 ASSERT(dstFormat
== MESA_FORMAT_CI8
);
2221 ASSERT(texelBytes
== 1);
2222 ASSERT(baseInternalFormat
== GL_COLOR_INDEX
);
2224 if (!ctx
->_ImageTransferState
&&
2225 !srcPacking
->SwapBytes
&&
2226 srcFormat
== GL_COLOR_INDEX
&&
2227 srcType
== GL_UNSIGNED_BYTE
) {
2228 /* simple memcpy path */
2229 memcpy_texture(ctx
, dims
,
2230 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2233 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2234 srcAddr
, srcPacking
);
2239 for (img
= 0; img
< srcDepth
; img
++) {
2240 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2241 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2242 + dstYoffset
* dstRowStride
2243 + dstXoffset
* texelBytes
;
2244 for (row
= 0; row
< srcHeight
; row
++) {
2245 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
2246 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
2247 _mesa_unpack_index_span(ctx
, srcWidth
, GL_UNSIGNED_BYTE
, dstRow
,
2248 srcType
, src
, srcPacking
,
2249 ctx
->_ImageTransferState
);
2250 dstRow
+= dstRowStride
;
2259 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
2262 _mesa_texstore_ycbcr(TEXSTORE_PARAMS
)
2264 const GLboolean littleEndian
= _mesa_little_endian();
2265 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2267 (void) ctx
; (void) dims
; (void) baseInternalFormat
;
2269 ASSERT((dstFormat
== MESA_FORMAT_YCBCR
) ||
2270 (dstFormat
== MESA_FORMAT_YCBCR_REV
));
2271 ASSERT(texelBytes
== 2);
2272 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
2273 ASSERT(srcFormat
== GL_YCBCR_MESA
);
2274 ASSERT((srcType
== GL_UNSIGNED_SHORT_8_8_MESA
) ||
2275 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
));
2276 ASSERT(baseInternalFormat
== GL_YCBCR_MESA
);
2278 /* always just memcpy since no pixel transfer ops apply */
2279 memcpy_texture(ctx
, dims
,
2280 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2283 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2284 srcAddr
, srcPacking
);
2286 /* Check if we need byte swapping */
2287 /* XXX the logic here _might_ be wrong */
2288 if (srcPacking
->SwapBytes
^
2289 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ^
2290 (dstFormat
== MESA_FORMAT_YCBCR_REV
) ^
2293 for (img
= 0; img
< srcDepth
; img
++) {
2294 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2295 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2296 + dstYoffset
* dstRowStride
2297 + dstXoffset
* texelBytes
;
2298 for (row
= 0; row
< srcHeight
; row
++) {
2299 _mesa_swap2((GLushort
*) dstRow
, srcWidth
);
2300 dstRow
+= dstRowStride
;
2308 _mesa_texstore_dudv8(TEXSTORE_PARAMS
)
2310 const GLboolean littleEndian
= _mesa_little_endian();
2311 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2313 ASSERT(dstFormat
== MESA_FORMAT_DUDV8
);
2314 ASSERT(texelBytes
== 2);
2315 ASSERT(ctx
->Extensions
.ATI_envmap_bumpmap
);
2316 ASSERT((srcFormat
== GL_DU8DV8_ATI
) ||
2317 (srcFormat
== GL_DUDV_ATI
));
2318 ASSERT(baseInternalFormat
== GL_DUDV_ATI
);
2320 if (!srcPacking
->SwapBytes
&& srcType
== GL_BYTE
&&
2322 /* simple memcpy path */
2323 memcpy_texture(ctx
, dims
,
2324 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2327 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2328 srcAddr
, srcPacking
);
2330 else if (srcType
== GL_BYTE
) {
2334 /* dstmap - how to swizzle from RGBA to dst format:
2344 dstmap
[2] = ZERO
; /* ? */
2345 dstmap
[3] = ONE
; /* ? */
2347 _mesa_swizzle_ubyte_image(ctx
, dims
,
2348 GL_LUMINANCE_ALPHA
, /* hack */
2349 GL_UNSIGNED_BYTE
, /* hack */
2350 GL_LUMINANCE_ALPHA
, /* hack */
2352 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2353 dstRowStride
, dstImageOffsets
,
2354 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2358 /* general path - note this is defined for 2d textures only */
2359 const GLint components
= _mesa_components_in_format(baseInternalFormat
);
2360 const GLint srcStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
2361 srcFormat
, srcType
);
2362 GLbyte
*tempImage
, *dst
, *src
;
2365 tempImage
= (GLbyte
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
2366 * components
* sizeof(GLbyte
));
2370 src
= (GLbyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2371 srcWidth
, srcHeight
,
2376 for (row
= 0; row
< srcHeight
; row
++) {
2377 _mesa_unpack_dudv_span_byte(ctx
, srcWidth
, baseInternalFormat
,
2378 dst
, srcFormat
, srcType
, src
,
2380 dst
+= srcWidth
* components
;
2385 dst
= (GLbyte
*) dstAddr
2386 + dstYoffset
* dstRowStride
2387 + dstXoffset
* texelBytes
;
2388 for (row
= 0; row
< srcHeight
; row
++) {
2389 memcpy(dst
, src
, srcWidth
* texelBytes
);
2390 dst
+= dstRowStride
;
2391 src
+= srcWidth
* texelBytes
;
2393 _mesa_free((void *) tempImage
);
2399 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or MESA_FORMAT_SIGNED_RGBA8888_REV
2402 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS
)
2404 const GLboolean littleEndian
= _mesa_little_endian();
2405 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2406 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2408 ASSERT(dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
||
2409 dstFormat
== MESA_FORMAT_SIGNED_RGBA8888_REV
);
2410 ASSERT(texelBytes
== 4);
2412 if (!ctx
->_ImageTransferState
&&
2413 !srcPacking
->SwapBytes
&&
2414 dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
&&
2415 baseInternalFormat
== GL_RGBA
&&
2416 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& !littleEndian
) ||
2417 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& littleEndian
))) {
2418 /* simple memcpy path */
2419 memcpy_texture(ctx
, dims
,
2420 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2423 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2424 srcAddr
, srcPacking
);
2426 else if (!ctx
->_ImageTransferState
&&
2427 !srcPacking
->SwapBytes
&&
2428 dstFormat
== MESA_FORMAT_SIGNED_RGBA8888_REV
&&
2429 baseInternalFormat
== GL_RGBA
&&
2430 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& littleEndian
) ||
2431 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& !littleEndian
))) {
2432 /* simple memcpy path */
2433 memcpy_texture(ctx
, dims
,
2434 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2437 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2438 srcAddr
, srcPacking
);
2440 else if (!ctx
->_ImageTransferState
&&
2441 (srcType
== GL_BYTE
) &&
2442 can_swizzle(baseInternalFormat
) &&
2443 can_swizzle(srcFormat
)) {
2447 /* dstmap - how to swizzle from RGBA to dst format:
2449 if ((littleEndian
&& dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
) ||
2450 (!littleEndian
&& dstFormat
== MESA_FORMAT_SIGNED_RGBA8888_REV
)) {
2463 _mesa_swizzle_ubyte_image(ctx
, dims
,
2468 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2469 dstRowStride
, dstImageOffsets
,
2470 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2475 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2478 srcWidth
, srcHeight
, srcDepth
,
2479 srcFormat
, srcType
, srcAddr
,
2481 const GLfloat
*srcRow
= tempImage
;
2482 GLint img
, row
, col
;
2485 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2486 for (img
= 0; img
< srcDepth
; img
++) {
2487 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2488 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2489 + dstYoffset
* dstRowStride
2490 + dstXoffset
* texelBytes
;
2491 for (row
= 0; row
< srcHeight
; row
++) {
2492 GLuint
*dstUI
= (GLuint
*) dstRow
;
2493 if (dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
) {
2494 for (col
= 0; col
< srcWidth
; col
++) {
2495 dstUI
[col
] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2496 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2497 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2498 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2503 for (col
= 0; col
< srcWidth
; col
++) {
2504 dstUI
[col
] = PACK_COLOR_8888_REV( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2505 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2506 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2507 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2511 dstRow
+= dstRowStride
;
2514 _mesa_free((void *) tempImage
);
2520 * Store a combined depth/stencil texture image.
2523 _mesa_texstore_z24_s8(TEXSTORE_PARAMS
)
2525 const GLfloat depthScale
= (GLfloat
) 0xffffff;
2526 const GLint srcRowStride
2527 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2531 ASSERT(dstFormat
== MESA_FORMAT_Z24_S8
);
2532 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
);
2533 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2535 /* In case we only upload depth we need to preserve the stencil */
2536 if (srcFormat
== GL_DEPTH_COMPONENT
) {
2537 for (img
= 0; img
< srcDepth
; img
++) {
2538 GLuint
*dstRow
= (GLuint
*) dstAddr
2539 + dstImageOffsets
[dstZoffset
+ img
]
2540 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2543 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2544 srcWidth
, srcHeight
,
2547 for (row
= 0; row
< srcHeight
; row
++) {
2548 GLuint depth
[MAX_WIDTH
];
2550 _mesa_unpack_depth_span(ctx
, srcWidth
,
2551 GL_UNSIGNED_INT
, /* dst type */
2552 depth
, /* dst addr */
2554 srcType
, src
, srcPacking
);
2556 for (i
= 0; i
< srcWidth
; i
++)
2557 dstRow
[i
] = depth
[i
] << 8 | (dstRow
[i
] & 0x000000FF);
2559 src
+= srcRowStride
;
2560 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2564 else if (ctx
->Pixel
.DepthScale
== 1.0f
&&
2565 ctx
->Pixel
.DepthBias
== 0.0f
&&
2566 !srcPacking
->SwapBytes
) {
2568 memcpy_texture(ctx
, dims
,
2569 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2572 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2573 srcAddr
, srcPacking
);
2577 const GLint srcRowStride
2578 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2582 for (img
= 0; img
< srcDepth
; img
++) {
2583 GLuint
*dstRow
= (GLuint
*) dstAddr
2584 + dstImageOffsets
[dstZoffset
+ img
]
2585 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2588 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2589 srcWidth
, srcHeight
,
2592 for (row
= 0; row
< srcHeight
; row
++) {
2593 GLubyte stencil
[MAX_WIDTH
];
2595 /* the 24 depth bits will be in the high position: */
2596 _mesa_unpack_depth_span(ctx
, srcWidth
,
2597 GL_UNSIGNED_INT_24_8_EXT
, /* dst type */
2598 dstRow
, /* dst addr */
2599 (GLuint
) depthScale
,
2600 srcType
, src
, srcPacking
);
2601 /* get the 8-bit stencil values */
2602 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2603 GL_UNSIGNED_BYTE
, /* dst type */
2604 stencil
, /* dst addr */
2605 srcType
, src
, srcPacking
,
2606 ctx
->_ImageTransferState
);
2607 /* merge stencil values into depth values */
2608 for (i
= 0; i
< srcWidth
; i
++)
2609 dstRow
[i
] |= stencil
[i
];
2611 src
+= srcRowStride
;
2612 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2621 * Store a combined depth/stencil texture image.
2624 _mesa_texstore_s8_z24(TEXSTORE_PARAMS
)
2626 const GLuint depthScale
= 0xffffff;
2627 const GLint srcRowStride
2628 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2632 ASSERT(dstFormat
== MESA_FORMAT_S8_Z24
);
2633 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
);
2634 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2636 /* In case we only upload depth we need to preserve the stencil */
2637 if (srcFormat
== GL_DEPTH_COMPONENT
) {
2638 for (img
= 0; img
< srcDepth
; img
++) {
2639 GLuint
*dstRow
= (GLuint
*) dstAddr
2640 + dstImageOffsets
[dstZoffset
+ img
]
2641 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2644 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2645 srcWidth
, srcHeight
,
2648 for (row
= 0; row
< srcHeight
; row
++) {
2649 GLuint depth
[MAX_WIDTH
];
2651 _mesa_unpack_depth_span(ctx
, srcWidth
,
2652 GL_UNSIGNED_INT
, /* dst type */
2653 depth
, /* dst addr */
2655 srcType
, src
, srcPacking
);
2657 for (i
= 0; i
< srcWidth
; i
++)
2658 dstRow
[i
] = depth
[i
] | (dstRow
[i
] & 0xFF000000);
2660 src
+= srcRowStride
;
2661 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2666 for (img
= 0; img
< srcDepth
; img
++) {
2667 GLuint
*dstRow
= (GLuint
*) dstAddr
2668 + dstImageOffsets
[dstZoffset
+ img
]
2669 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2672 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2673 srcWidth
, srcHeight
,
2676 for (row
= 0; row
< srcHeight
; row
++) {
2677 GLubyte stencil
[MAX_WIDTH
];
2679 /* the 24 depth bits will be in the low position: */
2680 _mesa_unpack_depth_span(ctx
, srcWidth
,
2681 GL_UNSIGNED_INT
, /* dst type */
2682 dstRow
, /* dst addr */
2684 srcType
, src
, srcPacking
);
2685 /* get the 8-bit stencil values */
2686 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2687 GL_UNSIGNED_BYTE
, /* dst type */
2688 stencil
, /* dst addr */
2689 srcType
, src
, srcPacking
,
2690 ctx
->_ImageTransferState
);
2691 /* merge stencil values into depth values */
2692 for (i
= 0; i
< srcWidth
; i
++)
2693 dstRow
[i
] |= stencil
[i
] << 24;
2695 src
+= srcRowStride
;
2696 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2704 * Store an image in any of the formats:
2705 * _mesa_texformat_rgba_float32
2706 * _mesa_texformat_rgb_float32
2707 * _mesa_texformat_alpha_float32
2708 * _mesa_texformat_luminance_float32
2709 * _mesa_texformat_luminance_alpha_float32
2710 * _mesa_texformat_intensity_float32
2713 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS
)
2715 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2716 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2717 const GLint components
= _mesa_components_in_format(baseFormat
);
2719 ASSERT(dstFormat
== MESA_FORMAT_RGBA_FLOAT32
||
2720 dstFormat
== MESA_FORMAT_RGB_FLOAT32
||
2721 dstFormat
== MESA_FORMAT_ALPHA_FLOAT32
||
2722 dstFormat
== MESA_FORMAT_LUMINANCE_FLOAT32
||
2723 dstFormat
== MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32
||
2724 dstFormat
== MESA_FORMAT_INTENSITY_FLOAT32
);
2725 ASSERT(baseInternalFormat
== GL_RGBA
||
2726 baseInternalFormat
== GL_RGB
||
2727 baseInternalFormat
== GL_ALPHA
||
2728 baseInternalFormat
== GL_LUMINANCE
||
2729 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
2730 baseInternalFormat
== GL_INTENSITY
);
2731 ASSERT(texelBytes
== components
* sizeof(GLfloat
));
2733 if (!ctx
->_ImageTransferState
&&
2734 !srcPacking
->SwapBytes
&&
2735 baseInternalFormat
== srcFormat
&&
2736 srcType
== GL_FLOAT
) {
2737 /* simple memcpy path */
2738 memcpy_texture(ctx
, dims
,
2739 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2742 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2743 srcAddr
, srcPacking
);
2747 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2750 srcWidth
, srcHeight
, srcDepth
,
2751 srcFormat
, srcType
, srcAddr
,
2753 const GLfloat
*srcRow
= tempImage
;
2758 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2759 bytesPerRow
= srcWidth
* components
* sizeof(GLfloat
);
2760 for (img
= 0; img
< srcDepth
; img
++) {
2761 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2762 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2763 + dstYoffset
* dstRowStride
2764 + dstXoffset
* texelBytes
;
2765 for (row
= 0; row
< srcHeight
; row
++) {
2766 _mesa_memcpy(dstRow
, srcRow
, bytesPerRow
);
2767 dstRow
+= dstRowStride
;
2768 srcRow
+= srcWidth
* components
;
2772 _mesa_free((void *) tempImage
);
2779 * As above, but store 16-bit floats.
2782 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS
)
2784 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2785 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2786 const GLint components
= _mesa_components_in_format(baseFormat
);
2788 ASSERT(dstFormat
== MESA_FORMAT_RGBA_FLOAT16
||
2789 dstFormat
== MESA_FORMAT_RGB_FLOAT16
||
2790 dstFormat
== MESA_FORMAT_ALPHA_FLOAT16
||
2791 dstFormat
== MESA_FORMAT_LUMINANCE_FLOAT16
||
2792 dstFormat
== MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16
||
2793 dstFormat
== MESA_FORMAT_INTENSITY_FLOAT16
);
2794 ASSERT(baseInternalFormat
== GL_RGBA
||
2795 baseInternalFormat
== GL_RGB
||
2796 baseInternalFormat
== GL_ALPHA
||
2797 baseInternalFormat
== GL_LUMINANCE
||
2798 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
2799 baseInternalFormat
== GL_INTENSITY
);
2800 ASSERT(texelBytes
== components
* sizeof(GLhalfARB
));
2802 if (!ctx
->_ImageTransferState
&&
2803 !srcPacking
->SwapBytes
&&
2804 baseInternalFormat
== srcFormat
&&
2805 srcType
== GL_HALF_FLOAT_ARB
) {
2806 /* simple memcpy path */
2807 memcpy_texture(ctx
, dims
,
2808 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2811 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2812 srcAddr
, srcPacking
);
2816 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2819 srcWidth
, srcHeight
, srcDepth
,
2820 srcFormat
, srcType
, srcAddr
,
2822 const GLfloat
*src
= tempImage
;
2826 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2827 for (img
= 0; img
< srcDepth
; img
++) {
2828 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2829 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2830 + dstYoffset
* dstRowStride
2831 + dstXoffset
* texelBytes
;
2832 for (row
= 0; row
< srcHeight
; row
++) {
2833 GLhalfARB
*dstTexel
= (GLhalfARB
*) dstRow
;
2835 for (i
= 0; i
< srcWidth
* components
; i
++) {
2836 dstTexel
[i
] = _mesa_float_to_half(src
[i
]);
2838 dstRow
+= dstRowStride
;
2839 src
+= srcWidth
* components
;
2843 _mesa_free((void *) tempImage
);
2849 #if FEATURE_EXT_texture_sRGB
2851 _mesa_texstore_srgb8(TEXSTORE_PARAMS
)
2853 gl_format newDstFormat
;
2856 ASSERT(dstFormat
== MESA_FORMAT_SRGB8
);
2858 /* reuse normal rgb texstore code */
2859 newDstFormat
= MESA_FORMAT_RGB888
;
2861 k
= _mesa_texstore_rgb888(ctx
, dims
, baseInternalFormat
,
2862 newDstFormat
, dstAddr
,
2863 dstXoffset
, dstYoffset
, dstZoffset
,
2864 dstRowStride
, dstImageOffsets
,
2865 srcWidth
, srcHeight
, srcDepth
,
2867 srcAddr
, srcPacking
);
2873 _mesa_texstore_srgba8(TEXSTORE_PARAMS
)
2875 gl_format newDstFormat
;
2878 ASSERT(dstFormat
== MESA_FORMAT_SRGBA8
);
2880 /* reuse normal rgba texstore code */
2881 newDstFormat
= MESA_FORMAT_RGBA8888
;
2882 k
= _mesa_texstore_rgba8888(ctx
, dims
, baseInternalFormat
,
2883 newDstFormat
, dstAddr
,
2884 dstXoffset
, dstYoffset
, dstZoffset
,
2885 dstRowStride
, dstImageOffsets
,
2886 srcWidth
, srcHeight
, srcDepth
,
2888 srcAddr
, srcPacking
);
2894 _mesa_texstore_sargb8(TEXSTORE_PARAMS
)
2896 gl_format newDstFormat
;
2899 ASSERT(dstFormat
== MESA_FORMAT_SARGB8
);
2901 /* reuse normal rgba texstore code */
2902 newDstFormat
= MESA_FORMAT_ARGB8888
;
2904 k
= _mesa_texstore_argb8888(ctx
, dims
, baseInternalFormat
,
2905 newDstFormat
, dstAddr
,
2906 dstXoffset
, dstYoffset
, dstZoffset
,
2907 dstRowStride
, dstImageOffsets
,
2908 srcWidth
, srcHeight
, srcDepth
,
2910 srcAddr
, srcPacking
);
2916 _mesa_texstore_sl8(TEXSTORE_PARAMS
)
2918 gl_format newDstFormat
;
2921 ASSERT(dstFormat
== MESA_FORMAT_SL8
);
2923 newDstFormat
= MESA_FORMAT_L8
;
2925 /* _mesa_textore_a8 handles luminance8 too */
2926 k
= _mesa_texstore_a8(ctx
, dims
, baseInternalFormat
,
2927 newDstFormat
, dstAddr
,
2928 dstXoffset
, dstYoffset
, dstZoffset
,
2929 dstRowStride
, dstImageOffsets
,
2930 srcWidth
, srcHeight
, srcDepth
,
2932 srcAddr
, srcPacking
);
2938 _mesa_texstore_sla8(TEXSTORE_PARAMS
)
2940 gl_format newDstFormat
;
2943 ASSERT(dstFormat
== MESA_FORMAT_SLA8
);
2945 /* reuse normal luminance/alpha texstore code */
2946 newDstFormat
= MESA_FORMAT_AL88
;
2948 k
= _mesa_texstore_al88(ctx
, dims
, baseInternalFormat
,
2949 newDstFormat
, dstAddr
,
2950 dstXoffset
, dstYoffset
, dstZoffset
,
2951 dstRowStride
, dstImageOffsets
,
2952 srcWidth
, srcHeight
, srcDepth
,
2954 srcAddr
, srcPacking
);
2958 #endif /* FEATURE_EXT_texture_sRGB */
2964 * Table mapping MESA_FORMAT_8 to _mesa_texstore_*()
2965 * XXX this is somewhat temporary.
2969 StoreTexImageFunc Store
;
2971 texstore_funcs
[MESA_FORMAT_COUNT
] =
2973 { MESA_FORMAT_NONE
, NULL
},
2974 { MESA_FORMAT_RGBA8888
, _mesa_texstore_rgba8888
},
2975 { MESA_FORMAT_RGBA8888_REV
, _mesa_texstore_rgba8888
},
2976 { MESA_FORMAT_ARGB8888
, _mesa_texstore_argb8888
},
2977 { MESA_FORMAT_ARGB8888_REV
, _mesa_texstore_argb8888
},
2978 { MESA_FORMAT_RGB888
, _mesa_texstore_rgb888
},
2979 { MESA_FORMAT_BGR888
, _mesa_texstore_bgr888
},
2980 { MESA_FORMAT_RGB565
, _mesa_texstore_rgb565
},
2981 { MESA_FORMAT_RGB565_REV
, _mesa_texstore_rgb565
},
2982 { MESA_FORMAT_ARGB4444
, _mesa_texstore_argb4444
},
2983 { MESA_FORMAT_ARGB4444_REV
, _mesa_texstore_argb4444
},
2984 { MESA_FORMAT_RGBA5551
, _mesa_texstore_rgba5551
},
2985 { MESA_FORMAT_ARGB1555
, _mesa_texstore_argb1555
},
2986 { MESA_FORMAT_ARGB1555_REV
, _mesa_texstore_argb1555
},
2987 { MESA_FORMAT_AL88
, _mesa_texstore_al88
},
2988 { MESA_FORMAT_AL88_REV
, _mesa_texstore_al88
},
2989 { MESA_FORMAT_RGB332
, _mesa_texstore_rgb332
},
2990 { MESA_FORMAT_A8
, _mesa_texstore_a8
},
2991 { MESA_FORMAT_L8
, _mesa_texstore_a8
},
2992 { MESA_FORMAT_I8
, _mesa_texstore_a8
},
2993 { MESA_FORMAT_CI8
, _mesa_texstore_ci8
},
2994 { MESA_FORMAT_YCBCR
, _mesa_texstore_ycbcr
},
2995 { MESA_FORMAT_YCBCR_REV
, _mesa_texstore_ycbcr
},
2996 { MESA_FORMAT_Z24_S8
, _mesa_texstore_z24_s8
},
2997 { MESA_FORMAT_S8_Z24
, _mesa_texstore_s8_z24
},
2998 { MESA_FORMAT_Z16
, _mesa_texstore_z16
},
2999 { MESA_FORMAT_Z32
, _mesa_texstore_z32
},
3000 { MESA_FORMAT_S8
, NULL
/*_mesa_texstore_s8*/ },
3001 { MESA_FORMAT_SRGB8
, _mesa_texstore_srgb8
},
3002 { MESA_FORMAT_SRGBA8
, _mesa_texstore_srgba8
},
3003 { MESA_FORMAT_SARGB8
, _mesa_texstore_sargb8
},
3004 { MESA_FORMAT_SL8
, _mesa_texstore_sl8
},
3005 { MESA_FORMAT_SLA8
, _mesa_texstore_sla8
},
3006 { MESA_FORMAT_SRGB_DXT1
, _mesa_texstore_rgb_dxt1
},
3007 { MESA_FORMAT_SRGBA_DXT1
, _mesa_texstore_rgba_dxt1
},
3008 { MESA_FORMAT_SRGBA_DXT3
, _mesa_texstore_rgba_dxt3
},
3009 { MESA_FORMAT_SRGBA_DXT5
, _mesa_texstore_rgba_dxt5
},
3010 { MESA_FORMAT_RGB_FXT1
, _mesa_texstore_rgb_fxt1
},
3011 { MESA_FORMAT_RGBA_FXT1
, _mesa_texstore_rgba_fxt1
},
3012 { MESA_FORMAT_RGB_DXT1
, _mesa_texstore_rgb_dxt1
},
3013 { MESA_FORMAT_RGBA_DXT1
, _mesa_texstore_rgba_dxt1
},
3014 { MESA_FORMAT_RGBA_DXT3
, _mesa_texstore_rgba_dxt3
},
3015 { MESA_FORMAT_RGBA_DXT5
, _mesa_texstore_rgba_dxt5
},
3016 { MESA_FORMAT_RGBA_FLOAT32
, _mesa_texstore_rgba_float32
},
3017 { MESA_FORMAT_RGBA_FLOAT16
, _mesa_texstore_rgba_float16
},
3018 { MESA_FORMAT_RGB_FLOAT32
, _mesa_texstore_rgba_float32
},
3019 { MESA_FORMAT_RGB_FLOAT16
, _mesa_texstore_rgba_float16
},
3020 { MESA_FORMAT_ALPHA_FLOAT32
, _mesa_texstore_rgba_float32
},
3021 { MESA_FORMAT_ALPHA_FLOAT16
, _mesa_texstore_rgba_float16
},
3022 { MESA_FORMAT_LUMINANCE_FLOAT32
, _mesa_texstore_rgba_float32
},
3023 { MESA_FORMAT_LUMINANCE_FLOAT16
, _mesa_texstore_rgba_float16
},
3024 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32
, _mesa_texstore_rgba_float32
},
3025 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16
, _mesa_texstore_rgba_float16
},
3026 { MESA_FORMAT_INTENSITY_FLOAT32
, _mesa_texstore_rgba_float32
},
3027 { MESA_FORMAT_INTENSITY_FLOAT16
, _mesa_texstore_rgba_float16
},
3028 { MESA_FORMAT_DUDV8
, _mesa_texstore_dudv8
},
3029 { MESA_FORMAT_SIGNED_RGBA8888
, _mesa_texstore_signed_rgba8888
},
3030 { MESA_FORMAT_SIGNED_RGBA8888_REV
, _mesa_texstore_signed_rgba8888
},
3035 * Return the StoreTexImageFunc pointer to store an image in the given format.
3037 static StoreTexImageFunc
3038 _mesa_get_texstore_func(gl_format format
)
3042 for (i
= 0; i
< MESA_FORMAT_COUNT
; i
++) {
3043 ASSERT(texstore_funcs
[i
].Name
== i
);
3046 ASSERT(texstore_funcs
[format
].Name
== format
);
3047 return texstore_funcs
[format
].Store
;
3052 * Store user data into texture memory.
3053 * Called via glTex[Sub]Image1/2/3D()
3056 _mesa_texstore(TEXSTORE_PARAMS
)
3058 StoreTexImageFunc storeImage
;
3061 storeImage
= _mesa_get_texstore_func(dstFormat
);
3065 success
= storeImage(ctx
, dims
, baseInternalFormat
,
3066 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3067 dstRowStride
, dstImageOffsets
,
3068 srcWidth
, srcHeight
, srcDepth
,
3069 srcFormat
, srcType
, srcAddr
, srcPacking
);
3075 * Check if an unpack PBO is active prior to fetching a texture image.
3076 * If so, do bounds checking and map the buffer into main memory.
3077 * Any errors detected will be recorded.
3078 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3081 _mesa_validate_pbo_teximage(GLcontext
*ctx
, GLuint dimensions
,
3082 GLsizei width
, GLsizei height
, GLsizei depth
,
3083 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3084 const struct gl_pixelstore_attrib
*unpack
,
3085 const char *funcName
)
3089 if (!_mesa_is_bufferobj(unpack
->BufferObj
)) {
3093 if (!_mesa_validate_pbo_access(dimensions
, unpack
, width
, height
, depth
,
3094 format
, type
, pixels
)) {
3095 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3099 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3100 GL_READ_ONLY_ARB
, unpack
->BufferObj
);
3102 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3106 return ADD_POINTERS(buf
, pixels
);
3111 * Check if an unpack PBO is active prior to fetching a compressed texture
3113 * If so, do bounds checking and map the buffer into main memory.
3114 * Any errors detected will be recorded.
3115 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3118 _mesa_validate_pbo_compressed_teximage(GLcontext
*ctx
,
3119 GLsizei imageSize
, const GLvoid
*pixels
,
3120 const struct gl_pixelstore_attrib
*packing
,
3121 const char *funcName
)
3125 if (!_mesa_is_bufferobj(packing
->BufferObj
)) {
3126 /* not using a PBO - return pointer unchanged */
3129 if ((const GLubyte
*) pixels
+ imageSize
>
3130 ((const GLubyte
*) 0) + packing
->BufferObj
->Size
) {
3131 /* out of bounds read! */
3132 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3136 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3137 GL_READ_ONLY_ARB
, packing
->BufferObj
);
3139 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3143 return ADD_POINTERS(buf
, pixels
);
3148 * This function must be called after either of the validate_pbo_*_teximage()
3149 * functions. It unmaps the PBO buffer if it was mapped earlier.
3152 _mesa_unmap_teximage_pbo(GLcontext
*ctx
,
3153 const struct gl_pixelstore_attrib
*unpack
)
3155 if (_mesa_is_bufferobj(unpack
->BufferObj
)) {
3156 ctx
->Driver
.UnmapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3162 /** Return texture size in bytes */
3164 texture_size(const struct gl_texture_image
*texImage
)
3166 GLuint sz
= _mesa_format_image_size(texImage
->TexFormat
, texImage
->Width
,
3167 texImage
->Height
, texImage
->Depth
);
3172 /** Return row stride in bytes */
3174 texture_row_stride(const struct gl_texture_image
*texImage
)
3178 if (_mesa_is_format_compressed(texImage
->TexFormat
)) {
3179 stride
= _mesa_compressed_row_stride(texImage
->TexFormat
,
3183 GLuint texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
);
3184 stride
= texImage
->RowStride
* texelBytes
;
3193 * This is the software fallback for Driver.TexImage1D()
3194 * and Driver.CopyTexImage1D().
3195 * \sa _mesa_store_teximage2d()
3196 * Note that the width may not be the actual texture width since it may
3197 * be changed by convolution w/ GL_REDUCE. The texImage->Width field will
3198 * have the actual texture size.
3201 _mesa_store_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3202 GLint internalFormat
,
3203 GLint width
, GLint border
,
3204 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3205 const struct gl_pixelstore_attrib
*packing
,
3206 struct gl_texture_object
*texObj
,
3207 struct gl_texture_image
*texImage
)
3213 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3214 ASSERT(texImage
->TexFormat
);
3216 _mesa_set_fetch_functions(texImage
, 1);
3218 /* allocate memory */
3219 sizeInBytes
= texture_size(texImage
);
3220 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3221 if (!texImage
->Data
) {
3222 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
3226 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
3227 pixels
, packing
, "glTexImage1D");
3229 /* Note: we check for a NULL image pointer here, _after_ we allocated
3230 * memory for the texture. That's what the GL spec calls for.
3235 const GLint dstRowStride
= 0;
3236 GLboolean success
= _mesa_texstore(ctx
, 1, texImage
->_BaseFormat
,
3237 texImage
->TexFormat
,
3239 0, 0, 0, /* dstX/Y/Zoffset */
3241 texImage
->ImageOffsets
,
3243 format
, type
, pixels
, packing
);
3245 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
3249 _mesa_unmap_teximage_pbo(ctx
, packing
);
3254 * This is the software fallback for Driver.TexImage2D()
3255 * and Driver.CopyTexImage2D().
3257 * This function is oriented toward storing images in main memory, rather
3258 * than VRAM. Device driver's can easily plug in their own replacement.
3260 * Note: width and height may be pre-convolved dimensions, but
3261 * texImage->Width and texImage->Height will be post-convolved dimensions.
3264 _mesa_store_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3265 GLint internalFormat
,
3266 GLint width
, GLint height
, GLint border
,
3267 GLenum format
, GLenum type
, const void *pixels
,
3268 const struct gl_pixelstore_attrib
*packing
,
3269 struct gl_texture_object
*texObj
,
3270 struct gl_texture_image
*texImage
)
3276 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3277 ASSERT(texImage
->TexFormat
);
3279 _mesa_set_fetch_functions(texImage
, 2);
3281 /* allocate memory */
3282 sizeInBytes
= texture_size(texImage
);
3283 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3284 if (!texImage
->Data
) {
3285 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
3289 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
3290 pixels
, packing
, "glTexImage2D");
3292 /* Note: we check for a NULL image pointer here, _after_ we allocated
3293 * memory for the texture. That's what the GL spec calls for.
3298 GLint dstRowStride
= texture_row_stride(texImage
);
3299 GLboolean success
= _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
3300 texImage
->TexFormat
,
3302 0, 0, 0, /* dstX/Y/Zoffset */
3304 texImage
->ImageOffsets
,
3306 format
, type
, pixels
, packing
);
3308 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
3312 _mesa_unmap_teximage_pbo(ctx
, packing
);
3318 * This is the software fallback for Driver.TexImage3D()
3319 * and Driver.CopyTexImage3D().
3320 * \sa _mesa_store_teximage2d()
3323 _mesa_store_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3324 GLint internalFormat
,
3325 GLint width
, GLint height
, GLint depth
, GLint border
,
3326 GLenum format
, GLenum type
, const void *pixels
,
3327 const struct gl_pixelstore_attrib
*packing
,
3328 struct gl_texture_object
*texObj
,
3329 struct gl_texture_image
*texImage
)
3335 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3336 ASSERT(texImage
->TexFormat
);
3338 _mesa_set_fetch_functions(texImage
, 3);
3340 /* allocate memory */
3341 sizeInBytes
= texture_size(texImage
);
3342 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3343 if (!texImage
->Data
) {
3344 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
3348 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
3349 type
, pixels
, packing
, "glTexImage3D");
3351 /* Note: we check for a NULL image pointer here, _after_ we allocated
3352 * memory for the texture. That's what the GL spec calls for.
3357 GLint dstRowStride
= texture_row_stride(texImage
);
3358 GLboolean success
= _mesa_texstore(ctx
, 3, texImage
->_BaseFormat
,
3359 texImage
->TexFormat
,
3361 0, 0, 0, /* dstX/Y/Zoffset */
3363 texImage
->ImageOffsets
,
3364 width
, height
, depth
,
3365 format
, type
, pixels
, packing
);
3367 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
3371 _mesa_unmap_teximage_pbo(ctx
, packing
);
3378 * This is the software fallback for Driver.TexSubImage1D()
3379 * and Driver.CopyTexSubImage1D().
3382 _mesa_store_texsubimage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3383 GLint xoffset
, GLint width
,
3384 GLenum format
, GLenum type
, const void *pixels
,
3385 const struct gl_pixelstore_attrib
*packing
,
3386 struct gl_texture_object
*texObj
,
3387 struct gl_texture_image
*texImage
)
3389 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3390 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
3391 pixels
, packing
, "glTexSubImage1D");
3396 const GLint dstRowStride
= 0;
3397 GLboolean success
= _mesa_texstore(ctx
, 1, texImage
->_BaseFormat
,
3398 texImage
->TexFormat
,
3400 xoffset
, 0, 0, /* offsets */
3402 texImage
->ImageOffsets
,
3404 format
, type
, pixels
, packing
);
3406 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
3410 _mesa_unmap_teximage_pbo(ctx
, packing
);
3416 * This is the software fallback for Driver.TexSubImage2D()
3417 * and Driver.CopyTexSubImage2D().
3420 _mesa_store_texsubimage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3421 GLint xoffset
, GLint yoffset
,
3422 GLint width
, GLint height
,
3423 GLenum format
, GLenum type
, const void *pixels
,
3424 const struct gl_pixelstore_attrib
*packing
,
3425 struct gl_texture_object
*texObj
,
3426 struct gl_texture_image
*texImage
)
3428 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3429 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
3430 pixels
, packing
, "glTexSubImage2D");
3435 GLint dstRowStride
= texture_row_stride(texImage
);
3436 GLboolean success
= _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
3437 texImage
->TexFormat
,
3439 xoffset
, yoffset
, 0,
3441 texImage
->ImageOffsets
,
3443 format
, type
, pixels
, packing
);
3445 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
3449 _mesa_unmap_teximage_pbo(ctx
, packing
);
3454 * This is the software fallback for Driver.TexSubImage3D().
3455 * and Driver.CopyTexSubImage3D().
3458 _mesa_store_texsubimage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3459 GLint xoffset
, GLint yoffset
, GLint zoffset
,
3460 GLint width
, GLint height
, GLint depth
,
3461 GLenum format
, GLenum type
, const void *pixels
,
3462 const struct gl_pixelstore_attrib
*packing
,
3463 struct gl_texture_object
*texObj
,
3464 struct gl_texture_image
*texImage
)
3466 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3467 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
3468 type
, pixels
, packing
,
3474 GLint dstRowStride
= texture_row_stride(texImage
);
3475 GLboolean success
= _mesa_texstore(ctx
, 3, texImage
->_BaseFormat
,
3476 texImage
->TexFormat
,
3478 xoffset
, yoffset
, zoffset
,
3480 texImage
->ImageOffsets
,
3481 width
, height
, depth
,
3482 format
, type
, pixels
, packing
);
3484 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3D");
3488 _mesa_unmap_teximage_pbo(ctx
, packing
);
3493 * Fallback for Driver.CompressedTexImage1D()
3496 _mesa_store_compressed_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3497 GLint internalFormat
,
3498 GLint width
, GLint border
,
3499 GLsizei imageSize
, const GLvoid
*data
,
3500 struct gl_texture_object
*texObj
,
3501 struct gl_texture_image
*texImage
)
3503 /* this space intentionally left blank */
3505 (void) target
; (void) level
;
3506 (void) internalFormat
;
3507 (void) width
; (void) border
;
3508 (void) imageSize
; (void) data
;
3516 * Fallback for Driver.CompressedTexImage2D()
3519 _mesa_store_compressed_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3520 GLint internalFormat
,
3521 GLint width
, GLint height
, GLint border
,
3522 GLsizei imageSize
, const GLvoid
*data
,
3523 struct gl_texture_object
*texObj
,
3524 struct gl_texture_image
*texImage
)
3526 (void) width
; (void) height
; (void) border
;
3528 /* This is pretty simple, basically just do a memcpy without worrying
3529 * about the usual image unpacking or image transfer operations.
3533 ASSERT(texImage
->Width
> 0);
3534 ASSERT(texImage
->Height
> 0);
3535 ASSERT(texImage
->Depth
== 1);
3536 ASSERT(texImage
->Data
== NULL
); /* was freed in glCompressedTexImage2DARB */
3539 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, 0, 0);
3540 ASSERT(texImage
->TexFormat
);
3542 _mesa_set_fetch_functions(texImage
, 2);
3544 /* allocate storage */
3545 texImage
->Data
= _mesa_alloc_texmemory(imageSize
);
3546 if (!texImage
->Data
) {
3547 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
3551 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
3553 "glCompressedTexImage2D");
3558 MEMCPY(texImage
->Data
, data
, imageSize
);
3560 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
3566 * Fallback for Driver.CompressedTexImage3D()
3569 _mesa_store_compressed_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3570 GLint internalFormat
,
3571 GLint width
, GLint height
, GLint depth
,
3573 GLsizei imageSize
, const GLvoid
*data
,
3574 struct gl_texture_object
*texObj
,
3575 struct gl_texture_image
*texImage
)
3577 /* this space intentionally left blank */
3579 (void) target
; (void) level
;
3580 (void) internalFormat
;
3581 (void) width
; (void) height
; (void) depth
;
3583 (void) imageSize
; (void) data
;
3591 * Fallback for Driver.CompressedTexSubImage1D()
3594 _mesa_store_compressed_texsubimage1d(GLcontext
*ctx
, GLenum target
,
3596 GLint xoffset
, GLsizei width
,
3598 GLsizei imageSize
, const GLvoid
*data
,
3599 struct gl_texture_object
*texObj
,
3600 struct gl_texture_image
*texImage
)
3602 /* there are no compressed 1D texture formats yet */
3604 (void) target
; (void) level
;
3605 (void) xoffset
; (void) width
;
3607 (void) imageSize
; (void) data
;
3614 * Fallback for Driver.CompressedTexSubImage2D()
3617 _mesa_store_compressed_texsubimage2d(GLcontext
*ctx
, GLenum target
,
3619 GLint xoffset
, GLint yoffset
,
3620 GLsizei width
, GLsizei height
,
3622 GLsizei imageSize
, const GLvoid
*data
,
3623 struct gl_texture_object
*texObj
,
3624 struct gl_texture_image
*texImage
)
3626 GLint bytesPerRow
, destRowStride
, srcRowStride
;
3630 const gl_format texFormat
= texImage
->TexFormat
;
3634 /* these should have been caught sooner */
3635 ASSERT((width
& 3) == 0 || width
== 2 || width
== 1);
3636 ASSERT((height
& 3) == 0 || height
== 2 || height
== 1);
3637 ASSERT((xoffset
& 3) == 0);
3638 ASSERT((yoffset
& 3) == 0);
3640 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3641 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
3643 "glCompressedTexSubImage2D");
3647 srcRowStride
= _mesa_compressed_row_stride(texFormat
, width
);
3648 src
= (const GLubyte
*) data
;
3650 destRowStride
= _mesa_compressed_row_stride(texFormat
, texImage
->Width
);
3651 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
3654 (GLubyte
*) texImage
->Data
);
3656 bytesPerRow
= srcRowStride
;
3659 for (i
= 0; i
< rows
; i
++) {
3660 MEMCPY(dest
, src
, bytesPerRow
);
3661 dest
+= destRowStride
;
3662 src
+= srcRowStride
;
3665 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
3670 * Fallback for Driver.CompressedTexSubImage3D()
3673 _mesa_store_compressed_texsubimage3d(GLcontext
*ctx
, GLenum target
,
3675 GLint xoffset
, GLint yoffset
, GLint zoffset
,
3676 GLsizei width
, GLsizei height
, GLsizei depth
,
3678 GLsizei imageSize
, const GLvoid
*data
,
3679 struct gl_texture_object
*texObj
,
3680 struct gl_texture_image
*texImage
)
3682 /* there are no compressed 3D texture formats yet */
3684 (void) target
; (void) level
;
3685 (void) xoffset
; (void) yoffset
; (void) zoffset
;
3686 (void) width
; (void) height
; (void) depth
;
3688 (void) imageSize
; (void) data
;