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, etc)
50 * These functions can handle most everything, including processing full
51 * images and sub-images.
56 #include "bufferobj.h"
62 #include "texcompress.h"
63 #include "texcompress_fxt1.h"
64 #include "texcompress_s3tc.h"
77 * Texture image storage function.
79 typedef GLboolean (*StoreTexImageFunc
)(TEXSTORE_PARAMS
);
83 * Return GL_TRUE if the given image format is one that be converted
84 * to another format by swizzling.
87 can_swizzle(GLenum logicalBaseFormat
)
89 switch (logicalBaseFormat
) {
92 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
),
215 MAP4(0, 1, ZERO
, ONE
),
223 * Convert a GL image format enum to an IDX_* value (see above).
226 get_map_idx(GLenum value
)
229 case GL_LUMINANCE
: return IDX_LUMINANCE
;
230 case GL_ALPHA
: return IDX_ALPHA
;
231 case GL_INTENSITY
: return IDX_INTENSITY
;
232 case GL_LUMINANCE_ALPHA
: return IDX_LUMINANCE_ALPHA
;
233 case GL_RGB
: return IDX_RGB
;
234 case GL_RGBA
: return IDX_RGBA
;
235 case GL_RED
: return IDX_RED
;
236 case GL_GREEN
: return IDX_GREEN
;
237 case GL_BLUE
: return IDX_BLUE
;
238 case GL_BGR
: return IDX_BGR
;
239 case GL_BGRA
: return IDX_BGRA
;
240 case GL_ABGR_EXT
: return IDX_ABGR
;
241 case GL_RG
: return IDX_RG
;
243 _mesa_problem(NULL
, "Unexpected inFormat");
250 * When promoting texture formats (see below) we need to compute the
251 * mapping of dest components back to source components.
252 * This function does that.
253 * \param inFormat the incoming format of the texture
254 * \param outFormat the final texture format
255 * \return map[6] a full 6-component map
258 compute_component_mapping(GLenum inFormat
, GLenum outFormat
,
261 const int inFmt
= get_map_idx(inFormat
);
262 const int outFmt
= get_map_idx(outFormat
);
263 const GLubyte
*in2rgba
= mappings
[inFmt
].to_rgba
;
264 const GLubyte
*rgba2out
= mappings
[outFmt
].from_rgba
;
267 for (i
= 0; i
< 4; i
++)
268 map
[i
] = in2rgba
[rgba2out
[i
]];
274 printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
275 inFormat
, _mesa_lookup_enum_by_nr(inFormat
),
276 outFormat
, _mesa_lookup_enum_by_nr(outFormat
),
288 * Make a temporary (color) texture image with GLfloat components.
289 * Apply all needed pixel unpacking and pixel transfer operations.
290 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
291 * Suppose the user specifies GL_LUMINANCE as the internal texture format
292 * but the graphics hardware doesn't support luminance textures. So, might
293 * use an RGB hardware format instead.
294 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
296 * \param ctx the rendering context
297 * \param dims image dimensions: 1, 2 or 3
298 * \param logicalBaseFormat basic texture derived from the user's
299 * internal texture format value
300 * \param textureBaseFormat the actual basic format of the texture
301 * \param srcWidth source image width
302 * \param srcHeight source image height
303 * \param srcDepth source image depth
304 * \param srcFormat source image format
305 * \param srcType source image type
306 * \param srcAddr source image address
307 * \param srcPacking source image pixel packing
308 * \return resulting image with format = textureBaseFormat and type = GLfloat.
311 make_temp_float_image(GLcontext
*ctx
, GLuint dims
,
312 GLenum logicalBaseFormat
,
313 GLenum textureBaseFormat
,
314 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
315 GLenum srcFormat
, GLenum srcType
,
316 const GLvoid
*srcAddr
,
317 const struct gl_pixelstore_attrib
*srcPacking
)
319 GLuint transferOps
= ctx
->_ImageTransferState
;
321 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
322 const GLint srcStride
=
323 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
327 ASSERT(dims
>= 1 && dims
<= 3);
329 ASSERT(logicalBaseFormat
== GL_RGBA
||
330 logicalBaseFormat
== GL_RGB
||
331 logicalBaseFormat
== GL_RG
||
332 logicalBaseFormat
== GL_RED
||
333 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
334 logicalBaseFormat
== GL_LUMINANCE
||
335 logicalBaseFormat
== GL_ALPHA
||
336 logicalBaseFormat
== GL_INTENSITY
||
337 logicalBaseFormat
== GL_COLOR_INDEX
||
338 logicalBaseFormat
== GL_DEPTH_COMPONENT
);
340 ASSERT(textureBaseFormat
== GL_RGBA
||
341 textureBaseFormat
== GL_RGB
||
342 textureBaseFormat
== GL_RG
||
343 textureBaseFormat
== GL_RED
||
344 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
345 textureBaseFormat
== GL_LUMINANCE
||
346 textureBaseFormat
== GL_ALPHA
||
347 textureBaseFormat
== GL_INTENSITY
||
348 textureBaseFormat
== GL_COLOR_INDEX
||
349 textureBaseFormat
== GL_DEPTH_COMPONENT
);
351 tempImage
= (GLfloat
*) malloc(srcWidth
* srcHeight
* srcDepth
352 * components
* sizeof(GLfloat
));
357 for (img
= 0; img
< srcDepth
; img
++) {
359 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
363 for (row
= 0; row
< srcHeight
; row
++) {
364 _mesa_unpack_color_span_float(ctx
, srcWidth
, logicalBaseFormat
,
365 dst
, srcFormat
, srcType
, src
,
366 srcPacking
, transferOps
);
367 dst
+= srcWidth
* components
;
372 if (logicalBaseFormat
!= textureBaseFormat
) {
374 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
375 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
380 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
381 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
382 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
384 /* The actual texture format should have at least as many components
385 * as the logical texture format.
387 ASSERT(texComponents
>= logComponents
);
389 newImage
= (GLfloat
*) malloc(srcWidth
* srcHeight
* srcDepth
390 * texComponents
* sizeof(GLfloat
));
396 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
398 n
= srcWidth
* srcHeight
* srcDepth
;
399 for (i
= 0; i
< n
; i
++) {
401 for (k
= 0; k
< texComponents
; k
++) {
404 newImage
[i
* texComponents
+ k
] = 0.0F
;
406 newImage
[i
* texComponents
+ k
] = 1.0F
;
408 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
413 tempImage
= newImage
;
421 * Make a temporary (color) texture image with GLchan components.
422 * Apply all needed pixel unpacking and pixel transfer operations.
423 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
424 * Suppose the user specifies GL_LUMINANCE as the internal texture format
425 * but the graphics hardware doesn't support luminance textures. So, might
426 * use an RGB hardware format instead.
427 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
429 * \param ctx the rendering context
430 * \param dims image dimensions: 1, 2 or 3
431 * \param logicalBaseFormat basic texture derived from the user's
432 * internal texture format value
433 * \param textureBaseFormat the actual basic format of the texture
434 * \param srcWidth source image width
435 * \param srcHeight source image height
436 * \param srcDepth source image depth
437 * \param srcFormat source image format
438 * \param srcType source image type
439 * \param srcAddr source image address
440 * \param srcPacking source image pixel packing
441 * \return resulting image with format = textureBaseFormat and type = GLchan.
444 _mesa_make_temp_chan_image(GLcontext
*ctx
, GLuint dims
,
445 GLenum logicalBaseFormat
,
446 GLenum textureBaseFormat
,
447 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
448 GLenum srcFormat
, GLenum srcType
,
449 const GLvoid
*srcAddr
,
450 const struct gl_pixelstore_attrib
*srcPacking
)
452 GLuint transferOps
= ctx
->_ImageTransferState
;
453 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
455 GLchan
*tempImage
, *dst
;
457 ASSERT(dims
>= 1 && dims
<= 3);
459 ASSERT(logicalBaseFormat
== GL_RGBA
||
460 logicalBaseFormat
== GL_RGB
||
461 logicalBaseFormat
== GL_RG
||
462 logicalBaseFormat
== GL_RED
||
463 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
464 logicalBaseFormat
== GL_LUMINANCE
||
465 logicalBaseFormat
== GL_ALPHA
||
466 logicalBaseFormat
== GL_INTENSITY
);
468 ASSERT(textureBaseFormat
== GL_RGBA
||
469 textureBaseFormat
== GL_RGB
||
470 textureBaseFormat
== GL_RG
||
471 textureBaseFormat
== GL_RED
||
472 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
473 textureBaseFormat
== GL_LUMINANCE
||
474 textureBaseFormat
== GL_ALPHA
||
475 textureBaseFormat
== GL_INTENSITY
);
477 /* unpack and transfer the source image */
478 tempImage
= (GLchan
*) malloc(srcWidth
* srcHeight
* srcDepth
479 * components
* sizeof(GLchan
));
485 for (img
= 0; img
< srcDepth
; img
++) {
486 const GLint srcStride
=
487 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
489 (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
493 for (row
= 0; row
< srcHeight
; row
++) {
494 _mesa_unpack_color_span_chan(ctx
, srcWidth
, logicalBaseFormat
, dst
,
495 srcFormat
, srcType
, src
, srcPacking
,
497 dst
+= srcWidth
* components
;
502 if (logicalBaseFormat
!= textureBaseFormat
) {
503 /* one more conversion step */
504 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
505 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
510 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
511 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
512 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
514 /* The actual texture format should have at least as many components
515 * as the logical texture format.
517 ASSERT(texComponents
>= logComponents
);
519 newImage
= (GLchan
*) malloc(srcWidth
* srcHeight
* srcDepth
520 * texComponents
* sizeof(GLchan
));
526 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
528 n
= srcWidth
* srcHeight
* srcDepth
;
529 for (i
= 0; i
< n
; i
++) {
531 for (k
= 0; k
< texComponents
; k
++) {
534 newImage
[i
* texComponents
+ k
] = 0;
536 newImage
[i
* texComponents
+ k
] = CHAN_MAX
;
538 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
543 tempImage
= newImage
;
551 * Copy GLubyte pixels from <src> to <dst> with swizzling.
552 * \param dst destination pixels
553 * \param dstComponents number of color components in destination pixels
554 * \param src source pixels
555 * \param srcComponents number of color components in source pixels
556 * \param map the swizzle mapping. map[X] says where to find the X component
557 * in the source image's pixels. For example, if the source image
558 * is GL_BGRA and X = red, map[0] yields 2.
559 * \param count number of pixels to copy/swizzle.
562 swizzle_copy(GLubyte
*dst
, GLuint dstComponents
, const GLubyte
*src
,
563 GLuint srcComponents
, const GLubyte
*map
, GLuint count
)
565 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
568 for (i = 0; i < count; i++) { \
570 if (srcComps == 4) { \
571 COPY_4UBV(tmp, src); \
574 for (j = 0; j < srcComps; j++) { \
579 for (j = 0; j < dstComps; j++) { \
580 dst[j] = tmp[map[j]]; \
591 ASSERT(srcComponents
<= 4);
592 ASSERT(dstComponents
<= 4);
594 switch (dstComponents
) {
596 switch (srcComponents
) {
598 SWZ_CPY(dst
, src
, count
, 4, 4);
601 SWZ_CPY(dst
, src
, count
, 4, 3);
604 SWZ_CPY(dst
, src
, count
, 4, 2);
607 SWZ_CPY(dst
, src
, count
, 4, 1);
614 switch (srcComponents
) {
616 SWZ_CPY(dst
, src
, count
, 3, 4);
619 SWZ_CPY(dst
, src
, count
, 3, 3);
622 SWZ_CPY(dst
, src
, count
, 3, 2);
625 SWZ_CPY(dst
, src
, count
, 3, 1);
632 switch (srcComponents
) {
634 SWZ_CPY(dst
, src
, count
, 2, 4);
637 SWZ_CPY(dst
, src
, count
, 2, 3);
640 SWZ_CPY(dst
, src
, count
, 2, 2);
643 SWZ_CPY(dst
, src
, count
, 2, 1);
650 switch (srcComponents
) {
652 SWZ_CPY(dst
, src
, count
, 1, 4);
655 SWZ_CPY(dst
, src
, count
, 1, 3);
658 SWZ_CPY(dst
, src
, count
, 1, 2);
661 SWZ_CPY(dst
, src
, count
, 1, 1);
675 static const GLubyte map_identity
[6] = { 0, 1, 2, 3, ZERO
, ONE
};
676 static const GLubyte map_3210
[6] = { 3, 2, 1, 0, ZERO
, ONE
};
678 /* Deal with the _REV input types:
680 static const GLubyte
*
681 type_mapping( GLenum srcType
)
685 case GL_UNSIGNED_BYTE
:
687 case GL_UNSIGNED_INT_8_8_8_8
:
688 return _mesa_little_endian() ? map_3210
: map_identity
;
689 case GL_UNSIGNED_INT_8_8_8_8_REV
:
690 return _mesa_little_endian() ? map_identity
: map_3210
;
696 /* Mapping required if input type is
698 static const GLubyte
*
699 byteswap_mapping( GLboolean swapBytes
,
707 case GL_UNSIGNED_BYTE
:
709 case GL_UNSIGNED_INT_8_8_8_8
:
710 case GL_UNSIGNED_INT_8_8_8_8_REV
:
720 * Transfer a GLubyte texture image with component swizzling.
723 _mesa_swizzle_ubyte_image(GLcontext
*ctx
,
728 GLenum baseInternalFormat
,
730 const GLubyte
*rgba2dst
,
731 GLuint dstComponents
,
734 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
736 const GLuint
*dstImageOffsets
,
738 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
739 const GLvoid
*srcAddr
,
740 const struct gl_pixelstore_attrib
*srcPacking
)
742 GLint srcComponents
= _mesa_components_in_format(srcFormat
);
743 const GLubyte
*srctype2ubyte
, *swap
;
744 GLubyte map
[4], src2base
[6], base2rgba
[6];
746 const GLint srcRowStride
=
747 _mesa_image_row_stride(srcPacking
, srcWidth
,
748 srcFormat
, GL_UNSIGNED_BYTE
);
749 const GLint srcImageStride
750 = _mesa_image_image_stride(srcPacking
, srcWidth
, srcHeight
, srcFormat
,
752 const GLubyte
*srcImage
753 = (const GLubyte
*) _mesa_image_address(dimensions
, srcPacking
, srcAddr
,
754 srcWidth
, srcHeight
, srcFormat
,
755 GL_UNSIGNED_BYTE
, 0, 0, 0);
759 /* Translate from src->baseInternal->GL_RGBA->dst. This will
760 * correctly deal with RGBA->RGB->RGBA conversions where the final
761 * A value must be 0xff regardless of the incoming alpha values.
763 compute_component_mapping(srcFormat
, baseInternalFormat
, src2base
);
764 compute_component_mapping(baseInternalFormat
, GL_RGBA
, base2rgba
);
765 swap
= byteswap_mapping(srcPacking
->SwapBytes
, srcType
);
766 srctype2ubyte
= type_mapping(srcType
);
769 for (i
= 0; i
< 4; i
++)
770 map
[i
] = srctype2ubyte
[swap
[src2base
[base2rgba
[rgba2dst
[i
]]]]];
772 /* printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */
774 if (srcComponents
== dstComponents
&&
775 srcRowStride
== dstRowStride
&&
776 srcRowStride
== srcWidth
* srcComponents
&&
778 /* 1 and 2D images only */
779 GLubyte
*dstImage
= (GLubyte
*) dstAddr
780 + dstYoffset
* dstRowStride
781 + dstXoffset
* dstComponents
;
782 swizzle_copy(dstImage
, dstComponents
, srcImage
, srcComponents
, map
,
783 srcWidth
* srcHeight
);
787 for (img
= 0; img
< srcDepth
; img
++) {
788 const GLubyte
*srcRow
= srcImage
;
789 GLubyte
*dstRow
= (GLubyte
*) dstAddr
790 + dstImageOffsets
[dstZoffset
+ img
] * dstComponents
791 + dstYoffset
* dstRowStride
792 + dstXoffset
* dstComponents
;
793 for (row
= 0; row
< srcHeight
; row
++) {
794 swizzle_copy(dstRow
, dstComponents
, srcRow
, srcComponents
, map
, srcWidth
);
795 dstRow
+= dstRowStride
;
796 srcRow
+= srcRowStride
;
798 srcImage
+= srcImageStride
;
805 * Teximage storage routine for when a simple memcpy will do.
806 * No pixel transfer operations or special texel encodings allowed.
807 * 1D, 2D and 3D images supported.
810 memcpy_texture(GLcontext
*ctx
,
814 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
816 const GLuint
*dstImageOffsets
,
817 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
818 GLenum srcFormat
, GLenum srcType
,
819 const GLvoid
*srcAddr
,
820 const struct gl_pixelstore_attrib
*srcPacking
)
822 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
824 const GLint srcImageStride
= _mesa_image_image_stride(srcPacking
,
825 srcWidth
, srcHeight
, srcFormat
, srcType
);
826 const GLubyte
*srcImage
= (const GLubyte
*) _mesa_image_address(dimensions
,
827 srcPacking
, srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, 0, 0, 0);
828 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
829 const GLint bytesPerRow
= srcWidth
* texelBytes
;
832 /* XXX update/re-enable for dstImageOffsets array */
833 const GLint bytesPerImage
= srcHeight
* bytesPerRow
;
834 const GLint bytesPerTexture
= srcDepth
* bytesPerImage
;
835 GLubyte
*dstImage
= (GLubyte
*) dstAddr
836 + dstZoffset
* dstImageStride
837 + dstYoffset
* dstRowStride
838 + dstXoffset
* texelBytes
;
840 if (dstRowStride
== srcRowStride
&&
841 dstRowStride
== bytesPerRow
&&
842 ((dstImageStride
== srcImageStride
&&
843 dstImageStride
== bytesPerImage
) ||
846 ctx
->Driver
.TextureMemCpy(dstImage
, srcImage
, bytesPerTexture
);
851 for (img
= 0; img
< srcDepth
; img
++) {
852 const GLubyte
*srcRow
= srcImage
;
853 GLubyte
*dstRow
= dstImage
;
854 for (row
= 0; row
< srcHeight
; row
++) {
855 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
856 dstRow
+= dstRowStride
;
857 srcRow
+= srcRowStride
;
859 srcImage
+= srcImageStride
;
860 dstImage
+= dstImageStride
;
866 for (img
= 0; img
< srcDepth
; img
++) {
867 const GLubyte
*srcRow
= srcImage
;
868 GLubyte
*dstRow
= (GLubyte
*) dstAddr
869 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
870 + dstYoffset
* dstRowStride
871 + dstXoffset
* texelBytes
;
872 for (row
= 0; row
< srcHeight
; row
++) {
873 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
874 dstRow
+= dstRowStride
;
875 srcRow
+= srcRowStride
;
877 srcImage
+= srcImageStride
;
884 * Store a 32-bit integer depth component texture image.
887 _mesa_texstore_z32(TEXSTORE_PARAMS
)
889 const GLuint depthScale
= 0xffffffff;
890 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
892 ASSERT(dstFormat
== MESA_FORMAT_Z32
);
893 ASSERT(texelBytes
== sizeof(GLuint
));
895 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
896 ctx
->Pixel
.DepthBias
== 0.0f
&&
897 !srcPacking
->SwapBytes
&&
898 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
899 srcFormat
== GL_DEPTH_COMPONENT
&&
900 srcType
== GL_UNSIGNED_INT
) {
901 /* simple memcpy path */
902 memcpy_texture(ctx
, dims
,
903 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
906 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
907 srcAddr
, srcPacking
);
912 for (img
= 0; img
< srcDepth
; img
++) {
913 GLubyte
*dstRow
= (GLubyte
*) dstAddr
914 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
915 + dstYoffset
* dstRowStride
916 + dstXoffset
* texelBytes
;
917 for (row
= 0; row
< srcHeight
; row
++) {
918 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
919 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
920 _mesa_unpack_depth_span(ctx
, srcWidth
,
921 GL_UNSIGNED_INT
, (GLuint
*) dstRow
,
922 depthScale
, srcType
, src
, srcPacking
);
923 dstRow
+= dstRowStride
;
932 * Store a 24-bit integer depth component texture image.
935 _mesa_texstore_x8_z24(TEXSTORE_PARAMS
)
937 const GLuint depthScale
= 0xffffff;
938 const GLuint texelBytes
= 4;
941 ASSERT(dstFormat
== MESA_FORMAT_X8_Z24
);
946 for (img
= 0; img
< srcDepth
; img
++) {
947 GLubyte
*dstRow
= (GLubyte
*) dstAddr
948 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
949 + dstYoffset
* dstRowStride
950 + dstXoffset
* texelBytes
;
951 for (row
= 0; row
< srcHeight
; row
++) {
952 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
953 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
954 _mesa_unpack_depth_span(ctx
, srcWidth
,
955 GL_UNSIGNED_INT
, (GLuint
*) dstRow
,
956 depthScale
, srcType
, src
, srcPacking
);
957 dstRow
+= dstRowStride
;
966 * Store a 24-bit integer depth component texture image.
969 _mesa_texstore_z24_x8(TEXSTORE_PARAMS
)
971 const GLuint depthScale
= 0xffffff;
972 const GLuint texelBytes
= 4;
975 ASSERT(dstFormat
== MESA_FORMAT_Z24_X8
);
980 for (img
= 0; img
< srcDepth
; img
++) {
981 GLubyte
*dstRow
= (GLubyte
*) dstAddr
982 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
983 + dstYoffset
* dstRowStride
984 + dstXoffset
* texelBytes
;
985 for (row
= 0; row
< srcHeight
; row
++) {
986 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
987 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
988 GLuint
*dst
= (GLuint
*) dstRow
;
990 _mesa_unpack_depth_span(ctx
, srcWidth
,
991 GL_UNSIGNED_INT
, dst
,
992 depthScale
, srcType
, src
, srcPacking
);
993 for (i
= 0; i
< srcWidth
; i
++)
995 dstRow
+= dstRowStride
;
1004 * Store a 16-bit integer depth component texture image.
1007 _mesa_texstore_z16(TEXSTORE_PARAMS
)
1009 const GLuint depthScale
= 0xffff;
1010 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1012 ASSERT(dstFormat
== MESA_FORMAT_Z16
);
1013 ASSERT(texelBytes
== sizeof(GLushort
));
1015 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1016 ctx
->Pixel
.DepthBias
== 0.0f
&&
1017 !srcPacking
->SwapBytes
&&
1018 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1019 srcFormat
== GL_DEPTH_COMPONENT
&&
1020 srcType
== GL_UNSIGNED_SHORT
) {
1021 /* simple memcpy path */
1022 memcpy_texture(ctx
, dims
,
1023 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1026 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1027 srcAddr
, srcPacking
);
1032 for (img
= 0; img
< srcDepth
; img
++) {
1033 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1034 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1035 + dstYoffset
* dstRowStride
1036 + dstXoffset
* texelBytes
;
1037 for (row
= 0; row
< srcHeight
; row
++) {
1038 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1039 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1040 GLushort
*dst16
= (GLushort
*) dstRow
;
1041 _mesa_unpack_depth_span(ctx
, srcWidth
,
1042 GL_UNSIGNED_SHORT
, dst16
, depthScale
,
1043 srcType
, src
, srcPacking
);
1044 dstRow
+= dstRowStride
;
1053 * Store an rgb565 or rgb565_rev texture image.
1056 _mesa_texstore_rgb565(TEXSTORE_PARAMS
)
1058 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1059 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1061 ASSERT(dstFormat
== MESA_FORMAT_RGB565
||
1062 dstFormat
== MESA_FORMAT_RGB565_REV
);
1063 ASSERT(texelBytes
== 2);
1065 if (!ctx
->_ImageTransferState
&&
1066 !srcPacking
->SwapBytes
&&
1067 dstFormat
== MESA_FORMAT_RGB565
&&
1068 baseInternalFormat
== GL_RGB
&&
1069 srcFormat
== GL_RGB
&&
1070 srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1071 /* simple memcpy path */
1072 memcpy_texture(ctx
, dims
,
1073 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1076 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1077 srcAddr
, srcPacking
);
1079 else if (!ctx
->_ImageTransferState
&&
1080 !srcPacking
->SwapBytes
&&
1081 baseInternalFormat
== GL_RGB
&&
1082 srcFormat
== GL_RGB
&&
1083 srcType
== GL_UNSIGNED_BYTE
&&
1085 /* do optimized tex store */
1086 const GLint srcRowStride
=
1087 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1088 const GLubyte
*src
= (const GLubyte
*)
1089 _mesa_image_address(dims
, srcPacking
, srcAddr
, srcWidth
, srcHeight
,
1090 srcFormat
, srcType
, 0, 0, 0);
1091 GLubyte
*dst
= (GLubyte
*) dstAddr
1092 + dstYoffset
* dstRowStride
1093 + dstXoffset
* texelBytes
;
1095 for (row
= 0; row
< srcHeight
; row
++) {
1096 const GLubyte
*srcUB
= (const GLubyte
*) src
;
1097 GLushort
*dstUS
= (GLushort
*) dst
;
1098 /* check for byteswapped format */
1099 if (dstFormat
== MESA_FORMAT_RGB565
) {
1100 for (col
= 0; col
< srcWidth
; col
++) {
1101 dstUS
[col
] = PACK_COLOR_565( srcUB
[0], srcUB
[1], srcUB
[2] );
1106 for (col
= 0; col
< srcWidth
; col
++) {
1107 dstUS
[col
] = PACK_COLOR_565_REV( srcUB
[0], srcUB
[1], srcUB
[2] );
1111 dst
+= dstRowStride
;
1112 src
+= srcRowStride
;
1117 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1120 srcWidth
, srcHeight
, srcDepth
,
1121 srcFormat
, srcType
, srcAddr
,
1123 const GLchan
*src
= tempImage
;
1124 GLint img
, row
, col
;
1127 for (img
= 0; img
< srcDepth
; img
++) {
1128 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1129 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1130 + dstYoffset
* dstRowStride
1131 + dstXoffset
* texelBytes
;
1132 for (row
= 0; row
< srcHeight
; row
++) {
1133 GLushort
*dstUS
= (GLushort
*) dstRow
;
1134 /* check for byteswapped format */
1135 if (dstFormat
== MESA_FORMAT_RGB565
) {
1136 for (col
= 0; col
< srcWidth
; col
++) {
1137 dstUS
[col
] = PACK_COLOR_565( CHAN_TO_UBYTE(src
[RCOMP
]),
1138 CHAN_TO_UBYTE(src
[GCOMP
]),
1139 CHAN_TO_UBYTE(src
[BCOMP
]) );
1144 for (col
= 0; col
< srcWidth
; col
++) {
1145 dstUS
[col
] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1146 CHAN_TO_UBYTE(src
[GCOMP
]),
1147 CHAN_TO_UBYTE(src
[BCOMP
]) );
1151 dstRow
+= dstRowStride
;
1154 free((void *) tempImage
);
1161 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1164 _mesa_texstore_rgba8888(TEXSTORE_PARAMS
)
1166 const GLboolean littleEndian
= _mesa_little_endian();
1167 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1168 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1170 ASSERT(dstFormat
== MESA_FORMAT_RGBA8888
||
1171 dstFormat
== MESA_FORMAT_RGBA8888_REV
);
1172 ASSERT(texelBytes
== 4);
1174 if (!ctx
->_ImageTransferState
&&
1175 !srcPacking
->SwapBytes
&&
1176 dstFormat
== MESA_FORMAT_RGBA8888
&&
1177 baseInternalFormat
== GL_RGBA
&&
1178 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1179 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1180 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1181 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
))) {
1182 /* simple memcpy path */
1183 memcpy_texture(ctx
, dims
,
1184 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1187 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1188 srcAddr
, srcPacking
);
1190 else if (!ctx
->_ImageTransferState
&&
1191 !srcPacking
->SwapBytes
&&
1192 dstFormat
== MESA_FORMAT_RGBA8888_REV
&&
1193 baseInternalFormat
== GL_RGBA
&&
1194 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1195 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1196 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1197 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
))) {
1198 /* simple memcpy path */
1199 memcpy_texture(ctx
, dims
,
1200 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1203 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1204 srcAddr
, srcPacking
);
1206 else if (!ctx
->_ImageTransferState
&&
1207 (srcType
== GL_UNSIGNED_BYTE
||
1208 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1209 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1210 can_swizzle(baseInternalFormat
) &&
1211 can_swizzle(srcFormat
)) {
1215 /* dstmap - how to swizzle from RGBA to dst format:
1217 if ((littleEndian
&& dstFormat
== MESA_FORMAT_RGBA8888
) ||
1218 (!littleEndian
&& dstFormat
== MESA_FORMAT_RGBA8888_REV
)) {
1231 _mesa_swizzle_ubyte_image(ctx
, dims
,
1236 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1237 dstRowStride
, dstImageOffsets
,
1238 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1243 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1246 srcWidth
, srcHeight
, srcDepth
,
1247 srcFormat
, srcType
, srcAddr
,
1249 const GLchan
*src
= tempImage
;
1250 GLint img
, row
, col
;
1253 for (img
= 0; img
< srcDepth
; img
++) {
1254 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1255 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1256 + dstYoffset
* dstRowStride
1257 + dstXoffset
* texelBytes
;
1258 for (row
= 0; row
< srcHeight
; row
++) {
1259 GLuint
*dstUI
= (GLuint
*) dstRow
;
1260 if (dstFormat
== MESA_FORMAT_RGBA8888
) {
1261 for (col
= 0; col
< srcWidth
; col
++) {
1262 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[RCOMP
]),
1263 CHAN_TO_UBYTE(src
[GCOMP
]),
1264 CHAN_TO_UBYTE(src
[BCOMP
]),
1265 CHAN_TO_UBYTE(src
[ACOMP
]) );
1270 for (col
= 0; col
< srcWidth
; col
++) {
1271 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1272 CHAN_TO_UBYTE(src
[GCOMP
]),
1273 CHAN_TO_UBYTE(src
[BCOMP
]),
1274 CHAN_TO_UBYTE(src
[ACOMP
]) );
1278 dstRow
+= dstRowStride
;
1281 free((void *) tempImage
);
1288 _mesa_texstore_argb8888(TEXSTORE_PARAMS
)
1290 const GLboolean littleEndian
= _mesa_little_endian();
1291 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1292 const GLenum baseFormat
= GL_RGBA
;
1294 ASSERT(dstFormat
== MESA_FORMAT_ARGB8888
||
1295 dstFormat
== MESA_FORMAT_ARGB8888_REV
||
1296 dstFormat
== MESA_FORMAT_XRGB8888
||
1297 dstFormat
== MESA_FORMAT_XRGB8888_REV
);
1298 ASSERT(texelBytes
== 4);
1300 if (!ctx
->_ImageTransferState
&&
1301 !srcPacking
->SwapBytes
&&
1302 (dstFormat
== MESA_FORMAT_ARGB8888
||
1303 dstFormat
== MESA_FORMAT_XRGB8888
) &&
1304 baseInternalFormat
== GL_RGBA
&&
1305 srcFormat
== GL_BGRA
&&
1306 ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1307 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
1308 /* simple memcpy path (little endian) */
1309 memcpy_texture(ctx
, dims
,
1310 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1313 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1314 srcAddr
, srcPacking
);
1316 else if (!ctx
->_ImageTransferState
&&
1317 !srcPacking
->SwapBytes
&&
1318 (dstFormat
== MESA_FORMAT_ARGB8888_REV
||
1319 dstFormat
== MESA_FORMAT_XRGB8888_REV
) &&
1320 baseInternalFormat
== GL_RGBA
&&
1321 srcFormat
== GL_BGRA
&&
1322 ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1323 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
1324 /* simple memcpy path (big endian) */
1325 memcpy_texture(ctx
, dims
,
1326 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1329 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1330 srcAddr
, srcPacking
);
1332 else if (!ctx
->_ImageTransferState
&&
1333 !srcPacking
->SwapBytes
&&
1334 (dstFormat
== MESA_FORMAT_ARGB8888
||
1335 dstFormat
== MESA_FORMAT_XRGB8888
) &&
1336 srcFormat
== GL_RGB
&&
1337 (baseInternalFormat
== GL_RGBA
||
1338 baseInternalFormat
== GL_RGB
) &&
1339 srcType
== GL_UNSIGNED_BYTE
) {
1341 for (img
= 0; img
< srcDepth
; img
++) {
1342 const GLint srcRowStride
=
1343 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1344 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1345 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1346 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1347 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1348 + dstYoffset
* dstRowStride
1349 + dstXoffset
* texelBytes
;
1350 for (row
= 0; row
< srcHeight
; row
++) {
1351 GLuint
*d4
= (GLuint
*) dstRow
;
1352 for (col
= 0; col
< srcWidth
; col
++) {
1353 d4
[col
] = PACK_COLOR_8888(0xff,
1354 srcRow
[col
* 3 + RCOMP
],
1355 srcRow
[col
* 3 + GCOMP
],
1356 srcRow
[col
* 3 + BCOMP
]);
1358 dstRow
+= dstRowStride
;
1359 srcRow
+= srcRowStride
;
1363 else if (!ctx
->_ImageTransferState
&&
1364 !srcPacking
->SwapBytes
&&
1365 dstFormat
== MESA_FORMAT_ARGB8888
&&
1366 srcFormat
== GL_RGBA
&&
1367 baseInternalFormat
== GL_RGBA
&&
1368 srcType
== GL_UNSIGNED_BYTE
) {
1369 /* same as above case, but src data has alpha too */
1370 GLint img
, row
, col
;
1371 /* For some reason, streaming copies to write-combined regions
1372 * are extremely sensitive to the characteristics of how the
1373 * source data is retrieved. By reordering the source reads to
1374 * be in-order, the speed of this operation increases by half.
1375 * Strangely the same isn't required for the RGB path, above.
1377 for (img
= 0; img
< srcDepth
; img
++) {
1378 const GLint srcRowStride
=
1379 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1380 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1381 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1382 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1383 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1384 + dstYoffset
* dstRowStride
1385 + dstXoffset
* texelBytes
;
1386 for (row
= 0; row
< srcHeight
; row
++) {
1387 GLuint
*d4
= (GLuint
*) dstRow
;
1388 for (col
= 0; col
< srcWidth
; col
++) {
1389 d4
[col
] = PACK_COLOR_8888(srcRow
[col
* 4 + ACOMP
],
1390 srcRow
[col
* 4 + RCOMP
],
1391 srcRow
[col
* 4 + GCOMP
],
1392 srcRow
[col
* 4 + BCOMP
]);
1394 dstRow
+= dstRowStride
;
1395 srcRow
+= srcRowStride
;
1399 else if (!ctx
->_ImageTransferState
&&
1400 (srcType
== GL_UNSIGNED_BYTE
||
1401 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1402 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1403 can_swizzle(baseInternalFormat
) &&
1404 can_swizzle(srcFormat
)) {
1408 /* dstmap - how to swizzle from RGBA to dst format:
1410 if ((littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888
) ||
1411 (littleEndian
&& dstFormat
== MESA_FORMAT_XRGB8888
) ||
1412 (!littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888_REV
) ||
1413 (!littleEndian
&& dstFormat
== MESA_FORMAT_XRGB8888_REV
)) {
1414 dstmap
[3] = 3; /* alpha */
1415 dstmap
[2] = 0; /* red */
1416 dstmap
[1] = 1; /* green */
1417 dstmap
[0] = 2; /* blue */
1420 assert((littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888_REV
) ||
1421 (!littleEndian
&& dstFormat
== MESA_FORMAT_ARGB8888
) ||
1422 (littleEndian
&& dstFormat
== MESA_FORMAT_XRGB8888_REV
) ||
1423 (!littleEndian
&& dstFormat
== MESA_FORMAT_XRGB8888
));
1430 _mesa_swizzle_ubyte_image(ctx
, dims
,
1436 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1439 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1444 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1447 srcWidth
, srcHeight
, srcDepth
,
1448 srcFormat
, srcType
, srcAddr
,
1450 const GLchan
*src
= tempImage
;
1451 GLint img
, row
, col
;
1454 for (img
= 0; img
< srcDepth
; img
++) {
1455 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1456 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1457 + dstYoffset
* dstRowStride
1458 + dstXoffset
* texelBytes
;
1459 for (row
= 0; row
< srcHeight
; row
++) {
1460 GLuint
*dstUI
= (GLuint
*) dstRow
;
1461 if (dstFormat
== MESA_FORMAT_ARGB8888
) {
1462 for (col
= 0; col
< srcWidth
; col
++) {
1463 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[ACOMP
]),
1464 CHAN_TO_UBYTE(src
[RCOMP
]),
1465 CHAN_TO_UBYTE(src
[GCOMP
]),
1466 CHAN_TO_UBYTE(src
[BCOMP
]) );
1470 else if (dstFormat
== MESA_FORMAT_XRGB8888
) {
1471 for (col
= 0; col
< srcWidth
; col
++) {
1472 dstUI
[col
] = PACK_COLOR_8888( 0xff,
1473 CHAN_TO_UBYTE(src
[RCOMP
]),
1474 CHAN_TO_UBYTE(src
[GCOMP
]),
1475 CHAN_TO_UBYTE(src
[BCOMP
]) );
1480 for (col
= 0; col
< srcWidth
; col
++) {
1481 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1482 CHAN_TO_UBYTE(src
[RCOMP
]),
1483 CHAN_TO_UBYTE(src
[GCOMP
]),
1484 CHAN_TO_UBYTE(src
[BCOMP
]) );
1488 dstRow
+= dstRowStride
;
1491 free((void *) tempImage
);
1498 _mesa_texstore_rgb888(TEXSTORE_PARAMS
)
1500 const GLboolean littleEndian
= _mesa_little_endian();
1501 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1502 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1504 ASSERT(dstFormat
== MESA_FORMAT_RGB888
);
1505 ASSERT(texelBytes
== 3);
1507 if (!ctx
->_ImageTransferState
&&
1508 !srcPacking
->SwapBytes
&&
1509 baseInternalFormat
== GL_RGB
&&
1510 srcFormat
== GL_BGR
&&
1511 srcType
== GL_UNSIGNED_BYTE
&&
1513 /* simple memcpy path */
1514 memcpy_texture(ctx
, dims
,
1515 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1518 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1519 srcAddr
, srcPacking
);
1521 else if (!ctx
->_ImageTransferState
&&
1522 !srcPacking
->SwapBytes
&&
1523 srcFormat
== GL_RGBA
&&
1524 srcType
== GL_UNSIGNED_BYTE
) {
1525 /* extract RGB from RGBA */
1526 GLint img
, row
, col
;
1527 for (img
= 0; img
< srcDepth
; img
++) {
1528 const GLint srcRowStride
=
1529 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1530 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1531 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1532 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1533 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1534 + dstYoffset
* dstRowStride
1535 + dstXoffset
* texelBytes
;
1536 for (row
= 0; row
< srcHeight
; row
++) {
1537 for (col
= 0; col
< srcWidth
; col
++) {
1538 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + BCOMP
];
1539 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1540 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + RCOMP
];
1542 dstRow
+= dstRowStride
;
1543 srcRow
+= srcRowStride
;
1547 else if (!ctx
->_ImageTransferState
&&
1548 srcType
== GL_UNSIGNED_BYTE
&&
1549 can_swizzle(baseInternalFormat
) &&
1550 can_swizzle(srcFormat
)) {
1554 /* dstmap - how to swizzle from RGBA to dst format:
1559 dstmap
[3] = ONE
; /* ? */
1561 _mesa_swizzle_ubyte_image(ctx
, dims
,
1566 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1567 dstRowStride
, dstImageOffsets
,
1568 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1573 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1576 srcWidth
, srcHeight
, srcDepth
,
1577 srcFormat
, srcType
, srcAddr
,
1579 const GLchan
*src
= (const GLchan
*) tempImage
;
1580 GLint img
, row
, col
;
1583 for (img
= 0; img
< srcDepth
; img
++) {
1584 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1585 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1586 + dstYoffset
* dstRowStride
1587 + dstXoffset
* texelBytes
;
1588 for (row
= 0; row
< srcHeight
; row
++) {
1591 for (col
= 0; col
< srcWidth
; col
++) {
1592 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1593 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1594 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1599 for (col
= 0; col
< srcWidth
; col
++) {
1600 dstRow
[col
* 3 + 0] = srcUB
[BCOMP
];
1601 dstRow
[col
* 3 + 1] = srcUB
[GCOMP
];
1602 dstRow
[col
* 3 + 2] = srcUB
[RCOMP
];
1607 for (col
= 0; col
< srcWidth
; col
++) {
1608 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[BCOMP
]);
1609 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1610 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[RCOMP
]);
1614 dstRow
+= dstRowStride
;
1617 free((void *) tempImage
);
1624 _mesa_texstore_bgr888(TEXSTORE_PARAMS
)
1626 const GLboolean littleEndian
= _mesa_little_endian();
1627 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1628 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1630 ASSERT(dstFormat
== MESA_FORMAT_BGR888
);
1631 ASSERT(texelBytes
== 3);
1633 if (!ctx
->_ImageTransferState
&&
1634 !srcPacking
->SwapBytes
&&
1635 baseInternalFormat
== GL_RGB
&&
1636 srcFormat
== GL_RGB
&&
1637 srcType
== GL_UNSIGNED_BYTE
&&
1639 /* simple memcpy path */
1640 memcpy_texture(ctx
, dims
,
1641 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1644 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1645 srcAddr
, srcPacking
);
1647 else if (!ctx
->_ImageTransferState
&&
1648 !srcPacking
->SwapBytes
&&
1649 srcFormat
== GL_RGBA
&&
1650 srcType
== GL_UNSIGNED_BYTE
) {
1651 /* extract BGR from RGBA */
1653 for (img
= 0; img
< srcDepth
; img
++) {
1654 const GLint srcRowStride
=
1655 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1656 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1657 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1658 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1659 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1660 + dstYoffset
* dstRowStride
1661 + dstXoffset
* texelBytes
;
1662 for (row
= 0; row
< srcHeight
; row
++) {
1663 for (col
= 0; col
< srcWidth
; col
++) {
1664 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + RCOMP
];
1665 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1666 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + BCOMP
];
1668 dstRow
+= dstRowStride
;
1669 srcRow
+= srcRowStride
;
1673 else if (!ctx
->_ImageTransferState
&&
1674 srcType
== GL_UNSIGNED_BYTE
&&
1675 can_swizzle(baseInternalFormat
) &&
1676 can_swizzle(srcFormat
)) {
1680 /* dstmap - how to swizzle from RGBA to dst format:
1685 dstmap
[3] = ONE
; /* ? */
1687 _mesa_swizzle_ubyte_image(ctx
, dims
,
1692 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1693 dstRowStride
, dstImageOffsets
,
1694 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1699 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1702 srcWidth
, srcHeight
, srcDepth
,
1703 srcFormat
, srcType
, srcAddr
,
1705 const GLchan
*src
= (const GLchan
*) tempImage
;
1706 GLint img
, row
, col
;
1709 for (img
= 0; img
< srcDepth
; img
++) {
1710 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1711 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1712 + dstYoffset
* dstRowStride
1713 + dstXoffset
* texelBytes
;
1714 for (row
= 0; row
< srcHeight
; row
++) {
1715 for (col
= 0; col
< srcWidth
; col
++) {
1716 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1717 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1718 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1721 dstRow
+= dstRowStride
;
1724 free((void *) tempImage
);
1731 _mesa_texstore_argb4444(TEXSTORE_PARAMS
)
1733 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1734 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1736 ASSERT(dstFormat
== MESA_FORMAT_ARGB4444
||
1737 dstFormat
== MESA_FORMAT_ARGB4444_REV
);
1738 ASSERT(texelBytes
== 2);
1740 if (!ctx
->_ImageTransferState
&&
1741 !srcPacking
->SwapBytes
&&
1742 dstFormat
== MESA_FORMAT_ARGB4444
&&
1743 baseInternalFormat
== GL_RGBA
&&
1744 srcFormat
== GL_BGRA
&&
1745 srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1746 /* simple memcpy path */
1747 memcpy_texture(ctx
, dims
,
1748 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1751 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1752 srcAddr
, srcPacking
);
1756 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1759 srcWidth
, srcHeight
, srcDepth
,
1760 srcFormat
, srcType
, srcAddr
,
1762 const GLchan
*src
= tempImage
;
1763 GLint img
, row
, col
;
1766 for (img
= 0; img
< srcDepth
; img
++) {
1767 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1768 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1769 + dstYoffset
* dstRowStride
1770 + dstXoffset
* texelBytes
;
1771 for (row
= 0; row
< srcHeight
; row
++) {
1772 GLushort
*dstUS
= (GLushort
*) dstRow
;
1773 if (dstFormat
== MESA_FORMAT_ARGB4444
) {
1774 for (col
= 0; col
< srcWidth
; col
++) {
1775 dstUS
[col
] = PACK_COLOR_4444( CHAN_TO_UBYTE(src
[ACOMP
]),
1776 CHAN_TO_UBYTE(src
[RCOMP
]),
1777 CHAN_TO_UBYTE(src
[GCOMP
]),
1778 CHAN_TO_UBYTE(src
[BCOMP
]) );
1783 for (col
= 0; col
< srcWidth
; col
++) {
1784 dstUS
[col
] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1785 CHAN_TO_UBYTE(src
[RCOMP
]),
1786 CHAN_TO_UBYTE(src
[GCOMP
]),
1787 CHAN_TO_UBYTE(src
[BCOMP
]) );
1791 dstRow
+= dstRowStride
;
1794 free((void *) tempImage
);
1800 _mesa_texstore_rgba5551(TEXSTORE_PARAMS
)
1802 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1803 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1805 ASSERT(dstFormat
== MESA_FORMAT_RGBA5551
);
1806 ASSERT(texelBytes
== 2);
1808 if (!ctx
->_ImageTransferState
&&
1809 !srcPacking
->SwapBytes
&&
1810 dstFormat
== MESA_FORMAT_RGBA5551
&&
1811 baseInternalFormat
== GL_RGBA
&&
1812 srcFormat
== GL_RGBA
&&
1813 srcType
== GL_UNSIGNED_SHORT_5_5_5_1
) {
1814 /* simple memcpy path */
1815 memcpy_texture(ctx
, dims
,
1816 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1819 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1820 srcAddr
, srcPacking
);
1824 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1827 srcWidth
, srcHeight
, srcDepth
,
1828 srcFormat
, srcType
, srcAddr
,
1830 const GLchan
*src
=tempImage
;
1831 GLint img
, row
, col
;
1834 for (img
= 0; img
< srcDepth
; img
++) {
1835 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1836 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1837 + dstYoffset
* dstRowStride
1838 + dstXoffset
* texelBytes
;
1839 for (row
= 0; row
< srcHeight
; row
++) {
1840 GLushort
*dstUS
= (GLushort
*) dstRow
;
1841 for (col
= 0; col
< srcWidth
; col
++) {
1842 dstUS
[col
] = PACK_COLOR_5551( CHAN_TO_UBYTE(src
[RCOMP
]),
1843 CHAN_TO_UBYTE(src
[GCOMP
]),
1844 CHAN_TO_UBYTE(src
[BCOMP
]),
1845 CHAN_TO_UBYTE(src
[ACOMP
]) );
1848 dstRow
+= dstRowStride
;
1851 free((void *) tempImage
);
1857 _mesa_texstore_argb1555(TEXSTORE_PARAMS
)
1859 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1860 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1862 ASSERT(dstFormat
== MESA_FORMAT_ARGB1555
||
1863 dstFormat
== MESA_FORMAT_ARGB1555_REV
);
1864 ASSERT(texelBytes
== 2);
1866 if (!ctx
->_ImageTransferState
&&
1867 !srcPacking
->SwapBytes
&&
1868 dstFormat
== MESA_FORMAT_ARGB1555
&&
1869 baseInternalFormat
== GL_RGBA
&&
1870 srcFormat
== GL_BGRA
&&
1871 srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
1872 /* simple memcpy path */
1873 memcpy_texture(ctx
, dims
,
1874 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1877 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1878 srcAddr
, srcPacking
);
1882 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1885 srcWidth
, srcHeight
, srcDepth
,
1886 srcFormat
, srcType
, srcAddr
,
1888 const GLchan
*src
=tempImage
;
1889 GLint img
, row
, col
;
1892 for (img
= 0; img
< srcDepth
; img
++) {
1893 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1894 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
1895 + dstYoffset
* dstRowStride
1896 + dstXoffset
* texelBytes
;
1897 for (row
= 0; row
< srcHeight
; row
++) {
1898 GLushort
*dstUS
= (GLushort
*) dstRow
;
1899 if (dstFormat
== MESA_FORMAT_ARGB1555
) {
1900 for (col
= 0; col
< srcWidth
; col
++) {
1901 dstUS
[col
] = PACK_COLOR_1555( CHAN_TO_UBYTE(src
[ACOMP
]),
1902 CHAN_TO_UBYTE(src
[RCOMP
]),
1903 CHAN_TO_UBYTE(src
[GCOMP
]),
1904 CHAN_TO_UBYTE(src
[BCOMP
]) );
1909 for (col
= 0; col
< srcWidth
; col
++) {
1910 dstUS
[col
] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1911 CHAN_TO_UBYTE(src
[RCOMP
]),
1912 CHAN_TO_UBYTE(src
[GCOMP
]),
1913 CHAN_TO_UBYTE(src
[BCOMP
]) );
1917 dstRow
+= dstRowStride
;
1920 free((void *) tempImage
);
1927 _mesa_texstore_unorm88(TEXSTORE_PARAMS
)
1929 const GLboolean littleEndian
= _mesa_little_endian();
1930 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
1931 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1933 ASSERT(dstFormat
== MESA_FORMAT_AL88
||
1934 dstFormat
== MESA_FORMAT_AL88_REV
||
1935 dstFormat
== MESA_FORMAT_RG88
||
1936 dstFormat
== MESA_FORMAT_RG88_REV
);
1937 ASSERT(texelBytes
== 2);
1939 if (!ctx
->_ImageTransferState
&&
1940 !srcPacking
->SwapBytes
&&
1941 (dstFormat
== MESA_FORMAT_AL88
|| dstFormat
== MESA_FORMAT_RG88
) &&
1942 baseInternalFormat
== srcFormat
&&
1943 srcType
== GL_UNSIGNED_BYTE
&&
1945 /* simple memcpy path */
1946 memcpy_texture(ctx
, dims
,
1947 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1950 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1951 srcAddr
, srcPacking
);
1953 else if (!ctx
->_ImageTransferState
&&
1955 srcType
== GL_UNSIGNED_BYTE
&&
1956 can_swizzle(baseInternalFormat
) &&
1957 can_swizzle(srcFormat
)) {
1961 /* dstmap - how to swizzle from RGBA to dst format:
1963 if (dstFormat
== MESA_FORMAT_AL88
|| dstFormat
== MESA_FORMAT_AL88_REV
) {
1964 if ((littleEndian
&& dstFormat
== MESA_FORMAT_AL88
) ||
1965 (!littleEndian
&& dstFormat
== MESA_FORMAT_AL88_REV
)) {
1975 if ((littleEndian
&& dstFormat
== MESA_FORMAT_RG88
) ||
1976 (!littleEndian
&& dstFormat
== MESA_FORMAT_RG88_REV
)) {
1985 dstmap
[2] = ZERO
; /* ? */
1986 dstmap
[3] = ONE
; /* ? */
1988 _mesa_swizzle_ubyte_image(ctx
, dims
,
1993 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1994 dstRowStride
, dstImageOffsets
,
1995 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
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 for (img
= 0; img
< srcDepth
; img
++) {
2011 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2012 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2013 + dstYoffset
* dstRowStride
2014 + dstXoffset
* texelBytes
;
2015 for (row
= 0; row
< srcHeight
; row
++) {
2016 GLushort
*dstUS
= (GLushort
*) dstRow
;
2017 if (dstFormat
== MESA_FORMAT_AL88
||
2018 dstFormat
== MESA_FORMAT_RG88
) {
2019 for (col
= 0; col
< srcWidth
; col
++) {
2020 /* src[0] is luminance, src[1] is alpha */
2021 dstUS
[col
] = PACK_COLOR_88( CHAN_TO_UBYTE(src
[1]),
2022 CHAN_TO_UBYTE(src
[0]) );
2027 for (col
= 0; col
< srcWidth
; col
++) {
2028 /* src[0] is luminance, src[1] is alpha */
2029 dstUS
[col
] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src
[1]),
2030 CHAN_TO_UBYTE(src
[0]) );
2034 dstRow
+= dstRowStride
;
2037 free((void *) tempImage
);
2044 _mesa_texstore_unorm1616(TEXSTORE_PARAMS
)
2046 const GLboolean littleEndian
= _mesa_little_endian();
2047 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2048 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2050 ASSERT(dstFormat
== MESA_FORMAT_AL1616
||
2051 dstFormat
== MESA_FORMAT_AL1616_REV
||
2052 dstFormat
== MESA_FORMAT_RG1616
||
2053 dstFormat
== MESA_FORMAT_RG1616_REV
);
2054 ASSERT(texelBytes
== 4);
2056 if (!ctx
->_ImageTransferState
&&
2057 !srcPacking
->SwapBytes
&&
2058 (dstFormat
== MESA_FORMAT_AL1616
|| dstFormat
== MESA_FORMAT_RG1616
) &&
2059 baseInternalFormat
== srcFormat
&&
2060 srcType
== GL_UNSIGNED_SHORT
&&
2062 /* simple memcpy path */
2063 memcpy_texture(ctx
, dims
,
2064 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2067 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2068 srcAddr
, srcPacking
);
2072 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2075 srcWidth
, srcHeight
, srcDepth
,
2076 srcFormat
, srcType
, srcAddr
,
2078 const GLfloat
*src
= tempImage
;
2079 GLint img
, row
, col
;
2082 for (img
= 0; img
< srcDepth
; img
++) {
2083 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2084 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2085 + dstYoffset
* dstRowStride
2086 + dstXoffset
* texelBytes
;
2087 for (row
= 0; row
< srcHeight
; row
++) {
2088 GLuint
*dstUI
= (GLuint
*) dstRow
;
2089 if (dstFormat
== MESA_FORMAT_AL1616
||
2090 dstFormat
== MESA_FORMAT_RG1616
) {
2091 for (col
= 0; col
< srcWidth
; col
++) {
2094 UNCLAMPED_FLOAT_TO_USHORT(l
, src
[0]);
2095 UNCLAMPED_FLOAT_TO_USHORT(a
, src
[1]);
2096 dstUI
[col
] = PACK_COLOR_1616(a
, l
);
2101 for (col
= 0; col
< srcWidth
; col
++) {
2104 UNCLAMPED_FLOAT_TO_USHORT(l
, src
[0]);
2105 UNCLAMPED_FLOAT_TO_USHORT(a
, src
[1]);
2106 dstUI
[col
] = PACK_COLOR_1616_REV(a
, l
);
2110 dstRow
+= dstRowStride
;
2113 free((void *) tempImage
);
2120 _mesa_texstore_r16(TEXSTORE_PARAMS
)
2122 const GLboolean littleEndian
= _mesa_little_endian();
2123 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2124 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2126 ASSERT(dstFormat
== MESA_FORMAT_R16
);
2127 ASSERT(texelBytes
== 2);
2129 if (!ctx
->_ImageTransferState
&&
2130 !srcPacking
->SwapBytes
&&
2131 dstFormat
== MESA_FORMAT_R16
&&
2132 baseInternalFormat
== GL_RED
&&
2133 srcFormat
== GL_RED
&&
2134 srcType
== GL_UNSIGNED_SHORT
&&
2136 /* simple memcpy path */
2137 memcpy_texture(ctx
, dims
,
2138 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2141 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2142 srcAddr
, srcPacking
);
2146 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2149 srcWidth
, srcHeight
, srcDepth
,
2150 srcFormat
, srcType
, srcAddr
,
2152 const GLfloat
*src
= tempImage
;
2153 GLint img
, row
, col
;
2156 for (img
= 0; img
< srcDepth
; img
++) {
2157 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2158 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2159 + dstYoffset
* dstRowStride
2160 + dstXoffset
* texelBytes
;
2161 for (row
= 0; row
< srcHeight
; row
++) {
2162 GLushort
*dstUS
= (GLushort
*) dstRow
;
2163 for (col
= 0; col
< srcWidth
; col
++) {
2166 UNCLAMPED_FLOAT_TO_USHORT(r
, src
[0]);
2170 dstRow
+= dstRowStride
;
2173 free((void *) tempImage
);
2180 _mesa_texstore_rgba_16(TEXSTORE_PARAMS
)
2182 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2183 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2185 ASSERT(dstFormat
== MESA_FORMAT_RGBA_16
);
2186 ASSERT(texelBytes
== 8);
2188 if (!ctx
->_ImageTransferState
&&
2189 !srcPacking
->SwapBytes
&&
2190 baseInternalFormat
== GL_RGBA
&&
2191 srcFormat
== GL_RGBA
&&
2192 srcType
== GL_UNSIGNED_SHORT
) {
2193 /* simple memcpy path */
2194 memcpy_texture(ctx
, dims
,
2195 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2198 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2199 srcAddr
, srcPacking
);
2203 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2206 srcWidth
, srcHeight
, srcDepth
,
2207 srcFormat
, srcType
, srcAddr
,
2209 const GLfloat
*src
= tempImage
;
2210 GLint img
, row
, col
;
2213 for (img
= 0; img
< srcDepth
; img
++) {
2214 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2215 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2216 + dstYoffset
* dstRowStride
2217 + dstXoffset
* texelBytes
;
2218 for (row
= 0; row
< srcHeight
; row
++) {
2219 GLushort
*dstUS
= (GLushort
*) dstRow
;
2220 for (col
= 0; col
< srcWidth
; col
++) {
2221 GLushort r
, g
, b
, a
;
2223 UNCLAMPED_FLOAT_TO_USHORT(r
, src
[0]);
2224 UNCLAMPED_FLOAT_TO_USHORT(g
, src
[1]);
2225 UNCLAMPED_FLOAT_TO_USHORT(b
, src
[2]);
2226 UNCLAMPED_FLOAT_TO_USHORT(a
, src
[3]);
2233 dstRow
+= dstRowStride
;
2236 free((void *) tempImage
);
2243 _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS
)
2245 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2246 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2248 ASSERT(dstFormat
== MESA_FORMAT_SIGNED_R_16
||
2249 dstFormat
== MESA_FORMAT_SIGNED_RG_16
||
2250 dstFormat
== MESA_FORMAT_SIGNED_RGB_16
||
2251 dstFormat
== MESA_FORMAT_SIGNED_RGBA_16
);
2253 if (!ctx
->_ImageTransferState
&&
2254 !srcPacking
->SwapBytes
&&
2255 baseInternalFormat
== GL_RGBA
&&
2256 dstFormat
== MESA_FORMAT_SIGNED_RGBA_16
&&
2257 srcFormat
== GL_RGBA
&&
2258 srcType
== GL_SHORT
) {
2259 /* simple memcpy path */
2260 memcpy_texture(ctx
, dims
,
2261 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2264 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2265 srcAddr
, srcPacking
);
2269 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2272 srcWidth
, srcHeight
, srcDepth
,
2273 srcFormat
, srcType
, srcAddr
,
2275 const GLfloat
*src
= tempImage
;
2276 const GLuint comps
= _mesa_get_format_bytes(dstFormat
) / 2;
2277 GLint img
, row
, col
;
2282 /* Note: tempImage is always float[4] / RGBA. We convert to 1, 2,
2283 * 3 or 4 components/pixel here.
2285 for (img
= 0; img
< srcDepth
; img
++) {
2286 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2287 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2288 + dstYoffset
* dstRowStride
2289 + dstXoffset
* texelBytes
;
2290 for (row
= 0; row
< srcHeight
; row
++) {
2291 GLshort
*dstRowS
= (GLshort
*) dstRow
;
2292 for (col
= 0; col
< srcWidth
; col
++) {
2294 for (c
= 0; c
< comps
; c
++) {
2296 UNCLAMPED_FLOAT_TO_SHORT(p
, src
[col
* 4 + c
]);
2297 dstRowS
[col
* comps
+ c
] = p
;
2300 dstRow
+= dstRowStride
;
2301 src
+= 4 * srcWidth
;
2304 free((void *) tempImage
);
2311 _mesa_texstore_rgb332(TEXSTORE_PARAMS
)
2313 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2314 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2316 ASSERT(dstFormat
== MESA_FORMAT_RGB332
);
2317 ASSERT(texelBytes
== 1);
2319 if (!ctx
->_ImageTransferState
&&
2320 !srcPacking
->SwapBytes
&&
2321 baseInternalFormat
== GL_RGB
&&
2322 srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_BYTE_3_3_2
) {
2323 /* simple memcpy path */
2324 memcpy_texture(ctx
, dims
,
2325 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2328 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2329 srcAddr
, srcPacking
);
2333 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2336 srcWidth
, srcHeight
, srcDepth
,
2337 srcFormat
, srcType
, srcAddr
,
2339 const GLchan
*src
= tempImage
;
2340 GLint img
, row
, col
;
2343 for (img
= 0; img
< srcDepth
; img
++) {
2344 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2345 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2346 + dstYoffset
* dstRowStride
2347 + dstXoffset
* texelBytes
;
2348 for (row
= 0; row
< srcHeight
; row
++) {
2349 for (col
= 0; col
< srcWidth
; col
++) {
2350 dstRow
[col
] = PACK_COLOR_332( CHAN_TO_UBYTE(src
[RCOMP
]),
2351 CHAN_TO_UBYTE(src
[GCOMP
]),
2352 CHAN_TO_UBYTE(src
[BCOMP
]) );
2355 dstRow
+= dstRowStride
;
2358 free((void *) tempImage
);
2365 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2368 _mesa_texstore_a8(TEXSTORE_PARAMS
)
2370 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2371 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2373 ASSERT(dstFormat
== MESA_FORMAT_A8
||
2374 dstFormat
== MESA_FORMAT_L8
||
2375 dstFormat
== MESA_FORMAT_I8
||
2376 dstFormat
== MESA_FORMAT_R8
);
2377 ASSERT(texelBytes
== 1);
2379 if (!ctx
->_ImageTransferState
&&
2380 !srcPacking
->SwapBytes
&&
2381 baseInternalFormat
== srcFormat
&&
2382 srcType
== GL_UNSIGNED_BYTE
) {
2383 /* simple memcpy path */
2384 memcpy_texture(ctx
, dims
,
2385 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2388 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2389 srcAddr
, srcPacking
);
2391 else if (!ctx
->_ImageTransferState
&&
2392 srcType
== GL_UNSIGNED_BYTE
&&
2393 can_swizzle(baseInternalFormat
) &&
2394 can_swizzle(srcFormat
)) {
2398 /* dstmap - how to swizzle from RGBA to dst format:
2400 if (dstFormat
== MESA_FORMAT_A8
) {
2406 dstmap
[1] = ZERO
; /* ? */
2407 dstmap
[2] = ZERO
; /* ? */
2408 dstmap
[3] = ONE
; /* ? */
2410 _mesa_swizzle_ubyte_image(ctx
, dims
,
2415 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2416 dstRowStride
, dstImageOffsets
,
2417 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2422 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2425 srcWidth
, srcHeight
, srcDepth
,
2426 srcFormat
, srcType
, srcAddr
,
2428 const GLchan
*src
= tempImage
;
2429 GLint img
, row
, col
;
2432 for (img
= 0; img
< srcDepth
; img
++) {
2433 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2434 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2435 + dstYoffset
* dstRowStride
2436 + dstXoffset
* texelBytes
;
2437 for (row
= 0; row
< srcHeight
; row
++) {
2438 for (col
= 0; col
< srcWidth
; col
++) {
2439 dstRow
[col
] = CHAN_TO_UBYTE(src
[col
]);
2441 dstRow
+= dstRowStride
;
2445 free((void *) tempImage
);
2453 _mesa_texstore_ci8(TEXSTORE_PARAMS
)
2455 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2457 (void) dims
; (void) baseInternalFormat
;
2458 ASSERT(dstFormat
== MESA_FORMAT_CI8
);
2459 ASSERT(texelBytes
== 1);
2460 ASSERT(baseInternalFormat
== GL_COLOR_INDEX
);
2462 if (!ctx
->_ImageTransferState
&&
2463 !srcPacking
->SwapBytes
&&
2464 srcFormat
== GL_COLOR_INDEX
&&
2465 srcType
== GL_UNSIGNED_BYTE
) {
2466 /* simple memcpy path */
2467 memcpy_texture(ctx
, dims
,
2468 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2471 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2472 srcAddr
, srcPacking
);
2477 for (img
= 0; img
< srcDepth
; img
++) {
2478 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2479 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2480 + dstYoffset
* dstRowStride
2481 + dstXoffset
* texelBytes
;
2482 for (row
= 0; row
< srcHeight
; row
++) {
2483 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
2484 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
2485 _mesa_unpack_index_span(ctx
, srcWidth
, GL_UNSIGNED_BYTE
, dstRow
,
2486 srcType
, src
, srcPacking
,
2487 ctx
->_ImageTransferState
);
2488 dstRow
+= dstRowStride
;
2497 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
2500 _mesa_texstore_ycbcr(TEXSTORE_PARAMS
)
2502 const GLboolean littleEndian
= _mesa_little_endian();
2503 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2505 (void) ctx
; (void) dims
; (void) baseInternalFormat
;
2507 ASSERT((dstFormat
== MESA_FORMAT_YCBCR
) ||
2508 (dstFormat
== MESA_FORMAT_YCBCR_REV
));
2509 ASSERT(texelBytes
== 2);
2510 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
2511 ASSERT(srcFormat
== GL_YCBCR_MESA
);
2512 ASSERT((srcType
== GL_UNSIGNED_SHORT_8_8_MESA
) ||
2513 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
));
2514 ASSERT(baseInternalFormat
== GL_YCBCR_MESA
);
2516 /* always just memcpy since no pixel transfer ops apply */
2517 memcpy_texture(ctx
, dims
,
2518 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2521 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2522 srcAddr
, srcPacking
);
2524 /* Check if we need byte swapping */
2525 /* XXX the logic here _might_ be wrong */
2526 if (srcPacking
->SwapBytes
^
2527 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ^
2528 (dstFormat
== MESA_FORMAT_YCBCR_REV
) ^
2531 for (img
= 0; img
< srcDepth
; img
++) {
2532 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2533 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2534 + dstYoffset
* dstRowStride
2535 + dstXoffset
* texelBytes
;
2536 for (row
= 0; row
< srcHeight
; row
++) {
2537 _mesa_swap2((GLushort
*) dstRow
, srcWidth
);
2538 dstRow
+= dstRowStride
;
2546 _mesa_texstore_dudv8(TEXSTORE_PARAMS
)
2548 const GLboolean littleEndian
= _mesa_little_endian();
2549 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2551 ASSERT(dstFormat
== MESA_FORMAT_DUDV8
);
2552 ASSERT(texelBytes
== 2);
2553 ASSERT(ctx
->Extensions
.ATI_envmap_bumpmap
);
2554 ASSERT((srcFormat
== GL_DU8DV8_ATI
) ||
2555 (srcFormat
== GL_DUDV_ATI
));
2556 ASSERT(baseInternalFormat
== GL_DUDV_ATI
);
2558 if (!srcPacking
->SwapBytes
&& srcType
== GL_BYTE
&&
2560 /* simple memcpy path */
2561 memcpy_texture(ctx
, dims
,
2562 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2565 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2566 srcAddr
, srcPacking
);
2568 else if (srcType
== GL_BYTE
) {
2572 /* dstmap - how to swizzle from RGBA to dst format:
2582 dstmap
[2] = ZERO
; /* ? */
2583 dstmap
[3] = ONE
; /* ? */
2585 _mesa_swizzle_ubyte_image(ctx
, dims
,
2586 GL_LUMINANCE_ALPHA
, /* hack */
2587 GL_UNSIGNED_BYTE
, /* hack */
2588 GL_LUMINANCE_ALPHA
, /* hack */
2590 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2591 dstRowStride
, dstImageOffsets
,
2592 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2596 /* general path - note this is defined for 2d textures only */
2597 const GLint components
= _mesa_components_in_format(baseInternalFormat
);
2598 const GLint srcStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
2599 srcFormat
, srcType
);
2600 GLbyte
*tempImage
, *dst
, *src
;
2603 tempImage
= (GLbyte
*) malloc(srcWidth
* srcHeight
* srcDepth
2604 * components
* sizeof(GLbyte
));
2608 src
= (GLbyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2609 srcWidth
, srcHeight
,
2614 for (row
= 0; row
< srcHeight
; row
++) {
2615 _mesa_unpack_dudv_span_byte(ctx
, srcWidth
, baseInternalFormat
,
2616 dst
, srcFormat
, srcType
, src
,
2618 dst
+= srcWidth
* components
;
2623 dst
= (GLbyte
*) dstAddr
2624 + dstYoffset
* dstRowStride
2625 + dstXoffset
* texelBytes
;
2626 for (row
= 0; row
< srcHeight
; row
++) {
2627 memcpy(dst
, src
, srcWidth
* texelBytes
);
2628 dst
+= dstRowStride
;
2629 src
+= srcWidth
* texelBytes
;
2631 free((void *) tempImage
);
2638 * Store a texture in MESA_FORMAT_SIGNED_R8 format.
2641 _mesa_texstore_signed_r8(TEXSTORE_PARAMS
)
2643 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2644 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2646 ASSERT(dstFormat
== MESA_FORMAT_SIGNED_R8
);
2647 ASSERT(texelBytes
== 1);
2649 /* XXX look at adding optimized paths */
2652 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2655 srcWidth
, srcHeight
, srcDepth
,
2656 srcFormat
, srcType
, srcAddr
,
2658 const GLfloat
*srcRow
= tempImage
;
2659 GLint img
, row
, col
;
2662 for (img
= 0; img
< srcDepth
; img
++) {
2663 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2664 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2665 + dstYoffset
* dstRowStride
2666 + dstXoffset
* texelBytes
;
2667 for (row
= 0; row
< srcHeight
; row
++) {
2668 GLubyte
*dstB
= (GLubyte
*) dstRow
;
2669 for (col
= 0; col
< srcWidth
; col
++) {
2670 dstB
[col
] = FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]);
2672 dstRow
+= dstRowStride
;
2675 free((void *) tempImage
);
2682 * Store a texture in MESA_FORMAT_SIGNED_RG88 format.
2685 _mesa_texstore_signed_rg88(TEXSTORE_PARAMS
)
2687 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2688 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2690 ASSERT(dstFormat
== MESA_FORMAT_SIGNED_RG88
);
2691 ASSERT(texelBytes
== 1);
2693 /* XXX look at adding optimized paths */
2696 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2699 srcWidth
, srcHeight
, srcDepth
,
2700 srcFormat
, srcType
, srcAddr
,
2702 const GLfloat
*srcRow
= tempImage
;
2703 GLint img
, row
, col
;
2706 for (img
= 0; img
< srcDepth
; img
++) {
2707 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2708 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2709 + dstYoffset
* dstRowStride
2710 + dstXoffset
* texelBytes
;
2711 for (row
= 0; row
< srcHeight
; row
++) {
2712 GLushort
*dstUS
= (GLushort
*) dstRow
;
2713 for (col
= 0; col
< srcWidth
; col
++) {
2714 dstUS
[col
] = PACK_COLOR_88(FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2715 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]));
2717 dstRow
+= dstRowStride
;
2720 free((void *) tempImage
);
2727 * Store a texture in MESA_FORMAT_SIGNED_RGBX8888.
2730 _mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS
)
2732 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2733 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2735 ASSERT(dstFormat
== MESA_FORMAT_SIGNED_RGBX8888
);
2736 ASSERT(texelBytes
== 4);
2740 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2743 srcWidth
, srcHeight
, srcDepth
,
2744 srcFormat
, srcType
, srcAddr
,
2746 const GLfloat
*srcRow
= tempImage
;
2747 GLint img
, row
, col
;
2750 for (img
= 0; img
< srcDepth
; img
++) {
2751 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2752 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2753 + dstYoffset
* dstRowStride
2754 + dstXoffset
* texelBytes
;
2755 for (row
= 0; row
< srcHeight
; row
++) {
2756 GLuint
*dstUI
= (GLuint
*) dstRow
;
2757 for (col
= 0; col
< srcWidth
; col
++) {
2758 dstUI
[col
] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2759 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2760 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2764 dstRow
+= dstRowStride
;
2767 free((void *) tempImage
);
2775 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or MESA_FORMAT_SIGNED_RGBA8888_REV
2778 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS
)
2780 const GLboolean littleEndian
= _mesa_little_endian();
2781 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
2782 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
2784 ASSERT(dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
||
2785 dstFormat
== MESA_FORMAT_SIGNED_RGBA8888_REV
);
2786 ASSERT(texelBytes
== 4);
2788 if (!ctx
->_ImageTransferState
&&
2789 !srcPacking
->SwapBytes
&&
2790 dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
&&
2791 baseInternalFormat
== GL_RGBA
&&
2792 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& !littleEndian
) ||
2793 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& littleEndian
))) {
2794 /* simple memcpy path */
2795 memcpy_texture(ctx
, dims
,
2796 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2799 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2800 srcAddr
, srcPacking
);
2802 else if (!ctx
->_ImageTransferState
&&
2803 !srcPacking
->SwapBytes
&&
2804 dstFormat
== MESA_FORMAT_SIGNED_RGBA8888_REV
&&
2805 baseInternalFormat
== GL_RGBA
&&
2806 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& littleEndian
) ||
2807 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& !littleEndian
))) {
2808 /* simple memcpy path */
2809 memcpy_texture(ctx
, dims
,
2810 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2813 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2814 srcAddr
, srcPacking
);
2816 else if (!ctx
->_ImageTransferState
&&
2817 (srcType
== GL_BYTE
) &&
2818 can_swizzle(baseInternalFormat
) &&
2819 can_swizzle(srcFormat
)) {
2823 /* dstmap - how to swizzle from RGBA to dst format:
2825 if ((littleEndian
&& dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
) ||
2826 (!littleEndian
&& dstFormat
== MESA_FORMAT_SIGNED_RGBA8888_REV
)) {
2839 _mesa_swizzle_ubyte_image(ctx
, dims
,
2844 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2845 dstRowStride
, dstImageOffsets
,
2846 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2851 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2854 srcWidth
, srcHeight
, srcDepth
,
2855 srcFormat
, srcType
, srcAddr
,
2857 const GLfloat
*srcRow
= tempImage
;
2858 GLint img
, row
, col
;
2861 for (img
= 0; img
< srcDepth
; img
++) {
2862 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2863 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
2864 + dstYoffset
* dstRowStride
2865 + dstXoffset
* texelBytes
;
2866 for (row
= 0; row
< srcHeight
; row
++) {
2867 GLuint
*dstUI
= (GLuint
*) dstRow
;
2868 if (dstFormat
== MESA_FORMAT_SIGNED_RGBA8888
) {
2869 for (col
= 0; col
< srcWidth
; col
++) {
2870 dstUI
[col
] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2871 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2872 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2873 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2878 for (col
= 0; col
< srcWidth
; col
++) {
2879 dstUI
[col
] = PACK_COLOR_8888_REV( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2880 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2881 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2882 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2886 dstRow
+= dstRowStride
;
2889 free((void *) tempImage
);
2896 * Store a combined depth/stencil texture image.
2899 _mesa_texstore_z24_s8(TEXSTORE_PARAMS
)
2901 const GLuint depthScale
= 0xffffff;
2902 const GLint srcRowStride
2903 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2907 ASSERT(dstFormat
== MESA_FORMAT_Z24_S8
);
2908 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
);
2909 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2912 if (srcFormat
!= GL_DEPTH_COMPONENT
&& ctx
->Pixel
.DepthScale
== 1.0f
&&
2913 ctx
->Pixel
.DepthBias
== 0.0f
&&
2914 !srcPacking
->SwapBytes
) {
2916 memcpy_texture(ctx
, dims
,
2917 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2920 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2921 srcAddr
, srcPacking
);
2922 } else if (srcFormat
== GL_DEPTH_COMPONENT
) {
2923 /* In case we only upload depth we need to preserve the stencil */
2924 for (img
= 0; img
< srcDepth
; img
++) {
2925 GLuint
*dstRow
= (GLuint
*) dstAddr
2926 + dstImageOffsets
[dstZoffset
+ img
]
2927 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2930 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2931 srcWidth
, srcHeight
,
2934 for (row
= 0; row
< srcHeight
; row
++) {
2935 GLuint depth
[MAX_WIDTH
];
2936 GLubyte stencil
[MAX_WIDTH
];
2938 GLboolean keepdepth
= GL_FALSE
, keepstencil
= GL_FALSE
;
2940 if (srcFormat
== GL_DEPTH_COMPONENT
) { /* preserve stencil */
2941 keepstencil
= GL_TRUE
;
2942 } else if (srcFormat
== GL_STENCIL_INDEX
) { /* preserve depth */
2943 keepdepth
= GL_TRUE
;
2946 if (keepdepth
== GL_FALSE
)
2947 /* the 24 depth bits will be in the low position: */
2948 _mesa_unpack_depth_span(ctx
, srcWidth
,
2949 GL_UNSIGNED_INT
, /* dst type */
2950 keepstencil
? depth
: dstRow
, /* dst addr */
2952 srcType
, src
, srcPacking
);
2954 if (keepstencil
== GL_FALSE
)
2955 /* get the 8-bit stencil values */
2956 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2957 GL_UNSIGNED_BYTE
, /* dst type */
2958 stencil
, /* dst addr */
2959 srcType
, src
, srcPacking
,
2960 ctx
->_ImageTransferState
);
2962 for (i
= 0; i
< srcWidth
; i
++) {
2964 dstRow
[i
] = depth
[i
] << 8 | (dstRow
[i
] & 0x000000FF);
2966 dstRow
[i
] = (dstRow
[i
] & 0xFFFFFF00) | (stencil
[i
] & 0xFF);
2969 src
+= srcRowStride
;
2970 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2979 * Store a combined depth/stencil texture image.
2982 _mesa_texstore_s8_z24(TEXSTORE_PARAMS
)
2984 const GLuint depthScale
= 0xffffff;
2985 const GLint srcRowStride
2986 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2990 ASSERT(dstFormat
== MESA_FORMAT_S8_Z24
);
2991 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
|| srcFormat
== GL_STENCIL_INDEX
);
2992 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2994 for (img
= 0; img
< srcDepth
; img
++) {
2995 GLuint
*dstRow
= (GLuint
*) dstAddr
2996 + dstImageOffsets
[dstZoffset
+ img
]
2997 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
3000 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
3001 srcWidth
, srcHeight
,
3004 for (row
= 0; row
< srcHeight
; row
++) {
3005 GLuint depth
[MAX_WIDTH
];
3006 GLubyte stencil
[MAX_WIDTH
];
3008 GLboolean keepdepth
= GL_FALSE
, keepstencil
= GL_FALSE
;
3010 if (srcFormat
== GL_DEPTH_COMPONENT
) { /* preserve stencil */
3011 keepstencil
= GL_TRUE
;
3012 } else if (srcFormat
== GL_STENCIL_INDEX
) { /* preserve depth */
3013 keepdepth
= GL_TRUE
;
3016 if (keepdepth
== GL_FALSE
)
3017 /* the 24 depth bits will be in the low position: */
3018 _mesa_unpack_depth_span(ctx
, srcWidth
,
3019 GL_UNSIGNED_INT
, /* dst type */
3020 keepstencil
? depth
: dstRow
, /* dst addr */
3022 srcType
, src
, srcPacking
);
3024 if (keepstencil
== GL_FALSE
)
3025 /* get the 8-bit stencil values */
3026 _mesa_unpack_stencil_span(ctx
, srcWidth
,
3027 GL_UNSIGNED_BYTE
, /* dst type */
3028 stencil
, /* dst addr */
3029 srcType
, src
, srcPacking
,
3030 ctx
->_ImageTransferState
);
3032 /* merge stencil values into depth values */
3033 for (i
= 0; i
< srcWidth
; i
++) {
3035 dstRow
[i
] = depth
[i
] | (dstRow
[i
] & 0xFF000000);
3037 dstRow
[i
] = (dstRow
[i
] & 0xFFFFFF) | (stencil
[i
] << 24);
3040 src
+= srcRowStride
;
3041 dstRow
+= dstRowStride
/ sizeof(GLuint
);
3048 * Store an image in any of the formats:
3049 * _mesa_texformat_rgba_float32
3050 * _mesa_texformat_rgb_float32
3051 * _mesa_texformat_alpha_float32
3052 * _mesa_texformat_luminance_float32
3053 * _mesa_texformat_luminance_alpha_float32
3054 * _mesa_texformat_intensity_float32
3057 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS
)
3059 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
3060 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
3061 const GLint components
= _mesa_components_in_format(baseFormat
);
3063 ASSERT(dstFormat
== MESA_FORMAT_RGBA_FLOAT32
||
3064 dstFormat
== MESA_FORMAT_RGB_FLOAT32
||
3065 dstFormat
== MESA_FORMAT_ALPHA_FLOAT32
||
3066 dstFormat
== MESA_FORMAT_LUMINANCE_FLOAT32
||
3067 dstFormat
== MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32
||
3068 dstFormat
== MESA_FORMAT_INTENSITY_FLOAT32
);
3069 ASSERT(baseInternalFormat
== GL_RGBA
||
3070 baseInternalFormat
== GL_RGB
||
3071 baseInternalFormat
== GL_ALPHA
||
3072 baseInternalFormat
== GL_LUMINANCE
||
3073 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
3074 baseInternalFormat
== GL_INTENSITY
);
3075 ASSERT(texelBytes
== components
* sizeof(GLfloat
));
3077 if (!ctx
->_ImageTransferState
&&
3078 !srcPacking
->SwapBytes
&&
3079 baseInternalFormat
== srcFormat
&&
3080 srcType
== GL_FLOAT
) {
3081 /* simple memcpy path */
3082 memcpy_texture(ctx
, dims
,
3083 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3086 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
3087 srcAddr
, srcPacking
);
3091 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
3094 srcWidth
, srcHeight
, srcDepth
,
3095 srcFormat
, srcType
, srcAddr
,
3097 const GLfloat
*srcRow
= tempImage
;
3102 bytesPerRow
= srcWidth
* components
* sizeof(GLfloat
);
3103 for (img
= 0; img
< srcDepth
; img
++) {
3104 GLubyte
*dstRow
= (GLubyte
*) dstAddr
3105 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
3106 + dstYoffset
* dstRowStride
3107 + dstXoffset
* texelBytes
;
3108 for (row
= 0; row
< srcHeight
; row
++) {
3109 memcpy(dstRow
, srcRow
, bytesPerRow
);
3110 dstRow
+= dstRowStride
;
3111 srcRow
+= srcWidth
* components
;
3115 free((void *) tempImage
);
3121 _mesa_texstore_s8(TEXSTORE_PARAMS
)
3123 ASSERT(dstFormat
== MESA_FORMAT_S8
);
3124 ASSERT(srcFormat
== GL_STENCIL_INDEX
);
3125 ASSERT(texelBytes
== 1);
3127 if (!ctx
->_ImageTransferState
&&
3128 !srcPacking
->SwapBytes
&&
3129 baseInternalFormat
== srcFormat
&&
3130 srcType
== GL_UNSIGNED_BYTE
) {
3131 /* simple memcpy path */
3132 memcpy_texture(ctx
, dims
,
3133 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3136 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
3137 srcAddr
, srcPacking
);
3139 const GLint srcRowStride
3140 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
3144 for (img
= 0; img
< srcDepth
; img
++) {
3145 GLubyte
*dstRow
= (GLubyte
*) dstAddr
3146 + dstImageOffsets
[dstZoffset
+ img
]
3147 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
3150 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
3151 srcWidth
, srcHeight
,
3154 for (row
= 0; row
< srcHeight
; row
++) {
3155 GLubyte stencil
[MAX_WIDTH
];
3158 /* get the 8-bit stencil values */
3159 _mesa_unpack_stencil_span(ctx
, srcWidth
,
3160 GL_UNSIGNED_BYTE
, /* dst type */
3161 stencil
, /* dst addr */
3162 srcType
, src
, srcPacking
,
3163 ctx
->_ImageTransferState
);
3164 /* merge stencil values into depth values */
3165 for (i
= 0; i
< srcWidth
; i
++)
3166 dstRow
[i
] = stencil
[i
];
3168 src
+= srcRowStride
;
3169 dstRow
+= dstRowStride
/ sizeof(GLubyte
);
3179 * As above, but store 16-bit floats.
3182 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS
)
3184 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
3185 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
3186 const GLint components
= _mesa_components_in_format(baseFormat
);
3188 ASSERT(dstFormat
== MESA_FORMAT_RGBA_FLOAT16
||
3189 dstFormat
== MESA_FORMAT_RGB_FLOAT16
||
3190 dstFormat
== MESA_FORMAT_ALPHA_FLOAT16
||
3191 dstFormat
== MESA_FORMAT_LUMINANCE_FLOAT16
||
3192 dstFormat
== MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16
||
3193 dstFormat
== MESA_FORMAT_INTENSITY_FLOAT16
);
3194 ASSERT(baseInternalFormat
== GL_RGBA
||
3195 baseInternalFormat
== GL_RGB
||
3196 baseInternalFormat
== GL_ALPHA
||
3197 baseInternalFormat
== GL_LUMINANCE
||
3198 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
3199 baseInternalFormat
== GL_INTENSITY
);
3200 ASSERT(texelBytes
== components
* sizeof(GLhalfARB
));
3202 if (!ctx
->_ImageTransferState
&&
3203 !srcPacking
->SwapBytes
&&
3204 baseInternalFormat
== srcFormat
&&
3205 srcType
== GL_HALF_FLOAT_ARB
) {
3206 /* simple memcpy path */
3207 memcpy_texture(ctx
, dims
,
3208 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3211 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
3212 srcAddr
, srcPacking
);
3216 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
3219 srcWidth
, srcHeight
, srcDepth
,
3220 srcFormat
, srcType
, srcAddr
,
3222 const GLfloat
*src
= tempImage
;
3226 for (img
= 0; img
< srcDepth
; img
++) {
3227 GLubyte
*dstRow
= (GLubyte
*) dstAddr
3228 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
3229 + dstYoffset
* dstRowStride
3230 + dstXoffset
* texelBytes
;
3231 for (row
= 0; row
< srcHeight
; row
++) {
3232 GLhalfARB
*dstTexel
= (GLhalfARB
*) dstRow
;
3234 for (i
= 0; i
< srcWidth
* components
; i
++) {
3235 dstTexel
[i
] = _mesa_float_to_half(src
[i
]);
3237 dstRow
+= dstRowStride
;
3238 src
+= srcWidth
* components
;
3242 free((void *) tempImage
);
3248 /* non-normalized, signed int8 */
3250 _mesa_texstore_rgba_int8(TEXSTORE_PARAMS
)
3252 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
3253 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
3254 const GLint components
= _mesa_components_in_format(baseFormat
);
3256 ASSERT(dstFormat
== MESA_FORMAT_RGBA_INT8
);
3257 ASSERT(baseInternalFormat
== GL_RGBA
||
3258 baseInternalFormat
== GL_RGB
||
3259 baseInternalFormat
== GL_ALPHA
||
3260 baseInternalFormat
== GL_LUMINANCE
||
3261 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
3262 baseInternalFormat
== GL_INTENSITY
);
3263 ASSERT(texelBytes
== components
* sizeof(GLbyte
));
3265 if (!ctx
->_ImageTransferState
&&
3266 !srcPacking
->SwapBytes
&&
3267 baseInternalFormat
== srcFormat
&&
3268 srcType
== GL_BYTE
) {
3269 /* simple memcpy path */
3270 memcpy_texture(ctx
, dims
,
3271 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3274 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
3275 srcAddr
, srcPacking
);
3279 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
3282 srcWidth
, srcHeight
, srcDepth
,
3283 srcFormat
, srcType
, srcAddr
,
3285 const GLfloat
*src
= tempImage
;
3289 for (img
= 0; img
< srcDepth
; img
++) {
3290 GLubyte
*dstRow
= (GLubyte
*) dstAddr
3291 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
3292 + dstYoffset
* dstRowStride
3293 + dstXoffset
* texelBytes
;
3294 for (row
= 0; row
< srcHeight
; row
++) {
3295 GLbyte
*dstTexel
= (GLbyte
*) dstRow
;
3297 for (i
= 0; i
< srcWidth
* components
; i
++) {
3298 dstTexel
[i
] = (GLbyte
) src
[i
];
3300 dstRow
+= dstRowStride
;
3301 src
+= srcWidth
* components
;
3305 free((void *) tempImage
);
3311 /* non-normalized, signed int16 */
3313 _mesa_texstore_rgba_int16(TEXSTORE_PARAMS
)
3315 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
3316 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
3317 const GLint components
= _mesa_components_in_format(baseFormat
);
3319 ASSERT(dstFormat
== MESA_FORMAT_RGBA_INT16
);
3320 ASSERT(baseInternalFormat
== GL_RGBA
||
3321 baseInternalFormat
== GL_RGB
||
3322 baseInternalFormat
== GL_ALPHA
||
3323 baseInternalFormat
== GL_LUMINANCE
||
3324 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
3325 baseInternalFormat
== GL_INTENSITY
);
3326 ASSERT(texelBytes
== components
* sizeof(GLshort
));
3328 if (!ctx
->_ImageTransferState
&&
3329 !srcPacking
->SwapBytes
&&
3330 baseInternalFormat
== srcFormat
&&
3331 srcType
== GL_INT
) {
3332 /* simple memcpy path */
3333 memcpy_texture(ctx
, dims
,
3334 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3337 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
3338 srcAddr
, srcPacking
);
3342 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
3345 srcWidth
, srcHeight
, srcDepth
,
3346 srcFormat
, srcType
, srcAddr
,
3348 const GLfloat
*src
= tempImage
;
3352 for (img
= 0; img
< srcDepth
; img
++) {
3353 GLubyte
*dstRow
= (GLubyte
*) dstAddr
3354 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
3355 + dstYoffset
* dstRowStride
3356 + dstXoffset
* texelBytes
;
3357 for (row
= 0; row
< srcHeight
; row
++) {
3358 GLshort
*dstTexel
= (GLshort
*) dstRow
;
3360 for (i
= 0; i
< srcWidth
* components
; i
++) {
3361 dstTexel
[i
] = (GLint
) src
[i
];
3363 dstRow
+= dstRowStride
;
3364 src
+= srcWidth
* components
;
3368 free((void *) tempImage
);
3374 /* non-normalized, signed int32 */
3376 _mesa_texstore_rgba_int32(TEXSTORE_PARAMS
)
3378 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
3379 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
3380 const GLint components
= _mesa_components_in_format(baseFormat
);
3382 ASSERT(dstFormat
== MESA_FORMAT_RGBA_INT32
);
3383 ASSERT(baseInternalFormat
== GL_RGBA
||
3384 baseInternalFormat
== GL_RGB
||
3385 baseInternalFormat
== GL_ALPHA
||
3386 baseInternalFormat
== GL_LUMINANCE
||
3387 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
3388 baseInternalFormat
== GL_INTENSITY
);
3389 ASSERT(texelBytes
== components
* sizeof(GLint
));
3391 if (!ctx
->_ImageTransferState
&&
3392 !srcPacking
->SwapBytes
&&
3393 baseInternalFormat
== srcFormat
&&
3394 srcType
== GL_INT
) {
3395 /* simple memcpy path */
3396 memcpy_texture(ctx
, dims
,
3397 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3400 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
3401 srcAddr
, srcPacking
);
3405 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
3408 srcWidth
, srcHeight
, srcDepth
,
3409 srcFormat
, srcType
, srcAddr
,
3411 const GLfloat
*src
= tempImage
;
3415 for (img
= 0; img
< srcDepth
; img
++) {
3416 GLubyte
*dstRow
= (GLubyte
*) dstAddr
3417 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
3418 + dstYoffset
* dstRowStride
3419 + dstXoffset
* texelBytes
;
3420 for (row
= 0; row
< srcHeight
; row
++) {
3421 GLint
*dstTexel
= (GLint
*) dstRow
;
3423 for (i
= 0; i
< srcWidth
* components
; i
++) {
3424 dstTexel
[i
] = (GLint
) src
[i
];
3426 dstRow
+= dstRowStride
;
3427 src
+= srcWidth
* components
;
3431 free((void *) tempImage
);
3437 /* non-normalized, unsigned int8 */
3439 _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS
)
3441 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
3442 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
3443 const GLint components
= _mesa_components_in_format(baseFormat
);
3445 ASSERT(dstFormat
== MESA_FORMAT_RGBA_UINT8
);
3446 ASSERT(baseInternalFormat
== GL_RGBA
||
3447 baseInternalFormat
== GL_RGB
||
3448 baseInternalFormat
== GL_ALPHA
||
3449 baseInternalFormat
== GL_LUMINANCE
||
3450 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
3451 baseInternalFormat
== GL_INTENSITY
);
3452 ASSERT(texelBytes
== components
* sizeof(GLubyte
));
3454 if (!ctx
->_ImageTransferState
&&
3455 !srcPacking
->SwapBytes
&&
3456 baseInternalFormat
== srcFormat
&&
3457 srcType
== GL_UNSIGNED_BYTE
) {
3458 /* simple memcpy path */
3459 memcpy_texture(ctx
, dims
,
3460 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3463 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
3464 srcAddr
, srcPacking
);
3468 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
3471 srcWidth
, srcHeight
, srcDepth
,
3472 srcFormat
, srcType
, srcAddr
,
3474 const GLfloat
*src
= tempImage
;
3478 for (img
= 0; img
< srcDepth
; img
++) {
3479 GLubyte
*dstRow
= (GLubyte
*) dstAddr
3480 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
3481 + dstYoffset
* dstRowStride
3482 + dstXoffset
* texelBytes
;
3483 for (row
= 0; row
< srcHeight
; row
++) {
3484 GLubyte
*dstTexel
= (GLubyte
*) dstRow
;
3486 for (i
= 0; i
< srcWidth
* components
; i
++) {
3487 dstTexel
[i
] = (GLubyte
) src
[i
];
3489 dstRow
+= dstRowStride
;
3490 src
+= srcWidth
* components
;
3494 free((void *) tempImage
);
3500 /* non-normalized, unsigned int16 */
3502 _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS
)
3504 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
3505 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
3506 const GLint components
= _mesa_components_in_format(baseFormat
);
3508 ASSERT(dstFormat
== MESA_FORMAT_RGBA_UINT16
);
3509 ASSERT(baseInternalFormat
== GL_RGBA
||
3510 baseInternalFormat
== GL_RGB
||
3511 baseInternalFormat
== GL_ALPHA
||
3512 baseInternalFormat
== GL_LUMINANCE
||
3513 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
3514 baseInternalFormat
== GL_INTENSITY
);
3515 ASSERT(texelBytes
== components
* sizeof(GLushort
));
3517 if (!ctx
->_ImageTransferState
&&
3518 !srcPacking
->SwapBytes
&&
3519 baseInternalFormat
== srcFormat
&&
3520 srcType
== GL_UNSIGNED_SHORT
) {
3521 /* simple memcpy path */
3522 memcpy_texture(ctx
, dims
,
3523 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3526 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
3527 srcAddr
, srcPacking
);
3531 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
3534 srcWidth
, srcHeight
, srcDepth
,
3535 srcFormat
, srcType
, srcAddr
,
3537 const GLfloat
*src
= tempImage
;
3541 for (img
= 0; img
< srcDepth
; img
++) {
3542 GLubyte
*dstRow
= (GLubyte
*) dstAddr
3543 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
3544 + dstYoffset
* dstRowStride
3545 + dstXoffset
* texelBytes
;
3546 for (row
= 0; row
< srcHeight
; row
++) {
3547 GLushort
*dstTexel
= (GLushort
*) dstRow
;
3549 for (i
= 0; i
< srcWidth
* components
; i
++) {
3550 dstTexel
[i
] = (GLushort
) src
[i
];
3552 dstRow
+= dstRowStride
;
3553 src
+= srcWidth
* components
;
3557 free((void *) tempImage
);
3563 /* non-normalized, unsigned int32 */
3565 _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS
)
3567 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
3568 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
3569 const GLint components
= _mesa_components_in_format(baseFormat
);
3571 ASSERT(dstFormat
== MESA_FORMAT_RGBA_UINT32
);
3572 ASSERT(baseInternalFormat
== GL_RGBA
||
3573 baseInternalFormat
== GL_RGB
||
3574 baseInternalFormat
== GL_ALPHA
||
3575 baseInternalFormat
== GL_LUMINANCE
||
3576 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
3577 baseInternalFormat
== GL_INTENSITY
);
3578 ASSERT(texelBytes
== components
* sizeof(GLuint
));
3580 if (!ctx
->_ImageTransferState
&&
3581 !srcPacking
->SwapBytes
&&
3582 baseInternalFormat
== srcFormat
&&
3583 srcType
== GL_UNSIGNED_INT
) {
3584 /* simple memcpy path */
3585 memcpy_texture(ctx
, dims
,
3586 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3589 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
3590 srcAddr
, srcPacking
);
3594 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
3597 srcWidth
, srcHeight
, srcDepth
,
3598 srcFormat
, srcType
, srcAddr
,
3600 const GLfloat
*src
= tempImage
;
3604 for (img
= 0; img
< srcDepth
; img
++) {
3605 GLubyte
*dstRow
= (GLubyte
*) dstAddr
3606 + dstImageOffsets
[dstZoffset
+ img
] * texelBytes
3607 + dstYoffset
* dstRowStride
3608 + dstXoffset
* texelBytes
;
3609 for (row
= 0; row
< srcHeight
; row
++) {
3610 GLuint
*dstTexel
= (GLuint
*) dstRow
;
3612 for (i
= 0; i
< srcWidth
* components
; i
++) {
3613 dstTexel
[i
] = (GLuint
) src
[i
];
3615 dstRow
+= dstRowStride
;
3616 src
+= srcWidth
* components
;
3620 free((void *) tempImage
);
3628 #if FEATURE_EXT_texture_sRGB
3630 _mesa_texstore_srgb8(TEXSTORE_PARAMS
)
3632 gl_format newDstFormat
;
3635 ASSERT(dstFormat
== MESA_FORMAT_SRGB8
);
3637 /* reuse normal rgb texstore code */
3638 newDstFormat
= MESA_FORMAT_RGB888
;
3640 k
= _mesa_texstore_rgb888(ctx
, dims
, baseInternalFormat
,
3641 newDstFormat
, dstAddr
,
3642 dstXoffset
, dstYoffset
, dstZoffset
,
3643 dstRowStride
, dstImageOffsets
,
3644 srcWidth
, srcHeight
, srcDepth
,
3646 srcAddr
, srcPacking
);
3652 _mesa_texstore_srgba8(TEXSTORE_PARAMS
)
3654 gl_format newDstFormat
;
3657 ASSERT(dstFormat
== MESA_FORMAT_SRGBA8
);
3659 /* reuse normal rgba texstore code */
3660 newDstFormat
= MESA_FORMAT_RGBA8888
;
3661 k
= _mesa_texstore_rgba8888(ctx
, dims
, baseInternalFormat
,
3662 newDstFormat
, dstAddr
,
3663 dstXoffset
, dstYoffset
, dstZoffset
,
3664 dstRowStride
, dstImageOffsets
,
3665 srcWidth
, srcHeight
, srcDepth
,
3667 srcAddr
, srcPacking
);
3673 _mesa_texstore_sargb8(TEXSTORE_PARAMS
)
3675 gl_format newDstFormat
;
3678 ASSERT(dstFormat
== MESA_FORMAT_SARGB8
);
3680 /* reuse normal rgba texstore code */
3681 newDstFormat
= MESA_FORMAT_ARGB8888
;
3683 k
= _mesa_texstore_argb8888(ctx
, dims
, baseInternalFormat
,
3684 newDstFormat
, dstAddr
,
3685 dstXoffset
, dstYoffset
, dstZoffset
,
3686 dstRowStride
, dstImageOffsets
,
3687 srcWidth
, srcHeight
, srcDepth
,
3689 srcAddr
, srcPacking
);
3695 _mesa_texstore_sl8(TEXSTORE_PARAMS
)
3697 gl_format newDstFormat
;
3700 ASSERT(dstFormat
== MESA_FORMAT_SL8
);
3702 newDstFormat
= MESA_FORMAT_L8
;
3704 /* _mesa_textore_a8 handles luminance8 too */
3705 k
= _mesa_texstore_a8(ctx
, dims
, baseInternalFormat
,
3706 newDstFormat
, dstAddr
,
3707 dstXoffset
, dstYoffset
, dstZoffset
,
3708 dstRowStride
, dstImageOffsets
,
3709 srcWidth
, srcHeight
, srcDepth
,
3711 srcAddr
, srcPacking
);
3717 _mesa_texstore_sla8(TEXSTORE_PARAMS
)
3719 gl_format newDstFormat
;
3722 ASSERT(dstFormat
== MESA_FORMAT_SLA8
);
3724 /* reuse normal luminance/alpha texstore code */
3725 newDstFormat
= MESA_FORMAT_AL88
;
3727 k
= _mesa_texstore_unorm88(ctx
, dims
, baseInternalFormat
,
3728 newDstFormat
, dstAddr
,
3729 dstXoffset
, dstYoffset
, dstZoffset
,
3730 dstRowStride
, dstImageOffsets
,
3731 srcWidth
, srcHeight
, srcDepth
,
3733 srcAddr
, srcPacking
);
3739 /* these are used only in texstore_funcs[] below */
3740 #define _mesa_texstore_srgb8 NULL
3741 #define _mesa_texstore_srgba8 NULL
3742 #define _mesa_texstore_sargb8 NULL
3743 #define _mesa_texstore_sl8 NULL
3744 #define _mesa_texstore_sla8 NULL
3746 #endif /* FEATURE_EXT_texture_sRGB */
3752 * Table mapping MESA_FORMAT_8 to _mesa_texstore_*()
3753 * XXX this is somewhat temporary.
3755 static const struct {
3757 StoreTexImageFunc Store
;
3759 texstore_funcs
[MESA_FORMAT_COUNT
] =
3761 { MESA_FORMAT_NONE
, NULL
},
3762 { MESA_FORMAT_RGBA8888
, _mesa_texstore_rgba8888
},
3763 { MESA_FORMAT_RGBA8888_REV
, _mesa_texstore_rgba8888
},
3764 { MESA_FORMAT_ARGB8888
, _mesa_texstore_argb8888
},
3765 { MESA_FORMAT_ARGB8888_REV
, _mesa_texstore_argb8888
},
3766 { MESA_FORMAT_XRGB8888
, _mesa_texstore_argb8888
},
3767 { MESA_FORMAT_XRGB8888_REV
, _mesa_texstore_argb8888
},
3768 { MESA_FORMAT_RGB888
, _mesa_texstore_rgb888
},
3769 { MESA_FORMAT_BGR888
, _mesa_texstore_bgr888
},
3770 { MESA_FORMAT_RGB565
, _mesa_texstore_rgb565
},
3771 { MESA_FORMAT_RGB565_REV
, _mesa_texstore_rgb565
},
3772 { MESA_FORMAT_ARGB4444
, _mesa_texstore_argb4444
},
3773 { MESA_FORMAT_ARGB4444_REV
, _mesa_texstore_argb4444
},
3774 { MESA_FORMAT_RGBA5551
, _mesa_texstore_rgba5551
},
3775 { MESA_FORMAT_ARGB1555
, _mesa_texstore_argb1555
},
3776 { MESA_FORMAT_ARGB1555_REV
, _mesa_texstore_argb1555
},
3777 { MESA_FORMAT_AL88
, _mesa_texstore_unorm88
},
3778 { MESA_FORMAT_AL88_REV
, _mesa_texstore_unorm88
},
3779 { MESA_FORMAT_AL1616
, _mesa_texstore_unorm1616
},
3780 { MESA_FORMAT_AL1616_REV
, _mesa_texstore_unorm1616
},
3781 { MESA_FORMAT_RGB332
, _mesa_texstore_rgb332
},
3782 { MESA_FORMAT_A8
, _mesa_texstore_a8
},
3783 { MESA_FORMAT_L8
, _mesa_texstore_a8
},
3784 { MESA_FORMAT_I8
, _mesa_texstore_a8
},
3785 { MESA_FORMAT_CI8
, _mesa_texstore_ci8
},
3786 { MESA_FORMAT_YCBCR
, _mesa_texstore_ycbcr
},
3787 { MESA_FORMAT_YCBCR_REV
, _mesa_texstore_ycbcr
},
3788 { MESA_FORMAT_R8
, _mesa_texstore_a8
},
3789 { MESA_FORMAT_RG88
, _mesa_texstore_unorm88
},
3790 { MESA_FORMAT_RG88_REV
, _mesa_texstore_unorm88
},
3791 { MESA_FORMAT_R16
, _mesa_texstore_r16
},
3792 { MESA_FORMAT_RG1616
, _mesa_texstore_unorm1616
},
3793 { MESA_FORMAT_RG1616_REV
, _mesa_texstore_unorm1616
},
3794 { MESA_FORMAT_Z24_S8
, _mesa_texstore_z24_s8
},
3795 { MESA_FORMAT_S8_Z24
, _mesa_texstore_s8_z24
},
3796 { MESA_FORMAT_Z16
, _mesa_texstore_z16
},
3797 { MESA_FORMAT_X8_Z24
, _mesa_texstore_x8_z24
},
3798 { MESA_FORMAT_Z24_X8
, _mesa_texstore_z24_x8
},
3799 { MESA_FORMAT_Z32
, _mesa_texstore_z32
},
3800 { MESA_FORMAT_S8
, _mesa_texstore_s8
},
3801 { MESA_FORMAT_SRGB8
, _mesa_texstore_srgb8
},
3802 { MESA_FORMAT_SRGBA8
, _mesa_texstore_srgba8
},
3803 { MESA_FORMAT_SARGB8
, _mesa_texstore_sargb8
},
3804 { MESA_FORMAT_SL8
, _mesa_texstore_sl8
},
3805 { MESA_FORMAT_SLA8
, _mesa_texstore_sla8
},
3806 { MESA_FORMAT_SRGB_DXT1
, _mesa_texstore_rgb_dxt1
},
3807 { MESA_FORMAT_SRGBA_DXT1
, _mesa_texstore_rgba_dxt1
},
3808 { MESA_FORMAT_SRGBA_DXT3
, _mesa_texstore_rgba_dxt3
},
3809 { MESA_FORMAT_SRGBA_DXT5
, _mesa_texstore_rgba_dxt5
},
3810 { MESA_FORMAT_RGB_FXT1
, _mesa_texstore_rgb_fxt1
},
3811 { MESA_FORMAT_RGBA_FXT1
, _mesa_texstore_rgba_fxt1
},
3812 { MESA_FORMAT_RGB_DXT1
, _mesa_texstore_rgb_dxt1
},
3813 { MESA_FORMAT_RGBA_DXT1
, _mesa_texstore_rgba_dxt1
},
3814 { MESA_FORMAT_RGBA_DXT3
, _mesa_texstore_rgba_dxt3
},
3815 { MESA_FORMAT_RGBA_DXT5
, _mesa_texstore_rgba_dxt5
},
3816 { MESA_FORMAT_RGBA_FLOAT32
, _mesa_texstore_rgba_float32
},
3817 { MESA_FORMAT_RGBA_FLOAT16
, _mesa_texstore_rgba_float16
},
3818 { MESA_FORMAT_RGB_FLOAT32
, _mesa_texstore_rgba_float32
},
3819 { MESA_FORMAT_RGB_FLOAT16
, _mesa_texstore_rgba_float16
},
3820 { MESA_FORMAT_ALPHA_FLOAT32
, _mesa_texstore_rgba_float32
},
3821 { MESA_FORMAT_ALPHA_FLOAT16
, _mesa_texstore_rgba_float16
},
3822 { MESA_FORMAT_LUMINANCE_FLOAT32
, _mesa_texstore_rgba_float32
},
3823 { MESA_FORMAT_LUMINANCE_FLOAT16
, _mesa_texstore_rgba_float16
},
3824 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32
, _mesa_texstore_rgba_float32
},
3825 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16
, _mesa_texstore_rgba_float16
},
3826 { MESA_FORMAT_INTENSITY_FLOAT32
, _mesa_texstore_rgba_float32
},
3827 { MESA_FORMAT_INTENSITY_FLOAT16
, _mesa_texstore_rgba_float16
},
3829 { MESA_FORMAT_RGBA_INT8
, _mesa_texstore_rgba_int8
},
3830 { MESA_FORMAT_RGBA_INT16
, _mesa_texstore_rgba_int16
},
3831 { MESA_FORMAT_RGBA_INT32
, _mesa_texstore_rgba_int32
},
3832 { MESA_FORMAT_RGBA_UINT8
, _mesa_texstore_rgba_uint8
},
3833 { MESA_FORMAT_RGBA_UINT16
, _mesa_texstore_rgba_uint16
},
3834 { MESA_FORMAT_RGBA_UINT32
, _mesa_texstore_rgba_uint32
},
3836 { MESA_FORMAT_DUDV8
, _mesa_texstore_dudv8
},
3838 { MESA_FORMAT_SIGNED_R8
, _mesa_texstore_signed_r8
},
3839 { MESA_FORMAT_SIGNED_RG88
, _mesa_texstore_signed_rg88
},
3840 { MESA_FORMAT_SIGNED_RGBX8888
, _mesa_texstore_signed_rgbx8888
},
3842 { MESA_FORMAT_SIGNED_RGBA8888
, _mesa_texstore_signed_rgba8888
},
3843 { MESA_FORMAT_SIGNED_RGBA8888_REV
, _mesa_texstore_signed_rgba8888
},
3845 { MESA_FORMAT_SIGNED_R_16
, _mesa_texstore_signed_rgba_16
},
3846 { MESA_FORMAT_SIGNED_RG_16
, _mesa_texstore_signed_rgba_16
},
3847 { MESA_FORMAT_SIGNED_RGB_16
, _mesa_texstore_signed_rgba_16
},
3848 { MESA_FORMAT_SIGNED_RGBA_16
, _mesa_texstore_signed_rgba_16
},
3849 { MESA_FORMAT_RGBA_16
, _mesa_texstore_rgba_16
}
3854 _mesa_texstore_null(TEXSTORE_PARAMS
)
3856 (void) ctx
; (void) dims
;
3857 (void) baseInternalFormat
;
3860 (void) dstXoffset
; (void) dstYoffset
; (void) dstZoffset
;
3861 (void) dstRowStride
; (void) dstImageOffsets
;
3862 (void) srcWidth
; (void) srcHeight
; (void) srcDepth
;
3863 (void) srcFormat
; (void) srcType
;
3867 /* should never happen */
3868 _mesa_problem(NULL
, "_mesa_texstore_null() is called");
3874 * Return the StoreTexImageFunc pointer to store an image in the given format.
3876 static StoreTexImageFunc
3877 _mesa_get_texstore_func(gl_format format
)
3881 for (i
= 0; i
< MESA_FORMAT_COUNT
; i
++) {
3882 ASSERT(texstore_funcs
[i
].Name
== i
);
3885 ASSERT(texstore_funcs
[format
].Name
== format
);
3887 if (texstore_funcs
[format
].Store
)
3888 return texstore_funcs
[format
].Store
;
3890 return _mesa_texstore_null
;
3895 * Store user data into texture memory.
3896 * Called via glTex[Sub]Image1/2/3D()
3899 _mesa_texstore(TEXSTORE_PARAMS
)
3901 StoreTexImageFunc storeImage
;
3904 storeImage
= _mesa_get_texstore_func(dstFormat
);
3906 success
= storeImage(ctx
, dims
, baseInternalFormat
,
3907 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
3908 dstRowStride
, dstImageOffsets
,
3909 srcWidth
, srcHeight
, srcDepth
,
3910 srcFormat
, srcType
, srcAddr
, srcPacking
);
3916 * Check if an unpack PBO is active prior to fetching a texture image.
3917 * If so, do bounds checking and map the buffer into main memory.
3918 * Any errors detected will be recorded.
3919 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3922 _mesa_validate_pbo_teximage(GLcontext
*ctx
, GLuint dimensions
,
3923 GLsizei width
, GLsizei height
, GLsizei depth
,
3924 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3925 const struct gl_pixelstore_attrib
*unpack
,
3926 const char *funcName
)
3930 if (!_mesa_is_bufferobj(unpack
->BufferObj
)) {
3934 if (!_mesa_validate_pbo_access(dimensions
, unpack
, width
, height
, depth
,
3935 format
, type
, pixels
)) {
3936 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3940 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3941 GL_READ_ONLY_ARB
, unpack
->BufferObj
);
3943 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3947 return ADD_POINTERS(buf
, pixels
);
3952 * Check if an unpack PBO is active prior to fetching a compressed texture
3954 * If so, do bounds checking and map the buffer into main memory.
3955 * Any errors detected will be recorded.
3956 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3959 _mesa_validate_pbo_compressed_teximage(GLcontext
*ctx
,
3960 GLsizei imageSize
, const GLvoid
*pixels
,
3961 const struct gl_pixelstore_attrib
*packing
,
3962 const char *funcName
)
3966 if (!_mesa_is_bufferobj(packing
->BufferObj
)) {
3967 /* not using a PBO - return pointer unchanged */
3970 if ((const GLubyte
*) pixels
+ imageSize
>
3971 ((const GLubyte
*) 0) + packing
->BufferObj
->Size
) {
3972 /* out of bounds read! */
3973 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3977 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3978 GL_READ_ONLY_ARB
, packing
->BufferObj
);
3980 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3984 return ADD_POINTERS(buf
, pixels
);
3989 * This function must be called after either of the validate_pbo_*_teximage()
3990 * functions. It unmaps the PBO buffer if it was mapped earlier.
3993 _mesa_unmap_teximage_pbo(GLcontext
*ctx
,
3994 const struct gl_pixelstore_attrib
*unpack
)
3996 if (_mesa_is_bufferobj(unpack
->BufferObj
)) {
3997 ctx
->Driver
.UnmapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
4003 /** Return texture size in bytes */
4005 texture_size(const struct gl_texture_image
*texImage
)
4007 GLuint sz
= _mesa_format_image_size(texImage
->TexFormat
, texImage
->Width
,
4008 texImage
->Height
, texImage
->Depth
);
4013 /** Return row stride in bytes */
4015 texture_row_stride(const struct gl_texture_image
*texImage
)
4017 GLuint stride
= _mesa_format_row_stride(texImage
->TexFormat
,
4025 * This is the software fallback for Driver.TexImage1D()
4026 * and Driver.CopyTexImage1D().
4027 * \sa _mesa_store_teximage2d()
4030 _mesa_store_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
4031 GLint internalFormat
,
4032 GLint width
, GLint border
,
4033 GLenum format
, GLenum type
, const GLvoid
*pixels
,
4034 const struct gl_pixelstore_attrib
*packing
,
4035 struct gl_texture_object
*texObj
,
4036 struct gl_texture_image
*texImage
)
4041 /* allocate memory */
4042 sizeInBytes
= texture_size(texImage
);
4043 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
4044 if (!texImage
->Data
) {
4045 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
4049 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
4050 pixels
, packing
, "glTexImage1D");
4052 /* Note: we check for a NULL image pointer here, _after_ we allocated
4053 * memory for the texture. That's what the GL spec calls for.
4058 const GLint dstRowStride
= 0;
4059 GLboolean success
= _mesa_texstore(ctx
, 1, texImage
->_BaseFormat
,
4060 texImage
->TexFormat
,
4062 0, 0, 0, /* dstX/Y/Zoffset */
4064 texImage
->ImageOffsets
,
4066 format
, type
, pixels
, packing
);
4068 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
4072 _mesa_unmap_teximage_pbo(ctx
, packing
);
4077 * This is the software fallback for Driver.TexImage2D()
4078 * and Driver.CopyTexImage2D().
4080 * This function is oriented toward storing images in main memory, rather
4081 * than VRAM. Device driver's can easily plug in their own replacement.
4084 _mesa_store_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
4085 GLint internalFormat
,
4086 GLint width
, GLint height
, GLint border
,
4087 GLenum format
, GLenum type
, const void *pixels
,
4088 const struct gl_pixelstore_attrib
*packing
,
4089 struct gl_texture_object
*texObj
,
4090 struct gl_texture_image
*texImage
)
4095 /* allocate memory */
4096 sizeInBytes
= texture_size(texImage
);
4097 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
4098 if (!texImage
->Data
) {
4099 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
4103 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
4104 pixels
, packing
, "glTexImage2D");
4106 /* Note: we check for a NULL image pointer here, _after_ we allocated
4107 * memory for the texture. That's what the GL spec calls for.
4112 GLint dstRowStride
= texture_row_stride(texImage
);
4113 GLboolean success
= _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
4114 texImage
->TexFormat
,
4116 0, 0, 0, /* dstX/Y/Zoffset */
4118 texImage
->ImageOffsets
,
4120 format
, type
, pixels
, packing
);
4122 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
4126 _mesa_unmap_teximage_pbo(ctx
, packing
);
4132 * This is the software fallback for Driver.TexImage3D()
4133 * and Driver.CopyTexImage3D().
4134 * \sa _mesa_store_teximage2d()
4137 _mesa_store_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
4138 GLint internalFormat
,
4139 GLint width
, GLint height
, GLint depth
, GLint border
,
4140 GLenum format
, GLenum type
, const void *pixels
,
4141 const struct gl_pixelstore_attrib
*packing
,
4142 struct gl_texture_object
*texObj
,
4143 struct gl_texture_image
*texImage
)
4148 /* allocate memory */
4149 sizeInBytes
= texture_size(texImage
);
4150 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
4151 if (!texImage
->Data
) {
4152 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
4156 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
4157 type
, pixels
, packing
, "glTexImage3D");
4159 /* Note: we check for a NULL image pointer here, _after_ we allocated
4160 * memory for the texture. That's what the GL spec calls for.
4165 GLint dstRowStride
= texture_row_stride(texImage
);
4166 GLboolean success
= _mesa_texstore(ctx
, 3, texImage
->_BaseFormat
,
4167 texImage
->TexFormat
,
4169 0, 0, 0, /* dstX/Y/Zoffset */
4171 texImage
->ImageOffsets
,
4172 width
, height
, depth
,
4173 format
, type
, pixels
, packing
);
4175 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
4179 _mesa_unmap_teximage_pbo(ctx
, packing
);
4186 * This is the software fallback for Driver.TexSubImage1D()
4187 * and Driver.CopyTexSubImage1D().
4190 _mesa_store_texsubimage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
4191 GLint xoffset
, GLint width
,
4192 GLenum format
, GLenum type
, const void *pixels
,
4193 const struct gl_pixelstore_attrib
*packing
,
4194 struct gl_texture_object
*texObj
,
4195 struct gl_texture_image
*texImage
)
4197 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4198 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
4199 pixels
, packing
, "glTexSubImage1D");
4204 const GLint dstRowStride
= 0;
4205 GLboolean success
= _mesa_texstore(ctx
, 1, texImage
->_BaseFormat
,
4206 texImage
->TexFormat
,
4208 xoffset
, 0, 0, /* offsets */
4210 texImage
->ImageOffsets
,
4212 format
, type
, pixels
, packing
);
4214 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
4218 _mesa_unmap_teximage_pbo(ctx
, packing
);
4224 * This is the software fallback for Driver.TexSubImage2D()
4225 * and Driver.CopyTexSubImage2D().
4228 _mesa_store_texsubimage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
4229 GLint xoffset
, GLint yoffset
,
4230 GLint width
, GLint height
,
4231 GLenum format
, GLenum type
, const void *pixels
,
4232 const struct gl_pixelstore_attrib
*packing
,
4233 struct gl_texture_object
*texObj
,
4234 struct gl_texture_image
*texImage
)
4236 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4237 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
4238 pixels
, packing
, "glTexSubImage2D");
4243 GLint dstRowStride
= texture_row_stride(texImage
);
4244 GLboolean success
= _mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
4245 texImage
->TexFormat
,
4247 xoffset
, yoffset
, 0,
4249 texImage
->ImageOffsets
,
4251 format
, type
, pixels
, packing
);
4253 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
4257 _mesa_unmap_teximage_pbo(ctx
, packing
);
4262 * This is the software fallback for Driver.TexSubImage3D().
4263 * and Driver.CopyTexSubImage3D().
4266 _mesa_store_texsubimage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
4267 GLint xoffset
, GLint yoffset
, GLint zoffset
,
4268 GLint width
, GLint height
, GLint depth
,
4269 GLenum format
, GLenum type
, const void *pixels
,
4270 const struct gl_pixelstore_attrib
*packing
,
4271 struct gl_texture_object
*texObj
,
4272 struct gl_texture_image
*texImage
)
4274 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4275 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
4276 type
, pixels
, packing
,
4282 GLint dstRowStride
= texture_row_stride(texImage
);
4283 GLboolean success
= _mesa_texstore(ctx
, 3, texImage
->_BaseFormat
,
4284 texImage
->TexFormat
,
4286 xoffset
, yoffset
, zoffset
,
4288 texImage
->ImageOffsets
,
4289 width
, height
, depth
,
4290 format
, type
, pixels
, packing
);
4292 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3D");
4296 _mesa_unmap_teximage_pbo(ctx
, packing
);
4301 * Fallback for Driver.CompressedTexImage1D()
4304 _mesa_store_compressed_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
4305 GLint internalFormat
,
4306 GLint width
, GLint border
,
4307 GLsizei imageSize
, const GLvoid
*data
,
4308 struct gl_texture_object
*texObj
,
4309 struct gl_texture_image
*texImage
)
4311 /* this space intentionally left blank */
4313 (void) target
; (void) level
;
4314 (void) internalFormat
;
4315 (void) width
; (void) border
;
4316 (void) imageSize
; (void) data
;
4324 * Fallback for Driver.CompressedTexImage2D()
4327 _mesa_store_compressed_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
4328 GLint internalFormat
,
4329 GLint width
, GLint height
, GLint border
,
4330 GLsizei imageSize
, const GLvoid
*data
,
4331 struct gl_texture_object
*texObj
,
4332 struct gl_texture_image
*texImage
)
4334 (void) width
; (void) height
; (void) border
;
4336 /* This is pretty simple, basically just do a memcpy without worrying
4337 * about the usual image unpacking or image transfer operations.
4341 ASSERT(texImage
->Width
> 0);
4342 ASSERT(texImage
->Height
> 0);
4343 ASSERT(texImage
->Depth
== 1);
4344 ASSERT(texImage
->Data
== NULL
); /* was freed in glCompressedTexImage2DARB */
4346 /* allocate storage */
4347 texImage
->Data
= _mesa_alloc_texmemory(imageSize
);
4348 if (!texImage
->Data
) {
4349 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
4353 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
4355 "glCompressedTexImage2D");
4360 memcpy(texImage
->Data
, data
, imageSize
);
4362 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
4368 * Fallback for Driver.CompressedTexImage3D()
4371 _mesa_store_compressed_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
4372 GLint internalFormat
,
4373 GLint width
, GLint height
, GLint depth
,
4375 GLsizei imageSize
, const GLvoid
*data
,
4376 struct gl_texture_object
*texObj
,
4377 struct gl_texture_image
*texImage
)
4379 /* this space intentionally left blank */
4381 (void) target
; (void) level
;
4382 (void) internalFormat
;
4383 (void) width
; (void) height
; (void) depth
;
4385 (void) imageSize
; (void) data
;
4393 * Fallback for Driver.CompressedTexSubImage1D()
4396 _mesa_store_compressed_texsubimage1d(GLcontext
*ctx
, GLenum target
,
4398 GLint xoffset
, GLsizei width
,
4400 GLsizei imageSize
, const GLvoid
*data
,
4401 struct gl_texture_object
*texObj
,
4402 struct gl_texture_image
*texImage
)
4404 /* there are no compressed 1D texture formats yet */
4406 (void) target
; (void) level
;
4407 (void) xoffset
; (void) width
;
4409 (void) imageSize
; (void) data
;
4416 * Fallback for Driver.CompressedTexSubImage2D()
4419 _mesa_store_compressed_texsubimage2d(GLcontext
*ctx
, GLenum target
,
4421 GLint xoffset
, GLint yoffset
,
4422 GLsizei width
, GLsizei height
,
4424 GLsizei imageSize
, const GLvoid
*data
,
4425 struct gl_texture_object
*texObj
,
4426 struct gl_texture_image
*texImage
)
4428 GLint bytesPerRow
, destRowStride
, srcRowStride
;
4432 const gl_format texFormat
= texImage
->TexFormat
;
4433 const GLint destWidth
= texImage
->Width
;
4436 _mesa_get_format_block_size(texFormat
, &bw
, &bh
);
4441 /* these should have been caught sooner */
4442 ASSERT((width
% bw
) == 0 || width
== 2 || width
== 1);
4443 ASSERT((height
% bh
) == 0 || height
== 2 || height
== 1);
4444 ASSERT((xoffset
% bw
) == 0);
4445 ASSERT((yoffset
% bh
) == 0);
4447 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4448 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
4450 "glCompressedTexSubImage2D");
4454 srcRowStride
= _mesa_format_row_stride(texFormat
, width
);
4455 src
= (const GLubyte
*) data
;
4457 destRowStride
= _mesa_format_row_stride(texFormat
, destWidth
);
4458 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
4459 texFormat
, destWidth
,
4460 (GLubyte
*) texImage
->Data
);
4462 bytesPerRow
= srcRowStride
; /* bytes per row of blocks */
4463 rows
= height
/ bh
; /* rows in blocks */
4465 /* copy rows of blocks */
4466 for (i
= 0; i
< rows
; i
++) {
4467 memcpy(dest
, src
, bytesPerRow
);
4468 dest
+= destRowStride
;
4469 src
+= srcRowStride
;
4472 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
4477 * Fallback for Driver.CompressedTexSubImage3D()
4480 _mesa_store_compressed_texsubimage3d(GLcontext
*ctx
, GLenum target
,
4482 GLint xoffset
, GLint yoffset
, GLint zoffset
,
4483 GLsizei width
, GLsizei height
, GLsizei depth
,
4485 GLsizei imageSize
, const GLvoid
*data
,
4486 struct gl_texture_object
*texObj
,
4487 struct gl_texture_image
*texImage
)
4489 /* there are no compressed 3D texture formats yet */
4491 (void) target
; (void) level
;
4492 (void) xoffset
; (void) yoffset
; (void) zoffset
;
4493 (void) width
; (void) height
; (void) depth
;
4495 (void) imageSize
; (void) data
;