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),
281 * Make a temporary (color) texture image with GLfloat components.
282 * Apply all needed pixel unpacking and pixel transfer operations.
283 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
284 * Suppose the user specifies GL_LUMINANCE as the internal texture format
285 * but the graphics hardware doesn't support luminance textures. So, might
286 * use an RGB hardware format instead.
287 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
289 * \param ctx the rendering context
290 * \param dims image dimensions: 1, 2 or 3
291 * \param logicalBaseFormat basic texture derived from the user's
292 * internal texture format value
293 * \param textureBaseFormat the actual basic format of the texture
294 * \param srcWidth source image width
295 * \param srcHeight source image height
296 * \param srcDepth source image depth
297 * \param srcFormat source image format
298 * \param srcType source image type
299 * \param srcAddr source image address
300 * \param srcPacking source image pixel packing
301 * \return resulting image with format = textureBaseFormat and type = GLfloat.
304 make_temp_float_image(GLcontext
*ctx
, GLuint dims
,
305 GLenum logicalBaseFormat
,
306 GLenum textureBaseFormat
,
307 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
308 GLenum srcFormat
, GLenum srcType
,
309 const GLvoid
*srcAddr
,
310 const struct gl_pixelstore_attrib
*srcPacking
)
312 GLuint transferOps
= ctx
->_ImageTransferState
;
315 ASSERT(dims
>= 1 && dims
<= 3);
317 ASSERT(logicalBaseFormat
== GL_RGBA
||
318 logicalBaseFormat
== GL_RGB
||
319 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
320 logicalBaseFormat
== GL_LUMINANCE
||
321 logicalBaseFormat
== GL_ALPHA
||
322 logicalBaseFormat
== GL_INTENSITY
||
323 logicalBaseFormat
== GL_COLOR_INDEX
||
324 logicalBaseFormat
== GL_DEPTH_COMPONENT
);
326 ASSERT(textureBaseFormat
== GL_RGBA
||
327 textureBaseFormat
== GL_RGB
||
328 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
329 textureBaseFormat
== GL_LUMINANCE
||
330 textureBaseFormat
== GL_ALPHA
||
331 textureBaseFormat
== GL_INTENSITY
||
332 textureBaseFormat
== GL_COLOR_INDEX
||
333 textureBaseFormat
== GL_DEPTH_COMPONENT
);
335 /* conventional color image */
337 if ((dims
== 1 && ctx
->Pixel
.Convolution1DEnabled
) ||
338 (dims
>= 2 && ctx
->Pixel
.Convolution2DEnabled
) ||
339 (dims
>= 2 && ctx
->Pixel
.Separable2DEnabled
)) {
340 /* need image convolution */
341 const GLuint preConvTransferOps
342 = (transferOps
& IMAGE_PRE_CONVOLUTION_BITS
) | IMAGE_CLAMP_BIT
;
343 const GLuint postConvTransferOps
344 = (transferOps
& IMAGE_POST_CONVOLUTION_BITS
) | IMAGE_CLAMP_BIT
;
346 GLint convWidth
= srcWidth
, convHeight
= srcHeight
;
349 /* pre-convolution image buffer (3D) */
350 tempImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
351 * 4 * sizeof(GLfloat
));
355 /* post-convolution image buffer (2D) */
356 convImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
357 * 4 * sizeof(GLfloat
));
359 _mesa_free(tempImage
);
363 /* loop over 3D image slices */
364 for (img
= 0; img
< srcDepth
; img
++) {
365 GLfloat
*dst
= tempImage
+ img
* (srcWidth
* srcHeight
* 4);
367 /* unpack and do transfer ops up to convolution */
368 for (row
= 0; row
< srcHeight
; row
++) {
369 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
370 srcAddr
, srcWidth
, srcHeight
,
371 srcFormat
, srcType
, img
, row
, 0);
372 _mesa_unpack_color_span_float(ctx
, srcWidth
, GL_RGBA
, dst
,
373 srcFormat
, srcType
, src
,
379 /* size after optional convolution */
380 convWidth
= srcWidth
;
381 convHeight
= srcHeight
;
386 GLfloat
*src
= tempImage
+ img
* (srcWidth
* srcHeight
* 4);
388 ASSERT(ctx
->Pixel
.Convolution1DEnabled
);
389 _mesa_convolve_1d_image(ctx
, &convWidth
, src
, convImage
);
392 if (ctx
->Pixel
.Convolution2DEnabled
) {
393 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
397 ASSERT(ctx
->Pixel
.Separable2DEnabled
);
398 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
404 /* do post-convolution transfer and pack into tempImage */
406 const GLint logComponents
407 = _mesa_components_in_format(logicalBaseFormat
);
408 const GLfloat
*src
= convImage
;
409 GLfloat
*dst
= tempImage
+ img
* (convWidth
* convHeight
* 4);
410 for (row
= 0; row
< convHeight
; row
++) {
411 _mesa_pack_rgba_span_float(ctx
, convWidth
,
412 (GLfloat (*)[4]) src
,
413 logicalBaseFormat
, GL_FLOAT
,
414 dst
, &ctx
->DefaultPacking
,
415 postConvTransferOps
);
416 src
+= convWidth
* 4;
417 dst
+= convWidth
* logComponents
;
420 } /* loop over 3D image slices */
422 _mesa_free(convImage
);
424 /* might need these below */
425 srcWidth
= convWidth
;
426 srcHeight
= convHeight
;
430 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
431 const GLint srcStride
=
432 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
436 tempImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
437 * components
* sizeof(GLfloat
));
442 for (img
= 0; img
< srcDepth
; img
++) {
444 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
448 for (row
= 0; row
< srcHeight
; row
++) {
449 _mesa_unpack_color_span_float(ctx
, srcWidth
, logicalBaseFormat
,
450 dst
, srcFormat
, srcType
, src
,
451 srcPacking
, transferOps
);
452 dst
+= srcWidth
* components
;
458 if (logicalBaseFormat
!= textureBaseFormat
) {
460 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
461 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
466 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
467 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
468 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
470 /* The actual texture format should have at least as many components
471 * as the logical texture format.
473 ASSERT(texComponents
>= logComponents
);
475 newImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
476 * texComponents
* sizeof(GLfloat
));
478 _mesa_free(tempImage
);
482 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
484 n
= srcWidth
* srcHeight
* srcDepth
;
485 for (i
= 0; i
< n
; i
++) {
487 for (k
= 0; k
< texComponents
; k
++) {
490 newImage
[i
* texComponents
+ k
] = 0.0F
;
492 newImage
[i
* texComponents
+ k
] = 1.0F
;
494 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
498 _mesa_free(tempImage
);
499 tempImage
= newImage
;
507 * Make a temporary (color) texture image with GLchan components.
508 * Apply all needed pixel unpacking and pixel transfer operations.
509 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
510 * Suppose the user specifies GL_LUMINANCE as the internal texture format
511 * but the graphics hardware doesn't support luminance textures. So, might
512 * use an RGB hardware format instead.
513 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
515 * \param ctx the rendering context
516 * \param dims image dimensions: 1, 2 or 3
517 * \param logicalBaseFormat basic texture derived from the user's
518 * internal texture format value
519 * \param textureBaseFormat the actual basic format of the texture
520 * \param srcWidth source image width
521 * \param srcHeight source image height
522 * \param srcDepth source image depth
523 * \param srcFormat source image format
524 * \param srcType source image type
525 * \param srcAddr source image address
526 * \param srcPacking source image pixel packing
527 * \return resulting image with format = textureBaseFormat and type = GLchan.
530 _mesa_make_temp_chan_image(GLcontext
*ctx
, GLuint dims
,
531 GLenum logicalBaseFormat
,
532 GLenum textureBaseFormat
,
533 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
534 GLenum srcFormat
, GLenum srcType
,
535 const GLvoid
*srcAddr
,
536 const struct gl_pixelstore_attrib
*srcPacking
)
538 GLuint transferOps
= ctx
->_ImageTransferState
;
539 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
540 GLboolean freeSrcImage
= GL_FALSE
;
542 GLchan
*tempImage
, *dst
;
544 ASSERT(dims
>= 1 && dims
<= 3);
546 ASSERT(logicalBaseFormat
== GL_RGBA
||
547 logicalBaseFormat
== GL_RGB
||
548 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
549 logicalBaseFormat
== GL_LUMINANCE
||
550 logicalBaseFormat
== GL_ALPHA
||
551 logicalBaseFormat
== GL_INTENSITY
);
553 ASSERT(textureBaseFormat
== GL_RGBA
||
554 textureBaseFormat
== GL_RGB
||
555 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
556 textureBaseFormat
== GL_LUMINANCE
||
557 textureBaseFormat
== GL_ALPHA
||
558 textureBaseFormat
== GL_INTENSITY
);
561 if ((dims
== 1 && ctx
->Pixel
.Convolution1DEnabled
) ||
562 (dims
>= 2 && ctx
->Pixel
.Convolution2DEnabled
) ||
563 (dims
>= 2 && ctx
->Pixel
.Separable2DEnabled
)) {
564 /* get convolved image */
565 GLfloat
*convImage
= make_temp_float_image(ctx
, dims
,
568 srcWidth
, srcHeight
, srcDepth
,
570 srcAddr
, srcPacking
);
573 /* the convolved image is our new source image */
575 srcFormat
= logicalBaseFormat
;
577 srcPacking
= &ctx
->DefaultPacking
;
578 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
580 freeSrcImage
= GL_TRUE
;
584 /* unpack and transfer the source image */
585 tempImage
= (GLchan
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
586 * components
* sizeof(GLchan
));
589 _mesa_free((void *) srcAddr
);
595 for (img
= 0; img
< srcDepth
; img
++) {
596 const GLint srcStride
=
597 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
599 (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
603 for (row
= 0; row
< srcHeight
; row
++) {
604 _mesa_unpack_color_span_chan(ctx
, srcWidth
, logicalBaseFormat
, dst
,
605 srcFormat
, srcType
, src
, srcPacking
,
607 dst
+= srcWidth
* components
;
612 /* If we made a temporary image for convolution, free it here */
614 _mesa_free((void *) srcAddr
);
617 if (logicalBaseFormat
!= textureBaseFormat
) {
618 /* one more conversion step */
619 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
620 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
625 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
626 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
627 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
629 /* The actual texture format should have at least as many components
630 * as the logical texture format.
632 ASSERT(texComponents
>= logComponents
);
634 newImage
= (GLchan
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
635 * texComponents
* sizeof(GLchan
));
637 _mesa_free(tempImage
);
641 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
643 n
= srcWidth
* srcHeight
* srcDepth
;
644 for (i
= 0; i
< n
; i
++) {
646 for (k
= 0; k
< texComponents
; k
++) {
649 newImage
[i
* texComponents
+ k
] = 0;
651 newImage
[i
* texComponents
+ k
] = CHAN_MAX
;
653 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
657 _mesa_free(tempImage
);
658 tempImage
= newImage
;
666 * Copy GLubyte pixels from <src> to <dst> with swizzling.
667 * \param dst destination pixels
668 * \param dstComponents number of color components in destination pixels
669 * \param src source pixels
670 * \param srcComponents number of color components in source pixels
671 * \param map the swizzle mapping. map[X] says where to find the X component
672 * in the source image's pixels. For example, if the source image
673 * is GL_BGRA and X = red, map[0] yields 2.
674 * \param count number of pixels to copy/swizzle.
677 swizzle_copy(GLubyte
*dst
, GLuint dstComponents
, const GLubyte
*src
,
678 GLuint srcComponents
, const GLubyte
*map
, GLuint count
)
680 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
683 for (i = 0; i < count; i++) { \
685 if (srcComps == 4) { \
686 COPY_4UBV(tmp, src); \
689 for (j = 0; j < srcComps; j++) { \
694 for (j = 0; j < dstComps; j++) { \
695 dst[j] = tmp[map[j]]; \
706 ASSERT(srcComponents
<= 4);
707 ASSERT(dstComponents
<= 4);
709 switch (dstComponents
) {
711 switch (srcComponents
) {
713 SWZ_CPY(dst
, src
, count
, 4, 4);
716 SWZ_CPY(dst
, src
, count
, 4, 3);
719 SWZ_CPY(dst
, src
, count
, 4, 2);
722 SWZ_CPY(dst
, src
, count
, 4, 1);
729 switch (srcComponents
) {
731 SWZ_CPY(dst
, src
, count
, 3, 4);
734 SWZ_CPY(dst
, src
, count
, 3, 3);
737 SWZ_CPY(dst
, src
, count
, 3, 2);
740 SWZ_CPY(dst
, src
, count
, 3, 1);
747 switch (srcComponents
) {
749 SWZ_CPY(dst
, src
, count
, 2, 4);
752 SWZ_CPY(dst
, src
, count
, 2, 3);
755 SWZ_CPY(dst
, src
, count
, 2, 2);
758 SWZ_CPY(dst
, src
, count
, 2, 1);
765 switch (srcComponents
) {
767 SWZ_CPY(dst
, src
, count
, 1, 4);
770 SWZ_CPY(dst
, src
, count
, 1, 3);
773 SWZ_CPY(dst
, src
, count
, 1, 2);
776 SWZ_CPY(dst
, src
, count
, 1, 1);
790 static const GLubyte map_identity
[6] = { 0, 1, 2, 3, ZERO
, ONE
};
791 static const GLubyte map_3210
[6] = { 3, 2, 1, 0, ZERO
, ONE
};
793 /* Deal with the _REV input types:
795 static const GLubyte
*
796 type_mapping( GLenum srcType
)
800 case GL_UNSIGNED_BYTE
:
802 case GL_UNSIGNED_INT_8_8_8_8
:
803 return _mesa_little_endian() ? map_3210
: map_identity
;
804 case GL_UNSIGNED_INT_8_8_8_8_REV
:
805 return _mesa_little_endian() ? map_identity
: map_3210
;
811 /* Mapping required if input type is
813 static const GLubyte
*
814 byteswap_mapping( GLboolean swapBytes
,
822 case GL_UNSIGNED_BYTE
:
824 case GL_UNSIGNED_INT_8_8_8_8
:
825 case GL_UNSIGNED_INT_8_8_8_8_REV
:
835 * Transfer a GLubyte texture image with component swizzling.
838 _mesa_swizzle_ubyte_image(GLcontext
*ctx
,
843 GLenum baseInternalFormat
,
845 const GLubyte
*rgba2dst
,
846 GLuint dstComponents
,
849 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
851 const GLuint
*dstImageOffsets
,
853 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
854 const GLvoid
*srcAddr
,
855 const struct gl_pixelstore_attrib
*srcPacking
)
857 GLint srcComponents
= _mesa_components_in_format(srcFormat
);
858 const GLubyte
*srctype2ubyte
, *swap
;
859 GLubyte map
[4], src2base
[6], base2rgba
[6];
861 const GLint srcRowStride
=
862 _mesa_image_row_stride(srcPacking
, srcWidth
,
863 srcFormat
, GL_UNSIGNED_BYTE
);
864 const GLint srcImageStride
865 = _mesa_image_image_stride(srcPacking
, srcWidth
, srcHeight
, srcFormat
,
867 const GLubyte
*srcImage
868 = (const GLubyte
*) _mesa_image_address(dimensions
, srcPacking
, srcAddr
,
869 srcWidth
, srcHeight
, srcFormat
,
870 GL_UNSIGNED_BYTE
, 0, 0, 0);
874 /* Translate from src->baseInternal->GL_RGBA->dst. This will
875 * correctly deal with RGBA->RGB->RGBA conversions where the final
876 * A value must be 0xff regardless of the incoming alpha values.
878 compute_component_mapping(srcFormat
, baseInternalFormat
, src2base
);
879 compute_component_mapping(baseInternalFormat
, GL_RGBA
, base2rgba
);
880 swap
= byteswap_mapping(srcPacking
->SwapBytes
, srcType
);
881 srctype2ubyte
= type_mapping(srcType
);
884 for (i
= 0; i
< 4; i
++)
885 map
[i
] = srctype2ubyte
[swap
[src2base
[base2rgba
[rgba2dst
[i
]]]]];
887 /* _mesa_printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */
889 if (srcComponents
== dstComponents
&&
890 srcRowStride
== dstRowStride
&&
891 srcRowStride
== srcWidth
* srcComponents
&&
893 /* 1 and 2D images only */
894 GLubyte
*dstImage
= (GLubyte
*) dstAddr
895 + dstYoffset
* dstRowStride
896 + dstXoffset
* dstComponents
;
897 swizzle_copy(dstImage
, dstComponents
, srcImage
, srcComponents
, map
,
898 srcWidth
* srcHeight
);
902 for (img
= 0; img
< srcDepth
; img
++) {
903 const GLubyte
*srcRow
= srcImage
;
904 GLubyte
*dstRow
= (GLubyte
*) dstAddr
905 + dstImageOffsets
[dstZoffset
+ img
] * dstComponents
906 + dstYoffset
* dstRowStride
907 + dstXoffset
* dstComponents
;
908 for (row
= 0; row
< srcHeight
; row
++) {
909 swizzle_copy(dstRow
, dstComponents
, srcRow
, srcComponents
, map
, srcWidth
);
910 dstRow
+= dstRowStride
;
911 srcRow
+= srcRowStride
;
913 srcImage
+= srcImageStride
;
920 * Teximage storage routine for when a simple memcpy will do.
921 * No pixel transfer operations or special texel encodings allowed.
922 * 1D, 2D and 3D images supported.
925 memcpy_texture(GLcontext
*ctx
,
929 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
931 const GLuint
*dstImageOffsets
,
932 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
933 GLenum srcFormat
, GLenum srcType
,
934 const GLvoid
*srcAddr
,
935 const struct gl_pixelstore_attrib
*srcPacking
)
937 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
939 const GLint srcImageStride
= _mesa_image_image_stride(srcPacking
,
940 srcWidth
, srcHeight
, srcFormat
, srcType
);
941 const GLubyte
*srcImage
= (const GLubyte
*) _mesa_image_address(dimensions
,
942 srcPacking
, srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, 0, 0, 0);
943 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
944 const GLint bytesPerRow
= srcWidth
* texelBytes
;
947 /* XXX update/re-enable for dstImageOffsets array */
948 const GLint bytesPerImage
= srcHeight
* bytesPerRow
;
949 const GLint bytesPerTexture
= srcDepth
* bytesPerImage
;
950 GLubyte
*dstImage
= (GLubyte
*) dstAddr
951 + dstZoffset
* dstImageStride
952 + dstYoffset
* dstRowStride
953 + dstXoffset
* texelBytes
;
955 if (dstRowStride
== srcRowStride
&&
956 dstRowStride
== bytesPerRow
&&
957 ((dstImageStride
== srcImageStride
&&
958 dstImageStride
== bytesPerImage
) ||
961 ctx
->Driver
.TextureMemCpy(dstImage
, srcImage
, bytesPerTexture
);
966 for (img
= 0; img
< srcDepth
; img
++) {
967 const GLubyte
*srcRow
= srcImage
;
968 GLubyte
*dstRow
= dstImage
;
969 for (row
= 0; row
< srcHeight
; row
++) {
970 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
971 dstRow
+= dstRowStride
;
972 srcRow
+= srcRowStride
;
974 srcImage
+= srcImageStride
;
975 dstImage
+= dstImageStride
;
981 for (img
= 0; img
< srcDepth
; img
++) {
982 const GLubyte
*srcRow
= srcImage
;
983 GLubyte
*dstRow
= (GLubyte
*) dstAddr
984 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
985 + dstYoffset
* dstRowStride
986 + dstXoffset
* texelBytes
;
987 for (row
= 0; row
< srcHeight
; row
++) {
988 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
989 dstRow
+= dstRowStride
;
990 srcRow
+= srcRowStride
;
992 srcImage
+= srcImageStride
;
999 * Store a 32-bit integer depth component texture image.
1002 _mesa_texstore_z32(TEXSTORE_PARAMS
)
1004 const GLuint depthScale
= 0xffffffff;
1005 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1007 ASSERT(dstFormat
== MESA_FORMAT_Z32
);
1008 ASSERT(texelBytes
== sizeof(GLuint
));
1010 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1011 ctx
->Pixel
.DepthBias
== 0.0f
&&
1012 !srcPacking
->SwapBytes
&&
1013 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1014 srcFormat
== GL_DEPTH_COMPONENT
&&
1015 srcType
== GL_UNSIGNED_INT
) {
1016 /* simple memcpy path */
1017 memcpy_texture(ctx
, dims
,
1018 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1021 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1022 srcAddr
, srcPacking
);
1027 for (img
= 0; img
< srcDepth
; img
++) {
1028 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1029 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1030 + dstYoffset
* dstRowStride
1031 + dstXoffset
* texelBytes
;
1032 for (row
= 0; row
< srcHeight
; row
++) {
1033 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1034 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1035 _mesa_unpack_depth_span(ctx
, srcWidth
,
1036 GL_UNSIGNED_INT
, (GLuint
*) dstRow
,
1037 depthScale
, srcType
, src
, srcPacking
);
1038 dstRow
+= dstRowStride
;
1047 * Store a 24-bit integer depth component texture image.
1050 _mesa_texstore_x8_z24(TEXSTORE_PARAMS
)
1052 const GLuint depthScale
= 0xffffff;
1053 const GLuint texelBytes
= 4;
1056 ASSERT(dstFormat
== MESA_FORMAT_X8_Z24
);
1061 for (img
= 0; img
< srcDepth
; img
++) {
1062 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1063 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1064 + dstYoffset
* dstRowStride
1065 + dstXoffset
* texelBytes
;
1066 for (row
= 0; row
< srcHeight
; row
++) {
1067 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1068 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1069 _mesa_unpack_depth_span(ctx
, srcWidth
,
1070 GL_UNSIGNED_INT
, (GLuint
*) dstRow
,
1071 depthScale
, srcType
, src
, srcPacking
);
1072 dstRow
+= dstRowStride
;
1081 * Store a 24-bit integer depth component texture image.
1084 _mesa_texstore_z24_x8(TEXSTORE_PARAMS
)
1086 const GLuint depthScale
= 0xffffff;
1087 const GLuint texelBytes
= 4;
1090 ASSERT(dstFormat
== MESA_FORMAT_Z24_X8
);
1095 for (img
= 0; img
< srcDepth
; img
++) {
1096 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1097 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1098 + dstYoffset
* dstRowStride
1099 + dstXoffset
* texelBytes
;
1100 for (row
= 0; row
< srcHeight
; row
++) {
1101 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1102 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1103 GLuint
*dst
= (GLuint
*) dstRow
;
1105 _mesa_unpack_depth_span(ctx
, srcWidth
,
1106 GL_UNSIGNED_INT
, dst
,
1107 depthScale
, srcType
, src
, srcPacking
);
1108 for (i
= 0; i
< srcWidth
; i
++)
1110 dstRow
+= dstRowStride
;
1119 * Store a 16-bit integer depth component texture image.
1122 _mesa_texstore_z16(TEXSTORE_PARAMS
)
1124 const GLuint depthScale
= 0xffff;
1125 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1127 ASSERT(dstFormat
== MESA_FORMAT_Z16
);
1128 ASSERT(texelBytes
== sizeof(GLushort
));
1130 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1131 ctx
->Pixel
.DepthBias
== 0.0f
&&
1132 !srcPacking
->SwapBytes
&&
1133 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1134 srcFormat
== GL_DEPTH_COMPONENT
&&
1135 srcType
== GL_UNSIGNED_SHORT
) {
1136 /* simple memcpy path */
1137 memcpy_texture(ctx
, dims
,
1138 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1141 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1142 srcAddr
, srcPacking
);
1147 for (img
= 0; img
< srcDepth
; img
++) {
1148 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1149 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1150 + dstYoffset
* dstRowStride
1151 + dstXoffset
* texelBytes
;
1152 for (row
= 0; row
< srcHeight
; row
++) {
1153 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1154 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1155 GLushort
*dst16
= (GLushort
*) dstRow
;
1156 _mesa_unpack_depth_span(ctx
, srcWidth
,
1157 GL_UNSIGNED_SHORT
, dst16
, depthScale
,
1158 srcType
, src
, srcPacking
);
1159 dstRow
+= dstRowStride
;
1168 * Store an rgb565 or rgb565_rev texture image.
1171 _mesa_texstore_rgb565(TEXSTORE_PARAMS
)
1173 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1174 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1176 ASSERT(dstFormat
== MESA_FORMAT_RGB565
||
1177 dstFormat
== MESA_FORMAT_RGB565_REV
);
1178 ASSERT(texelBytes
== 2);
1180 if (!ctx
->_ImageTransferState
&&
1181 !srcPacking
->SwapBytes
&&
1182 dstFormat
== MESA_FORMAT_RGB565
&&
1183 baseInternalFormat
== GL_RGB
&&
1184 srcFormat
== GL_RGB
&&
1185 srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1186 /* simple memcpy path */
1187 memcpy_texture(ctx
, dims
,
1188 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1191 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1192 srcAddr
, srcPacking
);
1194 else if (!ctx
->_ImageTransferState
&&
1195 !srcPacking
->SwapBytes
&&
1196 baseInternalFormat
== GL_RGB
&&
1197 srcFormat
== GL_RGB
&&
1198 srcType
== GL_UNSIGNED_BYTE
&&
1200 /* do optimized tex store */
1201 const GLint srcRowStride
=
1202 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1203 const GLubyte
*src
= (const GLubyte
*)
1204 _mesa_image_address(dims
, srcPacking
, srcAddr
, srcWidth
, srcHeight
,
1205 srcFormat
, srcType
, 0, 0, 0);
1206 GLubyte
*dst
= (GLubyte
*) dstAddr
1207 + dstYoffset
* dstRowStride
1208 + dstXoffset
* texelBytes
;
1210 for (row
= 0; row
< srcHeight
; row
++) {
1211 const GLubyte
*srcUB
= (const GLubyte
*) src
;
1212 GLushort
*dstUS
= (GLushort
*) dst
;
1213 /* check for byteswapped format */
1214 if (dstFormat
== MESA_FORMAT_RGB565
) {
1215 for (col
= 0; col
< srcWidth
; col
++) {
1216 dstUS
[col
] = PACK_COLOR_565( srcUB
[0], srcUB
[1], srcUB
[2] );
1221 for (col
= 0; col
< srcWidth
; col
++) {
1222 dstUS
[col
] = PACK_COLOR_565_REV( srcUB
[0], srcUB
[1], srcUB
[2] );
1226 dst
+= dstRowStride
;
1227 src
+= srcRowStride
;
1232 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1235 srcWidth
, srcHeight
, srcDepth
,
1236 srcFormat
, srcType
, srcAddr
,
1238 const GLchan
*src
= tempImage
;
1239 GLint img
, row
, col
;
1242 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1243 for (img
= 0; img
< srcDepth
; img
++) {
1244 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1245 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1246 + dstYoffset
* dstRowStride
1247 + dstXoffset
* texelBytes
;
1248 for (row
= 0; row
< srcHeight
; row
++) {
1249 GLushort
*dstUS
= (GLushort
*) dstRow
;
1250 /* check for byteswapped format */
1251 if (dstFormat
== MESA_FORMAT_RGB565
) {
1252 for (col
= 0; col
< srcWidth
; col
++) {
1253 dstUS
[col
] = PACK_COLOR_565( CHAN_TO_UBYTE(src
[RCOMP
]),
1254 CHAN_TO_UBYTE(src
[GCOMP
]),
1255 CHAN_TO_UBYTE(src
[BCOMP
]) );
1260 for (col
= 0; col
< srcWidth
; col
++) {
1261 dstUS
[col
] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1262 CHAN_TO_UBYTE(src
[GCOMP
]),
1263 CHAN_TO_UBYTE(src
[BCOMP
]) );
1267 dstRow
+= dstRowStride
;
1270 _mesa_free((void *) tempImage
);
1277 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1280 _mesa_texstore_rgba8888(TEXSTORE_PARAMS
)
1282 const GLboolean littleEndian
= _mesa_little_endian();
1283 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1284 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1286 ASSERT(dstFormat
== MESA_FORMAT_RGBA8888
||
1287 dstFormat
== MESA_FORMAT_RGBA8888_REV
);
1288 ASSERT(texelBytes
== 4);
1290 if (!ctx
->_ImageTransferState
&&
1291 !srcPacking
->SwapBytes
&&
1292 dstFormat
== MESA_FORMAT_RGBA8888
&&
1293 baseInternalFormat
== GL_RGBA
&&
1294 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1295 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1296 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1297 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
))) {
1298 /* simple memcpy path */
1299 memcpy_texture(ctx
, dims
,
1300 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1303 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1304 srcAddr
, srcPacking
);
1306 else if (!ctx
->_ImageTransferState
&&
1307 !srcPacking
->SwapBytes
&&
1308 dstFormat
== MESA_FORMAT_RGBA8888_REV
&&
1309 baseInternalFormat
== GL_RGBA
&&
1310 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1311 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1312 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1313 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
))) {
1314 /* simple memcpy path */
1315 memcpy_texture(ctx
, dims
,
1316 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1319 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1320 srcAddr
, srcPacking
);
1322 else if (!ctx
->_ImageTransferState
&&
1323 (srcType
== GL_UNSIGNED_BYTE
||
1324 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1325 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1326 can_swizzle(baseInternalFormat
) &&
1327 can_swizzle(srcFormat
)) {
1331 /* dstmap - how to swizzle from RGBA to dst format:
1333 if ((littleEndian
&& dstFormat
== MESA_FORMAT_RGBA8888
) ||
1334 (!littleEndian
&& dstFormat
== MESA_FORMAT_RGBA8888_REV
)) {
1347 _mesa_swizzle_ubyte_image(ctx
, dims
,
1352 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1353 dstRowStride
, dstImageOffsets
,
1354 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1359 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1362 srcWidth
, srcHeight
, srcDepth
,
1363 srcFormat
, srcType
, srcAddr
,
1365 const GLchan
*src
= tempImage
;
1366 GLint img
, row
, col
;
1369 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1370 for (img
= 0; img
< srcDepth
; img
++) {
1371 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1372 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1373 + dstYoffset
* dstRowStride
1374 + dstXoffset
* texelBytes
;
1375 for (row
= 0; row
< srcHeight
; row
++) {
1376 GLuint
*dstUI
= (GLuint
*) dstRow
;
1377 if (dstFormat
== MESA_FORMAT_RGBA8888
) {
1378 for (col
= 0; col
< srcWidth
; col
++) {
1379 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[RCOMP
]),
1380 CHAN_TO_UBYTE(src
[GCOMP
]),
1381 CHAN_TO_UBYTE(src
[BCOMP
]),
1382 CHAN_TO_UBYTE(src
[ACOMP
]) );
1387 for (col
= 0; col
< srcWidth
; col
++) {
1388 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1389 CHAN_TO_UBYTE(src
[GCOMP
]),
1390 CHAN_TO_UBYTE(src
[BCOMP
]),
1391 CHAN_TO_UBYTE(src
[ACOMP
]) );
1395 dstRow
+= dstRowStride
;
1398 _mesa_free((void *) tempImage
);
1405 _mesa_texstore_argb8888(TEXSTORE_PARAMS
)
1407 const GLboolean littleEndian
= _mesa_little_endian();
1408 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1409 const GLenum baseFormat
= GL_RGBA
;
1411 ASSERT(dstFormat
== MESA_FORMAT_ARGB8888
||
1412 dstFormat
== MESA_FORMAT_ARGB8888_REV
||
1413 dstFormat
== MESA_FORMAT_XRGB8888
);
1414 ASSERT(texelBytes
== 4);
1416 if (!ctx
->_ImageTransferState
&&
1417 !srcPacking
->SwapBytes
&&
1418 (dstFormat
== MESA_FORMAT_ARGB8888
||
1419 dstFormat
== MESA_FORMAT_XRGB8888
) &&
1420 baseInternalFormat
== GL_RGBA
&&
1421 srcFormat
== GL_BGRA
&&
1422 ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1423 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
1424 /* simple memcpy path (little endian) */
1425 memcpy_texture(ctx
, dims
,
1426 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1429 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1430 srcAddr
, srcPacking
);
1432 else if (!ctx
->_ImageTransferState
&&
1433 !srcPacking
->SwapBytes
&&
1434 dstFormat
== MESA_FORMAT_ARGB8888_REV
&&
1435 baseInternalFormat
== GL_RGBA
&&
1436 srcFormat
== GL_BGRA
&&
1437 ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1438 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
1439 /* simple memcpy path (big endian) */
1440 memcpy_texture(ctx
, dims
,
1441 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1444 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1445 srcAddr
, srcPacking
);
1447 else if (!ctx
->_ImageTransferState
&&
1448 !srcPacking
->SwapBytes
&&
1449 (dstFormat
== MESA_FORMAT_ARGB8888
||
1450 dstFormat
== MESA_FORMAT_XRGB8888
) &&
1451 srcFormat
== GL_RGB
&&
1452 (baseInternalFormat
== GL_RGBA
||
1453 baseInternalFormat
== GL_RGB
) &&
1454 srcType
== GL_UNSIGNED_BYTE
) {
1456 for (img
= 0; img
< srcDepth
; img
++) {
1457 const GLint srcRowStride
=
1458 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1459 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1460 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1461 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1462 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1463 + dstYoffset
* dstRowStride
1464 + dstXoffset
* texelBytes
;
1465 for (row
= 0; row
< srcHeight
; row
++) {
1466 GLuint
*d4
= (GLuint
*) dstRow
;
1467 for (col
= 0; col
< srcWidth
; col
++) {
1468 d4
[col
] = PACK_COLOR_8888(0xff,
1469 srcRow
[col
* 3 + RCOMP
],
1470 srcRow
[col
* 3 + GCOMP
],
1471 srcRow
[col
* 3 + BCOMP
]);
1473 dstRow
+= dstRowStride
;
1474 srcRow
+= srcRowStride
;
1478 else if (!ctx
->_ImageTransferState
&&
1479 !srcPacking
->SwapBytes
&&
1480 dstFormat
== MESA_FORMAT_ARGB8888
&&
1481 srcFormat
== GL_RGBA
&&
1482 baseInternalFormat
== GL_RGBA
&&
1483 srcType
== GL_UNSIGNED_BYTE
) {
1484 /* same as above case, but src data has alpha too */
1485 GLint img
, row
, col
;
1486 /* For some reason, streaming copies to write-combined regions
1487 * are extremely sensitive to the characteristics of how the
1488 * source data is retrieved. By reordering the source reads to
1489 * be in-order, the speed of this operation increases by half.
1490 * Strangely the same isn't required for the RGB path, above.
1492 for (img
= 0; img
< srcDepth
; img
++) {
1493 const GLint srcRowStride
=
1494 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1495 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1496 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1497 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1498 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1499 + dstYoffset
* dstRowStride
1500 + dstXoffset
* texelBytes
;
1501 for (row
= 0; row
< srcHeight
; row
++) {
1502 GLuint
*d4
= (GLuint
*) dstRow
;
1503 for (col
= 0; col
< srcWidth
; col
++) {
1504 d4
[col
] = PACK_COLOR_8888(srcRow
[col
* 4 + ACOMP
],
1505 srcRow
[col
* 4 + RCOMP
],
1506 srcRow
[col
* 4 + GCOMP
],
1507 srcRow
[col
* 4 + BCOMP
]);
1509 dstRow
+= dstRowStride
;
1510 srcRow
+= srcRowStride
;
1514 else if (!ctx
->_ImageTransferState
&&
1515 (srcType
== GL_UNSIGNED_BYTE
||
1516 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1517 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1518 can_swizzle(baseInternalFormat
) &&
1519 can_swizzle(srcFormat
)) {
1523 /* dstmap - how to swizzle from RGBA to dst format:
1525 if ((littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888
) ||
1526 (littleEndian
&& dstFormat
== MESA_FORMAT_XRGB8888
) ||
1527 (!littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888_REV
)) {
1528 dstmap
[3] = 3; /* alpha */
1529 dstmap
[2] = 0; /* red */
1530 dstmap
[1] = 1; /* green */
1531 dstmap
[0] = 2; /* blue */
1534 assert((littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888_REV
) ||
1535 (!littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888
) ||
1536 (!littleEndian
&& dstFormat
== MESA_FORMAT_XRGB8888
));
1543 _mesa_swizzle_ubyte_image(ctx
, dims
,
1549 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1552 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1557 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1560 srcWidth
, srcHeight
, srcDepth
,
1561 srcFormat
, srcType
, srcAddr
,
1563 const GLchan
*src
= tempImage
;
1564 GLint img
, row
, col
;
1567 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1568 for (img
= 0; img
< srcDepth
; img
++) {
1569 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1570 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1571 + dstYoffset
* dstRowStride
1572 + dstXoffset
* texelBytes
;
1573 for (row
= 0; row
< srcHeight
; row
++) {
1574 GLuint
*dstUI
= (GLuint
*) dstRow
;
1575 if (dstFormat
== MESA_FORMAT_ARGB8888
) {
1576 for (col
= 0; col
< srcWidth
; col
++) {
1577 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[ACOMP
]),
1578 CHAN_TO_UBYTE(src
[RCOMP
]),
1579 CHAN_TO_UBYTE(src
[GCOMP
]),
1580 CHAN_TO_UBYTE(src
[BCOMP
]) );
1584 else if (dstFormat
== MESA_FORMAT_XRGB8888
) {
1585 for (col
= 0; col
< srcWidth
; col
++) {
1586 dstUI
[col
] = PACK_COLOR_8888( 0xff,
1587 CHAN_TO_UBYTE(src
[RCOMP
]),
1588 CHAN_TO_UBYTE(src
[GCOMP
]),
1589 CHAN_TO_UBYTE(src
[BCOMP
]) );
1594 for (col
= 0; col
< srcWidth
; col
++) {
1595 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1596 CHAN_TO_UBYTE(src
[RCOMP
]),
1597 CHAN_TO_UBYTE(src
[GCOMP
]),
1598 CHAN_TO_UBYTE(src
[BCOMP
]) );
1602 dstRow
+= dstRowStride
;
1605 _mesa_free((void *) tempImage
);
1612 _mesa_texstore_rgb888(TEXSTORE_PARAMS
)
1614 const GLboolean littleEndian
= _mesa_little_endian();
1615 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1616 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1618 ASSERT(dstFormat
== MESA_FORMAT_RGB888
);
1619 ASSERT(texelBytes
== 3);
1621 if (!ctx
->_ImageTransferState
&&
1622 !srcPacking
->SwapBytes
&&
1623 baseInternalFormat
== GL_RGB
&&
1624 srcFormat
== GL_BGR
&&
1625 srcType
== GL_UNSIGNED_BYTE
&&
1627 /* simple memcpy path */
1628 memcpy_texture(ctx
, dims
,
1629 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1632 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1633 srcAddr
, srcPacking
);
1635 else if (!ctx
->_ImageTransferState
&&
1636 !srcPacking
->SwapBytes
&&
1637 srcFormat
== GL_RGBA
&&
1638 srcType
== GL_UNSIGNED_BYTE
) {
1639 /* extract RGB from RGBA */
1640 GLint img
, row
, col
;
1641 for (img
= 0; img
< srcDepth
; img
++) {
1642 const GLint srcRowStride
=
1643 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1644 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1645 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1646 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1647 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1648 + dstYoffset
* dstRowStride
1649 + dstXoffset
* texelBytes
;
1650 for (row
= 0; row
< srcHeight
; row
++) {
1651 for (col
= 0; col
< srcWidth
; col
++) {
1652 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + BCOMP
];
1653 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1654 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + RCOMP
];
1656 dstRow
+= dstRowStride
;
1657 srcRow
+= srcRowStride
;
1661 else if (!ctx
->_ImageTransferState
&&
1662 srcType
== GL_UNSIGNED_BYTE
&&
1663 can_swizzle(baseInternalFormat
) &&
1664 can_swizzle(srcFormat
)) {
1668 /* dstmap - how to swizzle from RGBA to dst format:
1673 dstmap
[3] = ONE
; /* ? */
1675 _mesa_swizzle_ubyte_image(ctx
, dims
,
1680 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1681 dstRowStride
, dstImageOffsets
,
1682 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1687 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1690 srcWidth
, srcHeight
, srcDepth
,
1691 srcFormat
, srcType
, srcAddr
,
1693 const GLchan
*src
= (const GLchan
*) tempImage
;
1694 GLint img
, row
, col
;
1697 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1698 for (img
= 0; img
< srcDepth
; img
++) {
1699 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1700 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1701 + dstYoffset
* dstRowStride
1702 + dstXoffset
* texelBytes
;
1703 for (row
= 0; row
< srcHeight
; row
++) {
1706 for (col
= 0; col
< srcWidth
; col
++) {
1707 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1708 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1709 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1714 for (col
= 0; col
< srcWidth
; col
++) {
1715 dstRow
[col
* 3 + 0] = srcUB
[BCOMP
];
1716 dstRow
[col
* 3 + 1] = srcUB
[GCOMP
];
1717 dstRow
[col
* 3 + 2] = srcUB
[RCOMP
];
1722 for (col
= 0; col
< srcWidth
; col
++) {
1723 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[BCOMP
]);
1724 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1725 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[RCOMP
]);
1729 dstRow
+= dstRowStride
;
1732 _mesa_free((void *) tempImage
);
1739 _mesa_texstore_bgr888(TEXSTORE_PARAMS
)
1741 const GLboolean littleEndian
= _mesa_little_endian();
1742 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1743 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1745 ASSERT(dstFormat
== MESA_FORMAT_BGR888
);
1746 ASSERT(texelBytes
== 3);
1748 if (!ctx
->_ImageTransferState
&&
1749 !srcPacking
->SwapBytes
&&
1750 baseInternalFormat
== GL_RGB
&&
1751 srcFormat
== GL_RGB
&&
1752 srcType
== GL_UNSIGNED_BYTE
&&
1754 /* simple memcpy path */
1755 memcpy_texture(ctx
, dims
,
1756 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1759 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1760 srcAddr
, srcPacking
);
1762 else if (!ctx
->_ImageTransferState
&&
1763 !srcPacking
->SwapBytes
&&
1764 srcFormat
== GL_RGBA
&&
1765 srcType
== GL_UNSIGNED_BYTE
) {
1766 /* extract BGR from RGBA */
1768 for (img
= 0; img
< srcDepth
; img
++) {
1769 const GLint srcRowStride
=
1770 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1771 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1772 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1773 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1774 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1775 + dstYoffset
* dstRowStride
1776 + dstXoffset
* texelBytes
;
1777 for (row
= 0; row
< srcHeight
; row
++) {
1778 for (col
= 0; col
< srcWidth
; col
++) {
1779 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + RCOMP
];
1780 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1781 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + BCOMP
];
1783 dstRow
+= dstRowStride
;
1784 srcRow
+= srcRowStride
;
1788 else if (!ctx
->_ImageTransferState
&&
1789 srcType
== GL_UNSIGNED_BYTE
&&
1790 can_swizzle(baseInternalFormat
) &&
1791 can_swizzle(srcFormat
)) {
1795 /* dstmap - how to swizzle from RGBA to dst format:
1800 dstmap
[3] = ONE
; /* ? */
1802 _mesa_swizzle_ubyte_image(ctx
, dims
,
1807 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1808 dstRowStride
, dstImageOffsets
,
1809 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1814 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1817 srcWidth
, srcHeight
, srcDepth
,
1818 srcFormat
, srcType
, srcAddr
,
1820 const GLchan
*src
= (const GLchan
*) tempImage
;
1821 GLint img
, row
, col
;
1824 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1825 for (img
= 0; img
< srcDepth
; img
++) {
1826 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1827 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1828 + dstYoffset
* dstRowStride
1829 + dstXoffset
* texelBytes
;
1830 for (row
= 0; row
< srcHeight
; row
++) {
1831 for (col
= 0; col
< srcWidth
; col
++) {
1832 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1833 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1834 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1837 dstRow
+= dstRowStride
;
1840 _mesa_free((void *) tempImage
);
1847 _mesa_texstore_argb4444(TEXSTORE_PARAMS
)
1849 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1850 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1852 ASSERT(dstFormat
== MESA_FORMAT_ARGB4444
||
1853 dstFormat
== MESA_FORMAT_ARGB4444_REV
);
1854 ASSERT(texelBytes
== 2);
1856 if (!ctx
->_ImageTransferState
&&
1857 !srcPacking
->SwapBytes
&&
1858 dstFormat
== MESA_FORMAT_ARGB4444
&&
1859 baseInternalFormat
== GL_RGBA
&&
1860 srcFormat
== GL_BGRA
&&
1861 srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1862 /* simple memcpy path */
1863 memcpy_texture(ctx
, dims
,
1864 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1867 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1868 srcAddr
, srcPacking
);
1872 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1875 srcWidth
, srcHeight
, srcDepth
,
1876 srcFormat
, srcType
, srcAddr
,
1878 const GLchan
*src
= tempImage
;
1879 GLint img
, row
, col
;
1882 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1883 for (img
= 0; img
< srcDepth
; img
++) {
1884 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1885 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1886 + dstYoffset
* dstRowStride
1887 + dstXoffset
* texelBytes
;
1888 for (row
= 0; row
< srcHeight
; row
++) {
1889 GLushort
*dstUS
= (GLushort
*) dstRow
;
1890 if (dstFormat
== MESA_FORMAT_ARGB4444
) {
1891 for (col
= 0; col
< srcWidth
; col
++) {
1892 dstUS
[col
] = PACK_COLOR_4444( CHAN_TO_UBYTE(src
[ACOMP
]),
1893 CHAN_TO_UBYTE(src
[RCOMP
]),
1894 CHAN_TO_UBYTE(src
[GCOMP
]),
1895 CHAN_TO_UBYTE(src
[BCOMP
]) );
1900 for (col
= 0; col
< srcWidth
; col
++) {
1901 dstUS
[col
] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1902 CHAN_TO_UBYTE(src
[RCOMP
]),
1903 CHAN_TO_UBYTE(src
[GCOMP
]),
1904 CHAN_TO_UBYTE(src
[BCOMP
]) );
1908 dstRow
+= dstRowStride
;
1911 _mesa_free((void *) tempImage
);
1917 _mesa_texstore_rgba5551(TEXSTORE_PARAMS
)
1919 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1920 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1922 ASSERT(dstFormat
== MESA_FORMAT_RGBA5551
);
1923 ASSERT(texelBytes
== 2);
1925 if (!ctx
->_ImageTransferState
&&
1926 !srcPacking
->SwapBytes
&&
1927 dstFormat
== MESA_FORMAT_RGBA5551
&&
1928 baseInternalFormat
== GL_RGBA
&&
1929 srcFormat
== GL_RGBA
&&
1930 srcType
== GL_UNSIGNED_SHORT_5_5_5_1
) {
1931 /* simple memcpy path */
1932 memcpy_texture(ctx
, dims
,
1933 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1936 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1937 srcAddr
, srcPacking
);
1941 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1944 srcWidth
, srcHeight
, srcDepth
,
1945 srcFormat
, srcType
, srcAddr
,
1947 const GLchan
*src
=tempImage
;
1948 GLint img
, row
, col
;
1951 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1952 for (img
= 0; img
< srcDepth
; img
++) {
1953 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1954 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1955 + dstYoffset
* dstRowStride
1956 + dstXoffset
* texelBytes
;
1957 for (row
= 0; row
< srcHeight
; row
++) {
1958 GLushort
*dstUS
= (GLushort
*) dstRow
;
1959 for (col
= 0; col
< srcWidth
; col
++) {
1960 dstUS
[col
] = PACK_COLOR_5551( CHAN_TO_UBYTE(src
[RCOMP
]),
1961 CHAN_TO_UBYTE(src
[GCOMP
]),
1962 CHAN_TO_UBYTE(src
[BCOMP
]),
1963 CHAN_TO_UBYTE(src
[ACOMP
]) );
1966 dstRow
+= dstRowStride
;
1969 _mesa_free((void *) tempImage
);
1975 _mesa_texstore_argb1555(TEXSTORE_PARAMS
)
1977 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1978 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1980 ASSERT(dstFormat
== MESA_FORMAT_ARGB1555
||
1981 dstFormat
== MESA_FORMAT_ARGB1555_REV
);
1982 ASSERT(texelBytes
== 2);
1984 if (!ctx
->_ImageTransferState
&&
1985 !srcPacking
->SwapBytes
&&
1986 dstFormat
== MESA_FORMAT_ARGB1555
&&
1987 baseInternalFormat
== GL_RGBA
&&
1988 srcFormat
== GL_BGRA
&&
1989 srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
1990 /* simple memcpy path */
1991 memcpy_texture(ctx
, dims
,
1992 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1995 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1996 srcAddr
, srcPacking
);
2000 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2003 srcWidth
, srcHeight
, srcDepth
,
2004 srcFormat
, srcType
, srcAddr
,
2006 const GLchan
*src
=tempImage
;
2007 GLint img
, row
, col
;
2010 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2011 for (img
= 0; img
< srcDepth
; img
++) {
2012 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2013 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2014 + dstYoffset
* dstRowStride
2015 + dstXoffset
* texelBytes
;
2016 for (row
= 0; row
< srcHeight
; row
++) {
2017 GLushort
*dstUS
= (GLushort
*) dstRow
;
2018 if (dstFormat
== MESA_FORMAT_ARGB1555
) {
2019 for (col
= 0; col
< srcWidth
; col
++) {
2020 dstUS
[col
] = PACK_COLOR_1555( CHAN_TO_UBYTE(src
[ACOMP
]),
2021 CHAN_TO_UBYTE(src
[RCOMP
]),
2022 CHAN_TO_UBYTE(src
[GCOMP
]),
2023 CHAN_TO_UBYTE(src
[BCOMP
]) );
2028 for (col
= 0; col
< srcWidth
; col
++) {
2029 dstUS
[col
] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
2030 CHAN_TO_UBYTE(src
[RCOMP
]),
2031 CHAN_TO_UBYTE(src
[GCOMP
]),
2032 CHAN_TO_UBYTE(src
[BCOMP
]) );
2036 dstRow
+= dstRowStride
;
2039 _mesa_free((void *) tempImage
);
2046 _mesa_texstore_al88(TEXSTORE_PARAMS
)
2048 const GLboolean littleEndian
= _mesa_little_endian();
2049 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2050 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2052 ASSERT(dstFormat
== MESA_FORMAT_AL88
||
2053 dstFormat
== MESA_FORMAT_AL88_REV
);
2054 ASSERT(texelBytes
== 2);
2056 if (!ctx
->_ImageTransferState
&&
2057 !srcPacking
->SwapBytes
&&
2058 dstFormat
== MESA_FORMAT_AL88
&&
2059 baseInternalFormat
== GL_LUMINANCE_ALPHA
&&
2060 srcFormat
== GL_LUMINANCE_ALPHA
&&
2061 srcType
== GL_UNSIGNED_BYTE
&&
2063 /* simple memcpy path */
2064 memcpy_texture(ctx
, dims
,
2065 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2068 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2069 srcAddr
, srcPacking
);
2071 else if (!ctx
->_ImageTransferState
&&
2073 srcType
== GL_UNSIGNED_BYTE
&&
2074 can_swizzle(baseInternalFormat
) &&
2075 can_swizzle(srcFormat
)) {
2079 /* dstmap - how to swizzle from RGBA to dst format:
2081 if ((littleEndian
&& dstFormat
== MESA_FORMAT_AL88
) ||
2082 (!littleEndian
&& dstFormat
== MESA_FORMAT_AL88_REV
)) {
2090 dstmap
[2] = ZERO
; /* ? */
2091 dstmap
[3] = ONE
; /* ? */
2093 _mesa_swizzle_ubyte_image(ctx
, dims
,
2098 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2099 dstRowStride
, dstImageOffsets
,
2100 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2105 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2108 srcWidth
, srcHeight
, srcDepth
,
2109 srcFormat
, srcType
, srcAddr
,
2111 const GLchan
*src
= tempImage
;
2112 GLint img
, row
, col
;
2115 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2116 for (img
= 0; img
< srcDepth
; img
++) {
2117 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2118 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2119 + dstYoffset
* dstRowStride
2120 + dstXoffset
* texelBytes
;
2121 for (row
= 0; row
< srcHeight
; row
++) {
2122 GLushort
*dstUS
= (GLushort
*) dstRow
;
2123 if (dstFormat
== MESA_FORMAT_AL88
) {
2124 for (col
= 0; col
< srcWidth
; col
++) {
2125 /* src[0] is luminance, src[1] is alpha */
2126 dstUS
[col
] = PACK_COLOR_88( CHAN_TO_UBYTE(src
[1]),
2127 CHAN_TO_UBYTE(src
[0]) );
2132 for (col
= 0; col
< srcWidth
; col
++) {
2133 /* src[0] is luminance, src[1] is alpha */
2134 dstUS
[col
] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src
[1]),
2135 CHAN_TO_UBYTE(src
[0]) );
2139 dstRow
+= dstRowStride
;
2142 _mesa_free((void *) tempImage
);
2149 _mesa_texstore_rgb332(TEXSTORE_PARAMS
)
2151 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2152 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2154 ASSERT(dstFormat
== MESA_FORMAT_RGB332
);
2155 ASSERT(texelBytes
== 1);
2157 if (!ctx
->_ImageTransferState
&&
2158 !srcPacking
->SwapBytes
&&
2159 baseInternalFormat
== GL_RGB
&&
2160 srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_BYTE_3_3_2
) {
2161 /* simple memcpy path */
2162 memcpy_texture(ctx
, dims
,
2163 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2166 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2167 srcAddr
, srcPacking
);
2171 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2174 srcWidth
, srcHeight
, srcDepth
,
2175 srcFormat
, srcType
, srcAddr
,
2177 const GLchan
*src
= tempImage
;
2178 GLint img
, row
, col
;
2181 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2182 for (img
= 0; img
< srcDepth
; img
++) {
2183 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2184 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2185 + dstYoffset
* dstRowStride
2186 + dstXoffset
* texelBytes
;
2187 for (row
= 0; row
< srcHeight
; row
++) {
2188 for (col
= 0; col
< srcWidth
; col
++) {
2189 dstRow
[col
] = PACK_COLOR_332( CHAN_TO_UBYTE(src
[RCOMP
]),
2190 CHAN_TO_UBYTE(src
[GCOMP
]),
2191 CHAN_TO_UBYTE(src
[BCOMP
]) );
2194 dstRow
+= dstRowStride
;
2197 _mesa_free((void *) tempImage
);
2204 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2207 _mesa_texstore_a8(TEXSTORE_PARAMS
)
2209 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2210 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2212 ASSERT(dstFormat
== MESA_FORMAT_A8
||
2213 dstFormat
== MESA_FORMAT_L8
||
2214 dstFormat
== MESA_FORMAT_I8
);
2215 ASSERT(texelBytes
== 1);
2217 if (!ctx
->_ImageTransferState
&&
2218 !srcPacking
->SwapBytes
&&
2219 baseInternalFormat
== srcFormat
&&
2220 srcType
== GL_UNSIGNED_BYTE
) {
2221 /* simple memcpy path */
2222 memcpy_texture(ctx
, dims
,
2223 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2226 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2227 srcAddr
, srcPacking
);
2229 else if (!ctx
->_ImageTransferState
&&
2230 srcType
== GL_UNSIGNED_BYTE
&&
2231 can_swizzle(baseInternalFormat
) &&
2232 can_swizzle(srcFormat
)) {
2236 /* dstmap - how to swizzle from RGBA to dst format:
2238 if (dstFormat
== MESA_FORMAT_A8
) {
2244 dstmap
[1] = ZERO
; /* ? */
2245 dstmap
[2] = ZERO
; /* ? */
2246 dstmap
[3] = ONE
; /* ? */
2248 _mesa_swizzle_ubyte_image(ctx
, dims
,
2253 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2254 dstRowStride
, dstImageOffsets
,
2255 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2260 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2263 srcWidth
, srcHeight
, srcDepth
,
2264 srcFormat
, srcType
, srcAddr
,
2266 const GLchan
*src
= tempImage
;
2267 GLint img
, row
, col
;
2270 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2271 for (img
= 0; img
< srcDepth
; img
++) {
2272 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2273 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2274 + dstYoffset
* dstRowStride
2275 + dstXoffset
* texelBytes
;
2276 for (row
= 0; row
< srcHeight
; row
++) {
2277 for (col
= 0; col
< srcWidth
; col
++) {
2278 dstRow
[col
] = CHAN_TO_UBYTE(src
[col
]);
2280 dstRow
+= dstRowStride
;
2284 _mesa_free((void *) tempImage
);
2292 _mesa_texstore_ci8(TEXSTORE_PARAMS
)
2294 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2296 (void) dims
; (void) baseInternalFormat
;
2297 ASSERT(dstFormat
== MESA_FORMAT_CI8
);
2298 ASSERT(texelBytes
== 1);
2299 ASSERT(baseInternalFormat
== GL_COLOR_INDEX
);
2301 if (!ctx
->_ImageTransferState
&&
2302 !srcPacking
->SwapBytes
&&
2303 srcFormat
== GL_COLOR_INDEX
&&
2304 srcType
== GL_UNSIGNED_BYTE
) {
2305 /* simple memcpy path */
2306 memcpy_texture(ctx
, dims
,
2307 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2310 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2311 srcAddr
, srcPacking
);
2316 for (img
= 0; img
< srcDepth
; img
++) {
2317 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2318 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2319 + dstYoffset
* dstRowStride
2320 + dstXoffset
* texelBytes
;
2321 for (row
= 0; row
< srcHeight
; row
++) {
2322 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
2323 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
2324 _mesa_unpack_index_span(ctx
, srcWidth
, GL_UNSIGNED_BYTE
, dstRow
,
2325 srcType
, src
, srcPacking
,
2326 ctx
->_ImageTransferState
);
2327 dstRow
+= dstRowStride
;
2336 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
2339 _mesa_texstore_ycbcr(TEXSTORE_PARAMS
)
2341 const GLboolean littleEndian
= _mesa_little_endian();
2342 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2344 (void) ctx
; (void) dims
; (void) baseInternalFormat
;
2346 ASSERT((dstFormat
== MESA_FORMAT_YCBCR
) ||
2347 (dstFormat
== MESA_FORMAT_YCBCR_REV
));
2348 ASSERT(texelBytes
== 2);
2349 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
2350 ASSERT(srcFormat
== GL_YCBCR_MESA
);
2351 ASSERT((srcType
== GL_UNSIGNED_SHORT_8_8_MESA
) ||
2352 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
));
2353 ASSERT(baseInternalFormat
== GL_YCBCR_MESA
);
2355 /* always just memcpy since no pixel transfer ops apply */
2356 memcpy_texture(ctx
, dims
,
2357 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2360 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2361 srcAddr
, srcPacking
);
2363 /* Check if we need byte swapping */
2364 /* XXX the logic here _might_ be wrong */
2365 if (srcPacking
->SwapBytes
^
2366 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ^
2367 (dstFormat
== MESA_FORMAT_YCBCR_REV
) ^
2370 for (img
= 0; img
< srcDepth
; img
++) {
2371 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2372 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2373 + dstYoffset
* dstRowStride
2374 + dstXoffset
* texelBytes
;
2375 for (row
= 0; row
< srcHeight
; row
++) {
2376 _mesa_swap2((GLushort
*) dstRow
, srcWidth
);
2377 dstRow
+= dstRowStride
;
2385 _mesa_texstore_dudv8(TEXSTORE_PARAMS
)
2387 const GLboolean littleEndian
= _mesa_little_endian();
2388 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2390 ASSERT(dstFormat
== MESA_FORMAT_DUDV8
);
2391 ASSERT(texelBytes
== 2);
2392 ASSERT(ctx
->Extensions
.ATI_envmap_bumpmap
);
2393 ASSERT((srcFormat
== GL_DU8DV8_ATI
) ||
2394 (srcFormat
== GL_DUDV_ATI
));
2395 ASSERT(baseInternalFormat
== GL_DUDV_ATI
);
2397 if (!srcPacking
->SwapBytes
&& srcType
== GL_BYTE
&&
2399 /* simple memcpy path */
2400 memcpy_texture(ctx
, dims
,
2401 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2404 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2405 srcAddr
, srcPacking
);
2407 else if (srcType
== GL_BYTE
) {
2411 /* dstmap - how to swizzle from RGBA to dst format:
2421 dstmap
[2] = ZERO
; /* ? */
2422 dstmap
[3] = ONE
; /* ? */
2424 _mesa_swizzle_ubyte_image(ctx
, dims
,
2425 GL_LUMINANCE_ALPHA
, /* hack */
2426 GL_UNSIGNED_BYTE
, /* hack */
2427 GL_LUMINANCE_ALPHA
, /* hack */
2429 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2430 dstRowStride
, dstImageOffsets
,
2431 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2435 /* general path - note this is defined for 2d textures only */
2436 const GLint components
= _mesa_components_in_format(baseInternalFormat
);
2437 const GLint srcStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
2438 srcFormat
, srcType
);
2439 GLbyte
*tempImage
, *dst
, *src
;
2442 tempImage
= (GLbyte
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
2443 * components
* sizeof(GLbyte
));
2447 src
= (GLbyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2448 srcWidth
, srcHeight
,
2453 for (row
= 0; row
< srcHeight
; row
++) {
2454 _mesa_unpack_dudv_span_byte(ctx
, srcWidth
, baseInternalFormat
,
2455 dst
, srcFormat
, srcType
, src
,
2457 dst
+= srcWidth
* components
;
2462 dst
= (GLbyte
*) dstAddr
2463 + dstYoffset
* dstRowStride
2464 + dstXoffset
* texelBytes
;
2465 for (row
= 0; row
< srcHeight
; row
++) {
2466 memcpy(dst
, src
, srcWidth
* texelBytes
);
2467 dst
+= dstRowStride
;
2468 src
+= srcWidth
* texelBytes
;
2470 _mesa_free((void *) tempImage
);
2476 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or MESA_FORMAT_SIGNED_RGBA8888_REV
2479 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS
)
2481 const GLboolean littleEndian
= _mesa_little_endian();
2482 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2483 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2485 ASSERT(dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
||
2486 dstFormat
== MESA_FORMAT_SIGNED_RGBA8888_REV
);
2487 ASSERT(texelBytes
== 4);
2489 if (!ctx
->_ImageTransferState
&&
2490 !srcPacking
->SwapBytes
&&
2491 dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
&&
2492 baseInternalFormat
== GL_RGBA
&&
2493 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& !littleEndian
) ||
2494 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& littleEndian
))) {
2495 /* simple memcpy path */
2496 memcpy_texture(ctx
, dims
,
2497 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2500 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2501 srcAddr
, srcPacking
);
2503 else if (!ctx
->_ImageTransferState
&&
2504 !srcPacking
->SwapBytes
&&
2505 dstFormat
== MESA_FORMAT_SIGNED_RGBA8888_REV
&&
2506 baseInternalFormat
== GL_RGBA
&&
2507 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& littleEndian
) ||
2508 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& !littleEndian
))) {
2509 /* simple memcpy path */
2510 memcpy_texture(ctx
, dims
,
2511 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2514 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2515 srcAddr
, srcPacking
);
2517 else if (!ctx
->_ImageTransferState
&&
2518 (srcType
== GL_BYTE
) &&
2519 can_swizzle(baseInternalFormat
) &&
2520 can_swizzle(srcFormat
)) {
2524 /* dstmap - how to swizzle from RGBA to dst format:
2526 if ((littleEndian
&& dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
) ||
2527 (!littleEndian
&& dstFormat
== MESA_FORMAT_SIGNED_RGBA8888_REV
)) {
2540 _mesa_swizzle_ubyte_image(ctx
, dims
,
2545 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2546 dstRowStride
, dstImageOffsets
,
2547 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2552 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2555 srcWidth
, srcHeight
, srcDepth
,
2556 srcFormat
, srcType
, srcAddr
,
2558 const GLfloat
*srcRow
= tempImage
;
2559 GLint img
, row
, col
;
2562 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2563 for (img
= 0; img
< srcDepth
; img
++) {
2564 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2565 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2566 + dstYoffset
* dstRowStride
2567 + dstXoffset
* texelBytes
;
2568 for (row
= 0; row
< srcHeight
; row
++) {
2569 GLuint
*dstUI
= (GLuint
*) dstRow
;
2570 if (dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
) {
2571 for (col
= 0; col
< srcWidth
; col
++) {
2572 dstUI
[col
] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2573 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2574 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2575 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2580 for (col
= 0; col
< srcWidth
; col
++) {
2581 dstUI
[col
] = PACK_COLOR_8888_REV( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2582 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2583 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2584 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2588 dstRow
+= dstRowStride
;
2591 _mesa_free((void *) tempImage
);
2597 * Store a combined depth/stencil texture image.
2600 _mesa_texstore_z24_s8(TEXSTORE_PARAMS
)
2602 const GLfloat depthScale
= (GLfloat
) 0xffffff;
2603 const GLint srcRowStride
2604 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2608 ASSERT(dstFormat
== MESA_FORMAT_Z24_S8
);
2609 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
);
2610 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2612 /* In case we only upload depth we need to preserve the stencil */
2613 if (srcFormat
== GL_DEPTH_COMPONENT
) {
2614 for (img
= 0; img
< srcDepth
; img
++) {
2615 GLuint
*dstRow
= (GLuint
*) dstAddr
2616 + dstImageOffsets
[dstZoffset
+ img
]
2617 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2620 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2621 srcWidth
, srcHeight
,
2624 for (row
= 0; row
< srcHeight
; row
++) {
2625 GLuint depth
[MAX_WIDTH
];
2627 _mesa_unpack_depth_span(ctx
, srcWidth
,
2628 GL_UNSIGNED_INT
, /* dst type */
2629 depth
, /* dst addr */
2631 srcType
, src
, srcPacking
);
2633 for (i
= 0; i
< srcWidth
; i
++)
2634 dstRow
[i
] = depth
[i
] << 8 | (dstRow
[i
] & 0x000000FF);
2636 src
+= srcRowStride
;
2637 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2641 else if (ctx
->Pixel
.DepthScale
== 1.0f
&&
2642 ctx
->Pixel
.DepthBias
== 0.0f
&&
2643 !srcPacking
->SwapBytes
) {
2645 memcpy_texture(ctx
, dims
,
2646 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2649 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2650 srcAddr
, srcPacking
);
2654 const GLint srcRowStride
2655 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2659 for (img
= 0; img
< srcDepth
; img
++) {
2660 GLuint
*dstRow
= (GLuint
*) dstAddr
2661 + dstImageOffsets
[dstZoffset
+ img
]
2662 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2665 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2666 srcWidth
, srcHeight
,
2669 for (row
= 0; row
< srcHeight
; row
++) {
2670 GLubyte stencil
[MAX_WIDTH
];
2672 /* the 24 depth bits will be in the high position: */
2673 _mesa_unpack_depth_span(ctx
, srcWidth
,
2674 GL_UNSIGNED_INT_24_8_EXT
, /* dst type */
2675 dstRow
, /* dst addr */
2676 (GLuint
) depthScale
,
2677 srcType
, src
, srcPacking
);
2678 /* get the 8-bit stencil values */
2679 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2680 GL_UNSIGNED_BYTE
, /* dst type */
2681 stencil
, /* dst addr */
2682 srcType
, src
, srcPacking
,
2683 ctx
->_ImageTransferState
);
2684 /* merge stencil values into depth values */
2685 for (i
= 0; i
< srcWidth
; i
++)
2686 dstRow
[i
] |= stencil
[i
];
2688 src
+= srcRowStride
;
2689 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2698 * Store a combined depth/stencil texture image.
2701 _mesa_texstore_s8_z24(TEXSTORE_PARAMS
)
2703 const GLuint depthScale
= 0xffffff;
2704 const GLint srcRowStride
2705 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2709 ASSERT(dstFormat
== MESA_FORMAT_S8_Z24
);
2710 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
);
2711 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2713 /* In case we only upload depth we need to preserve the stencil */
2714 if (srcFormat
== GL_DEPTH_COMPONENT
) {
2715 for (img
= 0; img
< srcDepth
; img
++) {
2716 GLuint
*dstRow
= (GLuint
*) dstAddr
2717 + dstImageOffsets
[dstZoffset
+ img
]
2718 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2721 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2722 srcWidth
, srcHeight
,
2725 for (row
= 0; row
< srcHeight
; row
++) {
2726 GLuint depth
[MAX_WIDTH
];
2728 _mesa_unpack_depth_span(ctx
, srcWidth
,
2729 GL_UNSIGNED_INT
, /* dst type */
2730 depth
, /* dst addr */
2732 srcType
, src
, srcPacking
);
2734 for (i
= 0; i
< srcWidth
; i
++)
2735 dstRow
[i
] = depth
[i
] | (dstRow
[i
] & 0xFF000000);
2737 src
+= srcRowStride
;
2738 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2743 for (img
= 0; img
< srcDepth
; img
++) {
2744 GLuint
*dstRow
= (GLuint
*) dstAddr
2745 + dstImageOffsets
[dstZoffset
+ img
]
2746 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2749 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2750 srcWidth
, srcHeight
,
2753 for (row
= 0; row
< srcHeight
; row
++) {
2754 GLubyte stencil
[MAX_WIDTH
];
2756 /* the 24 depth bits will be in the low position: */
2757 _mesa_unpack_depth_span(ctx
, srcWidth
,
2758 GL_UNSIGNED_INT
, /* dst type */
2759 dstRow
, /* dst addr */
2761 srcType
, src
, srcPacking
);
2762 /* get the 8-bit stencil values */
2763 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2764 GL_UNSIGNED_BYTE
, /* dst type */
2765 stencil
, /* dst addr */
2766 srcType
, src
, srcPacking
,
2767 ctx
->_ImageTransferState
);
2768 /* merge stencil values into depth values */
2769 for (i
= 0; i
< srcWidth
; i
++)
2770 dstRow
[i
] |= stencil
[i
] << 24;
2772 src
+= srcRowStride
;
2773 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2781 * Store an image in any of the formats:
2782 * _mesa_texformat_rgba_float32
2783 * _mesa_texformat_rgb_float32
2784 * _mesa_texformat_alpha_float32
2785 * _mesa_texformat_luminance_float32
2786 * _mesa_texformat_luminance_alpha_float32
2787 * _mesa_texformat_intensity_float32
2790 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS
)
2792 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2793 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2794 const GLint components
= _mesa_components_in_format(baseFormat
);
2796 ASSERT(dstFormat
== MESA_FORMAT_RGBA_FLOAT32
||
2797 dstFormat
== MESA_FORMAT_RGB_FLOAT32
||
2798 dstFormat
== MESA_FORMAT_ALPHA_FLOAT32
||
2799 dstFormat
== MESA_FORMAT_LUMINANCE_FLOAT32
||
2800 dstFormat
== MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32
||
2801 dstFormat
== MESA_FORMAT_INTENSITY_FLOAT32
);
2802 ASSERT(baseInternalFormat
== GL_RGBA
||
2803 baseInternalFormat
== GL_RGB
||
2804 baseInternalFormat
== GL_ALPHA
||
2805 baseInternalFormat
== GL_LUMINANCE
||
2806 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
2807 baseInternalFormat
== GL_INTENSITY
);
2808 ASSERT(texelBytes
== components
* sizeof(GLfloat
));
2810 if (!ctx
->_ImageTransferState
&&
2811 !srcPacking
->SwapBytes
&&
2812 baseInternalFormat
== srcFormat
&&
2813 srcType
== GL_FLOAT
) {
2814 /* simple memcpy path */
2815 memcpy_texture(ctx
, dims
,
2816 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2819 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2820 srcAddr
, srcPacking
);
2824 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2827 srcWidth
, srcHeight
, srcDepth
,
2828 srcFormat
, srcType
, srcAddr
,
2830 const GLfloat
*srcRow
= tempImage
;
2835 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2836 bytesPerRow
= srcWidth
* components
* sizeof(GLfloat
);
2837 for (img
= 0; img
< srcDepth
; img
++) {
2838 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2839 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2840 + dstYoffset
* dstRowStride
2841 + dstXoffset
* texelBytes
;
2842 for (row
= 0; row
< srcHeight
; row
++) {
2843 _mesa_memcpy(dstRow
, srcRow
, bytesPerRow
);
2844 dstRow
+= dstRowStride
;
2845 srcRow
+= srcWidth
* components
;
2849 _mesa_free((void *) tempImage
);
2856 * As above, but store 16-bit floats.
2859 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS
)
2861 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2862 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2863 const GLint components
= _mesa_components_in_format(baseFormat
);
2865 ASSERT(dstFormat
== MESA_FORMAT_RGBA_FLOAT16
||
2866 dstFormat
== MESA_FORMAT_RGB_FLOAT16
||
2867 dstFormat
== MESA_FORMAT_ALPHA_FLOAT16
||
2868 dstFormat
== MESA_FORMAT_LUMINANCE_FLOAT16
||
2869 dstFormat
== MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16
||
2870 dstFormat
== MESA_FORMAT_INTENSITY_FLOAT16
);
2871 ASSERT(baseInternalFormat
== GL_RGBA
||
2872 baseInternalFormat
== GL_RGB
||
2873 baseInternalFormat
== GL_ALPHA
||
2874 baseInternalFormat
== GL_LUMINANCE
||
2875 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
2876 baseInternalFormat
== GL_INTENSITY
);
2877 ASSERT(texelBytes
== components
* sizeof(GLhalfARB
));
2879 if (!ctx
->_ImageTransferState
&&
2880 !srcPacking
->SwapBytes
&&
2881 baseInternalFormat
== srcFormat
&&
2882 srcType
== GL_HALF_FLOAT_ARB
) {
2883 /* simple memcpy path */
2884 memcpy_texture(ctx
, dims
,
2885 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2888 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2889 srcAddr
, srcPacking
);
2893 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2896 srcWidth
, srcHeight
, srcDepth
,
2897 srcFormat
, srcType
, srcAddr
,
2899 const GLfloat
*src
= tempImage
;
2903 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2904 for (img
= 0; img
< srcDepth
; img
++) {
2905 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2906 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2907 + dstYoffset
* dstRowStride
2908 + dstXoffset
* texelBytes
;
2909 for (row
= 0; row
< srcHeight
; row
++) {
2910 GLhalfARB
*dstTexel
= (GLhalfARB
*) dstRow
;
2912 for (i
= 0; i
< srcWidth
* components
; i
++) {
2913 dstTexel
[i
] = _mesa_float_to_half(src
[i
]);
2915 dstRow
+= dstRowStride
;
2916 src
+= srcWidth
* components
;
2920 _mesa_free((void *) tempImage
);
2926 #if FEATURE_EXT_texture_sRGB
2928 _mesa_texstore_srgb8(TEXSTORE_PARAMS
)
2930 gl_format newDstFormat
;
2933 ASSERT(dstFormat
== MESA_FORMAT_SRGB8
);
2935 /* reuse normal rgb texstore code */
2936 newDstFormat
= MESA_FORMAT_RGB888
;
2938 k
= _mesa_texstore_rgb888(ctx
, dims
, baseInternalFormat
,
2939 newDstFormat
, dstAddr
,
2940 dstXoffset
, dstYoffset
, dstZoffset
,
2941 dstRowStride
, dstImageOffsets
,
2942 srcWidth
, srcHeight
, srcDepth
,
2944 srcAddr
, srcPacking
);
2950 _mesa_texstore_srgba8(TEXSTORE_PARAMS
)
2952 gl_format newDstFormat
;
2955 ASSERT(dstFormat
== MESA_FORMAT_SRGBA8
);
2957 /* reuse normal rgba texstore code */
2958 newDstFormat
= MESA_FORMAT_RGBA8888
;
2959 k
= _mesa_texstore_rgba8888(ctx
, dims
, baseInternalFormat
,
2960 newDstFormat
, dstAddr
,
2961 dstXoffset
, dstYoffset
, dstZoffset
,
2962 dstRowStride
, dstImageOffsets
,
2963 srcWidth
, srcHeight
, srcDepth
,
2965 srcAddr
, srcPacking
);
2971 _mesa_texstore_sargb8(TEXSTORE_PARAMS
)
2973 gl_format newDstFormat
;
2976 ASSERT(dstFormat
== MESA_FORMAT_SARGB8
);
2978 /* reuse normal rgba texstore code */
2979 newDstFormat
= MESA_FORMAT_ARGB8888
;
2981 k
= _mesa_texstore_argb8888(ctx
, dims
, baseInternalFormat
,
2982 newDstFormat
, dstAddr
,
2983 dstXoffset
, dstYoffset
, dstZoffset
,
2984 dstRowStride
, dstImageOffsets
,
2985 srcWidth
, srcHeight
, srcDepth
,
2987 srcAddr
, srcPacking
);
2993 _mesa_texstore_sl8(TEXSTORE_PARAMS
)
2995 gl_format newDstFormat
;
2998 ASSERT(dstFormat
== MESA_FORMAT_SL8
);
3000 newDstFormat
= MESA_FORMAT_L8
;
3002 /* _mesa_textore_a8 handles luminance8 too */
3003 k
= _mesa_texstore_a8(ctx
, dims
, baseInternalFormat
,
3004 newDstFormat
, dstAddr
,
3005 dstXoffset
, dstYoffset
, dstZoffset
,
3006 dstRowStride
, dstImageOffsets
,
3007 srcWidth
, srcHeight
, srcDepth
,
3009 srcAddr
, srcPacking
);
3015 _mesa_texstore_sla8(TEXSTORE_PARAMS
)
3017 gl_format newDstFormat
;
3020 ASSERT(dstFormat
== MESA_FORMAT_SLA8
);
3022 /* reuse normal luminance/alpha texstore code */
3023 newDstFormat
= MESA_FORMAT_AL88
;
3025 k
= _mesa_texstore_al88(ctx
, dims
, baseInternalFormat
,
3026 newDstFormat
, dstAddr
,
3027 dstXoffset
, dstYoffset
, dstZoffset
,
3028 dstRowStride
, dstImageOffsets
,
3029 srcWidth
, srcHeight
, srcDepth
,
3031 srcAddr
, srcPacking
);
3037 /* these are used only in texstore_funcs[] below */
3038 #define _mesa_texstore_srgb8 NULL
3039 #define _mesa_texstore_srgba8 NULL
3040 #define _mesa_texstore_sargb8 NULL
3041 #define _mesa_texstore_sl8 NULL
3042 #define _mesa_texstore_sla8 NULL
3044 #endif /* FEATURE_EXT_texture_sRGB */
3050 * Table mapping MESA_FORMAT_8 to _mesa_texstore_*()
3051 * XXX this is somewhat temporary.
3053 const static struct {
3055 StoreTexImageFunc Store
;
3057 texstore_funcs
[MESA_FORMAT_COUNT
] =
3059 { MESA_FORMAT_NONE
, NULL
},
3060 { MESA_FORMAT_RGBA8888
, _mesa_texstore_rgba8888
},
3061 { MESA_FORMAT_RGBA8888_REV
, _mesa_texstore_rgba8888
},
3062 { MESA_FORMAT_ARGB8888
, _mesa_texstore_argb8888
},
3063 { MESA_FORMAT_ARGB8888_REV
, _mesa_texstore_argb8888
},
3064 { MESA_FORMAT_XRGB8888
, _mesa_texstore_argb8888
},
3065 { MESA_FORMAT_RGB888
, _mesa_texstore_rgb888
},
3066 { MESA_FORMAT_BGR888
, _mesa_texstore_bgr888
},
3067 { MESA_FORMAT_RGB565
, _mesa_texstore_rgb565
},
3068 { MESA_FORMAT_RGB565_REV
, _mesa_texstore_rgb565
},
3069 { MESA_FORMAT_ARGB4444
, _mesa_texstore_argb4444
},
3070 { MESA_FORMAT_ARGB4444_REV
, _mesa_texstore_argb4444
},
3071 { MESA_FORMAT_RGBA5551
, _mesa_texstore_rgba5551
},
3072 { MESA_FORMAT_ARGB1555
, _mesa_texstore_argb1555
},
3073 { MESA_FORMAT_ARGB1555_REV
, _mesa_texstore_argb1555
},
3074 { MESA_FORMAT_AL88
, _mesa_texstore_al88
},
3075 { MESA_FORMAT_AL88_REV
, _mesa_texstore_al88
},
3076 { MESA_FORMAT_RGB332
, _mesa_texstore_rgb332
},
3077 { MESA_FORMAT_A8
, _mesa_texstore_a8
},
3078 { MESA_FORMAT_L8
, _mesa_texstore_a8
},
3079 { MESA_FORMAT_I8
, _mesa_texstore_a8
},
3080 { MESA_FORMAT_CI8
, _mesa_texstore_ci8
},
3081 { MESA_FORMAT_YCBCR
, _mesa_texstore_ycbcr
},
3082 { MESA_FORMAT_YCBCR_REV
, _mesa_texstore_ycbcr
},
3083 { MESA_FORMAT_Z24_S8
, _mesa_texstore_z24_s8
},
3084 { MESA_FORMAT_S8_Z24
, _mesa_texstore_s8_z24
},
3085 { MESA_FORMAT_Z16
, _mesa_texstore_z16
},
3086 { MESA_FORMAT_X8_Z24
, _mesa_texstore_x8_z24
},
3087 { MESA_FORMAT_Z24_X8
, _mesa_texstore_z24_x8
},
3088 { MESA_FORMAT_Z32
, _mesa_texstore_z32
},
3089 { MESA_FORMAT_S8
, NULL
/*_mesa_texstore_s8*/ },
3090 { MESA_FORMAT_SRGB8
, _mesa_texstore_srgb8
},
3091 { MESA_FORMAT_SRGBA8
, _mesa_texstore_srgba8
},
3092 { MESA_FORMAT_SARGB8
, _mesa_texstore_sargb8
},
3093 { MESA_FORMAT_SL8
, _mesa_texstore_sl8
},
3094 { MESA_FORMAT_SLA8
, _mesa_texstore_sla8
},
3095 { MESA_FORMAT_SRGB_DXT1
, _mesa_texstore_rgb_dxt1
},
3096 { MESA_FORMAT_SRGBA_DXT1
, _mesa_texstore_rgba_dxt1
},
3097 { MESA_FORMAT_SRGBA_DXT3
, _mesa_texstore_rgba_dxt3
},
3098 { MESA_FORMAT_SRGBA_DXT5
, _mesa_texstore_rgba_dxt5
},
3099 { MESA_FORMAT_RGB_FXT1
, _mesa_texstore_rgb_fxt1
},
3100 { MESA_FORMAT_RGBA_FXT1
, _mesa_texstore_rgba_fxt1
},
3101 { MESA_FORMAT_RGB_DXT1
, _mesa_texstore_rgb_dxt1
},
3102 { MESA_FORMAT_RGBA_DXT1
, _mesa_texstore_rgba_dxt1
},
3103 { MESA_FORMAT_RGBA_DXT3
, _mesa_texstore_rgba_dxt3
},
3104 { MESA_FORMAT_RGBA_DXT5
, _mesa_texstore_rgba_dxt5
},
3105 { MESA_FORMAT_RGBA_FLOAT32
, _mesa_texstore_rgba_float32
},
3106 { MESA_FORMAT_RGBA_FLOAT16
, _mesa_texstore_rgba_float16
},
3107 { MESA_FORMAT_RGB_FLOAT32
, _mesa_texstore_rgba_float32
},
3108 { MESA_FORMAT_RGB_FLOAT16
, _mesa_texstore_rgba_float16
},
3109 { MESA_FORMAT_ALPHA_FLOAT32
, _mesa_texstore_rgba_float32
},
3110 { MESA_FORMAT_ALPHA_FLOAT16
, _mesa_texstore_rgba_float16
},
3111 { MESA_FORMAT_LUMINANCE_FLOAT32
, _mesa_texstore_rgba_float32
},
3112 { MESA_FORMAT_LUMINANCE_FLOAT16
, _mesa_texstore_rgba_float16
},
3113 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32
, _mesa_texstore_rgba_float32
},
3114 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16
, _mesa_texstore_rgba_float16
},
3115 { MESA_FORMAT_INTENSITY_FLOAT32
, _mesa_texstore_rgba_float32
},
3116 { MESA_FORMAT_INTENSITY_FLOAT16
, _mesa_texstore_rgba_float16
},
3117 { MESA_FORMAT_DUDV8
, _mesa_texstore_dudv8
},
3118 { MESA_FORMAT_SIGNED_RGBA8888
, _mesa_texstore_signed_rgba8888
},
3119 { MESA_FORMAT_SIGNED_RGBA8888_REV
, _mesa_texstore_signed_rgba8888
},
3120 { MESA_FORMAT_SIGNED_RGBA_16
, NULL
},
3125 _mesa_texstore_null(TEXSTORE_PARAMS
)
3127 (void) ctx
; (void) dims
;
3128 (void) baseInternalFormat
;
3131 (void) dstXoffset
; (void) dstYoffset
; (void) dstZoffset
;
3132 (void) dstRowStride
; (void) dstImageOffsets
;
3133 (void) srcWidth
; (void) srcHeight
; (void) srcDepth
;
3134 (void) srcFormat
; (void) srcType
;
3138 /* should never happen */
3139 _mesa_problem(NULL
, "_mesa_texstore_null() is called");
3145 * Return the StoreTexImageFunc pointer to store an image in the given format.
3147 static StoreTexImageFunc
3148 _mesa_get_texstore_func(gl_format format
)
3152 for (i
= 0; i
< MESA_FORMAT_COUNT
; i
++) {
3153 ASSERT(texstore_funcs
[i
].Name
== i
);
3156 ASSERT(texstore_funcs
[format
].Name
== format
);
3158 if (texstore_funcs
[format
].Store
)
3159 return texstore_funcs
[format
].Store
;
3161 return _mesa_texstore_null
;
3166 * Store user data into texture memory.
3167 * Called via glTex[Sub]Image1/2/3D()
3170 _mesa_texstore(TEXSTORE_PARAMS
)
3172 StoreTexImageFunc storeImage
;
3175 storeImage
= _mesa_get_texstore_func(dstFormat
);
3177 success
= storeImage(ctx
, dims
, baseInternalFormat
,
3178 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3179 dstRowStride
, dstImageOffsets
,
3180 srcWidth
, srcHeight
, srcDepth
,
3181 srcFormat
, srcType
, srcAddr
, srcPacking
);
3187 * Check if an unpack PBO is active prior to fetching a texture image.
3188 * If so, do bounds checking and map the buffer into main memory.
3189 * Any errors detected will be recorded.
3190 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3193 _mesa_validate_pbo_teximage(GLcontext
*ctx
, GLuint dimensions
,
3194 GLsizei width
, GLsizei height
, GLsizei depth
,
3195 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3196 const struct gl_pixelstore_attrib
*unpack
,
3197 const char *funcName
)
3201 if (!_mesa_is_bufferobj(unpack
->BufferObj
)) {
3205 if (!_mesa_validate_pbo_access(dimensions
, unpack
, width
, height
, depth
,
3206 format
, type
, pixels
)) {
3207 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3211 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3212 GL_READ_ONLY_ARB
, unpack
->BufferObj
);
3214 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3218 return ADD_POINTERS(buf
, pixels
);
3223 * Check if an unpack PBO is active prior to fetching a compressed texture
3225 * If so, do bounds checking and map the buffer into main memory.
3226 * Any errors detected will be recorded.
3227 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3230 _mesa_validate_pbo_compressed_teximage(GLcontext
*ctx
,
3231 GLsizei imageSize
, const GLvoid
*pixels
,
3232 const struct gl_pixelstore_attrib
*packing
,
3233 const char *funcName
)
3237 if (!_mesa_is_bufferobj(packing
->BufferObj
)) {
3238 /* not using a PBO - return pointer unchanged */
3241 if ((const GLubyte
*) pixels
+ imageSize
>
3242 ((const GLubyte
*) 0) + packing
->BufferObj
->Size
) {
3243 /* out of bounds read! */
3244 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3248 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3249 GL_READ_ONLY_ARB
, packing
->BufferObj
);
3251 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3255 return ADD_POINTERS(buf
, pixels
);
3260 * This function must be called after either of the validate_pbo_*_teximage()
3261 * functions. It unmaps the PBO buffer if it was mapped earlier.
3264 _mesa_unmap_teximage_pbo(GLcontext
*ctx
,
3265 const struct gl_pixelstore_attrib
*unpack
)
3267 if (_mesa_is_bufferobj(unpack
->BufferObj
)) {
3268 ctx
->Driver
.UnmapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3274 /** Return texture size in bytes */
3276 texture_size(const struct gl_texture_image
*texImage
)
3278 GLuint sz
= _mesa_format_image_size(texImage
->TexFormat
, texImage
->Width
,
3279 texImage
->Height
, texImage
->Depth
);
3284 /** Return row stride in bytes */
3286 texture_row_stride(const struct gl_texture_image
*texImage
)
3288 GLuint stride
= _mesa_format_row_stride(texImage
->TexFormat
,
3296 * This is the software fallback for Driver.TexImage1D()
3297 * and Driver.CopyTexImage1D().
3298 * \sa _mesa_store_teximage2d()
3299 * Note that the width may not be the actual texture width since it may
3300 * be changed by convolution w/ GL_REDUCE. The texImage->Width field will
3301 * have the actual texture size.
3304 _mesa_store_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3305 GLint internalFormat
,
3306 GLint width
, GLint border
,
3307 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3308 const struct gl_pixelstore_attrib
*packing
,
3309 struct gl_texture_object
*texObj
,
3310 struct gl_texture_image
*texImage
)
3315 /* allocate memory */
3316 sizeInBytes
= texture_size(texImage
);
3317 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3318 if (!texImage
->Data
) {
3319 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
3323 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
3324 pixels
, packing
, "glTexImage1D");
3326 /* Note: we check for a NULL image pointer here, _after_ we allocated
3327 * memory for the texture. That's what the GL spec calls for.
3332 const GLint dstRowStride
= 0;
3333 GLboolean success
= _mesa_texstore(ctx
, 1, texImage
->_BaseFormat
,
3334 texImage
->TexFormat
,
3336 0, 0, 0, /* dstX/Y/Zoffset */
3338 texImage
->ImageOffsets
,
3340 format
, type
, pixels
, packing
);
3342 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
3346 _mesa_unmap_teximage_pbo(ctx
, packing
);
3351 * This is the software fallback for Driver.TexImage2D()
3352 * and Driver.CopyTexImage2D().
3354 * This function is oriented toward storing images in main memory, rather
3355 * than VRAM. Device driver's can easily plug in their own replacement.
3357 * Note: width and height may be pre-convolved dimensions, but
3358 * texImage->Width and texImage->Height will be post-convolved dimensions.
3361 _mesa_store_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3362 GLint internalFormat
,
3363 GLint width
, GLint height
, GLint border
,
3364 GLenum format
, GLenum type
, const void *pixels
,
3365 const struct gl_pixelstore_attrib
*packing
,
3366 struct gl_texture_object
*texObj
,
3367 struct gl_texture_image
*texImage
)
3372 /* allocate memory */
3373 sizeInBytes
= texture_size(texImage
);
3374 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3375 if (!texImage
->Data
) {
3376 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
3380 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
3381 pixels
, packing
, "glTexImage2D");
3383 /* Note: we check for a NULL image pointer here, _after_ we allocated
3384 * memory for the texture. That's what the GL spec calls for.
3389 GLint dstRowStride
= texture_row_stride(texImage
);
3390 GLboolean success
= _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
3391 texImage
->TexFormat
,
3393 0, 0, 0, /* dstX/Y/Zoffset */
3395 texImage
->ImageOffsets
,
3397 format
, type
, pixels
, packing
);
3399 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
3403 _mesa_unmap_teximage_pbo(ctx
, packing
);
3409 * This is the software fallback for Driver.TexImage3D()
3410 * and Driver.CopyTexImage3D().
3411 * \sa _mesa_store_teximage2d()
3414 _mesa_store_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3415 GLint internalFormat
,
3416 GLint width
, GLint height
, GLint depth
, GLint border
,
3417 GLenum format
, GLenum type
, const void *pixels
,
3418 const struct gl_pixelstore_attrib
*packing
,
3419 struct gl_texture_object
*texObj
,
3420 struct gl_texture_image
*texImage
)
3425 /* allocate memory */
3426 sizeInBytes
= texture_size(texImage
);
3427 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3428 if (!texImage
->Data
) {
3429 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
3433 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
3434 type
, pixels
, packing
, "glTexImage3D");
3436 /* Note: we check for a NULL image pointer here, _after_ we allocated
3437 * memory for the texture. That's what the GL spec calls for.
3442 GLint dstRowStride
= texture_row_stride(texImage
);
3443 GLboolean success
= _mesa_texstore(ctx
, 3, texImage
->_BaseFormat
,
3444 texImage
->TexFormat
,
3446 0, 0, 0, /* dstX/Y/Zoffset */
3448 texImage
->ImageOffsets
,
3449 width
, height
, depth
,
3450 format
, type
, pixels
, packing
);
3452 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
3456 _mesa_unmap_teximage_pbo(ctx
, packing
);
3463 * This is the software fallback for Driver.TexSubImage1D()
3464 * and Driver.CopyTexSubImage1D().
3467 _mesa_store_texsubimage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3468 GLint xoffset
, GLint width
,
3469 GLenum format
, GLenum type
, const void *pixels
,
3470 const struct gl_pixelstore_attrib
*packing
,
3471 struct gl_texture_object
*texObj
,
3472 struct gl_texture_image
*texImage
)
3474 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3475 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
3476 pixels
, packing
, "glTexSubImage1D");
3481 const GLint dstRowStride
= 0;
3482 GLboolean success
= _mesa_texstore(ctx
, 1, texImage
->_BaseFormat
,
3483 texImage
->TexFormat
,
3485 xoffset
, 0, 0, /* offsets */
3487 texImage
->ImageOffsets
,
3489 format
, type
, pixels
, packing
);
3491 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
3495 _mesa_unmap_teximage_pbo(ctx
, packing
);
3501 * This is the software fallback for Driver.TexSubImage2D()
3502 * and Driver.CopyTexSubImage2D().
3505 _mesa_store_texsubimage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3506 GLint xoffset
, GLint yoffset
,
3507 GLint width
, GLint height
,
3508 GLenum format
, GLenum type
, const void *pixels
,
3509 const struct gl_pixelstore_attrib
*packing
,
3510 struct gl_texture_object
*texObj
,
3511 struct gl_texture_image
*texImage
)
3513 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3514 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
3515 pixels
, packing
, "glTexSubImage2D");
3520 GLint dstRowStride
= texture_row_stride(texImage
);
3521 GLboolean success
= _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
3522 texImage
->TexFormat
,
3524 xoffset
, yoffset
, 0,
3526 texImage
->ImageOffsets
,
3528 format
, type
, pixels
, packing
);
3530 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
3534 _mesa_unmap_teximage_pbo(ctx
, packing
);
3539 * This is the software fallback for Driver.TexSubImage3D().
3540 * and Driver.CopyTexSubImage3D().
3543 _mesa_store_texsubimage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3544 GLint xoffset
, GLint yoffset
, GLint zoffset
,
3545 GLint width
, GLint height
, GLint depth
,
3546 GLenum format
, GLenum type
, const void *pixels
,
3547 const struct gl_pixelstore_attrib
*packing
,
3548 struct gl_texture_object
*texObj
,
3549 struct gl_texture_image
*texImage
)
3551 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3552 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
3553 type
, pixels
, packing
,
3559 GLint dstRowStride
= texture_row_stride(texImage
);
3560 GLboolean success
= _mesa_texstore(ctx
, 3, texImage
->_BaseFormat
,
3561 texImage
->TexFormat
,
3563 xoffset
, yoffset
, zoffset
,
3565 texImage
->ImageOffsets
,
3566 width
, height
, depth
,
3567 format
, type
, pixels
, packing
);
3569 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3D");
3573 _mesa_unmap_teximage_pbo(ctx
, packing
);
3578 * Fallback for Driver.CompressedTexImage1D()
3581 _mesa_store_compressed_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3582 GLint internalFormat
,
3583 GLint width
, GLint border
,
3584 GLsizei imageSize
, const GLvoid
*data
,
3585 struct gl_texture_object
*texObj
,
3586 struct gl_texture_image
*texImage
)
3588 /* this space intentionally left blank */
3590 (void) target
; (void) level
;
3591 (void) internalFormat
;
3592 (void) width
; (void) border
;
3593 (void) imageSize
; (void) data
;
3601 * Fallback for Driver.CompressedTexImage2D()
3604 _mesa_store_compressed_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3605 GLint internalFormat
,
3606 GLint width
, GLint height
, GLint border
,
3607 GLsizei imageSize
, const GLvoid
*data
,
3608 struct gl_texture_object
*texObj
,
3609 struct gl_texture_image
*texImage
)
3611 (void) width
; (void) height
; (void) border
;
3613 /* This is pretty simple, basically just do a memcpy without worrying
3614 * about the usual image unpacking or image transfer operations.
3618 ASSERT(texImage
->Width
> 0);
3619 ASSERT(texImage
->Height
> 0);
3620 ASSERT(texImage
->Depth
== 1);
3621 ASSERT(texImage
->Data
== NULL
); /* was freed in glCompressedTexImage2DARB */
3623 /* allocate storage */
3624 texImage
->Data
= _mesa_alloc_texmemory(imageSize
);
3625 if (!texImage
->Data
) {
3626 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
3630 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
3632 "glCompressedTexImage2D");
3637 MEMCPY(texImage
->Data
, data
, imageSize
);
3639 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
3645 * Fallback for Driver.CompressedTexImage3D()
3648 _mesa_store_compressed_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3649 GLint internalFormat
,
3650 GLint width
, GLint height
, GLint depth
,
3652 GLsizei imageSize
, const GLvoid
*data
,
3653 struct gl_texture_object
*texObj
,
3654 struct gl_texture_image
*texImage
)
3656 /* this space intentionally left blank */
3658 (void) target
; (void) level
;
3659 (void) internalFormat
;
3660 (void) width
; (void) height
; (void) depth
;
3662 (void) imageSize
; (void) data
;
3670 * Fallback for Driver.CompressedTexSubImage1D()
3673 _mesa_store_compressed_texsubimage1d(GLcontext
*ctx
, GLenum target
,
3675 GLint xoffset
, GLsizei width
,
3677 GLsizei imageSize
, const GLvoid
*data
,
3678 struct gl_texture_object
*texObj
,
3679 struct gl_texture_image
*texImage
)
3681 /* there are no compressed 1D texture formats yet */
3683 (void) target
; (void) level
;
3684 (void) xoffset
; (void) width
;
3686 (void) imageSize
; (void) data
;
3693 * Fallback for Driver.CompressedTexSubImage2D()
3696 _mesa_store_compressed_texsubimage2d(GLcontext
*ctx
, GLenum target
,
3698 GLint xoffset
, GLint yoffset
,
3699 GLsizei width
, GLsizei height
,
3701 GLsizei imageSize
, const GLvoid
*data
,
3702 struct gl_texture_object
*texObj
,
3703 struct gl_texture_image
*texImage
)
3705 GLint bytesPerRow
, destRowStride
, srcRowStride
;
3709 const gl_format texFormat
= texImage
->TexFormat
;
3710 const GLint destWidth
= texImage
->Width
;
3713 _mesa_get_format_block_size(texFormat
, &bw
, &bh
);
3718 /* these should have been caught sooner */
3719 ASSERT((width
% bw
) == 0 || width
== 2 || width
== 1);
3720 ASSERT((height
% bh
) == 0 || height
== 2 || height
== 1);
3721 ASSERT((xoffset
% bw
) == 0);
3722 ASSERT((yoffset
% bh
) == 0);
3724 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3725 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
3727 "glCompressedTexSubImage2D");
3731 srcRowStride
= _mesa_format_row_stride(texFormat
, width
);
3732 src
= (const GLubyte
*) data
;
3734 destRowStride
= _mesa_format_row_stride(texFormat
, destWidth
);
3735 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
3736 texFormat
, destWidth
,
3737 (GLubyte
*) texImage
->Data
);
3739 bytesPerRow
= srcRowStride
; /* bytes per row of blocks */
3740 rows
= height
/ bh
; /* rows in blocks */
3742 /* copy rows of blocks */
3743 for (i
= 0; i
< rows
; i
++) {
3744 MEMCPY(dest
, src
, bytesPerRow
);
3745 dest
+= destRowStride
;
3746 src
+= srcRowStride
;
3749 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
3754 * Fallback for Driver.CompressedTexSubImage3D()
3757 _mesa_store_compressed_texsubimage3d(GLcontext
*ctx
, GLenum target
,
3759 GLint xoffset
, GLint yoffset
, GLint zoffset
,
3760 GLsizei width
, GLsizei height
, GLsizei depth
,
3762 GLsizei imageSize
, const GLvoid
*data
,
3763 struct gl_texture_object
*texObj
,
3764 struct gl_texture_image
*texImage
)
3766 /* there are no compressed 3D texture formats yet */
3768 (void) target
; (void) level
;
3769 (void) xoffset
; (void) yoffset
; (void) zoffset
;
3770 (void) width
; (void) height
; (void) depth
;
3772 (void) imageSize
; (void) data
;