2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (c) 2008-2009 VMware, Inc.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 * The GL texture image functions in teximage.c basically just do
33 * error checking and data structure allocation. They in turn call
34 * device driver functions which actually copy/convert/store the user's
37 * However, most device drivers will be able to use the fallback functions
38 * in this file. That is, most drivers will have the following bit of
40 * ctx->Driver.TexImage1D = _mesa_store_teximage1d;
41 * ctx->Driver.TexImage2D = _mesa_store_teximage2d;
42 * ctx->Driver.TexImage3D = _mesa_store_teximage3d;
45 * Texture image processing is actually kind of complicated. We have to do:
46 * Format/type conversions
48 * pixel transfer (scale, bais, lookup, convolution!, etc)
50 * These functions can handle most everything, including processing full
51 * images and sub-images.
56 #include "bufferobj.h"
64 #include "texcompress.h"
65 #include "texformat.h"
78 * Return GL_TRUE if the given image format is one that be converted
79 * to another format by swizzling.
82 can_swizzle(GLenum logicalBaseFormat
)
84 switch (logicalBaseFormat
) {
87 case GL_LUMINANCE_ALPHA
:
121 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO)
122 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO)
123 #define MAP3(x,y,z) MAP4(x, y, z, ZERO)
124 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
127 static const struct {
130 GLubyte from_rgba
[6];
131 } mappings
[MAX_IDX
] =
141 MAP4(ZERO
, ZERO
, ZERO
, 0),
172 MAP4(0, ZERO
, ZERO
, ONE
),
178 MAP4(ZERO
, 0, ZERO
, ONE
),
184 MAP4(ZERO
, ZERO
, 0, ONE
),
210 * Convert a GL image format enum to an IDX_* value (see above).
213 get_map_idx(GLenum value
)
216 case GL_LUMINANCE
: return IDX_LUMINANCE
;
217 case GL_ALPHA
: return IDX_ALPHA
;
218 case GL_INTENSITY
: return IDX_INTENSITY
;
219 case GL_LUMINANCE_ALPHA
: return IDX_LUMINANCE_ALPHA
;
220 case GL_RGB
: return IDX_RGB
;
221 case GL_RGBA
: return IDX_RGBA
;
222 case GL_RED
: return IDX_RED
;
223 case GL_GREEN
: return IDX_GREEN
;
224 case GL_BLUE
: return IDX_BLUE
;
225 case GL_BGR
: return IDX_BGR
;
226 case GL_BGRA
: return IDX_BGRA
;
227 case GL_ABGR_EXT
: return IDX_ABGR
;
229 _mesa_problem(NULL
, "Unexpected inFormat");
236 * When promoting texture formats (see below) we need to compute the
237 * mapping of dest components back to source components.
238 * This function does that.
239 * \param inFormat the incoming format of the texture
240 * \param outFormat the final texture format
241 * \return map[6] a full 6-component map
244 compute_component_mapping(GLenum inFormat
, GLenum outFormat
,
247 const int inFmt
= get_map_idx(inFormat
);
248 const int outFmt
= get_map_idx(outFormat
);
249 const GLubyte
*in2rgba
= mappings
[inFmt
].to_rgba
;
250 const GLubyte
*rgba2out
= mappings
[outFmt
].from_rgba
;
253 for (i
= 0; i
< 4; i
++)
254 map
[i
] = in2rgba
[rgba2out
[i
]];
260 _mesa_printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
261 inFormat, _mesa_lookup_enum_by_nr(inFormat),
262 outFormat, _mesa_lookup_enum_by_nr(outFormat),
273 #if !FEATURE_convolve
275 _mesa_adjust_image_for_convolution(GLcontext
*ctx
, GLuint dims
,
276 GLsizei
*srcWidth
, GLsizei
*srcHeight
)
284 * Make a temporary (color) texture image with GLfloat components.
285 * Apply all needed pixel unpacking and pixel transfer operations.
286 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
287 * Suppose the user specifies GL_LUMINANCE as the internal texture format
288 * but the graphics hardware doesn't support luminance textures. So, might
289 * use an RGB hardware format instead.
290 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
292 * \param ctx the rendering context
293 * \param dims image dimensions: 1, 2 or 3
294 * \param logicalBaseFormat basic texture derived from the user's
295 * internal texture format value
296 * \param textureBaseFormat the actual basic format of the texture
297 * \param srcWidth source image width
298 * \param srcHeight source image height
299 * \param srcDepth source image depth
300 * \param srcFormat source image format
301 * \param srcType source image type
302 * \param srcAddr source image address
303 * \param srcPacking source image pixel packing
304 * \return resulting image with format = textureBaseFormat and type = GLfloat.
307 make_temp_float_image(GLcontext
*ctx
, GLuint dims
,
308 GLenum logicalBaseFormat
,
309 GLenum textureBaseFormat
,
310 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
311 GLenum srcFormat
, GLenum srcType
,
312 const GLvoid
*srcAddr
,
313 const struct gl_pixelstore_attrib
*srcPacking
)
315 GLuint transferOps
= ctx
->_ImageTransferState
;
318 ASSERT(dims
>= 1 && dims
<= 3);
320 ASSERT(logicalBaseFormat
== GL_RGBA
||
321 logicalBaseFormat
== GL_RGB
||
322 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
323 logicalBaseFormat
== GL_LUMINANCE
||
324 logicalBaseFormat
== GL_ALPHA
||
325 logicalBaseFormat
== GL_INTENSITY
||
326 logicalBaseFormat
== GL_COLOR_INDEX
||
327 logicalBaseFormat
== GL_DEPTH_COMPONENT
);
329 ASSERT(textureBaseFormat
== GL_RGBA
||
330 textureBaseFormat
== GL_RGB
||
331 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
332 textureBaseFormat
== GL_LUMINANCE
||
333 textureBaseFormat
== GL_ALPHA
||
334 textureBaseFormat
== GL_INTENSITY
||
335 textureBaseFormat
== GL_COLOR_INDEX
||
336 textureBaseFormat
== GL_DEPTH_COMPONENT
);
338 /* conventional color image */
340 if ((dims
== 1 && ctx
->Pixel
.Convolution1DEnabled
) ||
341 (dims
>= 2 && ctx
->Pixel
.Convolution2DEnabled
) ||
342 (dims
>= 2 && ctx
->Pixel
.Separable2DEnabled
)) {
343 /* need image convolution */
344 const GLuint preConvTransferOps
345 = (transferOps
& IMAGE_PRE_CONVOLUTION_BITS
) | IMAGE_CLAMP_BIT
;
346 const GLuint postConvTransferOps
347 = (transferOps
& IMAGE_POST_CONVOLUTION_BITS
) | IMAGE_CLAMP_BIT
;
349 GLint convWidth
, convHeight
;
352 /* pre-convolution image buffer (3D) */
353 tempImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
354 * 4 * sizeof(GLfloat
));
358 /* post-convolution image buffer (2D) */
359 convImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
360 * 4 * sizeof(GLfloat
));
362 _mesa_free(tempImage
);
366 /* loop over 3D image slices */
367 for (img
= 0; img
< srcDepth
; img
++) {
368 GLfloat
*dst
= tempImage
+ img
* (srcWidth
* srcHeight
* 4);
370 /* unpack and do transfer ops up to convolution */
371 for (row
= 0; row
< srcHeight
; row
++) {
372 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
373 srcAddr
, srcWidth
, srcHeight
,
374 srcFormat
, srcType
, img
, row
, 0);
375 _mesa_unpack_color_span_float(ctx
, srcWidth
, GL_RGBA
, dst
,
376 srcFormat
, srcType
, src
,
382 /* size after optional convolution */
383 convWidth
= srcWidth
;
384 convHeight
= srcHeight
;
389 GLfloat
*src
= tempImage
+ img
* (srcWidth
* srcHeight
* 4);
391 ASSERT(ctx
->Pixel
.Convolution1DEnabled
);
392 _mesa_convolve_1d_image(ctx
, &convWidth
, src
, convImage
);
395 if (ctx
->Pixel
.Convolution2DEnabled
) {
396 _mesa_convolve_2d_image(ctx
, &convWidth
, &convHeight
,
400 ASSERT(ctx
->Pixel
.Separable2DEnabled
);
401 _mesa_convolve_sep_image(ctx
, &convWidth
, &convHeight
,
407 /* do post-convolution transfer and pack into tempImage */
409 const GLint logComponents
410 = _mesa_components_in_format(logicalBaseFormat
);
411 const GLfloat
*src
= convImage
;
412 GLfloat
*dst
= tempImage
+ img
* (convWidth
* convHeight
* 4);
413 for (row
= 0; row
< convHeight
; row
++) {
414 _mesa_pack_rgba_span_float(ctx
, convWidth
,
415 (GLfloat (*)[4]) src
,
416 logicalBaseFormat
, GL_FLOAT
,
417 dst
, &ctx
->DefaultPacking
,
418 postConvTransferOps
);
419 src
+= convWidth
* 4;
420 dst
+= convWidth
* logComponents
;
423 } /* loop over 3D image slices */
425 _mesa_free(convImage
);
427 /* might need these below */
428 srcWidth
= convWidth
;
429 srcHeight
= convHeight
;
433 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
434 const GLint srcStride
= _mesa_image_row_stride(srcPacking
,
435 srcWidth
, srcFormat
, srcType
);
439 tempImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
440 * components
* sizeof(GLfloat
));
445 for (img
= 0; img
< srcDepth
; img
++) {
447 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
451 for (row
= 0; row
< srcHeight
; row
++) {
452 _mesa_unpack_color_span_float(ctx
, srcWidth
, logicalBaseFormat
,
453 dst
, srcFormat
, srcType
, src
,
454 srcPacking
, transferOps
);
455 dst
+= srcWidth
* components
;
461 if (logicalBaseFormat
!= textureBaseFormat
) {
463 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
464 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
469 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
470 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
471 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
473 /* The actual texture format should have at least as many components
474 * as the logical texture format.
476 ASSERT(texComponents
>= logComponents
);
478 newImage
= (GLfloat
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
479 * texComponents
* sizeof(GLfloat
));
481 _mesa_free(tempImage
);
485 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
487 n
= srcWidth
* srcHeight
* srcDepth
;
488 for (i
= 0; i
< n
; i
++) {
490 for (k
= 0; k
< texComponents
; k
++) {
493 newImage
[i
* texComponents
+ k
] = 0.0F
;
495 newImage
[i
* texComponents
+ k
] = 1.0F
;
497 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
501 _mesa_free(tempImage
);
502 tempImage
= newImage
;
510 * Make a temporary (color) texture image with GLchan components.
511 * Apply all needed pixel unpacking and pixel transfer operations.
512 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
513 * Suppose the user specifies GL_LUMINANCE as the internal texture format
514 * but the graphics hardware doesn't support luminance textures. So, might
515 * use an RGB hardware format instead.
516 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
518 * \param ctx the rendering context
519 * \param dims image dimensions: 1, 2 or 3
520 * \param logicalBaseFormat basic texture derived from the user's
521 * internal texture format value
522 * \param textureBaseFormat the actual basic format of the texture
523 * \param srcWidth source image width
524 * \param srcHeight source image height
525 * \param srcDepth source image depth
526 * \param srcFormat source image format
527 * \param srcType source image type
528 * \param srcAddr source image address
529 * \param srcPacking source image pixel packing
530 * \return resulting image with format = textureBaseFormat and type = GLchan.
533 _mesa_make_temp_chan_image(GLcontext
*ctx
, GLuint dims
,
534 GLenum logicalBaseFormat
,
535 GLenum textureBaseFormat
,
536 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
537 GLenum srcFormat
, GLenum srcType
,
538 const GLvoid
*srcAddr
,
539 const struct gl_pixelstore_attrib
*srcPacking
)
541 GLuint transferOps
= ctx
->_ImageTransferState
;
542 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
543 GLboolean freeSrcImage
= GL_FALSE
;
545 GLchan
*tempImage
, *dst
;
547 ASSERT(dims
>= 1 && dims
<= 3);
549 ASSERT(logicalBaseFormat
== GL_RGBA
||
550 logicalBaseFormat
== GL_RGB
||
551 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
552 logicalBaseFormat
== GL_LUMINANCE
||
553 logicalBaseFormat
== GL_ALPHA
||
554 logicalBaseFormat
== GL_INTENSITY
);
556 ASSERT(textureBaseFormat
== GL_RGBA
||
557 textureBaseFormat
== GL_RGB
||
558 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
559 textureBaseFormat
== GL_LUMINANCE
||
560 textureBaseFormat
== GL_ALPHA
||
561 textureBaseFormat
== GL_INTENSITY
);
564 if ((dims
== 1 && ctx
->Pixel
.Convolution1DEnabled
) ||
565 (dims
>= 2 && ctx
->Pixel
.Convolution2DEnabled
) ||
566 (dims
>= 2 && ctx
->Pixel
.Separable2DEnabled
)) {
567 /* get convolved image */
568 GLfloat
*convImage
= make_temp_float_image(ctx
, dims
,
571 srcWidth
, srcHeight
, srcDepth
,
573 srcAddr
, srcPacking
);
576 /* the convolved image is our new source image */
578 srcFormat
= logicalBaseFormat
;
580 srcPacking
= &ctx
->DefaultPacking
;
581 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
583 freeSrcImage
= GL_TRUE
;
587 /* unpack and transfer the source image */
588 tempImage
= (GLchan
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
589 * components
* sizeof(GLchan
));
592 _mesa_free((void *) srcAddr
);
598 for (img
= 0; img
< srcDepth
; img
++) {
599 const GLint srcStride
= _mesa_image_row_stride(srcPacking
,
603 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
607 for (row
= 0; row
< srcHeight
; row
++) {
608 _mesa_unpack_color_span_chan(ctx
, srcWidth
, logicalBaseFormat
, dst
,
609 srcFormat
, srcType
, src
, srcPacking
,
611 dst
+= srcWidth
* components
;
616 /* If we made a temporary image for convolution, free it here */
618 _mesa_free((void *) srcAddr
);
621 if (logicalBaseFormat
!= textureBaseFormat
) {
622 /* one more conversion step */
623 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
624 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
629 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
630 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
631 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
633 /* The actual texture format should have at least as many components
634 * as the logical texture format.
636 ASSERT(texComponents
>= logComponents
);
638 newImage
= (GLchan
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
639 * texComponents
* sizeof(GLchan
));
641 _mesa_free(tempImage
);
645 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
647 n
= srcWidth
* srcHeight
* srcDepth
;
648 for (i
= 0; i
< n
; i
++) {
650 for (k
= 0; k
< texComponents
; k
++) {
653 newImage
[i
* texComponents
+ k
] = 0;
655 newImage
[i
* texComponents
+ k
] = CHAN_MAX
;
657 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
661 _mesa_free(tempImage
);
662 tempImage
= newImage
;
670 * Copy GLubyte pixels from <src> to <dst> with swizzling.
671 * \param dst destination pixels
672 * \param dstComponents number of color components in destination pixels
673 * \param src source pixels
674 * \param srcComponents number of color components in source pixels
675 * \param map the swizzle mapping. map[X] says where to find the X component
676 * in the source image's pixels. For example, if the source image
677 * is GL_BGRA and X = red, map[0] yields 2.
678 * \param count number of pixels to copy/swizzle.
681 swizzle_copy(GLubyte
*dst
, GLuint dstComponents
, const GLubyte
*src
,
682 GLuint srcComponents
, const GLubyte
*map
, GLuint count
)
684 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
687 for (i = 0; i < count; i++) { \
689 if (srcComps == 4) { \
690 COPY_4UBV(tmp, src); \
693 for (j = 0; j < srcComps; j++) { \
698 for (j = 0; j < dstComps; j++) { \
699 dst[j] = tmp[map[j]]; \
710 ASSERT(srcComponents
<= 4);
711 ASSERT(dstComponents
<= 4);
713 switch (dstComponents
) {
715 switch (srcComponents
) {
717 SWZ_CPY(dst
, src
, count
, 4, 4);
720 SWZ_CPY(dst
, src
, count
, 4, 3);
723 SWZ_CPY(dst
, src
, count
, 4, 2);
726 SWZ_CPY(dst
, src
, count
, 4, 1);
733 switch (srcComponents
) {
735 SWZ_CPY(dst
, src
, count
, 3, 4);
738 SWZ_CPY(dst
, src
, count
, 3, 3);
741 SWZ_CPY(dst
, src
, count
, 3, 2);
744 SWZ_CPY(dst
, src
, count
, 3, 1);
751 switch (srcComponents
) {
753 SWZ_CPY(dst
, src
, count
, 2, 4);
756 SWZ_CPY(dst
, src
, count
, 2, 3);
759 SWZ_CPY(dst
, src
, count
, 2, 2);
762 SWZ_CPY(dst
, src
, count
, 2, 1);
769 switch (srcComponents
) {
771 SWZ_CPY(dst
, src
, count
, 1, 4);
774 SWZ_CPY(dst
, src
, count
, 1, 3);
777 SWZ_CPY(dst
, src
, count
, 1, 2);
780 SWZ_CPY(dst
, src
, count
, 1, 1);
794 static const GLubyte map_identity
[6] = { 0, 1, 2, 3, ZERO
, ONE
};
795 static const GLubyte map_3210
[6] = { 3, 2, 1, 0, ZERO
, ONE
};
797 /* Deal with the _REV input types:
799 static const GLubyte
*
800 type_mapping( GLenum srcType
)
804 case GL_UNSIGNED_BYTE
:
806 case GL_UNSIGNED_INT_8_8_8_8
:
807 return _mesa_little_endian() ? map_3210
: map_identity
;
808 case GL_UNSIGNED_INT_8_8_8_8_REV
:
809 return _mesa_little_endian() ? map_identity
: map_3210
;
815 /* Mapping required if input type is
817 static const GLubyte
*
818 byteswap_mapping( GLboolean swapBytes
,
826 case GL_UNSIGNED_BYTE
:
828 case GL_UNSIGNED_INT_8_8_8_8
:
829 case GL_UNSIGNED_INT_8_8_8_8_REV
:
839 * Transfer a GLubyte texture image with component swizzling.
842 _mesa_swizzle_ubyte_image(GLcontext
*ctx
,
847 GLenum baseInternalFormat
,
849 const GLubyte
*rgba2dst
,
850 GLuint dstComponents
,
853 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
855 const GLuint
*dstImageOffsets
,
857 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
858 const GLvoid
*srcAddr
,
859 const struct gl_pixelstore_attrib
*srcPacking
)
861 GLint srcComponents
= _mesa_components_in_format(srcFormat
);
862 const GLubyte
*srctype2ubyte
, *swap
;
863 GLubyte map
[4], src2base
[6], base2rgba
[6];
865 const GLint srcRowStride
=
866 _mesa_image_row_stride(srcPacking
, srcWidth
,
867 srcFormat
, GL_UNSIGNED_BYTE
);
868 const GLint srcImageStride
869 = _mesa_image_image_stride(srcPacking
, srcWidth
, srcHeight
, srcFormat
,
871 const GLubyte
*srcImage
872 = (const GLubyte
*) _mesa_image_address(dimensions
, srcPacking
, srcAddr
,
873 srcWidth
, srcHeight
, srcFormat
,
874 GL_UNSIGNED_BYTE
, 0, 0, 0);
878 /* Translate from src->baseInternal->GL_RGBA->dst. This will
879 * correctly deal with RGBA->RGB->RGBA conversions where the final
880 * A value must be 0xff regardless of the incoming alpha values.
882 compute_component_mapping(srcFormat
, baseInternalFormat
, src2base
);
883 compute_component_mapping(baseInternalFormat
, GL_RGBA
, base2rgba
);
884 swap
= byteswap_mapping(srcPacking
->SwapBytes
, srcType
);
885 srctype2ubyte
= type_mapping(srcType
);
888 for (i
= 0; i
< 4; i
++)
889 map
[i
] = srctype2ubyte
[swap
[src2base
[base2rgba
[rgba2dst
[i
]]]]];
891 /* _mesa_printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */
893 if (srcComponents
== dstComponents
&&
894 srcRowStride
== dstRowStride
&&
895 srcRowStride
== srcWidth
* srcComponents
&&
897 /* 1 and 2D images only */
898 GLubyte
*dstImage
= (GLubyte
*) dstAddr
899 + dstYoffset
* dstRowStride
900 + dstXoffset
* dstComponents
;
901 swizzle_copy(dstImage
, dstComponents
, srcImage
, srcComponents
, map
,
902 srcWidth
* srcHeight
);
906 for (img
= 0; img
< srcDepth
; img
++) {
907 const GLubyte
*srcRow
= srcImage
;
908 GLubyte
*dstRow
= (GLubyte
*) dstAddr
909 + dstImageOffsets
[dstZoffset
+ img
] * dstComponents
910 + dstYoffset
* dstRowStride
911 + dstXoffset
* dstComponents
;
912 for (row
= 0; row
< srcHeight
; row
++) {
913 swizzle_copy(dstRow
, dstComponents
, srcRow
, srcComponents
, map
, srcWidth
);
914 dstRow
+= dstRowStride
;
915 srcRow
+= srcRowStride
;
917 srcImage
+= srcImageStride
;
924 * Teximage storage routine for when a simple memcpy will do.
925 * No pixel transfer operations or special texel encodings allowed.
926 * 1D, 2D and 3D images supported.
929 memcpy_texture(GLcontext
*ctx
,
931 const struct gl_texture_format
*dstFormat
,
933 GLint dstXoffset
, GLint dstYoffset
, GLint dstZoffset
,
935 const GLuint
*dstImageOffsets
,
936 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
937 GLenum srcFormat
, GLenum srcType
,
938 const GLvoid
*srcAddr
,
939 const struct gl_pixelstore_attrib
*srcPacking
)
941 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
943 const GLint srcImageStride
= _mesa_image_image_stride(srcPacking
,
944 srcWidth
, srcHeight
, srcFormat
, srcType
);
945 const GLubyte
*srcImage
= (const GLubyte
*) _mesa_image_address(dimensions
,
946 srcPacking
, srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, 0, 0, 0);
947 const GLint bytesPerRow
= srcWidth
* dstFormat
->TexelBytes
;
950 /* XXX update/re-enable for dstImageOffsets array */
951 const GLint bytesPerImage
= srcHeight
* bytesPerRow
;
952 const GLint bytesPerTexture
= srcDepth
* bytesPerImage
;
953 GLubyte
*dstImage
= (GLubyte
*) dstAddr
954 + dstZoffset
* dstImageStride
955 + dstYoffset
* dstRowStride
956 + dstXoffset
* dstFormat
->TexelBytes
;
958 if (dstRowStride
== srcRowStride
&&
959 dstRowStride
== bytesPerRow
&&
960 ((dstImageStride
== srcImageStride
&&
961 dstImageStride
== bytesPerImage
) ||
964 ctx
->Driver
.TextureMemCpy(dstImage
, srcImage
, bytesPerTexture
);
969 for (img
= 0; img
< srcDepth
; img
++) {
970 const GLubyte
*srcRow
= srcImage
;
971 GLubyte
*dstRow
= dstImage
;
972 for (row
= 0; row
< srcHeight
; row
++) {
973 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
974 dstRow
+= dstRowStride
;
975 srcRow
+= srcRowStride
;
977 srcImage
+= srcImageStride
;
978 dstImage
+= dstImageStride
;
984 for (img
= 0; img
< srcDepth
; img
++) {
985 const GLubyte
*srcRow
= srcImage
;
986 GLubyte
*dstRow
= (GLubyte
*) dstAddr
987 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
988 + dstYoffset
* dstRowStride
989 + dstXoffset
* dstFormat
->TexelBytes
;
990 for (row
= 0; row
< srcHeight
; row
++) {
991 ctx
->Driver
.TextureMemCpy(dstRow
, srcRow
, bytesPerRow
);
992 dstRow
+= dstRowStride
;
993 srcRow
+= srcRowStride
;
995 srcImage
+= srcImageStride
;
1002 * Store an image in any of the formats:
1003 * _mesa_texformat_rgba
1004 * _mesa_texformat_rgb
1005 * _mesa_texformat_alpha
1006 * _mesa_texformat_luminance
1007 * _mesa_texformat_luminance_alpha
1008 * _mesa_texformat_intensity
1012 _mesa_texstore_rgba(TEXSTORE_PARAMS
)
1014 const GLint components
= _mesa_components_in_format(baseInternalFormat
);
1016 ASSERT(dstFormat
== &_mesa_texformat_rgba
||
1017 dstFormat
== &_mesa_texformat_rgb
||
1018 dstFormat
== &_mesa_texformat_alpha
||
1019 dstFormat
== &_mesa_texformat_luminance
||
1020 dstFormat
== &_mesa_texformat_luminance_alpha
||
1021 dstFormat
== &_mesa_texformat_intensity
);
1022 ASSERT(baseInternalFormat
== GL_RGBA
||
1023 baseInternalFormat
== GL_RGB
||
1024 baseInternalFormat
== GL_ALPHA
||
1025 baseInternalFormat
== GL_LUMINANCE
||
1026 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
1027 baseInternalFormat
== GL_INTENSITY
);
1028 ASSERT(dstFormat
->TexelBytes
== components
* sizeof(GLchan
));
1030 if (!ctx
->_ImageTransferState
&&
1031 !srcPacking
->SwapBytes
&&
1032 baseInternalFormat
== srcFormat
&&
1033 srcType
== CHAN_TYPE
) {
1034 /* simple memcpy path */
1035 memcpy_texture(ctx
, dims
,
1036 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1039 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1040 srcAddr
, srcPacking
);
1042 else if (!ctx
->_ImageTransferState
&&
1043 !srcPacking
->SwapBytes
&&
1044 dstFormat
== &_mesa_texformat_rgb
&&
1045 srcFormat
== GL_RGBA
&&
1046 srcType
== CHAN_TYPE
) {
1047 /* extract RGB from RGBA */
1048 GLint img
, row
, col
;
1049 for (img
= 0; img
< srcDepth
; img
++) {
1050 GLchan
*dstImage
= (GLchan
*)
1051 ((GLubyte
*) dstAddr
1052 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1053 + dstYoffset
* dstRowStride
1054 + dstXoffset
* dstFormat
->TexelBytes
);
1056 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1057 srcWidth
, srcFormat
, srcType
);
1058 GLchan
*srcRow
= (GLchan
*) _mesa_image_address(dims
, srcPacking
,
1059 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1060 GLchan
*dstRow
= dstImage
;
1061 for (row
= 0; row
< srcHeight
; row
++) {
1062 for (col
= 0; col
< srcWidth
; col
++) {
1063 dstRow
[col
* 3 + RCOMP
] = srcRow
[col
* 4 + RCOMP
];
1064 dstRow
[col
* 3 + GCOMP
] = srcRow
[col
* 4 + GCOMP
];
1065 dstRow
[col
* 3 + BCOMP
] = srcRow
[col
* 4 + BCOMP
];
1067 dstRow
+= dstRowStride
/ sizeof(GLchan
);
1068 srcRow
= (GLchan
*) ((GLubyte
*) srcRow
+ srcRowStride
);
1072 else if (!ctx
->_ImageTransferState
&&
1073 CHAN_TYPE
== GL_UNSIGNED_BYTE
&&
1074 (srcType
== GL_UNSIGNED_BYTE
||
1075 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1076 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1077 can_swizzle(baseInternalFormat
) &&
1078 can_swizzle(srcFormat
)) {
1080 const GLubyte
*dstmap
;
1083 /* dstmap - how to swizzle from RGBA to dst format:
1085 if (dstFormat
== &_mesa_texformat_rgba
) {
1086 dstmap
= mappings
[IDX_RGBA
].from_rgba
;
1089 else if (dstFormat
== &_mesa_texformat_rgb
) {
1090 dstmap
= mappings
[IDX_RGB
].from_rgba
;
1093 else if (dstFormat
== &_mesa_texformat_alpha
) {
1094 dstmap
= mappings
[IDX_ALPHA
].from_rgba
;
1097 else if (dstFormat
== &_mesa_texformat_luminance
) {
1098 dstmap
= mappings
[IDX_LUMINANCE
].from_rgba
;
1101 else if (dstFormat
== &_mesa_texformat_luminance_alpha
) {
1102 dstmap
= mappings
[IDX_LUMINANCE_ALPHA
].from_rgba
;
1105 else if (dstFormat
== &_mesa_texformat_intensity
) {
1106 dstmap
= mappings
[IDX_INTENSITY
].from_rgba
;
1110 _mesa_problem(ctx
, "Unexpected dstFormat in _mesa_texstore_rgba");
1114 _mesa_swizzle_ubyte_image(ctx
, dims
,
1119 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1120 dstRowStride
, dstImageOffsets
,
1121 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1126 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1128 dstFormat
->BaseFormat
,
1129 srcWidth
, srcHeight
, srcDepth
,
1130 srcFormat
, srcType
, srcAddr
,
1132 const GLchan
*src
= tempImage
;
1137 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1138 bytesPerRow
= srcWidth
* components
* sizeof(GLchan
);
1139 for (img
= 0; img
< srcDepth
; img
++) {
1140 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1141 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1142 + dstYoffset
* dstRowStride
1143 + dstXoffset
* dstFormat
->TexelBytes
;
1144 for (row
= 0; row
< srcHeight
; row
++) {
1145 _mesa_memcpy(dstRow
, src
, bytesPerRow
);
1146 dstRow
+= dstRowStride
;
1147 src
+= srcWidth
* components
;
1151 _mesa_free((void *) tempImage
);
1158 * Store a 32-bit integer depth component texture image.
1161 _mesa_texstore_z32(TEXSTORE_PARAMS
)
1163 const GLuint depthScale
= 0xffffffff;
1165 ASSERT(dstFormat
== &_mesa_texformat_z32
);
1166 ASSERT(dstFormat
->TexelBytes
== sizeof(GLuint
));
1168 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1169 ctx
->Pixel
.DepthBias
== 0.0f
&&
1170 !srcPacking
->SwapBytes
&&
1171 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1172 srcFormat
== GL_DEPTH_COMPONENT
&&
1173 srcType
== GL_UNSIGNED_INT
) {
1174 /* simple memcpy path */
1175 memcpy_texture(ctx
, dims
,
1176 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1179 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1180 srcAddr
, srcPacking
);
1185 for (img
= 0; img
< srcDepth
; img
++) {
1186 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1187 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1188 + dstYoffset
* dstRowStride
1189 + dstXoffset
* dstFormat
->TexelBytes
;
1190 for (row
= 0; row
< srcHeight
; row
++) {
1191 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1192 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1193 _mesa_unpack_depth_span(ctx
, srcWidth
,
1194 GL_UNSIGNED_INT
, (GLuint
*) dstRow
,
1195 depthScale
, srcType
, src
, srcPacking
);
1196 dstRow
+= dstRowStride
;
1206 * Store a 16-bit integer depth component texture image.
1209 _mesa_texstore_z16(TEXSTORE_PARAMS
)
1211 const GLuint depthScale
= 0xffff;
1213 ASSERT(dstFormat
== &_mesa_texformat_z16
);
1214 ASSERT(dstFormat
->TexelBytes
== sizeof(GLushort
));
1216 if (ctx
->Pixel
.DepthScale
== 1.0f
&&
1217 ctx
->Pixel
.DepthBias
== 0.0f
&&
1218 !srcPacking
->SwapBytes
&&
1219 baseInternalFormat
== GL_DEPTH_COMPONENT
&&
1220 srcFormat
== GL_DEPTH_COMPONENT
&&
1221 srcType
== GL_UNSIGNED_SHORT
) {
1222 /* simple memcpy path */
1223 memcpy_texture(ctx
, dims
,
1224 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1227 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1228 srcAddr
, srcPacking
);
1233 for (img
= 0; img
< srcDepth
; img
++) {
1234 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1235 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1236 + dstYoffset
* dstRowStride
1237 + dstXoffset
* dstFormat
->TexelBytes
;
1238 for (row
= 0; row
< srcHeight
; row
++) {
1239 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
1240 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
1241 GLushort
*dst16
= (GLushort
*) dstRow
;
1242 _mesa_unpack_depth_span(ctx
, srcWidth
,
1243 GL_UNSIGNED_SHORT
, dst16
, depthScale
,
1244 srcType
, src
, srcPacking
);
1245 dstRow
+= dstRowStride
;
1254 * Store an rgb565 or rgb565_rev texture image.
1257 _mesa_texstore_rgb565(TEXSTORE_PARAMS
)
1259 ASSERT(dstFormat
== &_mesa_texformat_rgb565
||
1260 dstFormat
== &_mesa_texformat_rgb565_rev
);
1261 ASSERT(dstFormat
->TexelBytes
== 2);
1263 if (!ctx
->_ImageTransferState
&&
1264 !srcPacking
->SwapBytes
&&
1265 dstFormat
== &_mesa_texformat_rgb565
&&
1266 baseInternalFormat
== GL_RGB
&&
1267 srcFormat
== GL_RGB
&&
1268 srcType
== GL_UNSIGNED_SHORT_5_6_5
) {
1269 /* simple memcpy path */
1270 memcpy_texture(ctx
, dims
,
1271 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1274 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1275 srcAddr
, srcPacking
);
1277 else if (!ctx
->_ImageTransferState
&&
1278 !srcPacking
->SwapBytes
&&
1279 baseInternalFormat
== GL_RGB
&&
1280 srcFormat
== GL_RGB
&&
1281 srcType
== GL_UNSIGNED_BYTE
&&
1283 /* do optimized tex store */
1284 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
1285 srcFormat
, srcType
);
1286 const GLubyte
*src
= (const GLubyte
*)
1287 _mesa_image_address(dims
, srcPacking
, srcAddr
, srcWidth
, srcHeight
,
1288 srcFormat
, srcType
, 0, 0, 0);
1289 GLubyte
*dst
= (GLubyte
*) dstAddr
1290 + dstYoffset
* dstRowStride
1291 + dstXoffset
* dstFormat
->TexelBytes
;
1293 for (row
= 0; row
< srcHeight
; row
++) {
1294 const GLubyte
*srcUB
= (const GLubyte
*) src
;
1295 GLushort
*dstUS
= (GLushort
*) dst
;
1296 /* check for byteswapped format */
1297 if (dstFormat
== &_mesa_texformat_rgb565
) {
1298 for (col
= 0; col
< srcWidth
; col
++) {
1299 dstUS
[col
] = PACK_COLOR_565( srcUB
[0], srcUB
[1], srcUB
[2] );
1304 for (col
= 0; col
< srcWidth
; col
++) {
1305 dstUS
[col
] = PACK_COLOR_565_REV( srcUB
[0], srcUB
[1], srcUB
[2] );
1309 dst
+= dstRowStride
;
1310 src
+= srcRowStride
;
1315 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1317 dstFormat
->BaseFormat
,
1318 srcWidth
, srcHeight
, srcDepth
,
1319 srcFormat
, srcType
, srcAddr
,
1321 const GLchan
*src
= tempImage
;
1322 GLint img
, row
, col
;
1325 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1326 for (img
= 0; img
< srcDepth
; img
++) {
1327 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1328 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1329 + dstYoffset
* dstRowStride
1330 + dstXoffset
* dstFormat
->TexelBytes
;
1331 for (row
= 0; row
< srcHeight
; row
++) {
1332 GLushort
*dstUS
= (GLushort
*) dstRow
;
1333 /* check for byteswapped format */
1334 if (dstFormat
== &_mesa_texformat_rgb565
) {
1335 for (col
= 0; col
< srcWidth
; col
++) {
1336 dstUS
[col
] = PACK_COLOR_565( CHAN_TO_UBYTE(src
[RCOMP
]),
1337 CHAN_TO_UBYTE(src
[GCOMP
]),
1338 CHAN_TO_UBYTE(src
[BCOMP
]) );
1343 for (col
= 0; col
< srcWidth
; col
++) {
1344 dstUS
[col
] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1345 CHAN_TO_UBYTE(src
[GCOMP
]),
1346 CHAN_TO_UBYTE(src
[BCOMP
]) );
1350 dstRow
+= dstRowStride
;
1353 _mesa_free((void *) tempImage
);
1360 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1363 _mesa_texstore_rgba8888(TEXSTORE_PARAMS
)
1365 const GLboolean littleEndian
= _mesa_little_endian();
1367 ASSERT(dstFormat
== &_mesa_texformat_rgba8888
||
1368 dstFormat
== &_mesa_texformat_rgba8888_rev
);
1369 ASSERT(dstFormat
->TexelBytes
== 4);
1371 if (!ctx
->_ImageTransferState
&&
1372 !srcPacking
->SwapBytes
&&
1373 dstFormat
== &_mesa_texformat_rgba8888
&&
1374 baseInternalFormat
== GL_RGBA
&&
1375 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1376 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1377 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1378 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
))) {
1379 /* simple memcpy path */
1380 memcpy_texture(ctx
, dims
,
1381 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1384 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1385 srcAddr
, srcPacking
);
1387 else if (!ctx
->_ImageTransferState
&&
1388 !srcPacking
->SwapBytes
&&
1389 dstFormat
== &_mesa_texformat_rgba8888_rev
&&
1390 baseInternalFormat
== GL_RGBA
&&
1391 ((srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
1392 (srcFormat
== GL_RGBA
&& srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1393 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_INT_8_8_8_8
) ||
1394 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
))) {
1395 /* simple memcpy path */
1396 memcpy_texture(ctx
, dims
,
1397 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1400 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1401 srcAddr
, srcPacking
);
1403 else if (!ctx
->_ImageTransferState
&&
1404 (srcType
== GL_UNSIGNED_BYTE
||
1405 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1406 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1407 can_swizzle(baseInternalFormat
) &&
1408 can_swizzle(srcFormat
)) {
1412 /* dstmap - how to swizzle from RGBA to dst format:
1414 if ((littleEndian
&& dstFormat
== &_mesa_texformat_rgba8888
) ||
1415 (!littleEndian
&& dstFormat
== &_mesa_texformat_rgba8888_rev
)) {
1428 _mesa_swizzle_ubyte_image(ctx
, dims
,
1433 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1434 dstRowStride
, dstImageOffsets
,
1435 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1440 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1442 dstFormat
->BaseFormat
,
1443 srcWidth
, srcHeight
, srcDepth
,
1444 srcFormat
, srcType
, srcAddr
,
1446 const GLchan
*src
= tempImage
;
1447 GLint img
, row
, col
;
1450 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1451 for (img
= 0; img
< srcDepth
; img
++) {
1452 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1453 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1454 + dstYoffset
* dstRowStride
1455 + dstXoffset
* dstFormat
->TexelBytes
;
1456 for (row
= 0; row
< srcHeight
; row
++) {
1457 GLuint
*dstUI
= (GLuint
*) dstRow
;
1458 if (dstFormat
== &_mesa_texformat_rgba8888
) {
1459 for (col
= 0; col
< srcWidth
; col
++) {
1460 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[RCOMP
]),
1461 CHAN_TO_UBYTE(src
[GCOMP
]),
1462 CHAN_TO_UBYTE(src
[BCOMP
]),
1463 CHAN_TO_UBYTE(src
[ACOMP
]) );
1468 for (col
= 0; col
< srcWidth
; col
++) {
1469 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[RCOMP
]),
1470 CHAN_TO_UBYTE(src
[GCOMP
]),
1471 CHAN_TO_UBYTE(src
[BCOMP
]),
1472 CHAN_TO_UBYTE(src
[ACOMP
]) );
1476 dstRow
+= dstRowStride
;
1479 _mesa_free((void *) tempImage
);
1486 _mesa_texstore_argb8888(TEXSTORE_PARAMS
)
1488 const GLboolean littleEndian
= _mesa_little_endian();
1490 ASSERT(dstFormat
== &_mesa_texformat_argb8888
||
1491 dstFormat
== &_mesa_texformat_argb8888_rev
);
1492 ASSERT(dstFormat
->TexelBytes
== 4);
1494 if (!ctx
->_ImageTransferState
&&
1495 !srcPacking
->SwapBytes
&&
1496 dstFormat
== &_mesa_texformat_argb8888
&&
1497 baseInternalFormat
== GL_RGBA
&&
1498 srcFormat
== GL_BGRA
&&
1499 ((srcType
== GL_UNSIGNED_BYTE
&& littleEndian
) ||
1500 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
)) {
1501 /* simple memcpy path (little endian) */
1502 memcpy_texture(ctx
, dims
,
1503 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1506 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1507 srcAddr
, srcPacking
);
1509 else if (!ctx
->_ImageTransferState
&&
1510 !srcPacking
->SwapBytes
&&
1511 dstFormat
== &_mesa_texformat_argb8888_rev
&&
1512 baseInternalFormat
== GL_RGBA
&&
1513 srcFormat
== GL_BGRA
&&
1514 ((srcType
== GL_UNSIGNED_BYTE
&& !littleEndian
) ||
1515 srcType
== GL_UNSIGNED_INT_8_8_8_8
)) {
1516 /* simple memcpy path (big endian) */
1517 memcpy_texture(ctx
, dims
,
1518 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1521 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1522 srcAddr
, srcPacking
);
1524 else if (!ctx
->_ImageTransferState
&&
1525 !srcPacking
->SwapBytes
&&
1526 dstFormat
== &_mesa_texformat_argb8888
&&
1527 srcFormat
== GL_RGB
&&
1528 (baseInternalFormat
== GL_RGBA
||
1529 baseInternalFormat
== GL_RGB
) &&
1530 srcType
== GL_UNSIGNED_BYTE
) {
1532 for (img
= 0; img
< srcDepth
; img
++) {
1533 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1534 srcWidth
, srcFormat
, srcType
);
1535 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1536 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1537 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1538 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1539 + dstYoffset
* dstRowStride
1540 + dstXoffset
* dstFormat
->TexelBytes
;
1541 for (row
= 0; row
< srcHeight
; row
++) {
1542 GLuint
*d4
= (GLuint
*) dstRow
;
1543 for (col
= 0; col
< srcWidth
; col
++) {
1544 d4
[col
] = PACK_COLOR_8888(0xff,
1545 srcRow
[col
* 3 + RCOMP
],
1546 srcRow
[col
* 3 + GCOMP
],
1547 srcRow
[col
* 3 + BCOMP
]);
1549 dstRow
+= dstRowStride
;
1550 srcRow
+= srcRowStride
;
1554 else if (!ctx
->_ImageTransferState
&&
1555 !srcPacking
->SwapBytes
&&
1556 dstFormat
== &_mesa_texformat_argb8888
&&
1557 srcFormat
== GL_RGBA
&&
1558 baseInternalFormat
== GL_RGBA
&&
1559 srcType
== GL_UNSIGNED_BYTE
) {
1560 /* same as above case, but src data has alpha too */
1561 GLint img
, row
, col
;
1562 /* For some reason, streaming copies to write-combined regions
1563 * are extremely sensitive to the characteristics of how the
1564 * source data is retrieved. By reordering the source reads to
1565 * be in-order, the speed of this operation increases by half.
1566 * Strangely the same isn't required for the RGB path, above.
1568 for (img
= 0; img
< srcDepth
; img
++) {
1569 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1570 srcWidth
, srcFormat
, srcType
);
1571 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1572 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1573 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1574 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1575 + dstYoffset
* dstRowStride
1576 + dstXoffset
* dstFormat
->TexelBytes
;
1577 for (row
= 0; row
< srcHeight
; row
++) {
1578 GLuint
*d4
= (GLuint
*) dstRow
;
1579 for (col
= 0; col
< srcWidth
; col
++) {
1580 d4
[col
] = PACK_COLOR_8888(srcRow
[col
* 4 + ACOMP
],
1581 srcRow
[col
* 4 + RCOMP
],
1582 srcRow
[col
* 4 + GCOMP
],
1583 srcRow
[col
* 4 + BCOMP
]);
1585 dstRow
+= dstRowStride
;
1586 srcRow
+= srcRowStride
;
1590 else if (!ctx
->_ImageTransferState
&&
1591 (srcType
== GL_UNSIGNED_BYTE
||
1592 srcType
== GL_UNSIGNED_INT_8_8_8_8
||
1593 srcType
== GL_UNSIGNED_INT_8_8_8_8_REV
) &&
1594 can_swizzle(baseInternalFormat
) &&
1595 can_swizzle(srcFormat
)) {
1599 /* dstmap - how to swizzle from RGBA to dst format:
1601 if ((littleEndian
&& dstFormat
== &_mesa_texformat_argb8888
) ||
1602 (!littleEndian
&& dstFormat
== &_mesa_texformat_argb8888_rev
)) {
1603 dstmap
[3] = 3; /* alpha */
1604 dstmap
[2] = 0; /* red */
1605 dstmap
[1] = 1; /* green */
1606 dstmap
[0] = 2; /* blue */
1609 assert((littleEndian
&& dstFormat
== &_mesa_texformat_argb8888_rev
) ||
1610 (!littleEndian
&& dstFormat
== &_mesa_texformat_argb8888
));
1617 _mesa_swizzle_ubyte_image(ctx
, dims
,
1623 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1626 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1631 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1633 dstFormat
->BaseFormat
,
1634 srcWidth
, srcHeight
, srcDepth
,
1635 srcFormat
, srcType
, srcAddr
,
1637 const GLchan
*src
= tempImage
;
1638 GLint img
, row
, col
;
1641 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1642 for (img
= 0; img
< srcDepth
; img
++) {
1643 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1644 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1645 + dstYoffset
* dstRowStride
1646 + dstXoffset
* dstFormat
->TexelBytes
;
1647 for (row
= 0; row
< srcHeight
; row
++) {
1648 GLuint
*dstUI
= (GLuint
*) dstRow
;
1649 if (dstFormat
== &_mesa_texformat_argb8888
) {
1650 for (col
= 0; col
< srcWidth
; col
++) {
1651 dstUI
[col
] = PACK_COLOR_8888( CHAN_TO_UBYTE(src
[ACOMP
]),
1652 CHAN_TO_UBYTE(src
[RCOMP
]),
1653 CHAN_TO_UBYTE(src
[GCOMP
]),
1654 CHAN_TO_UBYTE(src
[BCOMP
]) );
1659 for (col
= 0; col
< srcWidth
; col
++) {
1660 dstUI
[col
] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
1661 CHAN_TO_UBYTE(src
[RCOMP
]),
1662 CHAN_TO_UBYTE(src
[GCOMP
]),
1663 CHAN_TO_UBYTE(src
[BCOMP
]) );
1667 dstRow
+= dstRowStride
;
1670 _mesa_free((void *) tempImage
);
1677 _mesa_texstore_rgb888(TEXSTORE_PARAMS
)
1679 const GLboolean littleEndian
= _mesa_little_endian();
1681 ASSERT(dstFormat
== &_mesa_texformat_rgb888
);
1682 ASSERT(dstFormat
->TexelBytes
== 3);
1684 if (!ctx
->_ImageTransferState
&&
1685 !srcPacking
->SwapBytes
&&
1686 baseInternalFormat
== GL_RGB
&&
1687 srcFormat
== GL_BGR
&&
1688 srcType
== GL_UNSIGNED_BYTE
&&
1690 /* simple memcpy path */
1691 memcpy_texture(ctx
, dims
,
1692 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1695 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1696 srcAddr
, srcPacking
);
1698 else if (!ctx
->_ImageTransferState
&&
1699 !srcPacking
->SwapBytes
&&
1700 srcFormat
== GL_RGBA
&&
1701 srcType
== GL_UNSIGNED_BYTE
) {
1702 /* extract RGB from RGBA */
1703 GLint img
, row
, col
;
1704 for (img
= 0; img
< srcDepth
; img
++) {
1705 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1706 srcWidth
, srcFormat
, srcType
);
1707 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1708 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1709 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1710 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1711 + dstYoffset
* dstRowStride
1712 + dstXoffset
* dstFormat
->TexelBytes
;
1713 for (row
= 0; row
< srcHeight
; row
++) {
1714 for (col
= 0; col
< srcWidth
; col
++) {
1715 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + BCOMP
];
1716 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1717 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + RCOMP
];
1719 dstRow
+= dstRowStride
;
1720 srcRow
+= srcRowStride
;
1724 else if (!ctx
->_ImageTransferState
&&
1725 srcType
== GL_UNSIGNED_BYTE
&&
1726 can_swizzle(baseInternalFormat
) &&
1727 can_swizzle(srcFormat
)) {
1731 /* dstmap - how to swizzle from RGBA to dst format:
1736 dstmap
[3] = ONE
; /* ? */
1738 _mesa_swizzle_ubyte_image(ctx
, dims
,
1743 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1744 dstRowStride
, dstImageOffsets
,
1745 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1750 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1752 dstFormat
->BaseFormat
,
1753 srcWidth
, srcHeight
, srcDepth
,
1754 srcFormat
, srcType
, srcAddr
,
1756 const GLchan
*src
= (const GLchan
*) tempImage
;
1757 GLint img
, row
, col
;
1760 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1761 for (img
= 0; img
< srcDepth
; img
++) {
1762 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1763 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1764 + dstYoffset
* dstRowStride
1765 + dstXoffset
* dstFormat
->TexelBytes
;
1766 for (row
= 0; row
< srcHeight
; row
++) {
1769 for (col
= 0; col
< srcWidth
; col
++) {
1770 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1771 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1772 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1777 for (col
= 0; col
< srcWidth
; col
++) {
1778 dstRow
[col
* 3 + 0] = srcUB
[BCOMP
];
1779 dstRow
[col
* 3 + 1] = srcUB
[GCOMP
];
1780 dstRow
[col
* 3 + 2] = srcUB
[RCOMP
];
1785 for (col
= 0; col
< srcWidth
; col
++) {
1786 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[BCOMP
]);
1787 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1788 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[RCOMP
]);
1792 dstRow
+= dstRowStride
;
1795 _mesa_free((void *) tempImage
);
1802 _mesa_texstore_bgr888(TEXSTORE_PARAMS
)
1804 const GLboolean littleEndian
= _mesa_little_endian();
1806 ASSERT(dstFormat
== &_mesa_texformat_bgr888
);
1807 ASSERT(dstFormat
->TexelBytes
== 3);
1809 if (!ctx
->_ImageTransferState
&&
1810 !srcPacking
->SwapBytes
&&
1811 baseInternalFormat
== GL_RGB
&&
1812 srcFormat
== GL_RGB
&&
1813 srcType
== GL_UNSIGNED_BYTE
&&
1815 /* simple memcpy path */
1816 memcpy_texture(ctx
, dims
,
1817 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1820 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1821 srcAddr
, srcPacking
);
1823 else if (!ctx
->_ImageTransferState
&&
1824 !srcPacking
->SwapBytes
&&
1825 srcFormat
== GL_RGBA
&&
1826 srcType
== GL_UNSIGNED_BYTE
) {
1827 /* extract BGR from RGBA */
1829 for (img
= 0; img
< srcDepth
; img
++) {
1830 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
,
1831 srcWidth
, srcFormat
, srcType
);
1832 GLubyte
*srcRow
= (GLubyte
*) _mesa_image_address(dims
, srcPacking
,
1833 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, 0, 0);
1834 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1835 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1836 + dstYoffset
* dstRowStride
1837 + dstXoffset
* dstFormat
->TexelBytes
;
1838 for (row
= 0; row
< srcHeight
; row
++) {
1839 for (col
= 0; col
< srcWidth
; col
++) {
1840 dstRow
[col
* 3 + 0] = srcRow
[col
* 4 + RCOMP
];
1841 dstRow
[col
* 3 + 1] = srcRow
[col
* 4 + GCOMP
];
1842 dstRow
[col
* 3 + 2] = srcRow
[col
* 4 + BCOMP
];
1844 dstRow
+= dstRowStride
;
1845 srcRow
+= srcRowStride
;
1849 else if (!ctx
->_ImageTransferState
&&
1850 srcType
== GL_UNSIGNED_BYTE
&&
1851 can_swizzle(baseInternalFormat
) &&
1852 can_swizzle(srcFormat
)) {
1856 /* dstmap - how to swizzle from RGBA to dst format:
1861 dstmap
[3] = ONE
; /* ? */
1863 _mesa_swizzle_ubyte_image(ctx
, dims
,
1868 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1869 dstRowStride
, dstImageOffsets
,
1870 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
1875 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1877 dstFormat
->BaseFormat
,
1878 srcWidth
, srcHeight
, srcDepth
,
1879 srcFormat
, srcType
, srcAddr
,
1881 const GLchan
*src
= (const GLchan
*) tempImage
;
1882 GLint img
, row
, col
;
1885 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1886 for (img
= 0; img
< srcDepth
; img
++) {
1887 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1888 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1889 + dstYoffset
* dstRowStride
1890 + dstXoffset
* dstFormat
->TexelBytes
;
1891 for (row
= 0; row
< srcHeight
; row
++) {
1892 for (col
= 0; col
< srcWidth
; col
++) {
1893 dstRow
[col
* 3 + 0] = CHAN_TO_UBYTE(src
[RCOMP
]);
1894 dstRow
[col
* 3 + 1] = CHAN_TO_UBYTE(src
[GCOMP
]);
1895 dstRow
[col
* 3 + 2] = CHAN_TO_UBYTE(src
[BCOMP
]);
1898 dstRow
+= dstRowStride
;
1901 _mesa_free((void *) tempImage
);
1907 _mesa_texstore_rgba4444(TEXSTORE_PARAMS
)
1909 ASSERT(dstFormat
== &_mesa_texformat_rgba4444
);
1910 ASSERT(dstFormat
->TexelBytes
== 2);
1912 if (!ctx
->_ImageTransferState
&&
1913 !srcPacking
->SwapBytes
&&
1914 dstFormat
== &_mesa_texformat_rgba4444
&&
1915 baseInternalFormat
== GL_RGBA
&&
1916 srcFormat
== GL_RGBA
&&
1917 srcType
== GL_UNSIGNED_SHORT_4_4_4_4
){
1918 /* simple memcpy path */
1919 memcpy_texture(ctx
, dims
,
1920 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1923 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1924 srcAddr
, srcPacking
);
1928 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1930 dstFormat
->BaseFormat
,
1931 srcWidth
, srcHeight
, srcDepth
,
1932 srcFormat
, srcType
, srcAddr
,
1934 const GLchan
*src
= tempImage
;
1935 GLint img
, row
, col
;
1938 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1939 for (img
= 0; img
< srcDepth
; img
++) {
1940 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1941 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1942 + dstYoffset
* dstRowStride
1943 + dstXoffset
* dstFormat
->TexelBytes
;
1944 for (row
= 0; row
< srcHeight
; row
++) {
1945 GLushort
*dstUS
= (GLushort
*) dstRow
;
1946 for (col
= 0; col
< srcWidth
; col
++) {
1947 dstUS
[col
] = PACK_COLOR_4444( CHAN_TO_UBYTE(src
[RCOMP
]),
1948 CHAN_TO_UBYTE(src
[GCOMP
]),
1949 CHAN_TO_UBYTE(src
[BCOMP
]),
1950 CHAN_TO_UBYTE(src
[ACOMP
]) );
1953 dstRow
+= dstRowStride
;
1956 _mesa_free((void *) tempImage
);
1962 _mesa_texstore_argb4444(TEXSTORE_PARAMS
)
1964 ASSERT(dstFormat
== &_mesa_texformat_argb4444
||
1965 dstFormat
== &_mesa_texformat_argb4444_rev
);
1966 ASSERT(dstFormat
->TexelBytes
== 2);
1968 if (!ctx
->_ImageTransferState
&&
1969 !srcPacking
->SwapBytes
&&
1970 dstFormat
== &_mesa_texformat_argb4444
&&
1971 baseInternalFormat
== GL_RGBA
&&
1972 srcFormat
== GL_BGRA
&&
1973 srcType
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
1974 /* simple memcpy path */
1975 memcpy_texture(ctx
, dims
,
1976 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
1979 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1980 srcAddr
, srcPacking
);
1984 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
1986 dstFormat
->BaseFormat
,
1987 srcWidth
, srcHeight
, srcDepth
,
1988 srcFormat
, srcType
, srcAddr
,
1990 const GLchan
*src
= tempImage
;
1991 GLint img
, row
, col
;
1994 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
1995 for (img
= 0; img
< srcDepth
; img
++) {
1996 GLubyte
*dstRow
= (GLubyte
*) dstAddr
1997 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
1998 + dstYoffset
* dstRowStride
1999 + dstXoffset
* dstFormat
->TexelBytes
;
2000 for (row
= 0; row
< srcHeight
; row
++) {
2001 GLushort
*dstUS
= (GLushort
*) dstRow
;
2002 if (dstFormat
== &_mesa_texformat_argb4444
) {
2003 for (col
= 0; col
< srcWidth
; col
++) {
2004 dstUS
[col
] = PACK_COLOR_4444( CHAN_TO_UBYTE(src
[ACOMP
]),
2005 CHAN_TO_UBYTE(src
[RCOMP
]),
2006 CHAN_TO_UBYTE(src
[GCOMP
]),
2007 CHAN_TO_UBYTE(src
[BCOMP
]) );
2012 for (col
= 0; col
< srcWidth
; col
++) {
2013 dstUS
[col
] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
2014 CHAN_TO_UBYTE(src
[RCOMP
]),
2015 CHAN_TO_UBYTE(src
[GCOMP
]),
2016 CHAN_TO_UBYTE(src
[BCOMP
]) );
2020 dstRow
+= dstRowStride
;
2023 _mesa_free((void *) tempImage
);
2029 _mesa_texstore_rgba5551(TEXSTORE_PARAMS
)
2031 ASSERT(dstFormat
== &_mesa_texformat_rgba5551
);
2032 ASSERT(dstFormat
->TexelBytes
== 2);
2034 if (!ctx
->_ImageTransferState
&&
2035 !srcPacking
->SwapBytes
&&
2036 dstFormat
== &_mesa_texformat_rgba5551
&&
2037 baseInternalFormat
== GL_RGBA
&&
2038 srcFormat
== GL_RGBA
&&
2039 srcType
== GL_UNSIGNED_SHORT_5_5_5_1
) {
2040 /* simple memcpy path */
2041 memcpy_texture(ctx
, dims
,
2042 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2045 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2046 srcAddr
, srcPacking
);
2050 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2052 dstFormat
->BaseFormat
,
2053 srcWidth
, srcHeight
, srcDepth
,
2054 srcFormat
, srcType
, srcAddr
,
2056 const GLchan
*src
=tempImage
;
2057 GLint img
, row
, col
;
2060 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2061 for (img
= 0; img
< srcDepth
; img
++) {
2062 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2063 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2064 + dstYoffset
* dstRowStride
2065 + dstXoffset
* dstFormat
->TexelBytes
;
2066 for (row
= 0; row
< srcHeight
; row
++) {
2067 GLushort
*dstUS
= (GLushort
*) dstRow
;
2068 for (col
= 0; col
< srcWidth
; col
++) {
2069 dstUS
[col
] = PACK_COLOR_5551( CHAN_TO_UBYTE(src
[RCOMP
]),
2070 CHAN_TO_UBYTE(src
[GCOMP
]),
2071 CHAN_TO_UBYTE(src
[BCOMP
]),
2072 CHAN_TO_UBYTE(src
[ACOMP
]) );
2075 dstRow
+= dstRowStride
;
2078 _mesa_free((void *) tempImage
);
2084 _mesa_texstore_argb1555(TEXSTORE_PARAMS
)
2086 ASSERT(dstFormat
== &_mesa_texformat_argb1555
||
2087 dstFormat
== &_mesa_texformat_argb1555_rev
);
2088 ASSERT(dstFormat
->TexelBytes
== 2);
2090 if (!ctx
->_ImageTransferState
&&
2091 !srcPacking
->SwapBytes
&&
2092 dstFormat
== &_mesa_texformat_argb1555
&&
2093 baseInternalFormat
== GL_RGBA
&&
2094 srcFormat
== GL_BGRA
&&
2095 srcType
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
2096 /* simple memcpy path */
2097 memcpy_texture(ctx
, dims
,
2098 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2101 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2102 srcAddr
, srcPacking
);
2106 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2108 dstFormat
->BaseFormat
,
2109 srcWidth
, srcHeight
, srcDepth
,
2110 srcFormat
, srcType
, srcAddr
,
2112 const GLchan
*src
=tempImage
;
2113 GLint img
, row
, col
;
2116 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2117 for (img
= 0; img
< srcDepth
; img
++) {
2118 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2119 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2120 + dstYoffset
* dstRowStride
2121 + dstXoffset
* dstFormat
->TexelBytes
;
2122 for (row
= 0; row
< srcHeight
; row
++) {
2123 GLushort
*dstUS
= (GLushort
*) dstRow
;
2124 if (dstFormat
== &_mesa_texformat_argb1555
) {
2125 for (col
= 0; col
< srcWidth
; col
++) {
2126 dstUS
[col
] = PACK_COLOR_1555( CHAN_TO_UBYTE(src
[ACOMP
]),
2127 CHAN_TO_UBYTE(src
[RCOMP
]),
2128 CHAN_TO_UBYTE(src
[GCOMP
]),
2129 CHAN_TO_UBYTE(src
[BCOMP
]) );
2134 for (col
= 0; col
< srcWidth
; col
++) {
2135 dstUS
[col
] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src
[ACOMP
]),
2136 CHAN_TO_UBYTE(src
[RCOMP
]),
2137 CHAN_TO_UBYTE(src
[GCOMP
]),
2138 CHAN_TO_UBYTE(src
[BCOMP
]) );
2142 dstRow
+= dstRowStride
;
2145 _mesa_free((void *) tempImage
);
2152 _mesa_texstore_al88(TEXSTORE_PARAMS
)
2154 const GLboolean littleEndian
= _mesa_little_endian();
2156 ASSERT(dstFormat
== &_mesa_texformat_al88
||
2157 dstFormat
== &_mesa_texformat_al88_rev
);
2158 ASSERT(dstFormat
->TexelBytes
== 2);
2160 if (!ctx
->_ImageTransferState
&&
2161 !srcPacking
->SwapBytes
&&
2162 dstFormat
== &_mesa_texformat_al88
&&
2163 baseInternalFormat
== GL_LUMINANCE_ALPHA
&&
2164 srcFormat
== GL_LUMINANCE_ALPHA
&&
2165 srcType
== GL_UNSIGNED_BYTE
&&
2167 /* simple memcpy path */
2168 memcpy_texture(ctx
, dims
,
2169 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2172 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2173 srcAddr
, srcPacking
);
2175 else if (!ctx
->_ImageTransferState
&&
2177 srcType
== GL_UNSIGNED_BYTE
&&
2178 can_swizzle(baseInternalFormat
) &&
2179 can_swizzle(srcFormat
)) {
2183 /* dstmap - how to swizzle from RGBA to dst format:
2185 if ((littleEndian
&& dstFormat
== &_mesa_texformat_al88
) ||
2186 (!littleEndian
&& dstFormat
== &_mesa_texformat_al88_rev
)) {
2194 dstmap
[2] = ZERO
; /* ? */
2195 dstmap
[3] = ONE
; /* ? */
2197 _mesa_swizzle_ubyte_image(ctx
, dims
,
2202 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2203 dstRowStride
, dstImageOffsets
,
2204 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2209 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2211 dstFormat
->BaseFormat
,
2212 srcWidth
, srcHeight
, srcDepth
,
2213 srcFormat
, srcType
, srcAddr
,
2215 const GLchan
*src
= tempImage
;
2216 GLint img
, row
, col
;
2219 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2220 for (img
= 0; img
< srcDepth
; img
++) {
2221 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2222 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2223 + dstYoffset
* dstRowStride
2224 + dstXoffset
* dstFormat
->TexelBytes
;
2225 for (row
= 0; row
< srcHeight
; row
++) {
2226 GLushort
*dstUS
= (GLushort
*) dstRow
;
2227 if (dstFormat
== &_mesa_texformat_al88
) {
2228 for (col
= 0; col
< srcWidth
; col
++) {
2229 /* src[0] is luminance, src[1] is alpha */
2230 dstUS
[col
] = PACK_COLOR_88( CHAN_TO_UBYTE(src
[1]),
2231 CHAN_TO_UBYTE(src
[0]) );
2236 for (col
= 0; col
< srcWidth
; col
++) {
2237 /* src[0] is luminance, src[1] is alpha */
2238 dstUS
[col
] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src
[1]),
2239 CHAN_TO_UBYTE(src
[0]) );
2243 dstRow
+= dstRowStride
;
2246 _mesa_free((void *) tempImage
);
2253 _mesa_texstore_rgb332(TEXSTORE_PARAMS
)
2255 ASSERT(dstFormat
== &_mesa_texformat_rgb332
);
2256 ASSERT(dstFormat
->TexelBytes
== 1);
2258 if (!ctx
->_ImageTransferState
&&
2259 !srcPacking
->SwapBytes
&&
2260 baseInternalFormat
== GL_RGB
&&
2261 srcFormat
== GL_RGB
&& srcType
== GL_UNSIGNED_BYTE_3_3_2
) {
2262 /* simple memcpy path */
2263 memcpy_texture(ctx
, dims
,
2264 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2267 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2268 srcAddr
, srcPacking
);
2272 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2274 dstFormat
->BaseFormat
,
2275 srcWidth
, srcHeight
, srcDepth
,
2276 srcFormat
, srcType
, srcAddr
,
2278 const GLchan
*src
= tempImage
;
2279 GLint img
, row
, col
;
2282 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2283 for (img
= 0; img
< srcDepth
; img
++) {
2284 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2285 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2286 + dstYoffset
* dstRowStride
2287 + dstXoffset
* dstFormat
->TexelBytes
;
2288 for (row
= 0; row
< srcHeight
; row
++) {
2289 for (col
= 0; col
< srcWidth
; col
++) {
2290 dstRow
[col
] = PACK_COLOR_332( CHAN_TO_UBYTE(src
[RCOMP
]),
2291 CHAN_TO_UBYTE(src
[GCOMP
]),
2292 CHAN_TO_UBYTE(src
[BCOMP
]) );
2295 dstRow
+= dstRowStride
;
2298 _mesa_free((void *) tempImage
);
2305 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2308 _mesa_texstore_a8(TEXSTORE_PARAMS
)
2310 ASSERT(dstFormat
== &_mesa_texformat_a8
||
2311 dstFormat
== &_mesa_texformat_l8
||
2312 dstFormat
== &_mesa_texformat_i8
);
2313 ASSERT(dstFormat
->TexelBytes
== 1);
2315 if (!ctx
->_ImageTransferState
&&
2316 !srcPacking
->SwapBytes
&&
2317 baseInternalFormat
== srcFormat
&&
2318 srcType
== GL_UNSIGNED_BYTE
) {
2319 /* simple memcpy path */
2320 memcpy_texture(ctx
, dims
,
2321 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2324 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2325 srcAddr
, srcPacking
);
2327 else if (!ctx
->_ImageTransferState
&&
2328 srcType
== GL_UNSIGNED_BYTE
&&
2329 can_swizzle(baseInternalFormat
) &&
2330 can_swizzle(srcFormat
)) {
2334 /* dstmap - how to swizzle from RGBA to dst format:
2336 if (dstFormat
== &_mesa_texformat_a8
) {
2342 dstmap
[1] = ZERO
; /* ? */
2343 dstmap
[2] = ZERO
; /* ? */
2344 dstmap
[3] = ONE
; /* ? */
2346 _mesa_swizzle_ubyte_image(ctx
, dims
,
2351 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2352 dstRowStride
, dstImageOffsets
,
2353 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2358 const GLchan
*tempImage
= _mesa_make_temp_chan_image(ctx
, dims
,
2360 dstFormat
->BaseFormat
,
2361 srcWidth
, srcHeight
, srcDepth
,
2362 srcFormat
, srcType
, srcAddr
,
2364 const GLchan
*src
= tempImage
;
2365 GLint img
, row
, col
;
2368 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2369 for (img
= 0; img
< srcDepth
; img
++) {
2370 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2371 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2372 + dstYoffset
* dstRowStride
2373 + dstXoffset
* dstFormat
->TexelBytes
;
2374 for (row
= 0; row
< srcHeight
; row
++) {
2375 for (col
= 0; col
< srcWidth
; col
++) {
2376 dstRow
[col
] = CHAN_TO_UBYTE(src
[col
]);
2378 dstRow
+= dstRowStride
;
2382 _mesa_free((void *) tempImage
);
2390 _mesa_texstore_ci8(TEXSTORE_PARAMS
)
2392 (void) dims
; (void) baseInternalFormat
;
2393 ASSERT(dstFormat
== &_mesa_texformat_ci8
);
2394 ASSERT(dstFormat
->TexelBytes
== 1);
2395 ASSERT(baseInternalFormat
== GL_COLOR_INDEX
);
2397 if (!ctx
->_ImageTransferState
&&
2398 !srcPacking
->SwapBytes
&&
2399 srcFormat
== GL_COLOR_INDEX
&&
2400 srcType
== GL_UNSIGNED_BYTE
) {
2401 /* simple memcpy path */
2402 memcpy_texture(ctx
, dims
,
2403 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2406 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2407 srcAddr
, srcPacking
);
2412 for (img
= 0; img
< srcDepth
; img
++) {
2413 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2414 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2415 + dstYoffset
* dstRowStride
2416 + dstXoffset
* dstFormat
->TexelBytes
;
2417 for (row
= 0; row
< srcHeight
; row
++) {
2418 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
2419 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
2420 _mesa_unpack_index_span(ctx
, srcWidth
, GL_UNSIGNED_BYTE
, dstRow
,
2421 srcType
, src
, srcPacking
,
2422 ctx
->_ImageTransferState
);
2423 dstRow
+= dstRowStride
;
2432 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
2435 _mesa_texstore_ycbcr(TEXSTORE_PARAMS
)
2437 const GLboolean littleEndian
= _mesa_little_endian();
2438 (void) ctx
; (void) dims
; (void) baseInternalFormat
;
2440 ASSERT((dstFormat
== &_mesa_texformat_ycbcr
) ||
2441 (dstFormat
== &_mesa_texformat_ycbcr_rev
));
2442 ASSERT(dstFormat
->TexelBytes
== 2);
2443 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
2444 ASSERT(srcFormat
== GL_YCBCR_MESA
);
2445 ASSERT((srcType
== GL_UNSIGNED_SHORT_8_8_MESA
) ||
2446 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
));
2447 ASSERT(baseInternalFormat
== GL_YCBCR_MESA
);
2449 /* always just memcpy since no pixel transfer ops apply */
2450 memcpy_texture(ctx
, dims
,
2451 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2454 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2455 srcAddr
, srcPacking
);
2457 /* Check if we need byte swapping */
2458 /* XXX the logic here _might_ be wrong */
2459 if (srcPacking
->SwapBytes
^
2460 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ^
2461 (dstFormat
== &_mesa_texformat_ycbcr_rev
) ^
2464 for (img
= 0; img
< srcDepth
; img
++) {
2465 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2466 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2467 + dstYoffset
* dstRowStride
2468 + dstXoffset
* dstFormat
->TexelBytes
;
2469 for (row
= 0; row
< srcHeight
; row
++) {
2470 _mesa_swap2((GLushort
*) dstRow
, srcWidth
);
2471 dstRow
+= dstRowStride
;
2479 _mesa_texstore_dudv8(TEXSTORE_PARAMS
)
2481 const GLboolean littleEndian
= _mesa_little_endian();
2483 ASSERT(dstFormat
== &_mesa_texformat_dudv8
);
2484 ASSERT(dstFormat
->TexelBytes
== 2);
2485 ASSERT(ctx
->Extensions
.ATI_envmap_bumpmap
);
2486 ASSERT((srcFormat
== GL_DU8DV8_ATI
) ||
2487 (srcFormat
== GL_DUDV_ATI
));
2488 ASSERT(baseInternalFormat
== GL_DUDV_ATI
);
2490 if (!srcPacking
->SwapBytes
&& srcType
== GL_BYTE
&&
2492 /* simple memcpy path */
2493 memcpy_texture(ctx
, dims
,
2494 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2497 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2498 srcAddr
, srcPacking
);
2500 else if (srcType
== GL_BYTE
) {
2504 /* dstmap - how to swizzle from RGBA to dst format:
2514 dstmap
[2] = ZERO
; /* ? */
2515 dstmap
[3] = ONE
; /* ? */
2517 _mesa_swizzle_ubyte_image(ctx
, dims
,
2518 GL_LUMINANCE_ALPHA
, /* hack */
2519 GL_UNSIGNED_BYTE
, /* hack */
2520 GL_LUMINANCE_ALPHA
, /* hack */
2522 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2523 dstRowStride
, dstImageOffsets
,
2524 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2528 /* general path - note this is defined for 2d textures only */
2529 const GLint components
= _mesa_components_in_format(baseInternalFormat
);
2530 const GLint srcStride
= _mesa_image_row_stride(srcPacking
,
2531 srcWidth
, srcFormat
, srcType
);
2532 GLbyte
*tempImage
, *dst
, *src
;
2535 tempImage
= (GLbyte
*) _mesa_malloc(srcWidth
* srcHeight
* srcDepth
2536 * components
* sizeof(GLbyte
));
2540 src
= (GLbyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2541 srcWidth
, srcHeight
,
2546 for (row
= 0; row
< srcHeight
; row
++) {
2547 _mesa_unpack_dudv_span_byte(ctx
, srcWidth
, baseInternalFormat
,
2548 dst
, srcFormat
, srcType
, src
,
2550 dst
+= srcWidth
* components
;
2555 dst
= (GLbyte
*) dstAddr
2556 + dstYoffset
* dstRowStride
2557 + dstXoffset
* dstFormat
->TexelBytes
;
2558 for (row
= 0; row
< srcHeight
; row
++) {
2559 memcpy(dst
, src
, srcWidth
* dstFormat
->TexelBytes
);
2560 dst
+= dstRowStride
;
2561 src
+= srcWidth
* dstFormat
->TexelBytes
;
2563 _mesa_free((void *) tempImage
);
2569 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or MESA_FORMAT_SIGNED_RGBA8888_REV
2572 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS
)
2574 const GLboolean littleEndian
= _mesa_little_endian();
2576 ASSERT(dstFormat
== &_mesa_texformat_signed_rgba8888
||
2577 dstFormat
== &_mesa_texformat_signed_rgba8888_rev
);
2578 ASSERT(dstFormat
->TexelBytes
== 4);
2580 if (!ctx
->_ImageTransferState
&&
2581 !srcPacking
->SwapBytes
&&
2582 dstFormat
== &_mesa_texformat_signed_rgba8888
&&
2583 baseInternalFormat
== GL_RGBA
&&
2584 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& !littleEndian
) ||
2585 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& littleEndian
))) {
2586 /* simple memcpy path */
2587 memcpy_texture(ctx
, dims
,
2588 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2591 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2592 srcAddr
, srcPacking
);
2594 else if (!ctx
->_ImageTransferState
&&
2595 !srcPacking
->SwapBytes
&&
2596 dstFormat
== &_mesa_texformat_signed_rgba8888_rev
&&
2597 baseInternalFormat
== GL_RGBA
&&
2598 ((srcFormat
== GL_RGBA
&& srcType
== GL_BYTE
&& littleEndian
) ||
2599 (srcFormat
== GL_ABGR_EXT
&& srcType
== GL_BYTE
&& !littleEndian
))) {
2600 /* simple memcpy path */
2601 memcpy_texture(ctx
, dims
,
2602 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2605 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2606 srcAddr
, srcPacking
);
2608 else if (!ctx
->_ImageTransferState
&&
2609 (srcType
== GL_BYTE
) &&
2610 can_swizzle(baseInternalFormat
) &&
2611 can_swizzle(srcFormat
)) {
2615 /* dstmap - how to swizzle from RGBA to dst format:
2617 if ((littleEndian
&& dstFormat
== &_mesa_texformat_signed_rgba8888
) ||
2618 (!littleEndian
&& dstFormat
== &_mesa_texformat_signed_rgba8888_rev
)) {
2631 _mesa_swizzle_ubyte_image(ctx
, dims
,
2636 dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2637 dstRowStride
, dstImageOffsets
,
2638 srcWidth
, srcHeight
, srcDepth
, srcAddr
,
2643 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2645 dstFormat
->BaseFormat
,
2646 srcWidth
, srcHeight
, srcDepth
,
2647 srcFormat
, srcType
, srcAddr
,
2649 const GLfloat
*srcRow
= tempImage
;
2650 GLint img
, row
, col
;
2653 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2654 for (img
= 0; img
< srcDepth
; img
++) {
2655 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2656 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2657 + dstYoffset
* dstRowStride
2658 + dstXoffset
* dstFormat
->TexelBytes
;
2659 for (row
= 0; row
< srcHeight
; row
++) {
2660 GLuint
*dstUI
= (GLuint
*) dstRow
;
2661 if (dstFormat
== &_mesa_texformat_signed_rgba8888
) {
2662 for (col
= 0; col
< srcWidth
; col
++) {
2663 dstUI
[col
] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2664 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2665 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2666 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2671 for (col
= 0; col
< srcWidth
; col
++) {
2672 dstUI
[col
] = PACK_COLOR_8888_REV( FLOAT_TO_BYTE_TEX(srcRow
[RCOMP
]),
2673 FLOAT_TO_BYTE_TEX(srcRow
[GCOMP
]),
2674 FLOAT_TO_BYTE_TEX(srcRow
[BCOMP
]),
2675 FLOAT_TO_BYTE_TEX(srcRow
[ACOMP
]) );
2679 dstRow
+= dstRowStride
;
2682 _mesa_free((void *) tempImage
);
2688 * Store a combined depth/stencil texture image.
2691 _mesa_texstore_z24_s8(TEXSTORE_PARAMS
)
2693 const GLfloat depthScale
= (GLfloat
) 0xffffff;
2694 const GLint srcRowStride
2695 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2699 ASSERT(dstFormat
== &_mesa_texformat_z24_s8
);
2700 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
);
2701 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2703 /* In case we only upload depth we need to preserve the stencil */
2704 if (srcFormat
== GL_DEPTH_COMPONENT
) {
2705 for (img
= 0; img
< srcDepth
; img
++) {
2706 GLuint
*dstRow
= (GLuint
*) dstAddr
2707 + dstImageOffsets
[dstZoffset
+ img
]
2708 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2711 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2712 srcWidth
, srcHeight
,
2715 for (row
= 0; row
< srcHeight
; row
++) {
2716 GLuint depth
[MAX_WIDTH
];
2718 _mesa_unpack_depth_span(ctx
, srcWidth
,
2719 GL_UNSIGNED_INT
, /* dst type */
2720 depth
, /* dst addr */
2722 srcType
, src
, srcPacking
);
2724 for (i
= 0; i
< srcWidth
; i
++)
2725 dstRow
[i
] = depth
[i
] << 8 | (dstRow
[i
] & 0x000000FF);
2727 src
+= srcRowStride
;
2728 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2732 else if (ctx
->Pixel
.DepthScale
== 1.0f
&&
2733 ctx
->Pixel
.DepthBias
== 0.0f
&&
2734 !srcPacking
->SwapBytes
) {
2736 memcpy_texture(ctx
, dims
,
2737 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2740 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2741 srcAddr
, srcPacking
);
2745 const GLint srcRowStride
2746 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2750 for (img
= 0; img
< srcDepth
; img
++) {
2751 GLuint
*dstRow
= (GLuint
*) dstAddr
2752 + dstImageOffsets
[dstZoffset
+ img
]
2753 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2756 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2757 srcWidth
, srcHeight
,
2760 for (row
= 0; row
< srcHeight
; row
++) {
2761 GLubyte stencil
[MAX_WIDTH
];
2763 /* the 24 depth bits will be in the high position: */
2764 _mesa_unpack_depth_span(ctx
, srcWidth
,
2765 GL_UNSIGNED_INT_24_8_EXT
, /* dst type */
2766 dstRow
, /* dst addr */
2767 (GLuint
) depthScale
,
2768 srcType
, src
, srcPacking
);
2769 /* get the 8-bit stencil values */
2770 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2771 GL_UNSIGNED_BYTE
, /* dst type */
2772 stencil
, /* dst addr */
2773 srcType
, src
, srcPacking
,
2774 ctx
->_ImageTransferState
);
2775 /* merge stencil values into depth values */
2776 for (i
= 0; i
< srcWidth
; i
++)
2777 dstRow
[i
] |= stencil
[i
];
2779 src
+= srcRowStride
;
2780 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2789 * Store a combined depth/stencil texture image.
2792 _mesa_texstore_s8_z24(TEXSTORE_PARAMS
)
2794 const GLuint depthScale
= 0xffffff;
2795 const GLint srcRowStride
2796 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
2800 ASSERT(dstFormat
== &_mesa_texformat_s8_z24
);
2801 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
|| srcFormat
== GL_DEPTH_COMPONENT
);
2802 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
|| srcType
== GL_UNSIGNED_INT_24_8_EXT
);
2804 /* In case we only upload depth we need to preserve the stencil */
2805 if (srcFormat
== GL_DEPTH_COMPONENT
) {
2806 for (img
= 0; img
< srcDepth
; img
++) {
2807 GLuint
*dstRow
= (GLuint
*) dstAddr
2808 + dstImageOffsets
[dstZoffset
+ img
]
2809 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2812 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2813 srcWidth
, srcHeight
,
2816 for (row
= 0; row
< srcHeight
; row
++) {
2817 GLuint depth
[MAX_WIDTH
];
2819 _mesa_unpack_depth_span(ctx
, srcWidth
,
2820 GL_UNSIGNED_INT
, /* dst type */
2821 depth
, /* dst addr */
2823 srcType
, src
, srcPacking
);
2825 for (i
= 0; i
< srcWidth
; i
++)
2826 dstRow
[i
] = depth
[i
] | (dstRow
[i
] & 0xFF000000);
2828 src
+= srcRowStride
;
2829 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2834 for (img
= 0; img
< srcDepth
; img
++) {
2835 GLuint
*dstRow
= (GLuint
*) dstAddr
2836 + dstImageOffsets
[dstZoffset
+ img
]
2837 + dstYoffset
* dstRowStride
/ sizeof(GLuint
)
2840 = (const GLuint
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
2841 srcWidth
, srcHeight
,
2844 for (row
= 0; row
< srcHeight
; row
++) {
2845 GLubyte stencil
[MAX_WIDTH
];
2847 /* the 24 depth bits will be in the low position: */
2848 _mesa_unpack_depth_span(ctx
, srcWidth
,
2849 GL_UNSIGNED_INT
, /* dst type */
2850 dstRow
, /* dst addr */
2852 srcType
, src
, srcPacking
);
2853 /* get the 8-bit stencil values */
2854 _mesa_unpack_stencil_span(ctx
, srcWidth
,
2855 GL_UNSIGNED_BYTE
, /* dst type */
2856 stencil
, /* dst addr */
2857 srcType
, src
, srcPacking
,
2858 ctx
->_ImageTransferState
);
2859 /* merge stencil values into depth values */
2860 for (i
= 0; i
< srcWidth
; i
++)
2861 dstRow
[i
] |= stencil
[i
] << 24;
2863 src
+= srcRowStride
;
2864 dstRow
+= dstRowStride
/ sizeof(GLuint
);
2872 * Store an image in any of the formats:
2873 * _mesa_texformat_rgba_float32
2874 * _mesa_texformat_rgb_float32
2875 * _mesa_texformat_alpha_float32
2876 * _mesa_texformat_luminance_float32
2877 * _mesa_texformat_luminance_alpha_float32
2878 * _mesa_texformat_intensity_float32
2881 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS
)
2883 const GLint components
= _mesa_components_in_format(dstFormat
->BaseFormat
);
2885 ASSERT(dstFormat
== &_mesa_texformat_rgba_float32
||
2886 dstFormat
== &_mesa_texformat_rgb_float32
||
2887 dstFormat
== &_mesa_texformat_alpha_float32
||
2888 dstFormat
== &_mesa_texformat_luminance_float32
||
2889 dstFormat
== &_mesa_texformat_luminance_alpha_float32
||
2890 dstFormat
== &_mesa_texformat_intensity_float32
);
2891 ASSERT(baseInternalFormat
== GL_RGBA
||
2892 baseInternalFormat
== GL_RGB
||
2893 baseInternalFormat
== GL_ALPHA
||
2894 baseInternalFormat
== GL_LUMINANCE
||
2895 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
2896 baseInternalFormat
== GL_INTENSITY
);
2897 ASSERT(dstFormat
->TexelBytes
== components
* sizeof(GLfloat
));
2899 if (!ctx
->_ImageTransferState
&&
2900 !srcPacking
->SwapBytes
&&
2901 baseInternalFormat
== srcFormat
&&
2902 srcType
== GL_FLOAT
) {
2903 /* simple memcpy path */
2904 memcpy_texture(ctx
, dims
,
2905 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2908 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2909 srcAddr
, srcPacking
);
2913 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2915 dstFormat
->BaseFormat
,
2916 srcWidth
, srcHeight
, srcDepth
,
2917 srcFormat
, srcType
, srcAddr
,
2919 const GLfloat
*srcRow
= tempImage
;
2924 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2925 bytesPerRow
= srcWidth
* components
* sizeof(GLfloat
);
2926 for (img
= 0; img
< srcDepth
; img
++) {
2927 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2928 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2929 + dstYoffset
* dstRowStride
2930 + dstXoffset
* dstFormat
->TexelBytes
;
2931 for (row
= 0; row
< srcHeight
; row
++) {
2932 _mesa_memcpy(dstRow
, srcRow
, bytesPerRow
);
2933 dstRow
+= dstRowStride
;
2934 srcRow
+= srcWidth
* components
;
2938 _mesa_free((void *) tempImage
);
2945 * As above, but store 16-bit floats.
2948 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS
)
2950 const GLint components
= _mesa_components_in_format(dstFormat
->BaseFormat
);
2952 ASSERT(dstFormat
== &_mesa_texformat_rgba_float16
||
2953 dstFormat
== &_mesa_texformat_rgb_float16
||
2954 dstFormat
== &_mesa_texformat_alpha_float16
||
2955 dstFormat
== &_mesa_texformat_luminance_float16
||
2956 dstFormat
== &_mesa_texformat_luminance_alpha_float16
||
2957 dstFormat
== &_mesa_texformat_intensity_float16
);
2958 ASSERT(baseInternalFormat
== GL_RGBA
||
2959 baseInternalFormat
== GL_RGB
||
2960 baseInternalFormat
== GL_ALPHA
||
2961 baseInternalFormat
== GL_LUMINANCE
||
2962 baseInternalFormat
== GL_LUMINANCE_ALPHA
||
2963 baseInternalFormat
== GL_INTENSITY
);
2964 ASSERT(dstFormat
->TexelBytes
== components
* sizeof(GLhalfARB
));
2966 if (!ctx
->_ImageTransferState
&&
2967 !srcPacking
->SwapBytes
&&
2968 baseInternalFormat
== srcFormat
&&
2969 srcType
== GL_HALF_FLOAT_ARB
) {
2970 /* simple memcpy path */
2971 memcpy_texture(ctx
, dims
,
2972 dstFormat
, dstAddr
, dstXoffset
, dstYoffset
, dstZoffset
,
2975 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
2976 srcAddr
, srcPacking
);
2980 const GLfloat
*tempImage
= make_temp_float_image(ctx
, dims
,
2982 dstFormat
->BaseFormat
,
2983 srcWidth
, srcHeight
, srcDepth
,
2984 srcFormat
, srcType
, srcAddr
,
2986 const GLfloat
*src
= tempImage
;
2990 _mesa_adjust_image_for_convolution(ctx
, dims
, &srcWidth
, &srcHeight
);
2991 for (img
= 0; img
< srcDepth
; img
++) {
2992 GLubyte
*dstRow
= (GLubyte
*) dstAddr
2993 + dstImageOffsets
[dstZoffset
+ img
] * dstFormat
->TexelBytes
2994 + dstYoffset
* dstRowStride
2995 + dstXoffset
* dstFormat
->TexelBytes
;
2996 for (row
= 0; row
< srcHeight
; row
++) {
2997 GLhalfARB
*dstTexel
= (GLhalfARB
*) dstRow
;
2999 for (i
= 0; i
< srcWidth
* components
; i
++) {
3000 dstTexel
[i
] = _mesa_float_to_half(src
[i
]);
3002 dstRow
+= dstRowStride
;
3003 src
+= srcWidth
* components
;
3007 _mesa_free((void *) tempImage
);
3013 #if FEATURE_EXT_texture_sRGB
3015 _mesa_texstore_srgb8(TEXSTORE_PARAMS
)
3017 const struct gl_texture_format
*newDstFormat
;
3018 StoreTexImageFunc store
;
3021 ASSERT(dstFormat
== &_mesa_texformat_srgb8
);
3023 /* reuse normal rgb texstore code */
3024 newDstFormat
= &_mesa_texformat_rgb888
;
3025 store
= _mesa_texstore_rgb888
;
3027 k
= store(ctx
, dims
, baseInternalFormat
,
3028 newDstFormat
, dstAddr
,
3029 dstXoffset
, dstYoffset
, dstZoffset
,
3030 dstRowStride
, dstImageOffsets
,
3031 srcWidth
, srcHeight
, srcDepth
,
3033 srcAddr
, srcPacking
);
3039 _mesa_texstore_srgba8(TEXSTORE_PARAMS
)
3041 const struct gl_texture_format
*newDstFormat
;
3044 ASSERT(dstFormat
== &_mesa_texformat_srgba8
);
3046 /* reuse normal rgba texstore code */
3047 newDstFormat
= &_mesa_texformat_rgba8888
;
3049 k
= _mesa_texstore_rgba8888(ctx
, dims
, baseInternalFormat
,
3050 newDstFormat
, dstAddr
,
3051 dstXoffset
, dstYoffset
, dstZoffset
,
3052 dstRowStride
, dstImageOffsets
,
3053 srcWidth
, srcHeight
, srcDepth
,
3055 srcAddr
, srcPacking
);
3061 _mesa_texstore_sargb8(TEXSTORE_PARAMS
)
3063 const struct gl_texture_format
*newDstFormat
;
3066 ASSERT(dstFormat
== &_mesa_texformat_sargb8
);
3068 /* reuse normal rgba texstore code */
3069 newDstFormat
= &_mesa_texformat_argb8888
;
3071 k
= _mesa_texstore_argb8888(ctx
, dims
, baseInternalFormat
,
3072 newDstFormat
, dstAddr
,
3073 dstXoffset
, dstYoffset
, dstZoffset
,
3074 dstRowStride
, dstImageOffsets
,
3075 srcWidth
, srcHeight
, srcDepth
,
3077 srcAddr
, srcPacking
);
3083 _mesa_texstore_sl8(TEXSTORE_PARAMS
)
3085 const struct gl_texture_format
*newDstFormat
;
3088 ASSERT(dstFormat
== &_mesa_texformat_sl8
);
3090 newDstFormat
= &_mesa_texformat_l8
;
3092 /* _mesa_textore_a8 handles luminance8 too */
3093 k
= _mesa_texstore_a8(ctx
, dims
, baseInternalFormat
,
3094 newDstFormat
, dstAddr
,
3095 dstXoffset
, dstYoffset
, dstZoffset
,
3096 dstRowStride
, dstImageOffsets
,
3097 srcWidth
, srcHeight
, srcDepth
,
3099 srcAddr
, srcPacking
);
3105 _mesa_texstore_sla8(TEXSTORE_PARAMS
)
3107 const struct gl_texture_format
*newDstFormat
;
3110 ASSERT(dstFormat
== &_mesa_texformat_sla8
);
3112 /* reuse normal luminance/alpha texstore code */
3113 newDstFormat
= &_mesa_texformat_al88
;
3115 k
= _mesa_texstore_al88(ctx
, dims
, baseInternalFormat
,
3116 newDstFormat
, dstAddr
,
3117 dstXoffset
, dstYoffset
, dstZoffset
,
3118 dstRowStride
, dstImageOffsets
,
3119 srcWidth
, srcHeight
, srcDepth
,
3121 srcAddr
, srcPacking
);
3125 #endif /* FEATURE_EXT_texture_sRGB */
3129 * Check if an unpack PBO is active prior to fetching a texture image.
3130 * If so, do bounds checking and map the buffer into main memory.
3131 * Any errors detected will be recorded.
3132 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3135 _mesa_validate_pbo_teximage(GLcontext
*ctx
, GLuint dimensions
,
3136 GLsizei width
, GLsizei height
, GLsizei depth
,
3137 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3138 const struct gl_pixelstore_attrib
*unpack
,
3139 const char *funcName
)
3143 if (!_mesa_is_bufferobj(unpack
->BufferObj
)) {
3147 if (!_mesa_validate_pbo_access(dimensions
, unpack
, width
, height
, depth
,
3148 format
, type
, pixels
)) {
3149 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3153 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3154 GL_READ_ONLY_ARB
, unpack
->BufferObj
);
3156 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3160 return ADD_POINTERS(buf
, pixels
);
3165 * Check if an unpack PBO is active prior to fetching a compressed texture
3167 * If so, do bounds checking and map the buffer into main memory.
3168 * Any errors detected will be recorded.
3169 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3172 _mesa_validate_pbo_compressed_teximage(GLcontext
*ctx
,
3173 GLsizei imageSize
, const GLvoid
*pixels
,
3174 const struct gl_pixelstore_attrib
*packing
,
3175 const char *funcName
)
3179 if (!_mesa_is_bufferobj(packing
->BufferObj
)) {
3180 /* not using a PBO - return pointer unchanged */
3183 if ((const GLubyte
*) pixels
+ imageSize
>
3184 ((const GLubyte
*) 0) + packing
->BufferObj
->Size
) {
3185 /* out of bounds read! */
3186 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(invalid PBO access");
3190 buf
= (GLubyte
*) ctx
->Driver
.MapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3191 GL_READ_ONLY_ARB
, packing
->BufferObj
);
3193 _mesa_error(ctx
, GL_INVALID_OPERATION
, funcName
, "(PBO is mapped");
3197 return ADD_POINTERS(buf
, pixels
);
3202 * This function must be called after either of the validate_pbo_*_teximage()
3203 * functions. It unmaps the PBO buffer if it was mapped earlier.
3206 _mesa_unmap_teximage_pbo(GLcontext
*ctx
,
3207 const struct gl_pixelstore_attrib
*unpack
)
3209 if (_mesa_is_bufferobj(unpack
->BufferObj
)) {
3210 ctx
->Driver
.UnmapBuffer(ctx
, GL_PIXEL_UNPACK_BUFFER_EXT
,
3218 * Adaptor for fetching a GLchan texel from a float-valued texture.
3221 fetch_texel_float_to_chan(const struct gl_texture_image
*texImage
,
3222 GLint i
, GLint j
, GLint k
, GLchan
*texelOut
)
3225 ASSERT(texImage
->FetchTexelf
);
3226 texImage
->FetchTexelf(texImage
, i
, j
, k
, temp
);
3227 if (texImage
->TexFormat
->BaseFormat
== GL_DEPTH_COMPONENT
||
3228 texImage
->TexFormat
->BaseFormat
== GL_DEPTH_STENCIL_EXT
) {
3229 /* just one channel */
3230 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[0], temp
[0]);
3234 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[0], temp
[0]);
3235 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[1], temp
[1]);
3236 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[2], temp
[2]);
3237 UNCLAMPED_FLOAT_TO_CHAN(texelOut
[3], temp
[3]);
3243 * Adaptor for fetching a float texel from a GLchan-valued texture.
3246 fetch_texel_chan_to_float(const struct gl_texture_image
*texImage
,
3247 GLint i
, GLint j
, GLint k
, GLfloat
*texelOut
)
3250 ASSERT(texImage
->FetchTexelc
);
3251 texImage
->FetchTexelc(texImage
, i
, j
, k
, temp
);
3252 if (texImage
->TexFormat
->BaseFormat
== GL_DEPTH_COMPONENT
||
3253 texImage
->TexFormat
->BaseFormat
== GL_DEPTH_STENCIL_EXT
) {
3254 /* just one channel */
3255 texelOut
[0] = CHAN_TO_FLOAT(temp
[0]);
3259 texelOut
[0] = CHAN_TO_FLOAT(temp
[0]);
3260 texelOut
[1] = CHAN_TO_FLOAT(temp
[1]);
3261 texelOut
[2] = CHAN_TO_FLOAT(temp
[2]);
3262 texelOut
[3] = CHAN_TO_FLOAT(temp
[3]);
3268 * Initialize the texture image's FetchTexelc and FetchTexelf methods.
3271 _mesa_set_fetch_functions(struct gl_texture_image
*texImage
, GLuint dims
)
3273 ASSERT(dims
== 1 || dims
== 2 || dims
== 3);
3274 ASSERT(texImage
->TexFormat
);
3278 texImage
->FetchTexelc
= texImage
->TexFormat
->FetchTexel1D
;
3279 texImage
->FetchTexelf
= texImage
->TexFormat
->FetchTexel1Df
;
3282 texImage
->FetchTexelc
= texImage
->TexFormat
->FetchTexel2D
;
3283 texImage
->FetchTexelf
= texImage
->TexFormat
->FetchTexel2Df
;
3286 texImage
->FetchTexelc
= texImage
->TexFormat
->FetchTexel3D
;
3287 texImage
->FetchTexelf
= texImage
->TexFormat
->FetchTexel3Df
;
3293 /* now check if we need to use a float/chan adaptor */
3294 if (!texImage
->FetchTexelc
) {
3295 texImage
->FetchTexelc
= fetch_texel_float_to_chan
;
3297 else if (!texImage
->FetchTexelf
) {
3298 texImage
->FetchTexelf
= fetch_texel_chan_to_float
;
3302 ASSERT(texImage
->FetchTexelc
);
3303 ASSERT(texImage
->FetchTexelf
);
3308 compute_texture_size(GLcontext
*ctx
, struct gl_texture_image
*texImage
)
3310 if (texImage
->TexFormat
->TexelBytes
== 0) {
3311 /* must be a compressed format */
3312 texImage
->IsCompressed
= GL_TRUE
;
3313 texImage
->CompressedSize
=
3314 ctx
->Driver
.CompressedTextureSize(ctx
, texImage
->Width
,
3315 texImage
->Height
, texImage
->Depth
,
3316 texImage
->TexFormat
->MesaFormat
);
3319 /* non-compressed format */
3320 texImage
->IsCompressed
= GL_FALSE
;
3321 texImage
->CompressedSize
= 0;
3328 * This is the software fallback for Driver.TexImage1D()
3329 * and Driver.CopyTexImage1D().
3330 * \sa _mesa_store_teximage2d()
3331 * Note that the width may not be the actual texture width since it may
3332 * be changed by convolution w/ GL_REDUCE. The texImage->Width field will
3333 * have the actual texture size.
3336 _mesa_store_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3337 GLint internalFormat
,
3338 GLint width
, GLint border
,
3339 GLenum format
, GLenum type
, const GLvoid
*pixels
,
3340 const struct gl_pixelstore_attrib
*packing
,
3341 struct gl_texture_object
*texObj
,
3342 struct gl_texture_image
*texImage
)
3348 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3349 ASSERT(texImage
->TexFormat
);
3351 _mesa_set_fetch_functions(texImage
, 1);
3352 compute_texture_size(ctx
, texImage
);
3354 /* allocate memory */
3355 if (texImage
->IsCompressed
)
3356 sizeInBytes
= texImage
->CompressedSize
;
3358 sizeInBytes
= texImage
->Width
* texImage
->TexFormat
->TexelBytes
;
3359 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3360 if (!texImage
->Data
) {
3361 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
3365 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
3366 pixels
, packing
, "glTexImage1D");
3368 /* Note: we check for a NULL image pointer here, _after_ we allocated
3369 * memory for the texture. That's what the GL spec calls for.
3374 const GLint dstRowStride
= 0;
3376 ASSERT(texImage
->TexFormat
->StoreImage
);
3377 success
= texImage
->TexFormat
->StoreImage(ctx
, 1, texImage
->_BaseFormat
,
3378 texImage
->TexFormat
,
3380 0, 0, 0, /* dstX/Y/Zoffset */
3382 texImage
->ImageOffsets
,
3384 format
, type
, pixels
, packing
);
3386 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage1D");
3390 _mesa_unmap_teximage_pbo(ctx
, packing
);
3395 * This is the software fallback for Driver.TexImage2D()
3396 * and Driver.CopyTexImage2D().
3398 * This function is oriented toward storing images in main memory, rather
3399 * than VRAM. Device driver's can easily plug in their own replacement.
3401 * Note: width and height may be pre-convolved dimensions, but
3402 * texImage->Width and texImage->Height will be post-convolved dimensions.
3405 _mesa_store_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3406 GLint internalFormat
,
3407 GLint width
, GLint height
, GLint border
,
3408 GLenum format
, GLenum type
, const void *pixels
,
3409 const struct gl_pixelstore_attrib
*packing
,
3410 struct gl_texture_object
*texObj
,
3411 struct gl_texture_image
*texImage
)
3413 GLint texelBytes
, sizeInBytes
;
3417 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3418 ASSERT(texImage
->TexFormat
);
3420 _mesa_set_fetch_functions(texImage
, 2);
3421 compute_texture_size(ctx
, texImage
);
3423 texelBytes
= texImage
->TexFormat
->TexelBytes
;
3425 /* allocate memory */
3426 if (texImage
->IsCompressed
)
3427 sizeInBytes
= texImage
->CompressedSize
;
3429 sizeInBytes
= texImage
->Width
* texImage
->Height
* texelBytes
;
3430 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3431 if (!texImage
->Data
) {
3432 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
3436 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
3437 pixels
, packing
, "glTexImage2D");
3439 /* Note: we check for a NULL image pointer here, _after_ we allocated
3440 * memory for the texture. That's what the GL spec calls for.
3447 if (texImage
->IsCompressed
) {
3449 = _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, width
);
3452 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
3454 ASSERT(texImage
->TexFormat
->StoreImage
);
3455 success
= texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->_BaseFormat
,
3456 texImage
->TexFormat
,
3458 0, 0, 0, /* dstX/Y/Zoffset */
3460 texImage
->ImageOffsets
,
3462 format
, type
, pixels
, packing
);
3464 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage2D");
3468 _mesa_unmap_teximage_pbo(ctx
, packing
);
3474 * This is the software fallback for Driver.TexImage3D()
3475 * and Driver.CopyTexImage3D().
3476 * \sa _mesa_store_teximage2d()
3479 _mesa_store_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3480 GLint internalFormat
,
3481 GLint width
, GLint height
, GLint depth
, GLint border
,
3482 GLenum format
, GLenum type
, const void *pixels
,
3483 const struct gl_pixelstore_attrib
*packing
,
3484 struct gl_texture_object
*texObj
,
3485 struct gl_texture_image
*texImage
)
3487 GLint texelBytes
, sizeInBytes
;
3491 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, format
, type
);
3492 ASSERT(texImage
->TexFormat
);
3494 _mesa_set_fetch_functions(texImage
, 3);
3495 compute_texture_size(ctx
, texImage
);
3497 texelBytes
= texImage
->TexFormat
->TexelBytes
;
3499 /* allocate memory */
3500 if (texImage
->IsCompressed
)
3501 sizeInBytes
= texImage
->CompressedSize
;
3503 sizeInBytes
= width
* height
* depth
* texelBytes
;
3504 texImage
->Data
= _mesa_alloc_texmemory(sizeInBytes
);
3505 if (!texImage
->Data
) {
3506 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
3510 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
3511 type
, pixels
, packing
, "glTexImage3D");
3513 /* Note: we check for a NULL image pointer here, _after_ we allocated
3514 * memory for the texture. That's what the GL spec calls for.
3521 if (texImage
->IsCompressed
) {
3523 = _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
, width
);
3526 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
3528 ASSERT(texImage
->TexFormat
->StoreImage
);
3529 success
= texImage
->TexFormat
->StoreImage(ctx
, 3, texImage
->_BaseFormat
,
3530 texImage
->TexFormat
,
3532 0, 0, 0, /* dstX/Y/Zoffset */
3534 texImage
->ImageOffsets
,
3535 width
, height
, depth
,
3536 format
, type
, pixels
, packing
);
3538 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage3D");
3542 _mesa_unmap_teximage_pbo(ctx
, packing
);
3549 * This is the software fallback for Driver.TexSubImage1D()
3550 * and Driver.CopyTexSubImage1D().
3553 _mesa_store_texsubimage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3554 GLint xoffset
, GLint width
,
3555 GLenum format
, GLenum type
, const void *pixels
,
3556 const struct gl_pixelstore_attrib
*packing
,
3557 struct gl_texture_object
*texObj
,
3558 struct gl_texture_image
*texImage
)
3560 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3561 pixels
= _mesa_validate_pbo_teximage(ctx
, 1, width
, 1, 1, format
, type
,
3562 pixels
, packing
, "glTexSubImage1D");
3567 const GLint dstRowStride
= 0;
3569 ASSERT(texImage
->TexFormat
->StoreImage
);
3570 success
= texImage
->TexFormat
->StoreImage(ctx
, 1, texImage
->_BaseFormat
,
3571 texImage
->TexFormat
,
3573 xoffset
, 0, 0, /* offsets */
3575 texImage
->ImageOffsets
,
3577 format
, type
, pixels
, packing
);
3579 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage1D");
3583 _mesa_unmap_teximage_pbo(ctx
, packing
);
3589 * This is the software fallback for Driver.TexSubImage2D()
3590 * and Driver.CopyTexSubImage2D().
3593 _mesa_store_texsubimage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3594 GLint xoffset
, GLint yoffset
,
3595 GLint width
, GLint height
,
3596 GLenum format
, GLenum type
, const void *pixels
,
3597 const struct gl_pixelstore_attrib
*packing
,
3598 struct gl_texture_object
*texObj
,
3599 struct gl_texture_image
*texImage
)
3601 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3602 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1, format
, type
,
3603 pixels
, packing
, "glTexSubImage2D");
3608 GLint dstRowStride
= 0;
3610 if (texImage
->IsCompressed
) {
3611 dstRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
,
3615 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
3617 ASSERT(texImage
->TexFormat
->StoreImage
);
3618 success
= texImage
->TexFormat
->StoreImage(ctx
, 2, texImage
->_BaseFormat
,
3619 texImage
->TexFormat
,
3621 xoffset
, yoffset
, 0,
3623 texImage
->ImageOffsets
,
3625 format
, type
, pixels
, packing
);
3627 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage2D");
3631 _mesa_unmap_teximage_pbo(ctx
, packing
);
3636 * This is the software fallback for Driver.TexSubImage3D().
3637 * and Driver.CopyTexSubImage3D().
3640 _mesa_store_texsubimage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3641 GLint xoffset
, GLint yoffset
, GLint zoffset
,
3642 GLint width
, GLint height
, GLint depth
,
3643 GLenum format
, GLenum type
, const void *pixels
,
3644 const struct gl_pixelstore_attrib
*packing
,
3645 struct gl_texture_object
*texObj
,
3646 struct gl_texture_image
*texImage
)
3648 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3649 pixels
= _mesa_validate_pbo_teximage(ctx
, 3, width
, height
, depth
, format
,
3650 type
, pixels
, packing
,
3658 if (texImage
->IsCompressed
) {
3659 dstRowStride
= _mesa_compressed_row_stride(texImage
->TexFormat
->MesaFormat
,
3663 dstRowStride
= texImage
->RowStride
* texImage
->TexFormat
->TexelBytes
;
3665 ASSERT(texImage
->TexFormat
->StoreImage
);
3666 success
= texImage
->TexFormat
->StoreImage(ctx
, 3, texImage
->_BaseFormat
,
3667 texImage
->TexFormat
,
3669 xoffset
, yoffset
, zoffset
,
3671 texImage
->ImageOffsets
,
3672 width
, height
, depth
,
3673 format
, type
, pixels
, packing
);
3675 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexSubImage3D");
3679 _mesa_unmap_teximage_pbo(ctx
, packing
);
3684 * Fallback for Driver.CompressedTexImage1D()
3687 _mesa_store_compressed_teximage1d(GLcontext
*ctx
, GLenum target
, GLint level
,
3688 GLint internalFormat
,
3689 GLint width
, GLint border
,
3690 GLsizei imageSize
, const GLvoid
*data
,
3691 struct gl_texture_object
*texObj
,
3692 struct gl_texture_image
*texImage
)
3694 /* this space intentionally left blank */
3696 (void) target
; (void) level
;
3697 (void) internalFormat
;
3698 (void) width
; (void) border
;
3699 (void) imageSize
; (void) data
;
3707 * Fallback for Driver.CompressedTexImage2D()
3710 _mesa_store_compressed_teximage2d(GLcontext
*ctx
, GLenum target
, GLint level
,
3711 GLint internalFormat
,
3712 GLint width
, GLint height
, GLint border
,
3713 GLsizei imageSize
, const GLvoid
*data
,
3714 struct gl_texture_object
*texObj
,
3715 struct gl_texture_image
*texImage
)
3717 (void) width
; (void) height
; (void) border
;
3719 /* This is pretty simple, basically just do a memcpy without worrying
3720 * about the usual image unpacking or image transfer operations.
3724 ASSERT(texImage
->Width
> 0);
3725 ASSERT(texImage
->Height
> 0);
3726 ASSERT(texImage
->Depth
== 1);
3727 ASSERT(texImage
->Data
== NULL
); /* was freed in glCompressedTexImage2DARB */
3730 = ctx
->Driver
.ChooseTextureFormat(ctx
, internalFormat
, 0, 0);
3731 ASSERT(texImage
->TexFormat
);
3733 _mesa_set_fetch_functions(texImage
, 2);
3734 compute_texture_size(ctx
, texImage
);
3736 /* allocate storage */
3737 texImage
->Data
= _mesa_alloc_texmemory(imageSize
);
3738 if (!texImage
->Data
) {
3739 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage2DARB");
3743 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
3745 "glCompressedTexImage2D");
3750 ASSERT(texImage
->CompressedSize
== (GLuint
) imageSize
);
3751 MEMCPY(texImage
->Data
, data
, imageSize
);
3753 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
3759 * Fallback for Driver.CompressedTexImage3D()
3762 _mesa_store_compressed_teximage3d(GLcontext
*ctx
, GLenum target
, GLint level
,
3763 GLint internalFormat
,
3764 GLint width
, GLint height
, GLint depth
,
3766 GLsizei imageSize
, const GLvoid
*data
,
3767 struct gl_texture_object
*texObj
,
3768 struct gl_texture_image
*texImage
)
3770 /* this space intentionally left blank */
3772 (void) target
; (void) level
;
3773 (void) internalFormat
;
3774 (void) width
; (void) height
; (void) depth
;
3776 (void) imageSize
; (void) data
;
3784 * Fallback for Driver.CompressedTexSubImage1D()
3787 _mesa_store_compressed_texsubimage1d(GLcontext
*ctx
, GLenum target
,
3789 GLint xoffset
, GLsizei width
,
3791 GLsizei imageSize
, const GLvoid
*data
,
3792 struct gl_texture_object
*texObj
,
3793 struct gl_texture_image
*texImage
)
3795 /* there are no compressed 1D texture formats yet */
3797 (void) target
; (void) level
;
3798 (void) xoffset
; (void) width
;
3800 (void) imageSize
; (void) data
;
3807 * Fallback for Driver.CompressedTexSubImage2D()
3810 _mesa_store_compressed_texsubimage2d(GLcontext
*ctx
, GLenum target
,
3812 GLint xoffset
, GLint yoffset
,
3813 GLsizei width
, GLsizei height
,
3815 GLsizei imageSize
, const GLvoid
*data
,
3816 struct gl_texture_object
*texObj
,
3817 struct gl_texture_image
*texImage
)
3819 GLint bytesPerRow
, destRowStride
, srcRowStride
;
3823 const GLuint mesaFormat
= texImage
->TexFormat
->MesaFormat
;
3827 /* these should have been caught sooner */
3828 ASSERT((width
& 3) == 0 || width
== 2 || width
== 1);
3829 ASSERT((height
& 3) == 0 || height
== 2 || height
== 1);
3830 ASSERT((xoffset
& 3) == 0);
3831 ASSERT((yoffset
& 3) == 0);
3833 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3834 data
= _mesa_validate_pbo_compressed_teximage(ctx
, imageSize
, data
,
3836 "glCompressedTexSubImage2D");
3840 srcRowStride
= _mesa_compressed_row_stride(mesaFormat
, width
);
3841 src
= (const GLubyte
*) data
;
3843 destRowStride
= _mesa_compressed_row_stride(mesaFormat
, texImage
->Width
);
3844 dest
= _mesa_compressed_image_address(xoffset
, yoffset
, 0,
3845 texImage
->TexFormat
->MesaFormat
,
3847 (GLubyte
*) texImage
->Data
);
3849 bytesPerRow
= srcRowStride
;
3852 for (i
= 0; i
< rows
; i
++) {
3853 MEMCPY(dest
, src
, bytesPerRow
);
3854 dest
+= destRowStride
;
3855 src
+= srcRowStride
;
3858 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);
3863 * Fallback for Driver.CompressedTexSubImage3D()
3866 _mesa_store_compressed_texsubimage3d(GLcontext
*ctx
, GLenum target
,
3868 GLint xoffset
, GLint yoffset
, GLint zoffset
,
3869 GLsizei width
, GLsizei height
, GLsizei depth
,
3871 GLsizei imageSize
, const GLvoid
*data
,
3872 struct gl_texture_object
*texObj
,
3873 struct gl_texture_image
*texImage
)
3875 /* there are no compressed 3D texture formats yet */
3877 (void) target
; (void) level
;
3878 (void) xoffset
; (void) yoffset
; (void) zoffset
;
3879 (void) width
; (void) height
; (void) depth
;
3881 (void) imageSize
; (void) data
;