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"
79 * Texture image storage function.
81 typedef GLboolean (*StoreTexImageFunc
)(TEXSTORE_PARAMS
);
85 * Return GL_TRUE if the given image format is one that be converted
86 * to another format by swizzling.
89 can_swizzle(GLenum logicalBaseFormat
)
91 switch (logicalBaseFormat
) {
94 case GL_LUMINANCE_ALPHA
:
128 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO)
129 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO)
130 #define MAP3(x,y,z) MAP4(x, y, z, ZERO)
131 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
134 static const struct {
137 GLubyte from_rgba
[6];
138 } mappings
[MAX_IDX
] =
148 MAP4(ZERO
, ZERO
, ZERO
, 0),
179 MAP4(0, ZERO
, ZERO
, ONE
),
185 MAP4(ZERO
, 0, ZERO
, ONE
),
191 MAP4(ZERO
, ZERO
, 0, ONE
),
217 * Convert a GL image format enum to an IDX_* value (see above).
220 get_map_idx(GLenum value
)
223 case GL_LUMINANCE
: return IDX_LUMINANCE
;
224 case GL_ALPHA
: return IDX_ALPHA
;
225 case GL_INTENSITY
: return IDX_INTENSITY
;
226 case GL_LUMINANCE_ALPHA
: return IDX_LUMINANCE_ALPHA
;
227 case GL_RGB
: return IDX_RGB
;
228 case GL_RGBA
: return IDX_RGBA
;
229 case GL_RED
: return IDX_RED
;
230 case GL_GREEN
: return IDX_GREEN
;
231 case GL_BLUE
: return IDX_BLUE
;
232 case GL_BGR
: return IDX_BGR
;
233 case GL_BGRA
: return IDX_BGRA
;
234 case GL_ABGR_EXT
: return IDX_ABGR
;
236 _mesa_problem(NULL
, "Unexpected inFormat");
243 * When promoting texture formats (see below) we need to compute the
244 * mapping of dest components back to source components.
245 * This function does that.
246 * \param inFormat the incoming format of the texture
247 * \param outFormat the final texture format
248 * \return map[6] a full 6-component map
251 compute_component_mapping(GLenum inFormat
, GLenum outFormat
,
254 const int inFmt
= get_map_idx(inFormat
);
255 const int outFmt
= get_map_idx(outFormat
);
256 const GLubyte
*in2rgba
= mappings
[inFmt
].to_rgba
;
257 const GLubyte
*rgba2out
= mappings
[outFmt
].from_rgba
;
260 for (i
= 0; i
< 4; i
++)
261 map
[i
] = in2rgba
[rgba2out
[i
]];
267 _mesa_printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
268 inFormat, _mesa_lookup_enum_by_nr(inFormat),
269 outFormat, _mesa_lookup_enum_by_nr(outFormat),
280 #if !FEATURE_convolve
282 _mesa_adjust_image_for_convolution(GLcontext
*ctx
, GLuint dims
,
283 GLsizei
*srcWidth
, GLsizei
*srcHeight
)
291 * Make a temporary (color) texture image with GLfloat components.
292 * Apply all needed pixel unpacking and pixel transfer operations.
293 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
294 * Suppose the user specifies GL_LUMINANCE as the internal texture format
295 * but the graphics hardware doesn't support luminance textures. So, might
296 * use an RGB hardware format instead.
297 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
299 * \param ctx the rendering context
300 * \param dims image dimensions: 1, 2 or 3
301 * \param logicalBaseFormat basic texture derived from the user's
302 * internal texture format value
303 * \param textureBaseFormat the actual basic format of the texture
304 * \param srcWidth source image width
305 * \param srcHeight source image height
306 * \param srcDepth source image depth
307 * \param srcFormat source image format
308 * \param srcType source image type
309 * \param srcAddr source image address
310 * \param srcPacking source image pixel packing
311 * \return resulting image with format = textureBaseFormat and type = GLfloat.
314 make_temp_float_image(GLcontext
*ctx
, GLuint dims
,
315 GLenum logicalBaseFormat
,
316 GLenum textureBaseFormat
,
317 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
318 GLenum srcFormat
, GLenum srcType
,
319 const GLvoid
*srcAddr
,
320 const struct gl_pixelstore_attrib
*srcPacking
)
322 GLuint transferOps
= ctx
->_ImageTransferState
;
325 ASSERT(dims
>= 1 && dims
<= 3);
327 ASSERT(logicalBaseFormat
== GL_RGBA
||
328 logicalBaseFormat
== GL_RGB
||
329 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
330 logicalBaseFormat
== GL_LUMINANCE
||
331 logicalBaseFormat
== GL_ALPHA
||
332 logicalBaseFormat
== GL_INTENSITY
||
333 logicalBaseFormat
== GL_COLOR_INDEX
||
334 logicalBaseFormat
== GL_DEPTH_COMPONENT
);
336 ASSERT(textureBaseFormat
== GL_RGBA
||
337 textureBaseFormat
== GL_RGB
||
338 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
339 textureBaseFormat
== GL_LUMINANCE
||
340 textureBaseFormat
== GL_ALPHA
||
341 textureBaseFormat
== GL_INTENSITY
||
342 textureBaseFormat
== GL_COLOR_INDEX
||
343 textureBaseFormat
== GL_DEPTH_COMPONENT
);
345 /* conventional color image */
347 if ((dims
== 1 && ctx
->Pixel
.Convolution1DEnabled
) ||
348 (dims
>= 2 && ctx
->Pixel
.Convolution2DEnabled
) ||
349 (dims
>= 2 && ctx
->Pixel
.Separable2DEnabled
)) {
350 /* need image convolution */
351 const GLuint preConvTransferOps
352 = (transferOps
& IMAGE_PRE_CONVOLUTION_BITS
) | IMAGE_CLAMP_BIT
;
353 const GLuint postConvTransferOps
354 = (transferOps
& IMAGE_POST_CONVOLUTION_BITS
) | IMAGE_CLAMP_BIT
;
356 GLint convWidth
, convHeight
;
359 /* pre-convolution image buffer (3D) */
360 tempImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
361 * 4 * sizeof(GLfloat
));
365 /* post-convolution image buffer (2D) */
366 convImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
367 * 4 * sizeof(GLfloat
));
369 _mesa_free(tempImage
);
373 /* loop over 3D image slices */
374 for (img
= 0; img
< srcDepth
; img
++) {
375 GLfloat
*dst
= tempImage
+ img
* (srcWidth
* srcHeight
* 4);
377 /* unpack and do transfer ops up to convolution */
378 for (row
= 0; row
< srcHeight
; row
++) {
379 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
380 srcAddr
, srcWidth
, srcHeight
,
381 srcFormat
, srcType
, img
, row
, 0);
382 _mesa_unpack_color_span_float(ctx
, srcWidth
, GL_RGBA
, dst
,
383 srcFormat
, srcType
, src
,
389 /* size after optional convolution */
390 convWidth
= srcWidth
;
391 convHeight
= srcHeight
;
396 GLfloat
*src
= tempImage
+ img
* (srcWidth
* srcHeight
* 4);
398 ASSERT(ctx
->Pixel
.Convolution1DEnabled
);
399 _mesa_convolve_1d_image(ctx
, &convWidth
, src
, convImage
);
402 if (ctx
->Pixel
.Convolution2DEnabled
) {
403 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
407 ASSERT(ctx
->Pixel
.Separable2DEnabled
);
408 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
414 /* do post-convolution transfer and pack into tempImage */
416 const GLint logComponents
417 = _mesa_components_in_format(logicalBaseFormat
);
418 const GLfloat
*src
= convImage
;
419 GLfloat
*dst
= tempImage
+ img
* (convWidth
* convHeight
* 4);
420 for (row
= 0; row
< convHeight
; row
++) {
421 _mesa_pack_rgba_span_float(ctx
, convWidth
,
422 (GLfloat (*)[4]) src
,
423 logicalBaseFormat
, GL_FLOAT
,
424 dst
, &ctx
->DefaultPacking
,
425 postConvTransferOps
);
426 src
+= convWidth
* 4;
427 dst
+= convWidth
* logComponents
;
430 } /* loop over 3D image slices */
432 _mesa_free(convImage
);
434 /* might need these below */
435 srcWidth
= convWidth
;
436 srcHeight
= convHeight
;
440 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
441 const GLint srcStride
=
442 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
446 tempImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
447 * components
* sizeof(GLfloat
));
452 for (img
= 0; img
< srcDepth
; img
++) {
454 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
458 for (row
= 0; row
< srcHeight
; row
++) {
459 _mesa_unpack_color_span_float(ctx
, srcWidth
, logicalBaseFormat
,
460 dst
, srcFormat
, srcType
, src
,
461 srcPacking
, transferOps
);
462 dst
+= srcWidth
* components
;
468 if (logicalBaseFormat
!= textureBaseFormat
) {
470 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
471 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
476 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
477 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
478 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
480 /* The actual texture format should have at least as many components
481 * as the logical texture format.
483 ASSERT(texComponents
>= logComponents
);
485 newImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
486 * texComponents
* sizeof(GLfloat
));
488 _mesa_free(tempImage
);
492 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
494 n
= srcWidth
* srcHeight
* srcDepth
;
495 for (i
= 0; i
< n
; i
++) {
497 for (k
= 0; k
< texComponents
; k
++) {
500 newImage
[i
* texComponents
+ k
] = 0.0F
;
502 newImage
[i
* texComponents
+ k
] = 1.0F
;
504 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
508 _mesa_free(tempImage
);
509 tempImage
= newImage
;
517 * Make a temporary (color) texture image with GLchan components.
518 * Apply all needed pixel unpacking and pixel transfer operations.
519 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
520 * Suppose the user specifies GL_LUMINANCE as the internal texture format
521 * but the graphics hardware doesn't support luminance textures. So, might
522 * use an RGB hardware format instead.
523 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
525 * \param ctx the rendering context
526 * \param dims image dimensions: 1, 2 or 3
527 * \param logicalBaseFormat basic texture derived from the user's
528 * internal texture format value
529 * \param textureBaseFormat the actual basic format of the texture
530 * \param srcWidth source image width
531 * \param srcHeight source image height
532 * \param srcDepth source image depth
533 * \param srcFormat source image format
534 * \param srcType source image type
535 * \param srcAddr source image address
536 * \param srcPacking source image pixel packing
537 * \return resulting image with format = textureBaseFormat and type = GLchan.
540 _mesa_make_temp_chan_image(GLcontext
*ctx
, GLuint dims
,
541 GLenum logicalBaseFormat
,
542 GLenum textureBaseFormat
,
543 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
544 GLenum srcFormat
, GLenum srcType
,
545 const GLvoid
*srcAddr
,
546 const struct gl_pixelstore_attrib
*srcPacking
)
548 GLuint transferOps
= ctx
->_ImageTransferState
;
549 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
550 GLboolean freeSrcImage
= GL_FALSE
;
552 GLchan
*tempImage
, *dst
;
554 ASSERT(dims
>= 1 && dims
<= 3);
556 ASSERT(logicalBaseFormat
== GL_RGBA
||
557 logicalBaseFormat
== GL_RGB
||
558 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
559 logicalBaseFormat
== GL_LUMINANCE
||
560 logicalBaseFormat
== GL_ALPHA
||
561 logicalBaseFormat
== GL_INTENSITY
);
563 ASSERT(textureBaseFormat
== GL_RGBA
||
564 textureBaseFormat
== GL_RGB
||
565 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
566 textureBaseFormat
== GL_LUMINANCE
||
567 textureBaseFormat
== GL_ALPHA
||
568 textureBaseFormat
== GL_INTENSITY
);
571 if ((dims
== 1 && ctx
->Pixel
.Convolution1DEnabled
) ||
572 (dims
>= 2 && ctx
->Pixel
.Convolution2DEnabled
) ||
573 (dims
>= 2 && ctx
->Pixel
.Separable2DEnabled
)) {
574 /* get convolved image */
575 GLfloat
*convImage
= make_temp_float_image(ctx
, dims
,
578 srcWidth
, srcHeight
, srcDepth
,
580 srcAddr
, srcPacking
);
583 /* the convolved image is our new source image */
585 srcFormat
= logicalBaseFormat
;
587 srcPacking
= &ctx
->DefaultPacking
;
588 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
590 freeSrcImage
= GL_TRUE
;
594 /* unpack and transfer the source image */
595 tempImage
= (GLchan
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
596 * components
* sizeof(GLchan
));
601 for (img
= 0; img
< srcDepth
; img
++) {
602 const GLint srcStride
=
603 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
605 (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
609 for (row
= 0; row
< srcHeight
; row
++) {
610 _mesa_unpack_color_span_chan(ctx
, srcWidth
, logicalBaseFormat
, dst
,
611 srcFormat
, srcType
, src
, srcPacking
,
613 dst
+= srcWidth
* components
;
618 /* If we made a temporary image for convolution, free it here */
620 _mesa_free((void *) srcAddr
);
623 if (logicalBaseFormat
!= textureBaseFormat
) {
624 /* one more conversion step */
625 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
626 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
631 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
632 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
633 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
635 /* The actual texture format should have at least as many components
636 * as the logical texture format.
638 ASSERT(texComponents
>= logComponents
);
640 newImage
= (GLchan
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
641 * texComponents
* sizeof(GLchan
));
643 _mesa_free(tempImage
);
647 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
649 n
= srcWidth
* srcHeight
* srcDepth
;
650 for (i
= 0; i
< n
; i
++) {
652 for (k
= 0; k
< texComponents
; k
++) {
655 newImage
[i
* texComponents
+ k
] = 0;
657 newImage
[i
* texComponents
+ k
] = CHAN_MAX
;
659 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
663 _mesa_free(tempImage
);
664 tempImage
= newImage
;
672 * Copy GLubyte pixels from <src> to <dst> with swizzling.
673 * \param dst destination pixels
674 * \param dstComponents number of color components in destination pixels
675 * \param src source pixels
676 * \param srcComponents number of color components in source pixels
677 * \param map the swizzle mapping. map[X] says where to find the X component
678 * in the source image's pixels. For example, if the source image
679 * is GL_BGRA and X = red, map[0] yields 2.
680 * \param count number of pixels to copy/swizzle.
683 swizzle_copy(GLubyte
*dst
, GLuint dstComponents
, const GLubyte
*src
,
684 GLuint srcComponents
, const GLubyte
*map
, GLuint count
)
686 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
689 for (i = 0; i < count; i++) { \
691 if (srcComps == 4) { \
692 COPY_4UBV(tmp, src); \
695 for (j = 0; j < srcComps; j++) { \
700 for (j = 0; j < dstComps; j++) { \
701 dst[j] = tmp[map[j]]; \
712 ASSERT(srcComponents
<= 4);
713 ASSERT(dstComponents
<= 4);
715 switch (dstComponents
) {
717 switch (srcComponents
) {
719 SWZ_CPY(dst
, src
, count
, 4, 4);
722 SWZ_CPY(dst
, src
, count
, 4, 3);
725 SWZ_CPY(dst
, src
, count
, 4, 2);
728 SWZ_CPY(dst
, src
, count
, 4, 1);
735 switch (srcComponents
) {
737 SWZ_CPY(dst
, src
, count
, 3, 4);
740 SWZ_CPY(dst
, src
, count
, 3, 3);
743 SWZ_CPY(dst
, src
, count
, 3, 2);
746 SWZ_CPY(dst
, src
, count
, 3, 1);
753 switch (srcComponents
) {
755 SWZ_CPY(dst
, src
, count
, 2, 4);
758 SWZ_CPY(dst
, src
, count
, 2, 3);
761 SWZ_CPY(dst
, src
, count
, 2, 2);
764 SWZ_CPY(dst
, src
, count
, 2, 1);
771 switch (srcComponents
) {
773 SWZ_CPY(dst
, src
, count
, 1, 4);
776 SWZ_CPY(dst
, src
, count
, 1, 3);
779 SWZ_CPY(dst
, src
, count
, 1, 2);
782 SWZ_CPY(dst
, src
, count
, 1, 1);
796 static const GLubyte map_identity
[6] = { 0, 1, 2, 3, ZERO
, ONE
};
797 static const GLubyte map_3210
[6] = { 3, 2, 1, 0, ZERO
, ONE
};
799 /* Deal with the _REV input types:
801 static const GLubyte
*
802 type_mapping( GLenum srcType
)
806 case GL_UNSIGNED_BYTE
:
808 case GL_UNSIGNED_INT_8_8_8_8
:
809 return _mesa_little_endian() ? map_3210
: map_identity
;
810 case GL_UNSIGNED_INT_8_8_8_8_REV
:
811 return _mesa_little_endian() ? map_identity
: map_3210
;
817 /* Mapping required if input type is
819 static const GLubyte
*
820 byteswap_mapping( GLboolean swapBytes
,
828 case GL_UNSIGNED_BYTE
:
830 case GL_UNSIGNED_INT_8_8_8_8
:
831 case GL_UNSIGNED_INT_8_8_8_8_REV
:
841 * Transfer a GLubyte texture image with component swizzling.
844 _mesa_swizzle_ubyte_image(GLcontext
*ctx
,
849 GLenum baseInternalFormat
,
851 const GLubyte
*rgba2dst
,
852 GLuint dstComponents
,
855 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
857 const GLuint
*dstImageOffsets
,
859 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
860 const GLvoid
*srcAddr
,
861 const struct gl_pixelstore_attrib
*srcPacking
)
863 GLint srcComponents
= _mesa_components_in_format(srcFormat
);
864 const GLubyte
*srctype2ubyte
, *swap
;
865 GLubyte map
[4], src2base
[6], base2rgba
[6];
867 const GLint srcRowStride
=
868 _mesa_image_row_stride(srcPacking
, srcWidth
,
869 srcFormat
, GL_UNSIGNED_BYTE
);
870 const GLint srcImageStride
871 = _mesa_image_image_stride(srcPacking
, srcWidth
, srcHeight
, srcFormat
,
873 const GLubyte
*srcImage
874 = (const GLubyte
*) _mesa_image_address(dimensions
, srcPacking
, srcAddr
,
875 srcWidth
, srcHeight
, srcFormat
,
876 GL_UNSIGNED_BYTE
, 0, 0, 0);
880 /* Translate from src->baseInternal->GL_RGBA->dst. This will
881 * correctly deal with RGBA->RGB->RGBA conversions where the final
882 * A value must be 0xff regardless of the incoming alpha values.
884 compute_component_mapping(srcFormat
, baseInternalFormat
, src2base
);
885 compute_component_mapping(baseInternalFormat
, GL_RGBA
, base2rgba
);
886 swap
= byteswap_mapping(srcPacking
->SwapBytes
, srcType
);
887 srctype2ubyte
= type_mapping(srcType
);
890 for (i
= 0; i
< 4; i
++)
891 map
[i
] = srctype2ubyte
[swap
[src2base
[base2rgba
[rgba2dst
[i
]]]]];
893 /* _mesa_printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */
895 if (srcComponents
== dstComponents
&&
896 srcRowStride
== dstRowStride
&&
897 srcRowStride
== srcWidth
* srcComponents
&&
899 /* 1 and 2D images only */
900 GLubyte
*dstImage
= (GLubyte
*) dstAddr
901 + dstYoffset
* dstRowStride
902 + dstXoffset
* dstComponents
;
903 swizzle_copy(dstImage
, dstComponents
, srcImage
, srcComponents
, map
,
904 srcWidth
* srcHeight
);
908 for (img
= 0; img
< srcDepth
; img
++) {
909 const GLubyte
*srcRow
= srcImage
;
910 GLubyte
*dstRow
= (GLubyte
*) dstAddr
911 + dstImageOffsets
[dstZoffset
+ img
] * dstComponents
912 + dstYoffset
* dstRowStride
913 + dstXoffset
* dstComponents
;
914 for (row
= 0; row
< srcHeight
; row
++) {
915 swizzle_copy(dstRow
, dstComponents
, srcRow
, srcComponents
, map
, srcWidth
);
916 dstRow
+= dstRowStride
;
917 srcRow
+= srcRowStride
;
919 srcImage
+= srcImageStride
;
926 * Teximage storage routine for when a simple memcpy will do.
927 * No pixel transfer operations or special texel encodings allowed.
928 * 1D, 2D and 3D images supported.
931 memcpy_texture(GLcontext
*ctx
,
935 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
937 const GLuint
*dstImageOffsets
,
938 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
939 GLenum srcFormat
, GLenum srcType
,
940 const GLvoid
*srcAddr
,
941 const struct gl_pixelstore_attrib
*srcPacking
)
943 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
945 const GLint srcImageStride
= _mesa_image_image_stride(srcPacking
,
946 srcWidth
, srcHeight
, srcFormat
, srcType
);
947 const GLubyte
*srcImage
= (const GLubyte
*) _mesa_image_address(dimensions
,
948 srcPacking
, srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, 0, 0, 0);
949 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
950 const GLint bytesPerRow
= srcWidth
* texelBytes
;
953 /* XXX update/re-enable for dstImageOffsets array */
954 const GLint bytesPerImage
= srcHeight
* bytesPerRow
;
955 const GLint bytesPerTexture
= srcDepth
* bytesPerImage
;
956 GLubyte
*dstImage
= (GLubyte
*) dstAddr
957 + dstZoffset
* dstImageStride
958 + dstYoffset
* dstRowStride
959 + dstXoffset
* texelBytes
;
961 if (dstRowStride
== srcRowStride
&&
962 dstRowStride
== bytesPerRow
&&
963 ((dstImageStride
== srcImageStride
&&
964 dstImageStride
== bytesPerImage
) ||
967 ctx
->Driver
.TextureMemCpy(dstImage
, srcImage
, bytesPerTexture
);
972 for (img
= 0; img
< srcDepth
; img
++) {
973 const GLubyte
*srcRow
= srcImage
;
974 GLubyte
*dstRow
= dstImage
;
975 for (row
= 0; row
< srcHeight
; row
++) {
976 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
977 dstRow
+= dstRowStride
;
978 srcRow
+= srcRowStride
;
980 srcImage
+= srcImageStride
;
981 dstImage
+= dstImageStride
;
987 for (img
= 0; img
< srcDepth
; img
++) {
988 const GLubyte
*srcRow
= srcImage
;
989 GLubyte
*dstRow
= (GLubyte
*) dstAddr
990 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
991 + dstYoffset
* dstRowStride
992 + dstXoffset
* texelBytes
;
993 for (row
= 0; row
< srcHeight
; row
++) {
994 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
995 dstRow
+= dstRowStride
;
996 srcRow
+= srcRowStride
;
998 srcImage
+= srcImageStride
;
1005 * Store a 32-bit integer depth component texture image.
1008 _mesa_texstore_z32(TEXSTORE_PARAMS
)
1010 const GLuint depthScale
= 0xffffffff;
1011 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1013 ASSERT(dstFormat
== MESA_FORMAT_Z32
);
1014 ASSERT(texelBytes
== sizeof(GLuint
));
1016 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1017 ctx
->Pixel
.DepthBias
== 0.0f
&&
1018 !srcPacking
->SwapBytes
&&
1019 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1020 srcFormat
== GL_DEPTH_COMPONENT
&&
1021 srcType
== GL_UNSIGNED_INT
) {
1022 /* simple memcpy path */
1023 memcpy_texture(ctx
, dims
,
1024 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1027 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1028 srcAddr
, srcPacking
);
1033 for (img
= 0; img
< srcDepth
; img
++) {
1034 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1035 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1036 + dstYoffset
* dstRowStride
1037 + dstXoffset
* texelBytes
;
1038 for (row
= 0; row
< srcHeight
; row
++) {
1039 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1040 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1041 _mesa_unpack_depth_span(ctx
, srcWidth
,
1042 GL_UNSIGNED_INT
, (GLuint
*) dstRow
,
1043 depthScale
, srcType
, src
, srcPacking
);
1044 dstRow
+= dstRowStride
;
1054 * Store a 16-bit integer depth component texture image.
1057 _mesa_texstore_z16(TEXSTORE_PARAMS
)
1059 const GLuint depthScale
= 0xffff;
1060 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1062 ASSERT(dstFormat
== MESA_FORMAT_Z16
);
1063 ASSERT(texelBytes
== sizeof(GLushort
));
1065 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1066 ctx
->Pixel
.DepthBias
== 0.0f
&&
1067 !srcPacking
->SwapBytes
&&
1068 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1069 srcFormat
== GL_DEPTH_COMPONENT
&&
1070 srcType
== GL_UNSIGNED_SHORT
) {
1071 /* simple memcpy path */
1072 memcpy_texture(ctx
, dims
,
1073 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1076 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1077 srcAddr
, srcPacking
);
1082 for (img
= 0; img
< srcDepth
; img
++) {
1083 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1084 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1085 + dstYoffset
* dstRowStride
1086 + dstXoffset
* texelBytes
;
1087 for (row
= 0; row
< srcHeight
; row
++) {
1088 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1089 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1090 GLushort
*dst16
= (GLushort
*) dstRow
;
1091 _mesa_unpack_depth_span(ctx
, srcWidth
,
1092 GL_UNSIGNED_SHORT
, dst16
, depthScale
,
1093 srcType
, src
, srcPacking
);
1094 dstRow
+= dstRowStride
;
1103 * Store an rgb565 or rgb565_rev texture image.
1106 _mesa_texstore_rgb565(TEXSTORE_PARAMS
)
1108 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1109 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1111 ASSERT(dstFormat
== MESA_FORMAT_RGB565
||
1112 dstFormat
== MESA_FORMAT_RGB565_REV
);
1113 ASSERT(texelBytes
== 2);
1115 if (!ctx
->_ImageTransferState
&&
1116 !srcPacking
->SwapBytes
&&
1117 dstFormat
== MESA_FORMAT_RGB565
&&
1118 baseInternalFormat
== GL_RGB
&&
1119 srcFormat
== GL_RGB
&&
1120 srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1121 /* simple memcpy path */
1122 memcpy_texture(ctx
, dims
,
1123 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1126 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1127 srcAddr
, srcPacking
);
1129 else if (!ctx
->_ImageTransferState
&&
1130 !srcPacking
->SwapBytes
&&
1131 baseInternalFormat
== GL_RGB
&&
1132 srcFormat
== GL_RGB
&&
1133 srcType
== GL_UNSIGNED_BYTE
&&
1135 /* do optimized tex store */
1136 const GLint srcRowStride
=
1137 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1138 const GLubyte
*src
= (const GLubyte
*)
1139 _mesa_image_address(dims
, srcPacking
, srcAddr
, srcWidth
, srcHeight
,
1140 srcFormat
, srcType
, 0, 0, 0);
1141 GLubyte
*dst
= (GLubyte
*) dstAddr
1142 + dstYoffset
* dstRowStride
1143 + dstXoffset
* texelBytes
;
1145 for (row
= 0; row
< srcHeight
; row
++) {
1146 const GLubyte
*srcUB
= (const GLubyte
*) src
;
1147 GLushort
*dstUS
= (GLushort
*) dst
;
1148 /* check for byteswapped format */
1149 if (dstFormat
== MESA_FORMAT_RGB565
) {
1150 for (col
= 0; col
< srcWidth
; col
++) {
1151 dstUS
[col
] = PACK_COLOR_565( srcUB
[0], srcUB
[1], srcUB
[2] );
1156 for (col
= 0; col
< srcWidth
; col
++) {
1157 dstUS
[col
] = PACK_COLOR_565_REV( srcUB
[0], srcUB
[1], srcUB
[2] );
1161 dst
+= dstRowStride
;
1162 src
+= srcRowStride
;
1167 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1170 srcWidth
, srcHeight
, srcDepth
,
1171 srcFormat
, srcType
, srcAddr
,
1173 const GLchan
*src
= tempImage
;
1174 GLint img
, row
, col
;
1177 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1178 for (img
= 0; img
< srcDepth
; img
++) {
1179 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1180 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1181 + dstYoffset
* dstRowStride
1182 + dstXoffset
* texelBytes
;
1183 for (row
= 0; row
< srcHeight
; row
++) {
1184 GLushort
*dstUS
= (GLushort
*) dstRow
;
1185 /* check for byteswapped format */
1186 if (dstFormat
== MESA_FORMAT_RGB565
) {
1187 for (col
= 0; col
< srcWidth
; col
++) {
1188 dstUS
[col
] = PACK_COLOR_565( CHAN_TO_UBYTE(src
[RCOMP
]),
1189 CHAN_TO_UBYTE(src
[GCOMP
]),
1190 CHAN_TO_UBYTE(src
[BCOMP
]) );
1195 for (col
= 0; col
< srcWidth
; col
++) {
1196 dstUS
[col
] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1197 CHAN_TO_UBYTE(src
[GCOMP
]),
1198 CHAN_TO_UBYTE(src
[BCOMP
]) );
1202 dstRow
+= dstRowStride
;
1205 _mesa_free((void *) tempImage
);
1212 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1215 _mesa_texstore_rgba8888(TEXSTORE_PARAMS
)
1217 const GLboolean littleEndian
= _mesa_little_endian();
1218 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1219 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1221 ASSERT(dstFormat
== MESA_FORMAT_RGBA8888
||
1222 dstFormat
== MESA_FORMAT_RGBA8888_REV
);
1223 ASSERT(texelBytes
== 4);
1225 if (!ctx
->_ImageTransferState
&&
1226 !srcPacking
->SwapBytes
&&
1227 dstFormat
== MESA_FORMAT_RGBA8888
&&
1228 baseInternalFormat
== GL_RGBA
&&
1229 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1230 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1231 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1232 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
))) {
1233 /* simple memcpy path */
1234 memcpy_texture(ctx
, dims
,
1235 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1238 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1239 srcAddr
, srcPacking
);
1241 else if (!ctx
->_ImageTransferState
&&
1242 !srcPacking
->SwapBytes
&&
1243 dstFormat
== MESA_FORMAT_RGBA8888_REV
&&
1244 baseInternalFormat
== GL_RGBA
&&
1245 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1246 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1247 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1248 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
))) {
1249 /* simple memcpy path */
1250 memcpy_texture(ctx
, dims
,
1251 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1254 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1255 srcAddr
, srcPacking
);
1257 else if (!ctx
->_ImageTransferState
&&
1258 (srcType
== GL_UNSIGNED_BYTE
||
1259 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1260 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1261 can_swizzle(baseInternalFormat
) &&
1262 can_swizzle(srcFormat
)) {
1266 /* dstmap - how to swizzle from RGBA to dst format:
1268 if ((littleEndian
&& dstFormat
== MESA_FORMAT_RGBA8888
) ||
1269 (!littleEndian
&& dstFormat
== MESA_FORMAT_RGBA8888_REV
)) {
1282 _mesa_swizzle_ubyte_image(ctx
, dims
,
1287 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1288 dstRowStride
, dstImageOffsets
,
1289 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1294 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1297 srcWidth
, srcHeight
, srcDepth
,
1298 srcFormat
, srcType
, srcAddr
,
1300 const GLchan
*src
= tempImage
;
1301 GLint img
, row
, col
;
1304 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1305 for (img
= 0; img
< srcDepth
; img
++) {
1306 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1307 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1308 + dstYoffset
* dstRowStride
1309 + dstXoffset
* texelBytes
;
1310 for (row
= 0; row
< srcHeight
; row
++) {
1311 GLuint
*dstUI
= (GLuint
*) dstRow
;
1312 if (dstFormat
== MESA_FORMAT_RGBA8888
) {
1313 for (col
= 0; col
< srcWidth
; col
++) {
1314 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[RCOMP
]),
1315 CHAN_TO_UBYTE(src
[GCOMP
]),
1316 CHAN_TO_UBYTE(src
[BCOMP
]),
1317 CHAN_TO_UBYTE(src
[ACOMP
]) );
1322 for (col
= 0; col
< srcWidth
; col
++) {
1323 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1324 CHAN_TO_UBYTE(src
[GCOMP
]),
1325 CHAN_TO_UBYTE(src
[BCOMP
]),
1326 CHAN_TO_UBYTE(src
[ACOMP
]) );
1330 dstRow
+= dstRowStride
;
1333 _mesa_free((void *) tempImage
);
1340 _mesa_texstore_argb8888(TEXSTORE_PARAMS
)
1342 const GLboolean littleEndian
= _mesa_little_endian();
1343 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1344 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1346 ASSERT(dstFormat
== MESA_FORMAT_ARGB8888
||
1347 dstFormat
== MESA_FORMAT_ARGB8888_REV
);
1348 ASSERT(texelBytes
== 4);
1350 if (!ctx
->_ImageTransferState
&&
1351 !srcPacking
->SwapBytes
&&
1352 dstFormat
== MESA_FORMAT_ARGB8888
&&
1353 baseInternalFormat
== GL_RGBA
&&
1354 srcFormat
== GL_BGRA
&&
1355 ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1356 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
1357 /* simple memcpy path (little endian) */
1358 memcpy_texture(ctx
, dims
,
1359 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1362 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1363 srcAddr
, srcPacking
);
1365 else if (!ctx
->_ImageTransferState
&&
1366 !srcPacking
->SwapBytes
&&
1367 dstFormat
== MESA_FORMAT_ARGB8888_REV
&&
1368 baseInternalFormat
== GL_RGBA
&&
1369 srcFormat
== GL_BGRA
&&
1370 ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1371 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
1372 /* simple memcpy path (big endian) */
1373 memcpy_texture(ctx
, dims
,
1374 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1377 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1378 srcAddr
, srcPacking
);
1380 else if (!ctx
->_ImageTransferState
&&
1381 !srcPacking
->SwapBytes
&&
1382 dstFormat
== MESA_FORMAT_ARGB8888
&&
1383 srcFormat
== GL_RGB
&&
1384 (baseInternalFormat
== GL_RGBA
||
1385 baseInternalFormat
== GL_RGB
) &&
1386 srcType
== GL_UNSIGNED_BYTE
) {
1388 for (img
= 0; img
< srcDepth
; img
++) {
1389 const GLint srcRowStride
=
1390 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1391 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1392 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1393 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1394 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1395 + dstYoffset
* dstRowStride
1396 + dstXoffset
* texelBytes
;
1397 for (row
= 0; row
< srcHeight
; row
++) {
1398 GLuint
*d4
= (GLuint
*) dstRow
;
1399 for (col
= 0; col
< srcWidth
; col
++) {
1400 d4
[col
] = PACK_COLOR_8888(0xff,
1401 srcRow
[col
* 3 + RCOMP
],
1402 srcRow
[col
* 3 + GCOMP
],
1403 srcRow
[col
* 3 + BCOMP
]);
1405 dstRow
+= dstRowStride
;
1406 srcRow
+= srcRowStride
;
1410 else if (!ctx
->_ImageTransferState
&&
1411 !srcPacking
->SwapBytes
&&
1412 dstFormat
== MESA_FORMAT_ARGB8888
&&
1413 srcFormat
== GL_RGBA
&&
1414 baseInternalFormat
== GL_RGBA
&&
1415 srcType
== GL_UNSIGNED_BYTE
) {
1416 /* same as above case, but src data has alpha too */
1417 GLint img
, row
, col
;
1418 /* For some reason, streaming copies to write-combined regions
1419 * are extremely sensitive to the characteristics of how the
1420 * source data is retrieved. By reordering the source reads to
1421 * be in-order, the speed of this operation increases by half.
1422 * Strangely the same isn't required for the RGB path, above.
1424 for (img
= 0; img
< srcDepth
; img
++) {
1425 const GLint srcRowStride
=
1426 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1427 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1428 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1429 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1430 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1431 + dstYoffset
* dstRowStride
1432 + dstXoffset
* texelBytes
;
1433 for (row
= 0; row
< srcHeight
; row
++) {
1434 GLuint
*d4
= (GLuint
*) dstRow
;
1435 for (col
= 0; col
< srcWidth
; col
++) {
1436 d4
[col
] = PACK_COLOR_8888(srcRow
[col
* 4 + ACOMP
],
1437 srcRow
[col
* 4 + RCOMP
],
1438 srcRow
[col
* 4 + GCOMP
],
1439 srcRow
[col
* 4 + BCOMP
]);
1441 dstRow
+= dstRowStride
;
1442 srcRow
+= srcRowStride
;
1446 else if (!ctx
->_ImageTransferState
&&
1447 (srcType
== GL_UNSIGNED_BYTE
||
1448 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1449 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1450 can_swizzle(baseInternalFormat
) &&
1451 can_swizzle(srcFormat
)) {
1455 /* dstmap - how to swizzle from RGBA to dst format:
1457 if ((littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888
) ||
1458 (!littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888_REV
)) {
1459 dstmap
[3] = 3; /* alpha */
1460 dstmap
[2] = 0; /* red */
1461 dstmap
[1] = 1; /* green */
1462 dstmap
[0] = 2; /* blue */
1465 assert((littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888_REV
) ||
1466 (!littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888
));
1473 _mesa_swizzle_ubyte_image(ctx
, dims
,
1479 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1482 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1487 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1490 srcWidth
, srcHeight
, srcDepth
,
1491 srcFormat
, srcType
, srcAddr
,
1493 const GLchan
*src
= tempImage
;
1494 GLint img
, row
, col
;
1497 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1498 for (img
= 0; img
< srcDepth
; img
++) {
1499 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1500 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1501 + dstYoffset
* dstRowStride
1502 + dstXoffset
* texelBytes
;
1503 for (row
= 0; row
< srcHeight
; row
++) {
1504 GLuint
*dstUI
= (GLuint
*) dstRow
;
1505 if (dstFormat
== MESA_FORMAT_ARGB8888
) {
1506 for (col
= 0; col
< srcWidth
; col
++) {
1507 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[ACOMP
]),
1508 CHAN_TO_UBYTE(src
[RCOMP
]),
1509 CHAN_TO_UBYTE(src
[GCOMP
]),
1510 CHAN_TO_UBYTE(src
[BCOMP
]) );
1515 for (col
= 0; col
< srcWidth
; col
++) {
1516 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1517 CHAN_TO_UBYTE(src
[RCOMP
]),
1518 CHAN_TO_UBYTE(src
[GCOMP
]),
1519 CHAN_TO_UBYTE(src
[BCOMP
]) );
1523 dstRow
+= dstRowStride
;
1526 _mesa_free((void *) tempImage
);
1533 _mesa_texstore_rgb888(TEXSTORE_PARAMS
)
1535 const GLboolean littleEndian
= _mesa_little_endian();
1536 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1537 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1539 ASSERT(dstFormat
== MESA_FORMAT_RGB888
);
1540 ASSERT(texelBytes
== 3);
1542 if (!ctx
->_ImageTransferState
&&
1543 !srcPacking
->SwapBytes
&&
1544 baseInternalFormat
== GL_RGB
&&
1545 srcFormat
== GL_BGR
&&
1546 srcType
== GL_UNSIGNED_BYTE
&&
1548 /* simple memcpy path */
1549 memcpy_texture(ctx
, dims
,
1550 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1553 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1554 srcAddr
, srcPacking
);
1556 else if (!ctx
->_ImageTransferState
&&
1557 !srcPacking
->SwapBytes
&&
1558 srcFormat
== GL_RGBA
&&
1559 srcType
== GL_UNSIGNED_BYTE
) {
1560 /* extract RGB from RGBA */
1561 GLint img
, row
, col
;
1562 for (img
= 0; img
< srcDepth
; img
++) {
1563 const GLint srcRowStride
=
1564 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1565 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1566 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1567 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1568 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1569 + dstYoffset
* dstRowStride
1570 + dstXoffset
* texelBytes
;
1571 for (row
= 0; row
< srcHeight
; row
++) {
1572 for (col
= 0; col
< srcWidth
; col
++) {
1573 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + BCOMP
];
1574 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1575 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + RCOMP
];
1577 dstRow
+= dstRowStride
;
1578 srcRow
+= srcRowStride
;
1582 else if (!ctx
->_ImageTransferState
&&
1583 srcType
== GL_UNSIGNED_BYTE
&&
1584 can_swizzle(baseInternalFormat
) &&
1585 can_swizzle(srcFormat
)) {
1589 /* dstmap - how to swizzle from RGBA to dst format:
1594 dstmap
[3] = ONE
; /* ? */
1596 _mesa_swizzle_ubyte_image(ctx
, dims
,
1601 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1602 dstRowStride
, dstImageOffsets
,
1603 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1608 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1611 srcWidth
, srcHeight
, srcDepth
,
1612 srcFormat
, srcType
, srcAddr
,
1614 const GLchan
*src
= (const GLchan
*) tempImage
;
1615 GLint img
, row
, col
;
1618 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1619 for (img
= 0; img
< srcDepth
; img
++) {
1620 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1621 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1622 + dstYoffset
* dstRowStride
1623 + dstXoffset
* texelBytes
;
1624 for (row
= 0; row
< srcHeight
; row
++) {
1627 for (col
= 0; col
< srcWidth
; col
++) {
1628 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1629 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1630 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1635 for (col
= 0; col
< srcWidth
; col
++) {
1636 dstRow
[col
* 3 + 0] = srcUB
[BCOMP
];
1637 dstRow
[col
* 3 + 1] = srcUB
[GCOMP
];
1638 dstRow
[col
* 3 + 2] = srcUB
[RCOMP
];
1643 for (col
= 0; col
< srcWidth
; col
++) {
1644 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[BCOMP
]);
1645 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1646 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[RCOMP
]);
1650 dstRow
+= dstRowStride
;
1653 _mesa_free((void *) tempImage
);
1660 _mesa_texstore_bgr888(TEXSTORE_PARAMS
)
1662 const GLboolean littleEndian
= _mesa_little_endian();
1663 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1664 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1666 ASSERT(dstFormat
== MESA_FORMAT_BGR888
);
1667 ASSERT(texelBytes
== 3);
1669 if (!ctx
->_ImageTransferState
&&
1670 !srcPacking
->SwapBytes
&&
1671 baseInternalFormat
== GL_RGB
&&
1672 srcFormat
== GL_RGB
&&
1673 srcType
== GL_UNSIGNED_BYTE
&&
1675 /* simple memcpy path */
1676 memcpy_texture(ctx
, dims
,
1677 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1680 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1681 srcAddr
, srcPacking
);
1683 else if (!ctx
->_ImageTransferState
&&
1684 !srcPacking
->SwapBytes
&&
1685 srcFormat
== GL_RGBA
&&
1686 srcType
== GL_UNSIGNED_BYTE
) {
1687 /* extract BGR from RGBA */
1689 for (img
= 0; img
< srcDepth
; img
++) {
1690 const GLint srcRowStride
=
1691 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1692 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1693 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1694 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1695 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1696 + dstYoffset
* dstRowStride
1697 + dstXoffset
* texelBytes
;
1698 for (row
= 0; row
< srcHeight
; row
++) {
1699 for (col
= 0; col
< srcWidth
; col
++) {
1700 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + RCOMP
];
1701 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1702 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + BCOMP
];
1704 dstRow
+= dstRowStride
;
1705 srcRow
+= srcRowStride
;
1709 else if (!ctx
->_ImageTransferState
&&
1710 srcType
== GL_UNSIGNED_BYTE
&&
1711 can_swizzle(baseInternalFormat
) &&
1712 can_swizzle(srcFormat
)) {
1716 /* dstmap - how to swizzle from RGBA to dst format:
1721 dstmap
[3] = ONE
; /* ? */
1723 _mesa_swizzle_ubyte_image(ctx
, dims
,
1728 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1729 dstRowStride
, dstImageOffsets
,
1730 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1735 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1738 srcWidth
, srcHeight
, srcDepth
,
1739 srcFormat
, srcType
, srcAddr
,
1741 const GLchan
*src
= (const GLchan
*) tempImage
;
1742 GLint img
, row
, col
;
1745 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1746 for (img
= 0; img
< srcDepth
; img
++) {
1747 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1748 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1749 + dstYoffset
* dstRowStride
1750 + dstXoffset
* texelBytes
;
1751 for (row
= 0; row
< srcHeight
; row
++) {
1752 for (col
= 0; col
< srcWidth
; col
++) {
1753 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1754 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1755 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1758 dstRow
+= dstRowStride
;
1761 _mesa_free((void *) tempImage
);
1768 _mesa_texstore_argb4444(TEXSTORE_PARAMS
)
1770 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1771 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1773 ASSERT(dstFormat
== MESA_FORMAT_ARGB4444
||
1774 dstFormat
== MESA_FORMAT_ARGB4444_REV
);
1775 ASSERT(texelBytes
== 2);
1777 if (!ctx
->_ImageTransferState
&&
1778 !srcPacking
->SwapBytes
&&
1779 dstFormat
== MESA_FORMAT_ARGB4444
&&
1780 baseInternalFormat
== GL_RGBA
&&
1781 srcFormat
== GL_BGRA
&&
1782 srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1783 /* simple memcpy path */
1784 memcpy_texture(ctx
, dims
,
1785 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1788 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1789 srcAddr
, srcPacking
);
1793 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1796 srcWidth
, srcHeight
, srcDepth
,
1797 srcFormat
, srcType
, srcAddr
,
1799 const GLchan
*src
= tempImage
;
1800 GLint img
, row
, col
;
1803 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1804 for (img
= 0; img
< srcDepth
; img
++) {
1805 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1806 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1807 + dstYoffset
* dstRowStride
1808 + dstXoffset
* texelBytes
;
1809 for (row
= 0; row
< srcHeight
; row
++) {
1810 GLushort
*dstUS
= (GLushort
*) dstRow
;
1811 if (dstFormat
== MESA_FORMAT_ARGB4444
) {
1812 for (col
= 0; col
< srcWidth
; col
++) {
1813 dstUS
[col
] = PACK_COLOR_4444( CHAN_TO_UBYTE(src
[ACOMP
]),
1814 CHAN_TO_UBYTE(src
[RCOMP
]),
1815 CHAN_TO_UBYTE(src
[GCOMP
]),
1816 CHAN_TO_UBYTE(src
[BCOMP
]) );
1821 for (col
= 0; col
< srcWidth
; col
++) {
1822 dstUS
[col
] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1823 CHAN_TO_UBYTE(src
[RCOMP
]),
1824 CHAN_TO_UBYTE(src
[GCOMP
]),
1825 CHAN_TO_UBYTE(src
[BCOMP
]) );
1829 dstRow
+= dstRowStride
;
1832 _mesa_free((void *) tempImage
);
1838 _mesa_texstore_rgba5551(TEXSTORE_PARAMS
)
1840 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1841 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1843 ASSERT(dstFormat
== MESA_FORMAT_RGBA5551
);
1844 ASSERT(texelBytes
== 2);
1846 if (!ctx
->_ImageTransferState
&&
1847 !srcPacking
->SwapBytes
&&
1848 dstFormat
== MESA_FORMAT_RGBA5551
&&
1849 baseInternalFormat
== GL_RGBA
&&
1850 srcFormat
== GL_RGBA
&&
1851 srcType
== GL_UNSIGNED_SHORT_5_5_5_1
) {
1852 /* simple memcpy path */
1853 memcpy_texture(ctx
, dims
,
1854 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1857 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1858 srcAddr
, srcPacking
);
1862 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1865 srcWidth
, srcHeight
, srcDepth
,
1866 srcFormat
, srcType
, srcAddr
,
1868 const GLchan
*src
=tempImage
;
1869 GLint img
, row
, col
;
1872 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1873 for (img
= 0; img
< srcDepth
; img
++) {
1874 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1875 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1876 + dstYoffset
* dstRowStride
1877 + dstXoffset
* texelBytes
;
1878 for (row
= 0; row
< srcHeight
; row
++) {
1879 GLushort
*dstUS
= (GLushort
*) dstRow
;
1880 for (col
= 0; col
< srcWidth
; col
++) {
1881 dstUS
[col
] = PACK_COLOR_5551( CHAN_TO_UBYTE(src
[RCOMP
]),
1882 CHAN_TO_UBYTE(src
[GCOMP
]),
1883 CHAN_TO_UBYTE(src
[BCOMP
]),
1884 CHAN_TO_UBYTE(src
[ACOMP
]) );
1887 dstRow
+= dstRowStride
;
1890 _mesa_free((void *) tempImage
);
1896 _mesa_texstore_argb1555(TEXSTORE_PARAMS
)
1898 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1899 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1901 ASSERT(dstFormat
== MESA_FORMAT_ARGB1555
||
1902 dstFormat
== MESA_FORMAT_ARGB1555_REV
);
1903 ASSERT(texelBytes
== 2);
1905 if (!ctx
->_ImageTransferState
&&
1906 !srcPacking
->SwapBytes
&&
1907 dstFormat
== MESA_FORMAT_ARGB1555
&&
1908 baseInternalFormat
== GL_RGBA
&&
1909 srcFormat
== GL_BGRA
&&
1910 srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
1911 /* simple memcpy path */
1912 memcpy_texture(ctx
, dims
,
1913 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1916 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1917 srcAddr
, srcPacking
);
1921 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1924 srcWidth
, srcHeight
, srcDepth
,
1925 srcFormat
, srcType
, srcAddr
,
1927 const GLchan
*src
=tempImage
;
1928 GLint img
, row
, col
;
1931 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1932 for (img
= 0; img
< srcDepth
; img
++) {
1933 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1934 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1935 + dstYoffset
* dstRowStride
1936 + dstXoffset
* texelBytes
;
1937 for (row
= 0; row
< srcHeight
; row
++) {
1938 GLushort
*dstUS
= (GLushort
*) dstRow
;
1939 if (dstFormat
== MESA_FORMAT_ARGB1555
) {
1940 for (col
= 0; col
< srcWidth
; col
++) {
1941 dstUS
[col
] = PACK_COLOR_1555( CHAN_TO_UBYTE(src
[ACOMP
]),
1942 CHAN_TO_UBYTE(src
[RCOMP
]),
1943 CHAN_TO_UBYTE(src
[GCOMP
]),
1944 CHAN_TO_UBYTE(src
[BCOMP
]) );
1949 for (col
= 0; col
< srcWidth
; col
++) {
1950 dstUS
[col
] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1951 CHAN_TO_UBYTE(src
[RCOMP
]),
1952 CHAN_TO_UBYTE(src
[GCOMP
]),
1953 CHAN_TO_UBYTE(src
[BCOMP
]) );
1957 dstRow
+= dstRowStride
;
1960 _mesa_free((void *) tempImage
);
1967 _mesa_texstore_al88(TEXSTORE_PARAMS
)
1969 const GLboolean littleEndian
= _mesa_little_endian();
1970 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1971 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1973 ASSERT(dstFormat
== MESA_FORMAT_AL88
||
1974 dstFormat
== MESA_FORMAT_AL88_REV
);
1975 ASSERT(texelBytes
== 2);
1977 if (!ctx
->_ImageTransferState
&&
1978 !srcPacking
->SwapBytes
&&
1979 dstFormat
== MESA_FORMAT_AL88
&&
1980 baseInternalFormat
== GL_LUMINANCE_ALPHA
&&
1981 srcFormat
== GL_LUMINANCE_ALPHA
&&
1982 srcType
== GL_UNSIGNED_BYTE
&&
1984 /* simple memcpy path */
1985 memcpy_texture(ctx
, dims
,
1986 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1989 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1990 srcAddr
, srcPacking
);
1992 else if (!ctx
->_ImageTransferState
&&
1994 srcType
== GL_UNSIGNED_BYTE
&&
1995 can_swizzle(baseInternalFormat
) &&
1996 can_swizzle(srcFormat
)) {
2000 /* dstmap - how to swizzle from RGBA to dst format:
2002 if ((littleEndian
&& dstFormat
== MESA_FORMAT_AL88
) ||
2003 (!littleEndian
&& dstFormat
== MESA_FORMAT_AL88_REV
)) {
2011 dstmap
[2] = ZERO
; /* ? */
2012 dstmap
[3] = ONE
; /* ? */
2014 _mesa_swizzle_ubyte_image(ctx
, dims
,
2019 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2020 dstRowStride
, dstImageOffsets
,
2021 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2026 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2029 srcWidth
, srcHeight
, srcDepth
,
2030 srcFormat
, srcType
, srcAddr
,
2032 const GLchan
*src
= tempImage
;
2033 GLint img
, row
, col
;
2036 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2037 for (img
= 0; img
< srcDepth
; img
++) {
2038 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2039 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2040 + dstYoffset
* dstRowStride
2041 + dstXoffset
* texelBytes
;
2042 for (row
= 0; row
< srcHeight
; row
++) {
2043 GLushort
*dstUS
= (GLushort
*) dstRow
;
2044 if (dstFormat
== MESA_FORMAT_AL88
) {
2045 for (col
= 0; col
< srcWidth
; col
++) {
2046 /* src[0] is luminance, src[1] is alpha */
2047 dstUS
[col
] = PACK_COLOR_88( CHAN_TO_UBYTE(src
[1]),
2048 CHAN_TO_UBYTE(src
[0]) );
2053 for (col
= 0; col
< srcWidth
; col
++) {
2054 /* src[0] is luminance, src[1] is alpha */
2055 dstUS
[col
] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src
[1]),
2056 CHAN_TO_UBYTE(src
[0]) );
2060 dstRow
+= dstRowStride
;
2063 _mesa_free((void *) tempImage
);
2070 _mesa_texstore_rgb332(TEXSTORE_PARAMS
)
2072 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2073 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2075 ASSERT(dstFormat
== MESA_FORMAT_RGB332
);
2076 ASSERT(texelBytes
== 1);
2078 if (!ctx
->_ImageTransferState
&&
2079 !srcPacking
->SwapBytes
&&
2080 baseInternalFormat
== GL_RGB
&&
2081 srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_BYTE_3_3_2
) {
2082 /* simple memcpy path */
2083 memcpy_texture(ctx
, dims
,
2084 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2087 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2088 srcAddr
, srcPacking
);
2092 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2095 srcWidth
, srcHeight
, srcDepth
,
2096 srcFormat
, srcType
, srcAddr
,
2098 const GLchan
*src
= tempImage
;
2099 GLint img
, row
, col
;
2102 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2103 for (img
= 0; img
< srcDepth
; img
++) {
2104 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2105 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2106 + dstYoffset
* dstRowStride
2107 + dstXoffset
* texelBytes
;
2108 for (row
= 0; row
< srcHeight
; row
++) {
2109 for (col
= 0; col
< srcWidth
; col
++) {
2110 dstRow
[col
] = PACK_COLOR_332( CHAN_TO_UBYTE(src
[RCOMP
]),
2111 CHAN_TO_UBYTE(src
[GCOMP
]),
2112 CHAN_TO_UBYTE(src
[BCOMP
]) );
2115 dstRow
+= dstRowStride
;
2118 _mesa_free((void *) tempImage
);
2125 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2128 _mesa_texstore_a8(TEXSTORE_PARAMS
)
2130 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2131 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2133 ASSERT(dstFormat
== MESA_FORMAT_A8
||
2134 dstFormat
== MESA_FORMAT_L8
||
2135 dstFormat
== MESA_FORMAT_I8
);
2136 ASSERT(texelBytes
== 1);
2138 if (!ctx
->_ImageTransferState
&&
2139 !srcPacking
->SwapBytes
&&
2140 baseInternalFormat
== srcFormat
&&
2141 srcType
== GL_UNSIGNED_BYTE
) {
2142 /* simple memcpy path */
2143 memcpy_texture(ctx
, dims
,
2144 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2147 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2148 srcAddr
, srcPacking
);
2150 else if (!ctx
->_ImageTransferState
&&
2151 srcType
== GL_UNSIGNED_BYTE
&&
2152 can_swizzle(baseInternalFormat
) &&
2153 can_swizzle(srcFormat
)) {
2157 /* dstmap - how to swizzle from RGBA to dst format:
2159 if (dstFormat
== MESA_FORMAT_A8
) {
2165 dstmap
[1] = ZERO
; /* ? */
2166 dstmap
[2] = ZERO
; /* ? */
2167 dstmap
[3] = ONE
; /* ? */
2169 _mesa_swizzle_ubyte_image(ctx
, dims
,
2174 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2175 dstRowStride
, dstImageOffsets
,
2176 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2181 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2184 srcWidth
, srcHeight
, srcDepth
,
2185 srcFormat
, srcType
, srcAddr
,
2187 const GLchan
*src
= tempImage
;
2188 GLint img
, row
, col
;
2191 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2192 for (img
= 0; img
< srcDepth
; img
++) {
2193 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2194 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2195 + dstYoffset
* dstRowStride
2196 + dstXoffset
* texelBytes
;
2197 for (row
= 0; row
< srcHeight
; row
++) {
2198 for (col
= 0; col
< srcWidth
; col
++) {
2199 dstRow
[col
] = CHAN_TO_UBYTE(src
[col
]);
2201 dstRow
+= dstRowStride
;
2205 _mesa_free((void *) tempImage
);
2213 _mesa_texstore_ci8(TEXSTORE_PARAMS
)
2215 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2217 (void) dims
; (void) baseInternalFormat
;
2218 ASSERT(dstFormat
== MESA_FORMAT_CI8
);
2219 ASSERT(texelBytes
== 1);
2220 ASSERT(baseInternalFormat
== GL_COLOR_INDEX
);
2222 if (!ctx
->_ImageTransferState
&&
2223 !srcPacking
->SwapBytes
&&
2224 srcFormat
== GL_COLOR_INDEX
&&
2225 srcType
== GL_UNSIGNED_BYTE
) {
2226 /* simple memcpy path */
2227 memcpy_texture(ctx
, dims
,
2228 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2231 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2232 srcAddr
, srcPacking
);
2237 for (img
= 0; img
< srcDepth
; img
++) {
2238 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2239 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2240 + dstYoffset
* dstRowStride
2241 + dstXoffset
* texelBytes
;
2242 for (row
= 0; row
< srcHeight
; row
++) {
2243 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
2244 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
2245 _mesa_unpack_index_span(ctx
, srcWidth
, GL_UNSIGNED_BYTE
, dstRow
,
2246 srcType
, src
, srcPacking
,
2247 ctx
->_ImageTransferState
);
2248 dstRow
+= dstRowStride
;
2257 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
2260 _mesa_texstore_ycbcr(TEXSTORE_PARAMS
)
2262 const GLboolean littleEndian
= _mesa_little_endian();
2263 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2265 (void) ctx
; (void) dims
; (void) baseInternalFormat
;
2267 ASSERT((dstFormat
== MESA_FORMAT_YCBCR
) ||
2268 (dstFormat
== MESA_FORMAT_YCBCR_REV
));
2269 ASSERT(texelBytes
== 2);
2270 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
2271 ASSERT(srcFormat
== GL_YCBCR_MESA
);
2272 ASSERT((srcType
== GL_UNSIGNED_SHORT_8_8_MESA
) ||
2273 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
));
2274 ASSERT(baseInternalFormat
== GL_YCBCR_MESA
);
2276 /* always just memcpy since no pixel transfer ops apply */
2277 memcpy_texture(ctx
, dims
,
2278 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2281 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2282 srcAddr
, srcPacking
);
2284 /* Check if we need byte swapping */
2285 /* XXX the logic here _might_ be wrong */
2286 if (srcPacking
->SwapBytes
^
2287 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ^
2288 (dstFormat
== MESA_FORMAT_YCBCR_REV
) ^
2291 for (img
= 0; img
< srcDepth
; img
++) {
2292 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2293 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2294 + dstYoffset
* dstRowStride
2295 + dstXoffset
* texelBytes
;
2296 for (row
= 0; row
< srcHeight
; row
++) {
2297 _mesa_swap2((GLushort
*) dstRow
, srcWidth
);
2298 dstRow
+= dstRowStride
;
2306 _mesa_texstore_dudv8(TEXSTORE_PARAMS
)
2308 const GLboolean littleEndian
= _mesa_little_endian();
2309 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2311 ASSERT(dstFormat
== MESA_FORMAT_DUDV8
);
2312 ASSERT(texelBytes
== 2);
2313 ASSERT(ctx
->Extensions
.ATI_envmap_bumpmap
);
2314 ASSERT((srcFormat
== GL_DU8DV8_ATI
) ||
2315 (srcFormat
== GL_DUDV_ATI
));
2316 ASSERT(baseInternalFormat
== GL_DUDV_ATI
);
2318 if (!srcPacking
->SwapBytes
&& srcType
== GL_BYTE
&&
2320 /* simple memcpy path */
2321 memcpy_texture(ctx
, dims
,
2322 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2325 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2326 srcAddr
, srcPacking
);
2328 else if (srcType
== GL_BYTE
) {
2332 /* dstmap - how to swizzle from RGBA to dst format:
2342 dstmap
[2] = ZERO
; /* ? */
2343 dstmap
[3] = ONE
; /* ? */
2345 _mesa_swizzle_ubyte_image(ctx
, dims
,
2346 GL_LUMINANCE_ALPHA
, /* hack */
2347 GL_UNSIGNED_BYTE
, /* hack */
2348 GL_LUMINANCE_ALPHA
, /* hack */
2350 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2351 dstRowStride
, dstImageOffsets
,
2352 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2356 /* general path - note this is defined for 2d textures only */
2357 const GLint components
= _mesa_components_in_format(baseInternalFormat
);
2358 const GLint srcStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
2359 srcFormat
, srcType
);
2360 GLbyte
*tempImage
, *dst
, *src
;
2363 tempImage
= (GLbyte
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
2364 * components
* sizeof(GLbyte
));
2368 src
= (GLbyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2369 srcWidth
, srcHeight
,
2374 for (row
= 0; row
< srcHeight
; row
++) {
2375 _mesa_unpack_dudv_span_byte(ctx
, srcWidth
, baseInternalFormat
,
2376 dst
, srcFormat
, srcType
, src
,
2378 dst
+= srcWidth
* components
;
2383 dst
= (GLbyte
*) dstAddr
2384 + dstYoffset
* dstRowStride
2385 + dstXoffset
* texelBytes
;
2386 for (row
= 0; row
< srcHeight
; row
++) {
2387 memcpy(dst
, src
, srcWidth
* texelBytes
);
2388 dst
+= dstRowStride
;
2389 src
+= srcWidth
* texelBytes
;
2391 _mesa_free((void *) tempImage
);
2397 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or MESA_FORMAT_SIGNED_RGBA8888_REV
2400 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS
)
2402 const GLboolean littleEndian
= _mesa_little_endian();
2403 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2404 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2406 ASSERT(dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
||
2407 dstFormat
== MESA_FORMAT_SIGNED_RGBA8888_REV
);
2408 ASSERT(texelBytes
== 4);
2410 if (!ctx
->_ImageTransferState
&&
2411 !srcPacking
->SwapBytes
&&
2412 dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
&&
2413 baseInternalFormat
== GL_RGBA
&&
2414 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& !littleEndian
) ||
2415 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& littleEndian
))) {
2416 /* simple memcpy path */
2417 memcpy_texture(ctx
, dims
,
2418 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2421 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2422 srcAddr
, srcPacking
);
2424 else if (!ctx
->_ImageTransferState
&&
2425 !srcPacking
->SwapBytes
&&
2426 dstFormat
== MESA_FORMAT_SIGNED_RGBA8888_REV
&&
2427 baseInternalFormat
== GL_RGBA
&&
2428 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& littleEndian
) ||
2429 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& !littleEndian
))) {
2430 /* simple memcpy path */
2431 memcpy_texture(ctx
, dims
,
2432 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2435 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2436 srcAddr
, srcPacking
);
2438 else if (!ctx
->_ImageTransferState
&&
2439 (srcType
== GL_BYTE
) &&
2440 can_swizzle(baseInternalFormat
) &&
2441 can_swizzle(srcFormat
)) {
2445 /* dstmap - how to swizzle from RGBA to dst format:
2447 if ((littleEndian
&& dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
) ||
2448 (!littleEndian
&& dstFormat
== MESA_FORMAT_SIGNED_RGBA8888_REV
)) {
2461 _mesa_swizzle_ubyte_image(ctx
, dims
,
2466 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2467 dstRowStride
, dstImageOffsets
,
2468 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2473 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2476 srcWidth
, srcHeight
, srcDepth
,
2477 srcFormat
, srcType
, srcAddr
,
2479 const GLfloat
*srcRow
= tempImage
;
2480 GLint img
, row
, col
;
2483 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2484 for (img
= 0; img
< srcDepth
; img
++) {
2485 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2486 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2487 + dstYoffset
* dstRowStride
2488 + dstXoffset
* texelBytes
;
2489 for (row
= 0; row
< srcHeight
; row
++) {
2490 GLuint
*dstUI
= (GLuint
*) dstRow
;
2491 if (dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
) {
2492 for (col
= 0; col
< srcWidth
; col
++) {
2493 dstUI
[col
] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2494 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2495 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2496 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2501 for (col
= 0; col
< srcWidth
; col
++) {
2502 dstUI
[col
] = PACK_COLOR_8888_REV( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2503 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2504 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2505 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2509 dstRow
+= dstRowStride
;
2512 _mesa_free((void *) tempImage
);
2518 * Store a combined depth/stencil texture image.
2521 _mesa_texstore_z24_s8(TEXSTORE_PARAMS
)
2523 const GLfloat depthScale
= (GLfloat
) 0xffffff;
2524 const GLint srcRowStride
2525 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2529 ASSERT(dstFormat
== MESA_FORMAT_Z24_S8
);
2530 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
);
2531 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2533 /* In case we only upload depth we need to preserve the stencil */
2534 if (srcFormat
== GL_DEPTH_COMPONENT
) {
2535 for (img
= 0; img
< srcDepth
; img
++) {
2536 GLuint
*dstRow
= (GLuint
*) dstAddr
2537 + dstImageOffsets
[dstZoffset
+ img
]
2538 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2541 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2542 srcWidth
, srcHeight
,
2545 for (row
= 0; row
< srcHeight
; row
++) {
2546 GLuint depth
[MAX_WIDTH
];
2548 _mesa_unpack_depth_span(ctx
, srcWidth
,
2549 GL_UNSIGNED_INT
, /* dst type */
2550 depth
, /* dst addr */
2552 srcType
, src
, srcPacking
);
2554 for (i
= 0; i
< srcWidth
; i
++)
2555 dstRow
[i
] = depth
[i
] << 8 | (dstRow
[i
] & 0x000000FF);
2557 src
+= srcRowStride
;
2558 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2562 else if (ctx
->Pixel
.DepthScale
== 1.0f
&&
2563 ctx
->Pixel
.DepthBias
== 0.0f
&&
2564 !srcPacking
->SwapBytes
) {
2566 memcpy_texture(ctx
, dims
,
2567 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2570 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2571 srcAddr
, srcPacking
);
2575 const GLint srcRowStride
2576 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2580 for (img
= 0; img
< srcDepth
; img
++) {
2581 GLuint
*dstRow
= (GLuint
*) dstAddr
2582 + dstImageOffsets
[dstZoffset
+ img
]
2583 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2586 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2587 srcWidth
, srcHeight
,
2590 for (row
= 0; row
< srcHeight
; row
++) {
2591 GLubyte stencil
[MAX_WIDTH
];
2593 /* the 24 depth bits will be in the high position: */
2594 _mesa_unpack_depth_span(ctx
, srcWidth
,
2595 GL_UNSIGNED_INT_24_8_EXT
, /* dst type */
2596 dstRow
, /* dst addr */
2597 (GLuint
) depthScale
,
2598 srcType
, src
, srcPacking
);
2599 /* get the 8-bit stencil values */
2600 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2601 GL_UNSIGNED_BYTE
, /* dst type */
2602 stencil
, /* dst addr */
2603 srcType
, src
, srcPacking
,
2604 ctx
->_ImageTransferState
);
2605 /* merge stencil values into depth values */
2606 for (i
= 0; i
< srcWidth
; i
++)
2607 dstRow
[i
] |= stencil
[i
];
2609 src
+= srcRowStride
;
2610 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2619 * Store a combined depth/stencil texture image.
2622 _mesa_texstore_s8_z24(TEXSTORE_PARAMS
)
2624 const GLuint depthScale
= 0xffffff;
2625 const GLint srcRowStride
2626 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2630 ASSERT(dstFormat
== MESA_FORMAT_S8_Z24
);
2631 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
);
2632 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2634 /* In case we only upload depth we need to preserve the stencil */
2635 if (srcFormat
== GL_DEPTH_COMPONENT
) {
2636 for (img
= 0; img
< srcDepth
; img
++) {
2637 GLuint
*dstRow
= (GLuint
*) dstAddr
2638 + dstImageOffsets
[dstZoffset
+ img
]
2639 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2642 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2643 srcWidth
, srcHeight
,
2646 for (row
= 0; row
< srcHeight
; row
++) {
2647 GLuint depth
[MAX_WIDTH
];
2649 _mesa_unpack_depth_span(ctx
, srcWidth
,
2650 GL_UNSIGNED_INT
, /* dst type */
2651 depth
, /* dst addr */
2653 srcType
, src
, srcPacking
);
2655 for (i
= 0; i
< srcWidth
; i
++)
2656 dstRow
[i
] = depth
[i
] | (dstRow
[i
] & 0xFF000000);
2658 src
+= srcRowStride
;
2659 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2664 for (img
= 0; img
< srcDepth
; img
++) {
2665 GLuint
*dstRow
= (GLuint
*) dstAddr
2666 + dstImageOffsets
[dstZoffset
+ img
]
2667 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2670 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2671 srcWidth
, srcHeight
,
2674 for (row
= 0; row
< srcHeight
; row
++) {
2675 GLubyte stencil
[MAX_WIDTH
];
2677 /* the 24 depth bits will be in the low position: */
2678 _mesa_unpack_depth_span(ctx
, srcWidth
,
2679 GL_UNSIGNED_INT
, /* dst type */
2680 dstRow
, /* dst addr */
2682 srcType
, src
, srcPacking
);
2683 /* get the 8-bit stencil values */
2684 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2685 GL_UNSIGNED_BYTE
, /* dst type */
2686 stencil
, /* dst addr */
2687 srcType
, src
, srcPacking
,
2688 ctx
->_ImageTransferState
);
2689 /* merge stencil values into depth values */
2690 for (i
= 0; i
< srcWidth
; i
++)
2691 dstRow
[i
] |= stencil
[i
] << 24;
2693 src
+= srcRowStride
;
2694 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2702 * Store an image in any of the formats:
2703 * _mesa_texformat_rgba_float32
2704 * _mesa_texformat_rgb_float32
2705 * _mesa_texformat_alpha_float32
2706 * _mesa_texformat_luminance_float32
2707 * _mesa_texformat_luminance_alpha_float32
2708 * _mesa_texformat_intensity_float32
2711 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS
)
2713 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2714 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2715 const GLint components
= _mesa_components_in_format(baseFormat
);
2717 ASSERT(dstFormat
== MESA_FORMAT_RGBA_FLOAT32
||
2718 dstFormat
== MESA_FORMAT_RGB_FLOAT32
||
2719 dstFormat
== MESA_FORMAT_ALPHA_FLOAT32
||
2720 dstFormat
== MESA_FORMAT_LUMINANCE_FLOAT32
||
2721 dstFormat
== MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32
||
2722 dstFormat
== MESA_FORMAT_INTENSITY_FLOAT32
);
2723 ASSERT(baseInternalFormat
== GL_RGBA
||
2724 baseInternalFormat
== GL_RGB
||
2725 baseInternalFormat
== GL_ALPHA
||
2726 baseInternalFormat
== GL_LUMINANCE
||
2727 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
2728 baseInternalFormat
== GL_INTENSITY
);
2729 ASSERT(texelBytes
== components
* sizeof(GLfloat
));
2731 if (!ctx
->_ImageTransferState
&&
2732 !srcPacking
->SwapBytes
&&
2733 baseInternalFormat
== srcFormat
&&
2734 srcType
== GL_FLOAT
) {
2735 /* simple memcpy path */
2736 memcpy_texture(ctx
, dims
,
2737 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2740 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2741 srcAddr
, srcPacking
);
2745 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2748 srcWidth
, srcHeight
, srcDepth
,
2749 srcFormat
, srcType
, srcAddr
,
2751 const GLfloat
*srcRow
= tempImage
;
2756 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2757 bytesPerRow
= srcWidth
* components
* sizeof(GLfloat
);
2758 for (img
= 0; img
< srcDepth
; img
++) {
2759 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2760 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2761 + dstYoffset
* dstRowStride
2762 + dstXoffset
* texelBytes
;
2763 for (row
= 0; row
< srcHeight
; row
++) {
2764 _mesa_memcpy(dstRow
, srcRow
, bytesPerRow
);
2765 dstRow
+= dstRowStride
;
2766 srcRow
+= srcWidth
* components
;
2770 _mesa_free((void *) tempImage
);
2777 * As above, but store 16-bit floats.
2780 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS
)
2782 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2783 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2784 const GLint components
= _mesa_components_in_format(baseFormat
);
2786 ASSERT(dstFormat
== MESA_FORMAT_RGBA_FLOAT16
||
2787 dstFormat
== MESA_FORMAT_RGB_FLOAT16
||
2788 dstFormat
== MESA_FORMAT_ALPHA_FLOAT16
||
2789 dstFormat
== MESA_FORMAT_LUMINANCE_FLOAT16
||
2790 dstFormat
== MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16
||
2791 dstFormat
== MESA_FORMAT_INTENSITY_FLOAT16
);
2792 ASSERT(baseInternalFormat
== GL_RGBA
||
2793 baseInternalFormat
== GL_RGB
||
2794 baseInternalFormat
== GL_ALPHA
||
2795 baseInternalFormat
== GL_LUMINANCE
||
2796 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
2797 baseInternalFormat
== GL_INTENSITY
);
2798 ASSERT(texelBytes
== components
* sizeof(GLhalfARB
));
2800 if (!ctx
->_ImageTransferState
&&
2801 !srcPacking
->SwapBytes
&&
2802 baseInternalFormat
== srcFormat
&&
2803 srcType
== GL_HALF_FLOAT_ARB
) {
2804 /* simple memcpy path */
2805 memcpy_texture(ctx
, dims
,
2806 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2809 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2810 srcAddr
, srcPacking
);
2814 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2817 srcWidth
, srcHeight
, srcDepth
,
2818 srcFormat
, srcType
, srcAddr
,
2820 const GLfloat
*src
= tempImage
;
2824 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2825 for (img
= 0; img
< srcDepth
; img
++) {
2826 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2827 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2828 + dstYoffset
* dstRowStride
2829 + dstXoffset
* texelBytes
;
2830 for (row
= 0; row
< srcHeight
; row
++) {
2831 GLhalfARB
*dstTexel
= (GLhalfARB
*) dstRow
;
2833 for (i
= 0; i
< srcWidth
* components
; i
++) {
2834 dstTexel
[i
] = _mesa_float_to_half(src
[i
]);
2836 dstRow
+= dstRowStride
;
2837 src
+= srcWidth
* components
;
2841 _mesa_free((void *) tempImage
);
2847 #if FEATURE_EXT_texture_sRGB
2849 _mesa_texstore_srgb8(TEXSTORE_PARAMS
)
2851 gl_format newDstFormat
;
2854 ASSERT(dstFormat
== MESA_FORMAT_SRGB8
);
2856 /* reuse normal rgb texstore code */
2857 newDstFormat
= MESA_FORMAT_RGB888
;
2859 k
= _mesa_texstore_rgb888(ctx
, dims
, baseInternalFormat
,
2860 newDstFormat
, dstAddr
,
2861 dstXoffset
, dstYoffset
, dstZoffset
,
2862 dstRowStride
, dstImageOffsets
,
2863 srcWidth
, srcHeight
, srcDepth
,
2865 srcAddr
, srcPacking
);
2871 _mesa_texstore_srgba8(TEXSTORE_PARAMS
)
2873 gl_format newDstFormat
;
2876 ASSERT(dstFormat
== MESA_FORMAT_SRGBA8
);
2878 /* reuse normal rgba texstore code */
2879 newDstFormat
= MESA_FORMAT_RGBA8888
;
2880 k
= _mesa_texstore_rgba8888(ctx
, dims
, baseInternalFormat
,
2881 newDstFormat
, dstAddr
,
2882 dstXoffset
, dstYoffset
, dstZoffset
,
2883 dstRowStride
, dstImageOffsets
,
2884 srcWidth
, srcHeight
, srcDepth
,
2886 srcAddr
, srcPacking
);
2892 _mesa_texstore_sargb8(TEXSTORE_PARAMS
)
2894 gl_format newDstFormat
;
2897 ASSERT(dstFormat
== MESA_FORMAT_SARGB8
);
2899 /* reuse normal rgba texstore code */
2900 newDstFormat
= MESA_FORMAT_ARGB8888
;
2902 k
= _mesa_texstore_argb8888(ctx
, dims
, baseInternalFormat
,
2903 newDstFormat
, dstAddr
,
2904 dstXoffset
, dstYoffset
, dstZoffset
,
2905 dstRowStride
, dstImageOffsets
,
2906 srcWidth
, srcHeight
, srcDepth
,
2908 srcAddr
, srcPacking
);
2914 _mesa_texstore_sl8(TEXSTORE_PARAMS
)
2916 gl_format newDstFormat
;
2919 ASSERT(dstFormat
== MESA_FORMAT_SL8
);
2921 newDstFormat
= MESA_FORMAT_L8
;
2923 /* _mesa_textore_a8 handles luminance8 too */
2924 k
= _mesa_texstore_a8(ctx
, dims
, baseInternalFormat
,
2925 newDstFormat
, dstAddr
,
2926 dstXoffset
, dstYoffset
, dstZoffset
,
2927 dstRowStride
, dstImageOffsets
,
2928 srcWidth
, srcHeight
, srcDepth
,
2930 srcAddr
, srcPacking
);
2936 _mesa_texstore_sla8(TEXSTORE_PARAMS
)
2938 gl_format newDstFormat
;
2941 ASSERT(dstFormat
== MESA_FORMAT_SLA8
);
2943 /* reuse normal luminance/alpha texstore code */
2944 newDstFormat
= MESA_FORMAT_AL88
;
2946 k
= _mesa_texstore_al88(ctx
, dims
, baseInternalFormat
,
2947 newDstFormat
, dstAddr
,
2948 dstXoffset
, dstYoffset
, dstZoffset
,
2949 dstRowStride
, dstImageOffsets
,
2950 srcWidth
, srcHeight
, srcDepth
,
2952 srcAddr
, srcPacking
);
2956 #endif /* FEATURE_EXT_texture_sRGB */
2962 * Table mapping MESA_FORMAT_8 to _mesa_texstore_*()
2963 * XXX this is somewhat temporary.
2967 StoreTexImageFunc Store
;
2969 texstore_funcs
[MESA_FORMAT_COUNT
] =
2971 { MESA_FORMAT_NONE
, NULL
},
2972 { MESA_FORMAT_RGBA8888
, _mesa_texstore_rgba8888
},
2973 { MESA_FORMAT_RGBA8888_REV
, _mesa_texstore_rgba8888
},
2974 { MESA_FORMAT_ARGB8888
, _mesa_texstore_argb8888
},
2975 { MESA_FORMAT_ARGB8888_REV
, _mesa_texstore_argb8888
},
2976 { MESA_FORMAT_RGB888
, _mesa_texstore_rgb888
},
2977 { MESA_FORMAT_BGR888
, _mesa_texstore_bgr888
},
2978 { MESA_FORMAT_RGB565
, _mesa_texstore_rgb565
},
2979 { MESA_FORMAT_RGB565_REV
, _mesa_texstore_rgb565
},
2980 { MESA_FORMAT_ARGB4444
, _mesa_texstore_argb4444
},
2981 { MESA_FORMAT_ARGB4444_REV
, _mesa_texstore_argb4444
},
2982 { MESA_FORMAT_RGBA5551
, _mesa_texstore_rgba5551
},
2983 { MESA_FORMAT_ARGB1555
, _mesa_texstore_argb1555
},
2984 { MESA_FORMAT_ARGB1555_REV
, _mesa_texstore_argb1555
},
2985 { MESA_FORMAT_AL88
, _mesa_texstore_al88
},
2986 { MESA_FORMAT_AL88_REV
, _mesa_texstore_al88
},
2987 { MESA_FORMAT_RGB332
, _mesa_texstore_rgb332
},
2988 { MESA_FORMAT_A8
, _mesa_texstore_a8
},
2989 { MESA_FORMAT_L8
, _mesa_texstore_a8
},
2990 { MESA_FORMAT_I8
, _mesa_texstore_a8
},
2991 { MESA_FORMAT_CI8
, _mesa_texstore_ci8
},
2992 { MESA_FORMAT_YCBCR
, _mesa_texstore_ycbcr
},
2993 { MESA_FORMAT_YCBCR_REV
, _mesa_texstore_ycbcr
},
2994 { MESA_FORMAT_Z24_S8
, _mesa_texstore_z24_s8
},
2995 { MESA_FORMAT_S8_Z24
, _mesa_texstore_s8_z24
},
2996 { MESA_FORMAT_Z16
, _mesa_texstore_z16
},
2997 { MESA_FORMAT_Z32
, _mesa_texstore_z32
},
2998 { MESA_FORMAT_S8
, NULL
/*_mesa_texstore_s8*/ },
2999 { MESA_FORMAT_SRGB8
, _mesa_texstore_srgb8
},
3000 { MESA_FORMAT_SRGBA8
, _mesa_texstore_srgba8
},
3001 { MESA_FORMAT_SARGB8
, _mesa_texstore_sargb8
},
3002 { MESA_FORMAT_SL8
, _mesa_texstore_sl8
},
3003 { MESA_FORMAT_SLA8
, _mesa_texstore_sla8
},
3004 { MESA_FORMAT_SRGB_DXT1
, _mesa_texstore_rgb_dxt1
},
3005 { MESA_FORMAT_SRGBA_DXT1
, _mesa_texstore_rgba_dxt1
},
3006 { MESA_FORMAT_SRGBA_DXT3
, _mesa_texstore_rgba_dxt3
},
3007 { MESA_FORMAT_SRGBA_DXT5
, _mesa_texstore_rgba_dxt5
},
3008 { MESA_FORMAT_RGB_FXT1
, _mesa_texstore_rgb_fxt1
},
3009 { MESA_FORMAT_RGBA_FXT1
, _mesa_texstore_rgba_fxt1
},
3010 { MESA_FORMAT_RGB_DXT1
, _mesa_texstore_rgb_dxt1
},
3011 { MESA_FORMAT_RGBA_DXT1
, _mesa_texstore_rgba_dxt1
},
3012 { MESA_FORMAT_RGBA_DXT3
, _mesa_texstore_rgba_dxt3
},
3013 { MESA_FORMAT_RGBA_DXT5
, _mesa_texstore_rgba_dxt5
},
3014 { MESA_FORMAT_RGBA_FLOAT32
, _mesa_texstore_rgba_float32
},
3015 { MESA_FORMAT_RGBA_FLOAT16
, _mesa_texstore_rgba_float16
},
3016 { MESA_FORMAT_RGB_FLOAT32
, _mesa_texstore_rgba_float32
},
3017 { MESA_FORMAT_RGB_FLOAT16
, _mesa_texstore_rgba_float16
},
3018 { MESA_FORMAT_ALPHA_FLOAT32
, _mesa_texstore_rgba_float32
},
3019 { MESA_FORMAT_ALPHA_FLOAT16
, _mesa_texstore_rgba_float16
},
3020 { MESA_FORMAT_LUMINANCE_FLOAT32
, _mesa_texstore_rgba_float32
},
3021 { MESA_FORMAT_LUMINANCE_FLOAT16
, _mesa_texstore_rgba_float16
},
3022 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32
, _mesa_texstore_rgba_float32
},
3023 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16
, _mesa_texstore_rgba_float16
},
3024 { MESA_FORMAT_INTENSITY_FLOAT32
, _mesa_texstore_rgba_float32
},
3025 { MESA_FORMAT_INTENSITY_FLOAT16
, _mesa_texstore_rgba_float16
},
3026 { MESA_FORMAT_DUDV8
, _mesa_texstore_dudv8
},
3027 { MESA_FORMAT_SIGNED_RGBA8888
, _mesa_texstore_signed_rgba8888
},
3028 { MESA_FORMAT_SIGNED_RGBA8888_REV
, _mesa_texstore_signed_rgba8888
},
3029 { MESA_FORMAT_SIGNED_RGBA_16
, NULL
},
3034 * Return the StoreTexImageFunc pointer to store an image in the given format.
3036 static StoreTexImageFunc
3037 _mesa_get_texstore_func(gl_format format
)
3041 for (i
= 0; i
< MESA_FORMAT_COUNT
; i
++) {
3042 ASSERT(texstore_funcs
[i
].Name
== i
);
3045 ASSERT(texstore_funcs
[format
].Name
== format
);
3046 return texstore_funcs
[format
].Store
;
3051 * Store user data into texture memory.
3052 * Called via glTex[Sub]Image1/2/3D()
3055 _mesa_texstore(TEXSTORE_PARAMS
)
3057 StoreTexImageFunc storeImage
;
3060 storeImage
= _mesa_get_texstore_func(dstFormat
);
3064 success
= storeImage(ctx
, dims
, baseInternalFormat
,
3065 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3066 dstRowStride
, dstImageOffsets
,
3067 srcWidth
, srcHeight
, srcDepth
,
3068 srcFormat
, srcType
, srcAddr
, srcPacking
);
3074 * Check if an unpack PBO is active prior to fetching a texture image.
3075 * If so, do bounds checking and map the buffer into main memory.
3076 * Any errors detected will be recorded.
3077 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3080 _mesa_validate_pbo_teximage(GLcontext
*ctx
, GLuint dimensions
,
3081 GLsizei width
, GLsizei height
, GLsizei depth
,
3082 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3083 const struct gl_pixelstore_attrib
*unpack
,
3084 const char *funcName
)
3088 if (!_mesa_is_bufferobj(unpack
->BufferObj
)) {
3092 if (!_mesa_validate_pbo_access(dimensions
, unpack
, width
, height
, depth
,
3093 format
, type
, pixels
)) {
3094 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3098 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3099 GL_READ_ONLY_ARB
, unpack
->BufferObj
);
3101 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3105 return ADD_POINTERS(buf
, pixels
);
3110 * Check if an unpack PBO is active prior to fetching a compressed texture
3112 * If so, do bounds checking and map the buffer into main memory.
3113 * Any errors detected will be recorded.
3114 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3117 _mesa_validate_pbo_compressed_teximage(GLcontext
*ctx
,
3118 GLsizei imageSize
, const GLvoid
*pixels
,
3119 const struct gl_pixelstore_attrib
*packing
,
3120 const char *funcName
)
3124 if (!_mesa_is_bufferobj(packing
->BufferObj
)) {
3125 /* not using a PBO - return pointer unchanged */
3128 if ((const GLubyte
*) pixels
+ imageSize
>
3129 ((const GLubyte
*) 0) + packing
->BufferObj
->Size
) {
3130 /* out of bounds read! */
3131 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3135 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3136 GL_READ_ONLY_ARB
, packing
->BufferObj
);
3138 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3142 return ADD_POINTERS(buf
, pixels
);
3147 * This function must be called after either of the validate_pbo_*_teximage()
3148 * functions. It unmaps the PBO buffer if it was mapped earlier.
3151 _mesa_unmap_teximage_pbo(GLcontext
*ctx
,
3152 const struct gl_pixelstore_attrib
*unpack
)
3154 if (_mesa_is_bufferobj(unpack
->BufferObj
)) {
3155 ctx
->Driver
.UnmapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3161 /** Return texture size in bytes */
3163 texture_size(const struct gl_texture_image
*texImage
)
3165 GLuint sz
= _mesa_format_image_size(texImage
->TexFormat
, texImage
->Width
,
3166 texImage
->Height
, texImage
->Depth
);
3171 /** Return row stride in bytes */
3173 texture_row_stride(const struct gl_texture_image
*texImage
)
3177 if (_mesa_is_format_compressed(texImage
->TexFormat
)) {
3178 stride
= _mesa_compressed_row_stride(texImage
->TexFormat
,
3182 GLuint texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
);
3183 stride
= texImage
->RowStride
* texelBytes
;
3192 * This is the software fallback for Driver.TexImage1D()
3193 * and Driver.CopyTexImage1D().
3194 * \sa _mesa_store_teximage2d()
3195 * Note that the width may not be the actual texture width since it may
3196 * be changed by convolution w/ GL_REDUCE. The texImage->Width field will
3197 * have the actual texture size.
3200 _mesa_store_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3201 GLint internalFormat
,
3202 GLint width
, GLint border
,
3203 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3204 const struct gl_pixelstore_attrib
*packing
,
3205 struct gl_texture_object
*texObj
,
3206 struct gl_texture_image
*texImage
)
3212 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3213 ASSERT(texImage
->TexFormat
);
3215 /* allocate memory */
3216 sizeInBytes
= texture_size(texImage
);
3217 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3218 if (!texImage
->Data
) {
3219 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
3223 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
3224 pixels
, packing
, "glTexImage1D");
3226 /* Note: we check for a NULL image pointer here, _after_ we allocated
3227 * memory for the texture. That's what the GL spec calls for.
3232 const GLint dstRowStride
= 0;
3233 GLboolean success
= _mesa_texstore(ctx
, 1, texImage
->_BaseFormat
,
3234 texImage
->TexFormat
,
3236 0, 0, 0, /* dstX/Y/Zoffset */
3238 texImage
->ImageOffsets
,
3240 format
, type
, pixels
, packing
);
3242 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
3246 _mesa_unmap_teximage_pbo(ctx
, packing
);
3251 * This is the software fallback for Driver.TexImage2D()
3252 * and Driver.CopyTexImage2D().
3254 * This function is oriented toward storing images in main memory, rather
3255 * than VRAM. Device driver's can easily plug in their own replacement.
3257 * Note: width and height may be pre-convolved dimensions, but
3258 * texImage->Width and texImage->Height will be post-convolved dimensions.
3261 _mesa_store_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3262 GLint internalFormat
,
3263 GLint width
, GLint height
, GLint border
,
3264 GLenum format
, GLenum type
, const void *pixels
,
3265 const struct gl_pixelstore_attrib
*packing
,
3266 struct gl_texture_object
*texObj
,
3267 struct gl_texture_image
*texImage
)
3273 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3274 ASSERT(texImage
->TexFormat
);
3276 /* allocate memory */
3277 sizeInBytes
= texture_size(texImage
);
3278 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3279 if (!texImage
->Data
) {
3280 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
3284 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
3285 pixels
, packing
, "glTexImage2D");
3287 /* Note: we check for a NULL image pointer here, _after_ we allocated
3288 * memory for the texture. That's what the GL spec calls for.
3293 GLint dstRowStride
= texture_row_stride(texImage
);
3294 GLboolean success
= _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
3295 texImage
->TexFormat
,
3297 0, 0, 0, /* dstX/Y/Zoffset */
3299 texImage
->ImageOffsets
,
3301 format
, type
, pixels
, packing
);
3303 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
3307 _mesa_unmap_teximage_pbo(ctx
, packing
);
3313 * This is the software fallback for Driver.TexImage3D()
3314 * and Driver.CopyTexImage3D().
3315 * \sa _mesa_store_teximage2d()
3318 _mesa_store_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3319 GLint internalFormat
,
3320 GLint width
, GLint height
, GLint depth
, GLint border
,
3321 GLenum format
, GLenum type
, const void *pixels
,
3322 const struct gl_pixelstore_attrib
*packing
,
3323 struct gl_texture_object
*texObj
,
3324 struct gl_texture_image
*texImage
)
3330 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3331 ASSERT(texImage
->TexFormat
);
3333 /* allocate memory */
3334 sizeInBytes
= texture_size(texImage
);
3335 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3336 if (!texImage
->Data
) {
3337 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
3341 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
3342 type
, pixels
, packing
, "glTexImage3D");
3344 /* Note: we check for a NULL image pointer here, _after_ we allocated
3345 * memory for the texture. That's what the GL spec calls for.
3350 GLint dstRowStride
= texture_row_stride(texImage
);
3351 GLboolean success
= _mesa_texstore(ctx
, 3, texImage
->_BaseFormat
,
3352 texImage
->TexFormat
,
3354 0, 0, 0, /* dstX/Y/Zoffset */
3356 texImage
->ImageOffsets
,
3357 width
, height
, depth
,
3358 format
, type
, pixels
, packing
);
3360 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
3364 _mesa_unmap_teximage_pbo(ctx
, packing
);
3371 * This is the software fallback for Driver.TexSubImage1D()
3372 * and Driver.CopyTexSubImage1D().
3375 _mesa_store_texsubimage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3376 GLint xoffset
, GLint width
,
3377 GLenum format
, GLenum type
, const void *pixels
,
3378 const struct gl_pixelstore_attrib
*packing
,
3379 struct gl_texture_object
*texObj
,
3380 struct gl_texture_image
*texImage
)
3382 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3383 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
3384 pixels
, packing
, "glTexSubImage1D");
3389 const GLint dstRowStride
= 0;
3390 GLboolean success
= _mesa_texstore(ctx
, 1, texImage
->_BaseFormat
,
3391 texImage
->TexFormat
,
3393 xoffset
, 0, 0, /* offsets */
3395 texImage
->ImageOffsets
,
3397 format
, type
, pixels
, packing
);
3399 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
3403 _mesa_unmap_teximage_pbo(ctx
, packing
);
3409 * This is the software fallback for Driver.TexSubImage2D()
3410 * and Driver.CopyTexSubImage2D().
3413 _mesa_store_texsubimage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3414 GLint xoffset
, GLint yoffset
,
3415 GLint width
, GLint height
,
3416 GLenum format
, GLenum type
, const void *pixels
,
3417 const struct gl_pixelstore_attrib
*packing
,
3418 struct gl_texture_object
*texObj
,
3419 struct gl_texture_image
*texImage
)
3421 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3422 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
3423 pixels
, packing
, "glTexSubImage2D");
3428 GLint dstRowStride
= texture_row_stride(texImage
);
3429 GLboolean success
= _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
3430 texImage
->TexFormat
,
3432 xoffset
, yoffset
, 0,
3434 texImage
->ImageOffsets
,
3436 format
, type
, pixels
, packing
);
3438 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
3442 _mesa_unmap_teximage_pbo(ctx
, packing
);
3447 * This is the software fallback for Driver.TexSubImage3D().
3448 * and Driver.CopyTexSubImage3D().
3451 _mesa_store_texsubimage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3452 GLint xoffset
, GLint yoffset
, GLint zoffset
,
3453 GLint width
, GLint height
, GLint depth
,
3454 GLenum format
, GLenum type
, const void *pixels
,
3455 const struct gl_pixelstore_attrib
*packing
,
3456 struct gl_texture_object
*texObj
,
3457 struct gl_texture_image
*texImage
)
3459 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3460 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
3461 type
, pixels
, packing
,
3467 GLint dstRowStride
= texture_row_stride(texImage
);
3468 GLboolean success
= _mesa_texstore(ctx
, 3, texImage
->_BaseFormat
,
3469 texImage
->TexFormat
,
3471 xoffset
, yoffset
, zoffset
,
3473 texImage
->ImageOffsets
,
3474 width
, height
, depth
,
3475 format
, type
, pixels
, packing
);
3477 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3D");
3481 _mesa_unmap_teximage_pbo(ctx
, packing
);
3486 * Fallback for Driver.CompressedTexImage1D()
3489 _mesa_store_compressed_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3490 GLint internalFormat
,
3491 GLint width
, GLint border
,
3492 GLsizei imageSize
, const GLvoid
*data
,
3493 struct gl_texture_object
*texObj
,
3494 struct gl_texture_image
*texImage
)
3496 /* this space intentionally left blank */
3498 (void) target
; (void) level
;
3499 (void) internalFormat
;
3500 (void) width
; (void) border
;
3501 (void) imageSize
; (void) data
;
3509 * Fallback for Driver.CompressedTexImage2D()
3512 _mesa_store_compressed_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3513 GLint internalFormat
,
3514 GLint width
, GLint height
, GLint border
,
3515 GLsizei imageSize
, const GLvoid
*data
,
3516 struct gl_texture_object
*texObj
,
3517 struct gl_texture_image
*texImage
)
3519 (void) width
; (void) height
; (void) border
;
3521 /* This is pretty simple, basically just do a memcpy without worrying
3522 * about the usual image unpacking or image transfer operations.
3526 ASSERT(texImage
->Width
> 0);
3527 ASSERT(texImage
->Height
> 0);
3528 ASSERT(texImage
->Depth
== 1);
3529 ASSERT(texImage
->Data
== NULL
); /* was freed in glCompressedTexImage2DARB */
3532 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, 0, 0);
3533 ASSERT(texImage
->TexFormat
);
3535 /* allocate storage */
3536 texImage
->Data
= _mesa_alloc_texmemory(imageSize
);
3537 if (!texImage
->Data
) {
3538 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
3542 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
3544 "glCompressedTexImage2D");
3549 MEMCPY(texImage
->Data
, data
, imageSize
);
3551 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
3557 * Fallback for Driver.CompressedTexImage3D()
3560 _mesa_store_compressed_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3561 GLint internalFormat
,
3562 GLint width
, GLint height
, GLint depth
,
3564 GLsizei imageSize
, const GLvoid
*data
,
3565 struct gl_texture_object
*texObj
,
3566 struct gl_texture_image
*texImage
)
3568 /* this space intentionally left blank */
3570 (void) target
; (void) level
;
3571 (void) internalFormat
;
3572 (void) width
; (void) height
; (void) depth
;
3574 (void) imageSize
; (void) data
;
3582 * Fallback for Driver.CompressedTexSubImage1D()
3585 _mesa_store_compressed_texsubimage1d(GLcontext
*ctx
, GLenum target
,
3587 GLint xoffset
, GLsizei width
,
3589 GLsizei imageSize
, const GLvoid
*data
,
3590 struct gl_texture_object
*texObj
,
3591 struct gl_texture_image
*texImage
)
3593 /* there are no compressed 1D texture formats yet */
3595 (void) target
; (void) level
;
3596 (void) xoffset
; (void) width
;
3598 (void) imageSize
; (void) data
;
3605 * Fallback for Driver.CompressedTexSubImage2D()
3608 _mesa_store_compressed_texsubimage2d(GLcontext
*ctx
, GLenum target
,
3610 GLint xoffset
, GLint yoffset
,
3611 GLsizei width
, GLsizei height
,
3613 GLsizei imageSize
, const GLvoid
*data
,
3614 struct gl_texture_object
*texObj
,
3615 struct gl_texture_image
*texImage
)
3617 GLint bytesPerRow
, destRowStride
, srcRowStride
;
3621 const gl_format texFormat
= texImage
->TexFormat
;
3625 /* these should have been caught sooner */
3626 ASSERT((width
& 3) == 0 || width
== 2 || width
== 1);
3627 ASSERT((height
& 3) == 0 || height
== 2 || height
== 1);
3628 ASSERT((xoffset
& 3) == 0);
3629 ASSERT((yoffset
& 3) == 0);
3631 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3632 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
3634 "glCompressedTexSubImage2D");
3638 srcRowStride
= _mesa_compressed_row_stride(texFormat
, width
);
3639 src
= (const GLubyte
*) data
;
3641 destRowStride
= _mesa_compressed_row_stride(texFormat
, texImage
->Width
);
3642 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
3645 (GLubyte
*) texImage
->Data
);
3647 bytesPerRow
= srcRowStride
;
3650 for (i
= 0; i
< rows
; i
++) {
3651 MEMCPY(dest
, src
, bytesPerRow
);
3652 dest
+= destRowStride
;
3653 src
+= srcRowStride
;
3656 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
3661 * Fallback for Driver.CompressedTexSubImage3D()
3664 _mesa_store_compressed_texsubimage3d(GLcontext
*ctx
, GLenum target
,
3666 GLint xoffset
, GLint yoffset
, GLint zoffset
,
3667 GLsizei width
, GLsizei height
, GLsizei depth
,
3669 GLsizei imageSize
, const GLvoid
*data
,
3670 struct gl_texture_object
*texObj
,
3671 struct gl_texture_image
*texImage
)
3673 /* there are no compressed 3D texture formats yet */
3675 (void) target
; (void) level
;
3676 (void) xoffset
; (void) yoffset
; (void) zoffset
;
3677 (void) width
; (void) height
; (void) depth
;
3679 (void) imageSize
; (void) data
;