2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (c) 2008-2009 VMware, Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * 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.TexImage = _mesa_store_teximage;
41 * ctx->Driver.TexSubImage = _mesa_store_texsubimage;
44 * Texture image processing is actually kind of complicated. We have to do:
45 * Format/type conversions
47 * pixel transfer (scale, bais, lookup, etc)
49 * These functions can handle most everything, including processing full
50 * images and sub-images.
55 #include "bufferobj.h"
57 #include "format_pack.h"
58 #include "format_utils.h"
66 #include "texcompress.h"
67 #include "texcompress_fxt1.h"
68 #include "texcompress_rgtc.h"
69 #include "texcompress_s3tc.h"
70 #include "texcompress_etc.h"
71 #include "texcompress_bptc.h"
75 #include "glformats.h"
76 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
77 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
87 * Texture image storage function.
89 typedef GLboolean (*StoreTexImageFunc
)(TEXSTORE_PARAMS
);
109 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO)
110 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO)
111 #define MAP3(x,y,z) MAP4(x, y, z, ZERO)
112 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
115 static const struct {
118 GLubyte from_rgba
[6];
119 } mappings
[MAX_IDX
] =
129 MAP4(ZERO
, ZERO
, ZERO
, 0),
159 MAP4(0, ZERO
, ZERO
, ONE
),
165 MAP4(ZERO
, 0, ZERO
, ONE
),
171 MAP4(ZERO
, ZERO
, 0, ONE
),
195 MAP4(0, 1, ZERO
, ONE
),
203 * Convert a GL image format enum to an IDX_* value (see above).
206 get_map_idx(GLenum value
)
210 case GL_LUMINANCE_INTEGER_EXT
:
211 return IDX_LUMINANCE
;
213 case GL_ALPHA_INTEGER
:
216 return IDX_INTENSITY
;
217 case GL_LUMINANCE_ALPHA
:
218 case GL_LUMINANCE_ALPHA_INTEGER_EXT
:
219 return IDX_LUMINANCE_ALPHA
;
224 case GL_RGBA_INTEGER
:
237 case GL_BGRA_INTEGER
:
245 _mesa_problem(NULL
, "Unexpected inFormat %s",
246 _mesa_lookup_enum_by_nr(value
));
253 * When promoting texture formats (see below) we need to compute the
254 * mapping of dest components back to source components.
255 * This function does that.
256 * \param inFormat the incoming format of the texture
257 * \param outFormat the final texture format
258 * \return map[6] a full 6-component map
261 compute_component_mapping(GLenum inFormat
, GLenum outFormat
,
264 const int inFmt
= get_map_idx(inFormat
);
265 const int outFmt
= get_map_idx(outFormat
);
266 const GLubyte
*in2rgba
= mappings
[inFmt
].to_rgba
;
267 const GLubyte
*rgba2out
= mappings
[outFmt
].from_rgba
;
270 for (i
= 0; i
< 4; i
++)
271 map
[i
] = in2rgba
[rgba2out
[i
]];
277 printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
278 inFormat
, _mesa_lookup_enum_by_nr(inFormat
),
279 outFormat
, _mesa_lookup_enum_by_nr(outFormat
),
291 * Make a temporary (color) texture image with GLfloat components.
292 * Apply all needed pixel unpacking and pixel transfer operations.
293 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
294 * Suppose the user specifies GL_LUMINANCE as the internal texture format
295 * but the graphics hardware doesn't support luminance textures. So, we might
296 * use an RGB hardware format instead.
297 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
299 * \param ctx the rendering context
300 * \param dims image dimensions: 1, 2 or 3
301 * \param logicalBaseFormat basic texture derived from the user's
302 * internal texture format value
303 * \param textureBaseFormat the actual basic format of the texture
304 * \param srcWidth source image width
305 * \param srcHeight source image height
306 * \param srcDepth source image depth
307 * \param srcFormat source image format
308 * \param srcType source image type
309 * \param srcAddr source image address
310 * \param srcPacking source image pixel packing
311 * \return resulting image with format = textureBaseFormat and type = GLfloat.
314 _mesa_make_temp_float_image(struct gl_context
*ctx
, GLuint dims
,
315 GLenum logicalBaseFormat
,
316 GLenum textureBaseFormat
,
317 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
318 GLenum srcFormat
, GLenum srcType
,
319 const GLvoid
*srcAddr
,
320 const struct gl_pixelstore_attrib
*srcPacking
,
321 GLbitfield transferOps
)
324 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
325 const GLint srcStride
=
326 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
330 ASSERT(dims
>= 1 && dims
<= 3);
332 ASSERT(logicalBaseFormat
== GL_RGBA
||
333 logicalBaseFormat
== GL_RGB
||
334 logicalBaseFormat
== GL_RG
||
335 logicalBaseFormat
== GL_RED
||
336 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
337 logicalBaseFormat
== GL_LUMINANCE
||
338 logicalBaseFormat
== GL_ALPHA
||
339 logicalBaseFormat
== GL_INTENSITY
||
340 logicalBaseFormat
== GL_DEPTH_COMPONENT
);
342 ASSERT(textureBaseFormat
== GL_RGBA
||
343 textureBaseFormat
== GL_RGB
||
344 textureBaseFormat
== GL_RG
||
345 textureBaseFormat
== GL_RED
||
346 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
347 textureBaseFormat
== GL_LUMINANCE
||
348 textureBaseFormat
== GL_ALPHA
||
349 textureBaseFormat
== GL_INTENSITY
||
350 textureBaseFormat
== GL_DEPTH_COMPONENT
);
352 tempImage
= malloc(srcWidth
* srcHeight
* srcDepth
353 * components
* sizeof(GLfloat
));
358 for (img
= 0; img
< srcDepth
; img
++) {
360 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
364 for (row
= 0; row
< srcHeight
; row
++) {
365 _mesa_unpack_color_span_float(ctx
, srcWidth
, logicalBaseFormat
,
366 dst
, srcFormat
, srcType
, src
,
367 srcPacking
, transferOps
);
368 dst
+= srcWidth
* components
;
373 if (logicalBaseFormat
!= textureBaseFormat
) {
375 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
376 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
381 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
382 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
383 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
385 /* The actual texture format should have at least as many components
386 * as the logical texture format.
388 ASSERT(texComponents
>= logComponents
);
390 newImage
= malloc(srcWidth
* srcHeight
* srcDepth
391 * texComponents
* sizeof(GLfloat
));
397 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
399 n
= srcWidth
* srcHeight
* srcDepth
;
400 for (i
= 0; i
< n
; i
++) {
402 for (k
= 0; k
< texComponents
; k
++) {
405 newImage
[i
* texComponents
+ k
] = 0.0F
;
407 newImage
[i
* texComponents
+ k
] = 1.0F
;
409 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
414 tempImage
= newImage
;
422 * Make temporary image with uint pixel values. Used for unsigned
423 * integer-valued textures.
426 make_temp_uint_image(struct gl_context
*ctx
, GLuint dims
,
427 GLenum logicalBaseFormat
,
428 GLenum textureBaseFormat
,
429 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
430 GLenum srcFormat
, GLenum srcType
,
431 const GLvoid
*srcAddr
,
432 const struct gl_pixelstore_attrib
*srcPacking
)
435 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
436 const GLint srcStride
=
437 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
441 ASSERT(dims
>= 1 && dims
<= 3);
443 ASSERT(logicalBaseFormat
== GL_RGBA
||
444 logicalBaseFormat
== GL_RGB
||
445 logicalBaseFormat
== GL_RG
||
446 logicalBaseFormat
== GL_RED
||
447 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
448 logicalBaseFormat
== GL_LUMINANCE
||
449 logicalBaseFormat
== GL_INTENSITY
||
450 logicalBaseFormat
== GL_ALPHA
);
452 ASSERT(textureBaseFormat
== GL_RGBA
||
453 textureBaseFormat
== GL_RGB
||
454 textureBaseFormat
== GL_RG
||
455 textureBaseFormat
== GL_RED
||
456 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
457 textureBaseFormat
== GL_LUMINANCE
||
458 textureBaseFormat
== GL_INTENSITY
||
459 textureBaseFormat
== GL_ALPHA
);
461 tempImage
= malloc(srcWidth
* srcHeight
* srcDepth
462 * components
* sizeof(GLuint
));
467 for (img
= 0; img
< srcDepth
; img
++) {
469 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
473 for (row
= 0; row
< srcHeight
; row
++) {
474 _mesa_unpack_color_span_uint(ctx
, srcWidth
, logicalBaseFormat
,
475 dst
, srcFormat
, srcType
, src
,
477 dst
+= srcWidth
* components
;
482 if (logicalBaseFormat
!= textureBaseFormat
) {
484 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
485 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
490 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
491 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
492 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
494 /* The actual texture format should have at least as many components
495 * as the logical texture format.
497 ASSERT(texComponents
>= logComponents
);
499 newImage
= malloc(srcWidth
* srcHeight
* srcDepth
500 * texComponents
* sizeof(GLuint
));
506 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
508 n
= srcWidth
* srcHeight
* srcDepth
;
509 for (i
= 0; i
< n
; i
++) {
511 for (k
= 0; k
< texComponents
; k
++) {
514 newImage
[i
* texComponents
+ k
] = 0;
516 newImage
[i
* texComponents
+ k
] = 1;
518 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
523 tempImage
= newImage
;
532 * Make a temporary (color) texture image with GLubyte components.
533 * Apply all needed pixel unpacking and pixel transfer operations.
534 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
535 * Suppose the user specifies GL_LUMINANCE as the internal texture format
536 * but the graphics hardware doesn't support luminance textures. So, we might
537 * use an RGB hardware format instead.
538 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
540 * \param ctx the rendering context
541 * \param dims image dimensions: 1, 2 or 3
542 * \param logicalBaseFormat basic texture derived from the user's
543 * internal texture format value
544 * \param textureBaseFormat the actual basic format of the texture
545 * \param srcWidth source image width
546 * \param srcHeight source image height
547 * \param srcDepth source image depth
548 * \param srcFormat source image format
549 * \param srcType source image type
550 * \param srcAddr source image address
551 * \param srcPacking source image pixel packing
552 * \return resulting image with format = textureBaseFormat and type = GLubyte.
555 _mesa_make_temp_ubyte_image(struct gl_context
*ctx
, GLuint dims
,
556 GLenum logicalBaseFormat
,
557 GLenum textureBaseFormat
,
558 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
559 GLenum srcFormat
, GLenum srcType
,
560 const GLvoid
*srcAddr
,
561 const struct gl_pixelstore_attrib
*srcPacking
)
563 GLuint transferOps
= ctx
->_ImageTransferState
;
564 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
566 GLubyte
*tempImage
, *dst
;
568 ASSERT(dims
>= 1 && dims
<= 3);
570 ASSERT(logicalBaseFormat
== GL_RGBA
||
571 logicalBaseFormat
== GL_RGB
||
572 logicalBaseFormat
== GL_RG
||
573 logicalBaseFormat
== GL_RED
||
574 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
575 logicalBaseFormat
== GL_LUMINANCE
||
576 logicalBaseFormat
== GL_ALPHA
||
577 logicalBaseFormat
== GL_INTENSITY
);
579 ASSERT(textureBaseFormat
== GL_RGBA
||
580 textureBaseFormat
== GL_RGB
||
581 textureBaseFormat
== GL_RG
||
582 textureBaseFormat
== GL_RED
||
583 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
584 textureBaseFormat
== GL_LUMINANCE
||
585 textureBaseFormat
== GL_ALPHA
||
586 textureBaseFormat
== GL_INTENSITY
);
588 /* unpack and transfer the source image */
589 tempImage
= malloc(srcWidth
* srcHeight
* srcDepth
590 * components
* sizeof(GLubyte
));
596 for (img
= 0; img
< srcDepth
; img
++) {
597 const GLint srcStride
=
598 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
600 (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
604 for (row
= 0; row
< srcHeight
; row
++) {
605 _mesa_unpack_color_span_ubyte(ctx
, srcWidth
, logicalBaseFormat
, dst
,
606 srcFormat
, srcType
, src
, srcPacking
,
608 dst
+= srcWidth
* components
;
613 if (logicalBaseFormat
!= textureBaseFormat
) {
614 /* one more conversion step */
615 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
616 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
621 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
622 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
623 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
625 /* The actual texture format should have at least as many components
626 * as the logical texture format.
628 ASSERT(texComponents
>= logComponents
);
630 newImage
= malloc(srcWidth
* srcHeight
* srcDepth
631 * texComponents
* sizeof(GLubyte
));
637 compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
639 n
= srcWidth
* srcHeight
* srcDepth
;
640 for (i
= 0; i
< n
; i
++) {
642 for (k
= 0; k
< texComponents
; k
++) {
645 newImage
[i
* texComponents
+ k
] = 0;
647 newImage
[i
* texComponents
+ k
] = 255;
649 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
654 tempImage
= newImage
;
661 static const GLubyte map_identity
[6] = { 0, 1, 2, 3, ZERO
, ONE
};
662 static const GLubyte map_3210
[6] = { 3, 2, 1, 0, ZERO
, ONE
};
663 static const GLubyte map_1032
[6] = { 1, 0, 3, 2, ZERO
, ONE
};
667 * Teximage storage routine for when a simple memcpy will do.
668 * No pixel transfer operations or special texel encodings allowed.
669 * 1D, 2D and 3D images supported.
672 memcpy_texture(struct gl_context
*ctx
,
674 mesa_format dstFormat
,
677 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
678 GLenum srcFormat
, GLenum srcType
,
679 const GLvoid
*srcAddr
,
680 const struct gl_pixelstore_attrib
*srcPacking
)
682 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
684 const GLint srcImageStride
= _mesa_image_image_stride(srcPacking
,
685 srcWidth
, srcHeight
, srcFormat
, srcType
);
686 const GLubyte
*srcImage
= (const GLubyte
*) _mesa_image_address(dimensions
,
687 srcPacking
, srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, 0, 0, 0);
688 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
689 const GLint bytesPerRow
= srcWidth
* texelBytes
;
691 if (dstRowStride
== srcRowStride
&&
692 dstRowStride
== bytesPerRow
) {
693 /* memcpy image by image */
695 for (img
= 0; img
< srcDepth
; img
++) {
696 GLubyte
*dstImage
= dstSlices
[img
];
697 memcpy(dstImage
, srcImage
, bytesPerRow
* srcHeight
);
698 srcImage
+= srcImageStride
;
702 /* memcpy row by row */
704 for (img
= 0; img
< srcDepth
; img
++) {
705 const GLubyte
*srcRow
= srcImage
;
706 GLubyte
*dstRow
= dstSlices
[img
];
707 for (row
= 0; row
< srcHeight
; row
++) {
708 memcpy(dstRow
, srcRow
, bytesPerRow
);
709 dstRow
+= dstRowStride
;
710 srcRow
+= srcRowStride
;
712 srcImage
+= srcImageStride
;
719 * General-case function for storing a color texture images with
720 * components that can be represented with ubytes. Example destination
721 * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565.
724 store_ubyte_texture(TEXSTORE_PARAMS
)
726 const GLint srcRowStride
= srcWidth
* 4 * sizeof(GLubyte
);
727 GLubyte
*tempImage
, *src
;
730 tempImage
= _mesa_make_temp_ubyte_image(ctx
, dims
,
733 srcWidth
, srcHeight
, srcDepth
,
734 srcFormat
, srcType
, srcAddr
,
739 /* This way we will use the RGB versions of the packing functions and it
740 * will work for both RGB and sRGB textures*/
741 dstFormat
= _mesa_get_srgb_format_linear(dstFormat
);
744 for (img
= 0; img
< srcDepth
; img
++) {
745 _mesa_pack_ubyte_rgba_rect(dstFormat
, srcWidth
, srcHeight
,
747 dstSlices
[img
], dstRowStride
);
748 src
+= srcHeight
* srcRowStride
;
759 * Store a 32-bit integer or float depth component texture image.
762 _mesa_texstore_z32(TEXSTORE_PARAMS
)
764 const GLuint depthScale
= 0xffffffff;
767 ASSERT(dstFormat
== MESA_FORMAT_Z_UNORM32
||
768 dstFormat
== MESA_FORMAT_Z_FLOAT32
);
769 ASSERT(_mesa_get_format_bytes(dstFormat
) == sizeof(GLuint
));
771 if (dstFormat
== MESA_FORMAT_Z_UNORM32
)
772 dstType
= GL_UNSIGNED_INT
;
779 for (img
= 0; img
< srcDepth
; img
++) {
780 GLubyte
*dstRow
= dstSlices
[img
];
781 for (row
= 0; row
< srcHeight
; row
++) {
782 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
783 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
784 _mesa_unpack_depth_span(ctx
, srcWidth
,
786 depthScale
, srcType
, src
, srcPacking
);
787 dstRow
+= dstRowStride
;
796 * Store a 24-bit integer depth component texture image.
799 _mesa_texstore_x8_z24(TEXSTORE_PARAMS
)
801 const GLuint depthScale
= 0xffffff;
804 ASSERT(dstFormat
== MESA_FORMAT_Z24_UNORM_X8_UINT
);
809 for (img
= 0; img
< srcDepth
; img
++) {
810 GLubyte
*dstRow
= dstSlices
[img
];
811 for (row
= 0; row
< srcHeight
; row
++) {
812 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
813 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
814 _mesa_unpack_depth_span(ctx
, srcWidth
,
815 GL_UNSIGNED_INT
, (GLuint
*) dstRow
,
816 depthScale
, srcType
, src
, srcPacking
);
817 dstRow
+= dstRowStride
;
826 * Store a 24-bit integer depth component texture image.
829 _mesa_texstore_z24_x8(TEXSTORE_PARAMS
)
831 const GLuint depthScale
= 0xffffff;
834 ASSERT(dstFormat
== MESA_FORMAT_X8_UINT_Z24_UNORM
);
839 for (img
= 0; img
< srcDepth
; img
++) {
840 GLubyte
*dstRow
= dstSlices
[img
];
841 for (row
= 0; row
< srcHeight
; row
++) {
842 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
843 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
844 GLuint
*dst
= (GLuint
*) dstRow
;
846 _mesa_unpack_depth_span(ctx
, srcWidth
,
847 GL_UNSIGNED_INT
, dst
,
848 depthScale
, srcType
, src
, srcPacking
);
849 for (i
= 0; i
< srcWidth
; i
++)
851 dstRow
+= dstRowStride
;
860 * Store a 16-bit integer depth component texture image.
863 _mesa_texstore_z16(TEXSTORE_PARAMS
)
865 const GLuint depthScale
= 0xffff;
867 ASSERT(dstFormat
== MESA_FORMAT_Z_UNORM16
);
868 ASSERT(_mesa_get_format_bytes(dstFormat
) == sizeof(GLushort
));
873 for (img
= 0; img
< srcDepth
; img
++) {
874 GLubyte
*dstRow
= dstSlices
[img
];
875 for (row
= 0; row
< srcHeight
; row
++) {
876 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
877 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
878 GLushort
*dst16
= (GLushort
*) dstRow
;
879 _mesa_unpack_depth_span(ctx
, srcWidth
,
880 GL_UNSIGNED_SHORT
, dst16
, depthScale
,
881 srcType
, src
, srcPacking
);
882 dstRow
+= dstRowStride
;
891 * Store an rgb565 or rgb565_rev texture image.
894 _mesa_texstore_rgb565(TEXSTORE_PARAMS
)
896 ASSERT(dstFormat
== MESA_FORMAT_B5G6R5_UNORM
||
897 dstFormat
== MESA_FORMAT_R5G6B5_UNORM
);
898 ASSERT(_mesa_get_format_bytes(dstFormat
) == 2);
900 if (!ctx
->_ImageTransferState
&&
901 !srcPacking
->SwapBytes
&&
902 baseInternalFormat
== GL_RGB
&&
903 srcFormat
== GL_RGB
&&
904 srcType
== GL_UNSIGNED_BYTE
&&
906 /* do optimized tex store */
907 const GLint srcRowStride
=
908 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
909 const GLubyte
*src
= (const GLubyte
*)
910 _mesa_image_address(dims
, srcPacking
, srcAddr
, srcWidth
, srcHeight
,
911 srcFormat
, srcType
, 0, 0, 0);
912 GLubyte
*dst
= dstSlices
[0];
914 for (row
= 0; row
< srcHeight
; row
++) {
915 const GLubyte
*srcUB
= (const GLubyte
*) src
;
916 GLushort
*dstUS
= (GLushort
*) dst
;
917 /* check for byteswapped format */
918 if (dstFormat
== MESA_FORMAT_B5G6R5_UNORM
) {
919 for (col
= 0; col
< srcWidth
; col
++) {
920 dstUS
[col
] = PACK_COLOR_565( srcUB
[0], srcUB
[1], srcUB
[2] );
925 for (col
= 0; col
< srcWidth
; col
++) {
926 dstUS
[col
] = PACK_COLOR_565( srcUB
[2], srcUB
[1], srcUB
[0] );
941 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
944 _mesa_texstore_ycbcr(TEXSTORE_PARAMS
)
946 const GLboolean littleEndian
= _mesa_little_endian();
948 (void) ctx
; (void) dims
; (void) baseInternalFormat
;
950 ASSERT((dstFormat
== MESA_FORMAT_YCBCR
) ||
951 (dstFormat
== MESA_FORMAT_YCBCR_REV
));
952 ASSERT(_mesa_get_format_bytes(dstFormat
) == 2);
953 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
954 ASSERT(srcFormat
== GL_YCBCR_MESA
);
955 ASSERT((srcType
== GL_UNSIGNED_SHORT_8_8_MESA
) ||
956 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
));
957 ASSERT(baseInternalFormat
== GL_YCBCR_MESA
);
959 /* always just memcpy since no pixel transfer ops apply */
960 memcpy_texture(ctx
, dims
,
962 dstRowStride
, dstSlices
,
963 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
964 srcAddr
, srcPacking
);
966 /* Check if we need byte swapping */
967 /* XXX the logic here _might_ be wrong */
968 if (srcPacking
->SwapBytes
^
969 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ^
970 (dstFormat
== MESA_FORMAT_YCBCR_REV
) ^
973 for (img
= 0; img
< srcDepth
; img
++) {
974 GLubyte
*dstRow
= dstSlices
[img
];
975 for (row
= 0; row
< srcHeight
; row
++) {
976 _mesa_swap2((GLushort
*) dstRow
, srcWidth
);
977 dstRow
+= dstRowStride
;
986 * Store a combined depth/stencil texture image.
989 _mesa_texstore_z24_s8(TEXSTORE_PARAMS
)
991 const GLuint depthScale
= 0xffffff;
992 const GLint srcRowStride
993 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
995 GLuint
*depth
= malloc(srcWidth
* sizeof(GLuint
));
996 GLubyte
*stencil
= malloc(srcWidth
* sizeof(GLubyte
));
998 ASSERT(dstFormat
== MESA_FORMAT_S8_UINT_Z24_UNORM
);
999 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
||
1000 srcFormat
== GL_DEPTH_COMPONENT
||
1001 srcFormat
== GL_STENCIL_INDEX
);
1002 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
||
1003 srcType
== GL_UNSIGNED_INT_24_8_EXT
||
1004 srcType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
1006 if (!depth
|| !stencil
) {
1012 /* In case we only upload depth we need to preserve the stencil */
1013 for (img
= 0; img
< srcDepth
; img
++) {
1014 GLuint
*dstRow
= (GLuint
*) dstSlices
[img
];
1016 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
1017 srcWidth
, srcHeight
,
1020 for (row
= 0; row
< srcHeight
; row
++) {
1022 GLboolean keepdepth
= GL_FALSE
, keepstencil
= GL_FALSE
;
1024 if (srcFormat
== GL_DEPTH_COMPONENT
) { /* preserve stencil */
1025 keepstencil
= GL_TRUE
;
1027 else if (srcFormat
== GL_STENCIL_INDEX
) { /* preserve depth */
1028 keepdepth
= GL_TRUE
;
1031 if (keepdepth
== GL_FALSE
)
1032 /* the 24 depth bits will be in the low position: */
1033 _mesa_unpack_depth_span(ctx
, srcWidth
,
1034 GL_UNSIGNED_INT
, /* dst type */
1035 keepstencil
? depth
: dstRow
, /* dst addr */
1037 srcType
, src
, srcPacking
);
1039 if (keepstencil
== GL_FALSE
)
1040 /* get the 8-bit stencil values */
1041 _mesa_unpack_stencil_span(ctx
, srcWidth
,
1042 GL_UNSIGNED_BYTE
, /* dst type */
1043 stencil
, /* dst addr */
1044 srcType
, src
, srcPacking
,
1045 ctx
->_ImageTransferState
);
1047 for (i
= 0; i
< srcWidth
; i
++) {
1049 dstRow
[i
] = depth
[i
] << 8 | (dstRow
[i
] & 0x000000FF);
1051 dstRow
[i
] = (dstRow
[i
] & 0xFFFFFF00) | (stencil
[i
] & 0xFF);
1053 src
+= srcRowStride
;
1054 dstRow
+= dstRowStride
/ sizeof(GLuint
);
1065 * Store a combined depth/stencil texture image.
1068 _mesa_texstore_s8_z24(TEXSTORE_PARAMS
)
1070 const GLuint depthScale
= 0xffffff;
1071 const GLint srcRowStride
1072 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1077 ASSERT(dstFormat
== MESA_FORMAT_Z24_UNORM_S8_UINT
);
1078 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
||
1079 srcFormat
== GL_DEPTH_COMPONENT
||
1080 srcFormat
== GL_STENCIL_INDEX
);
1081 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
||
1082 srcType
== GL_UNSIGNED_INT_24_8_EXT
||
1083 srcType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
1085 depth
= malloc(srcWidth
* sizeof(GLuint
));
1086 stencil
= malloc(srcWidth
* sizeof(GLubyte
));
1088 if (!depth
|| !stencil
) {
1094 for (img
= 0; img
< srcDepth
; img
++) {
1095 GLuint
*dstRow
= (GLuint
*) dstSlices
[img
];
1097 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
1098 srcWidth
, srcHeight
,
1101 for (row
= 0; row
< srcHeight
; row
++) {
1103 GLboolean keepdepth
= GL_FALSE
, keepstencil
= GL_FALSE
;
1105 if (srcFormat
== GL_DEPTH_COMPONENT
) { /* preserve stencil */
1106 keepstencil
= GL_TRUE
;
1108 else if (srcFormat
== GL_STENCIL_INDEX
) { /* preserve depth */
1109 keepdepth
= GL_TRUE
;
1112 if (keepdepth
== GL_FALSE
)
1113 /* the 24 depth bits will be in the low position: */
1114 _mesa_unpack_depth_span(ctx
, srcWidth
,
1115 GL_UNSIGNED_INT
, /* dst type */
1116 keepstencil
? depth
: dstRow
, /* dst addr */
1118 srcType
, src
, srcPacking
);
1120 if (keepstencil
== GL_FALSE
)
1121 /* get the 8-bit stencil values */
1122 _mesa_unpack_stencil_span(ctx
, srcWidth
,
1123 GL_UNSIGNED_BYTE
, /* dst type */
1124 stencil
, /* dst addr */
1125 srcType
, src
, srcPacking
,
1126 ctx
->_ImageTransferState
);
1128 /* merge stencil values into depth values */
1129 for (i
= 0; i
< srcWidth
; i
++) {
1131 dstRow
[i
] = depth
[i
] | (dstRow
[i
] & 0xFF000000);
1133 dstRow
[i
] = (dstRow
[i
] & 0xFFFFFF) | (stencil
[i
] << 24);
1136 src
+= srcRowStride
;
1137 dstRow
+= dstRowStride
/ sizeof(GLuint
);
1149 * Store simple 8-bit/value stencil texture data.
1152 _mesa_texstore_s8(TEXSTORE_PARAMS
)
1154 ASSERT(dstFormat
== MESA_FORMAT_S_UINT8
);
1155 ASSERT(srcFormat
== GL_STENCIL_INDEX
);
1158 const GLint srcRowStride
1159 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1161 GLubyte
*stencil
= malloc(srcWidth
* sizeof(GLubyte
));
1166 for (img
= 0; img
< srcDepth
; img
++) {
1167 GLubyte
*dstRow
= dstSlices
[img
];
1169 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
1170 srcWidth
, srcHeight
,
1173 for (row
= 0; row
< srcHeight
; row
++) {
1176 /* get the 8-bit stencil values */
1177 _mesa_unpack_stencil_span(ctx
, srcWidth
,
1178 GL_UNSIGNED_BYTE
, /* dst type */
1179 stencil
, /* dst addr */
1180 srcType
, src
, srcPacking
,
1181 ctx
->_ImageTransferState
);
1182 /* merge stencil values into depth values */
1183 for (i
= 0; i
< srcWidth
; i
++)
1184 dstRow
[i
] = stencil
[i
];
1186 src
+= srcRowStride
;
1187 dstRow
+= dstRowStride
/ sizeof(GLubyte
);
1199 _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS
)
1202 const GLint srcRowStride
1203 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
1206 ASSERT(dstFormat
== MESA_FORMAT_Z32_FLOAT_S8X24_UINT
);
1207 ASSERT(srcFormat
== GL_DEPTH_STENCIL
||
1208 srcFormat
== GL_DEPTH_COMPONENT
||
1209 srcFormat
== GL_STENCIL_INDEX
);
1210 ASSERT(srcFormat
!= GL_DEPTH_STENCIL
||
1211 srcType
== GL_UNSIGNED_INT_24_8
||
1212 srcType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
1214 /* In case we only upload depth we need to preserve the stencil */
1215 for (img
= 0; img
< srcDepth
; img
++) {
1216 uint64_t *dstRow
= (uint64_t *) dstSlices
[img
];
1218 = (const uint64_t *) _mesa_image_address(dims
, srcPacking
, srcAddr
,
1219 srcWidth
, srcHeight
,
1222 for (row
= 0; row
< srcHeight
; row
++) {
1223 /* The unpack functions with:
1224 * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
1225 * only write their own dword, so the other dword (stencil
1226 * or depth) is preserved. */
1227 if (srcFormat
!= GL_STENCIL_INDEX
)
1228 _mesa_unpack_depth_span(ctx
, srcWidth
,
1229 GL_FLOAT_32_UNSIGNED_INT_24_8_REV
, /* dst type */
1230 dstRow
, /* dst addr */
1231 ~0U, srcType
, src
, srcPacking
);
1233 if (srcFormat
!= GL_DEPTH_COMPONENT
)
1234 _mesa_unpack_stencil_span(ctx
, srcWidth
,
1235 GL_FLOAT_32_UNSIGNED_INT_24_8_REV
, /* dst type */
1236 dstRow
, /* dst addr */
1237 srcType
, src
, srcPacking
,
1238 ctx
->_ImageTransferState
);
1240 src
+= srcRowStride
;
1241 dstRow
+= dstRowStride
/ sizeof(uint64_t);
1248 _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS
)
1250 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1252 ASSERT(dstFormat
== MESA_FORMAT_B10G10R10A2_UINT
);
1253 ASSERT(_mesa_get_format_bytes(dstFormat
) == 4);
1257 const GLuint
*tempImage
= make_temp_uint_image(ctx
, dims
,
1260 srcWidth
, srcHeight
,
1261 srcDepth
, srcFormat
,
1264 const GLuint
*src
= tempImage
;
1265 GLint img
, row
, col
;
1266 GLboolean is_unsigned
= _mesa_is_type_unsigned(srcType
);
1269 for (img
= 0; img
< srcDepth
; img
++) {
1270 GLubyte
*dstRow
= dstSlices
[img
];
1272 for (row
= 0; row
< srcHeight
; row
++) {
1273 GLuint
*dstUI
= (GLuint
*) dstRow
;
1275 for (col
= 0; col
< srcWidth
; col
++) {
1277 r
= MIN2(src
[RCOMP
], 0x3ff);
1278 g
= MIN2(src
[GCOMP
], 0x3ff);
1279 b
= MIN2(src
[BCOMP
], 0x3ff);
1280 a
= MIN2(src
[ACOMP
], 0x003);
1281 dstUI
[col
] = (a
<< 30) | (r
<< 20) | (g
<< 10) | (b
);
1285 for (col
= 0; col
< srcWidth
; col
++) {
1287 r
= CLAMP((GLint
) src
[RCOMP
], 0, 0x3ff);
1288 g
= CLAMP((GLint
) src
[GCOMP
], 0, 0x3ff);
1289 b
= CLAMP((GLint
) src
[BCOMP
], 0, 0x3ff);
1290 a
= CLAMP((GLint
) src
[ACOMP
], 0, 0x003);
1291 dstUI
[col
] = (a
<< 30) | (r
<< 20) | (g
<< 10) | (b
);
1295 dstRow
+= dstRowStride
;
1298 free((void *) tempImage
);
1304 _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS
)
1306 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1308 ASSERT(dstFormat
== MESA_FORMAT_R10G10B10A2_UINT
);
1309 ASSERT(_mesa_get_format_bytes(dstFormat
) == 4);
1313 const GLuint
*tempImage
= make_temp_uint_image(ctx
, dims
,
1316 srcWidth
, srcHeight
,
1317 srcDepth
, srcFormat
,
1320 const GLuint
*src
= tempImage
;
1321 GLint img
, row
, col
;
1322 GLboolean is_unsigned
= _mesa_is_type_unsigned(srcType
);
1325 for (img
= 0; img
< srcDepth
; img
++) {
1326 GLubyte
*dstRow
= dstSlices
[img
];
1328 for (row
= 0; row
< srcHeight
; row
++) {
1329 GLuint
*dstUI
= (GLuint
*) dstRow
;
1331 for (col
= 0; col
< srcWidth
; col
++) {
1333 r
= MIN2(src
[RCOMP
], 0x3ff);
1334 g
= MIN2(src
[GCOMP
], 0x3ff);
1335 b
= MIN2(src
[BCOMP
], 0x3ff);
1336 a
= MIN2(src
[ACOMP
], 0x003);
1337 dstUI
[col
] = (a
<< 30) | (b
<< 20) | (g
<< 10) | (r
);
1341 for (col
= 0; col
< srcWidth
; col
++) {
1343 r
= CLAMP((GLint
) src
[RCOMP
], 0, 0x3ff);
1344 g
= CLAMP((GLint
) src
[GCOMP
], 0, 0x3ff);
1345 b
= CLAMP((GLint
) src
[BCOMP
], 0, 0x3ff);
1346 a
= CLAMP((GLint
) src
[ACOMP
], 0, 0x003);
1347 dstUI
[col
] = (a
<< 30) | (b
<< 20) | (g
<< 10) | (r
);
1351 dstRow
+= dstRowStride
;
1354 free((void *) tempImage
);
1361 texstore_depth_stencil(TEXSTORE_PARAMS
)
1363 static StoreTexImageFunc table
[MESA_FORMAT_COUNT
];
1364 static GLboolean initialized
= GL_FALSE
;
1367 memset(table
, 0, sizeof table
);
1369 table
[MESA_FORMAT_S8_UINT_Z24_UNORM
] = _mesa_texstore_z24_s8
;
1370 table
[MESA_FORMAT_Z24_UNORM_S8_UINT
] = _mesa_texstore_s8_z24
;
1371 table
[MESA_FORMAT_Z_UNORM16
] = _mesa_texstore_z16
;
1372 table
[MESA_FORMAT_Z24_UNORM_X8_UINT
] = _mesa_texstore_x8_z24
;
1373 table
[MESA_FORMAT_X8_UINT_Z24_UNORM
] = _mesa_texstore_z24_x8
;
1374 table
[MESA_FORMAT_Z_UNORM32
] = _mesa_texstore_z32
;
1375 table
[MESA_FORMAT_S_UINT8
] = _mesa_texstore_s8
;
1376 table
[MESA_FORMAT_Z_FLOAT32
] = _mesa_texstore_z32
;
1377 table
[MESA_FORMAT_Z32_FLOAT_S8X24_UINT
] = _mesa_texstore_z32f_x24s8
;
1379 initialized
= GL_TRUE
;
1382 ASSERT(table
[dstFormat
]);
1383 return table
[dstFormat
](ctx
, dims
, baseInternalFormat
,
1384 dstFormat
, dstRowStride
, dstSlices
,
1385 srcWidth
, srcHeight
, srcDepth
,
1386 srcFormat
, srcType
, srcAddr
, srcPacking
);
1390 texstore_compressed(TEXSTORE_PARAMS
)
1392 static StoreTexImageFunc table
[MESA_FORMAT_COUNT
];
1393 static GLboolean initialized
= GL_FALSE
;
1396 memset(table
, 0, sizeof table
);
1398 table
[MESA_FORMAT_SRGB_DXT1
] = _mesa_texstore_rgb_dxt1
;
1399 table
[MESA_FORMAT_SRGBA_DXT1
] = _mesa_texstore_rgba_dxt1
;
1400 table
[MESA_FORMAT_SRGBA_DXT3
] = _mesa_texstore_rgba_dxt3
;
1401 table
[MESA_FORMAT_SRGBA_DXT5
] = _mesa_texstore_rgba_dxt5
;
1402 table
[MESA_FORMAT_RGB_FXT1
] = _mesa_texstore_rgb_fxt1
;
1403 table
[MESA_FORMAT_RGBA_FXT1
] = _mesa_texstore_rgba_fxt1
;
1404 table
[MESA_FORMAT_RGB_DXT1
] = _mesa_texstore_rgb_dxt1
;
1405 table
[MESA_FORMAT_RGBA_DXT1
] = _mesa_texstore_rgba_dxt1
;
1406 table
[MESA_FORMAT_RGBA_DXT3
] = _mesa_texstore_rgba_dxt3
;
1407 table
[MESA_FORMAT_RGBA_DXT5
] = _mesa_texstore_rgba_dxt5
;
1408 table
[MESA_FORMAT_R_RGTC1_UNORM
] = _mesa_texstore_red_rgtc1
;
1409 table
[MESA_FORMAT_R_RGTC1_SNORM
] = _mesa_texstore_signed_red_rgtc1
;
1410 table
[MESA_FORMAT_RG_RGTC2_UNORM
] = _mesa_texstore_rg_rgtc2
;
1411 table
[MESA_FORMAT_RG_RGTC2_SNORM
] = _mesa_texstore_signed_rg_rgtc2
;
1412 table
[MESA_FORMAT_L_LATC1_UNORM
] = _mesa_texstore_red_rgtc1
;
1413 table
[MESA_FORMAT_L_LATC1_SNORM
] = _mesa_texstore_signed_red_rgtc1
;
1414 table
[MESA_FORMAT_LA_LATC2_UNORM
] = _mesa_texstore_rg_rgtc2
;
1415 table
[MESA_FORMAT_LA_LATC2_SNORM
] = _mesa_texstore_signed_rg_rgtc2
;
1416 table
[MESA_FORMAT_ETC1_RGB8
] = _mesa_texstore_etc1_rgb8
;
1417 table
[MESA_FORMAT_ETC2_RGB8
] = _mesa_texstore_etc2_rgb8
;
1418 table
[MESA_FORMAT_ETC2_SRGB8
] = _mesa_texstore_etc2_srgb8
;
1419 table
[MESA_FORMAT_ETC2_RGBA8_EAC
] = _mesa_texstore_etc2_rgba8_eac
;
1420 table
[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC
] = _mesa_texstore_etc2_srgb8_alpha8_eac
;
1421 table
[MESA_FORMAT_ETC2_R11_EAC
] = _mesa_texstore_etc2_r11_eac
;
1422 table
[MESA_FORMAT_ETC2_RG11_EAC
] = _mesa_texstore_etc2_rg11_eac
;
1423 table
[MESA_FORMAT_ETC2_SIGNED_R11_EAC
] = _mesa_texstore_etc2_signed_r11_eac
;
1424 table
[MESA_FORMAT_ETC2_SIGNED_RG11_EAC
] = _mesa_texstore_etc2_signed_rg11_eac
;
1425 table
[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1
] =
1426 _mesa_texstore_etc2_rgb8_punchthrough_alpha1
;
1427 table
[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1
] =
1428 _mesa_texstore_etc2_srgb8_punchthrough_alpha1
;
1430 table
[MESA_FORMAT_BPTC_RGBA_UNORM
] =
1431 _mesa_texstore_bptc_rgba_unorm
;
1432 table
[MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM
] =
1433 _mesa_texstore_bptc_rgba_unorm
;
1434 table
[MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT
] =
1435 _mesa_texstore_bptc_rgb_signed_float
;
1436 table
[MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT
] =
1437 _mesa_texstore_bptc_rgb_unsigned_float
;
1439 initialized
= GL_TRUE
;
1442 ASSERT(table
[dstFormat
]);
1443 return table
[dstFormat
](ctx
, dims
, baseInternalFormat
,
1444 dstFormat
, dstRowStride
, dstSlices
,
1445 srcWidth
, srcHeight
, srcDepth
,
1446 srcFormat
, srcType
, srcAddr
, srcPacking
);
1450 invert_swizzle(uint8_t dst
[4], const uint8_t src
[4])
1454 dst
[0] = MESA_FORMAT_SWIZZLE_NONE
;
1455 dst
[1] = MESA_FORMAT_SWIZZLE_NONE
;
1456 dst
[2] = MESA_FORMAT_SWIZZLE_NONE
;
1457 dst
[3] = MESA_FORMAT_SWIZZLE_NONE
;
1459 for (i
= 0; i
< 4; ++i
)
1460 for (j
= 0; j
< 4; ++j
)
1461 if (src
[j
] == i
&& dst
[i
] == MESA_FORMAT_SWIZZLE_NONE
)
1465 /** Store a texture by per-channel conversions and swizzling.
1467 * This function attempts to perform a texstore operation by doing simple
1468 * per-channel conversions and swizzling. This covers a huge chunk of the
1469 * texture storage operations that anyone cares about. If this function is
1470 * incapable of performing the operation, it bails and returns GL_FALSE.
1473 texstore_swizzle(TEXSTORE_PARAMS
)
1475 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
1476 srcFormat
, srcType
);
1477 const GLint srcImageStride
= _mesa_image_image_stride(srcPacking
,
1478 srcWidth
, srcHeight
, srcFormat
, srcType
);
1479 const GLubyte
*srcImage
= (const GLubyte
*) _mesa_image_address(dims
,
1480 srcPacking
, srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, 0, 0, 0);
1481 const int src_components
= _mesa_components_in_format(srcFormat
);
1483 GLubyte swizzle
[4], rgba2base
[6], base2src
[6], rgba2dst
[4], dst2rgba
[4];
1484 const GLubyte
*swap
;
1487 bool is_array
, normalized
, need_swap
;
1489 const GLubyte
*src_row
;
1492 is_array
= _mesa_format_to_array(dstFormat
, &dst_type
, &dst_components
,
1493 rgba2dst
, &normalized
);
1498 if (srcFormat
== GL_COLOR_INDEX
)
1501 if (_mesa_texstore_needs_transfer_ops(ctx
, baseInternalFormat
, dstFormat
))
1506 case GL_UNSIGNED_BYTE
:
1508 case GL_UNSIGNED_SHORT
:
1510 case GL_UNSIGNED_INT
:
1512 /* If wa have to swap bytes in a multi-byte datatype, that means
1513 * we're not doing an array conversion anymore */
1514 if (srcPacking
->SwapBytes
)
1518 case GL_UNSIGNED_INT_8_8_8_8
:
1519 need_swap
= srcPacking
->SwapBytes
;
1520 if (_mesa_little_endian())
1521 need_swap
= !need_swap
;
1522 srcType
= GL_UNSIGNED_BYTE
;
1524 case GL_UNSIGNED_INT_8_8_8_8_REV
:
1525 need_swap
= srcPacking
->SwapBytes
;
1526 if (!_mesa_little_endian())
1527 need_swap
= !need_swap
;
1528 srcType
= GL_UNSIGNED_BYTE
;
1533 swap
= need_swap
? map_3210
: map_identity
;
1535 compute_component_mapping(srcFormat
, baseInternalFormat
, base2src
);
1536 compute_component_mapping(baseInternalFormat
, GL_RGBA
, rgba2base
);
1537 invert_swizzle(dst2rgba
, rgba2dst
);
1539 for (i
= 0; i
< 4; i
++) {
1540 if (dst2rgba
[i
] == MESA_FORMAT_SWIZZLE_NONE
)
1541 swizzle
[i
] = MESA_FORMAT_SWIZZLE_NONE
;
1543 swizzle
[i
] = swap
[base2src
[rgba2base
[dst2rgba
[i
]]]];
1546 /* Is it normalized? */
1547 normalized
|= !_mesa_is_enum_format_integer(srcFormat
);
1549 for (img
= 0; img
< srcDepth
; img
++) {
1550 if (dstRowStride
== srcWidth
* dst_components
&&
1551 srcRowStride
== srcWidth
* src_components
) {
1552 _mesa_swizzle_and_convert(dstSlices
[img
], dst_type
, dst_components
,
1553 srcImage
, srcType
, src_components
,
1554 swizzle
, normalized
, srcWidth
* srcHeight
);
1557 dst_row
= dstSlices
[img
];
1558 for (row
= 0; row
< srcHeight
; row
++) {
1559 _mesa_swizzle_and_convert(dst_row
, dst_type
, dst_components
,
1560 src_row
, srcType
, src_components
,
1561 swizzle
, normalized
, srcWidth
);
1562 dst_row
+= dstRowStride
;
1563 src_row
+= srcRowStride
;
1566 srcImage
+= srcImageStride
;
1573 /** Stores a texture by converting float and then to the texture format
1575 * This function performs a texstore operation by converting to float,
1576 * applying pixel transfer ops, and then converting to the texture's
1577 * internal format using pixel store functions. This function will work
1578 * for any rgb or srgb textore format.
1581 texstore_via_float(TEXSTORE_PARAMS
)
1584 const GLint src_stride
=
1585 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1588 uint8_t *src_row
, *dst_row
, map
[4], rgba2base
[6], base2rgba
[6];
1590 tmp_row
= malloc(srcWidth
* 4 * sizeof(*tmp_row
));
1594 /* The GL spec (4.0, compatibility profile) only specifies srgb
1595 * conversion as something that is done in the sampler during the
1596 * filtering process before the colors are handed to the shader.
1597 * Furthermore, the flowchart (Figure 3.7 in the 4.0 compatibility spec)
1598 * does not list RGB <-> sRGB conversions anywhere. Therefore, we just
1599 * treat sRGB formats the same as RGB formats for the purposes of
1600 * texture upload and transfer ops.
1602 dstFormat
= _mesa_get_srgb_format_linear(dstFormat
);
1604 need_convert
= false;
1605 if (baseInternalFormat
!= _mesa_get_format_base_format(dstFormat
)) {
1606 compute_component_mapping(GL_RGBA
, baseInternalFormat
, base2rgba
);
1607 compute_component_mapping(baseInternalFormat
, GL_RGBA
, rgba2base
);
1608 for (i
= 0; i
< 4; ++i
) {
1609 map
[i
] = base2rgba
[rgba2base
[i
]];
1611 need_convert
= true;
1615 for (img
= 0; img
< srcDepth
; img
++) {
1616 dst_row
= dstSlices
[img
];
1617 src_row
= _mesa_image_address(dims
, srcPacking
, srcAddr
,
1618 srcWidth
, srcHeight
,
1621 for (row
= 0; row
< srcHeight
; row
++) {
1622 _mesa_unpack_color_span_float(ctx
, srcWidth
, GL_RGBA
, tmp_row
,
1623 srcFormat
, srcType
, src_row
,
1624 srcPacking
, ctx
->_ImageTransferState
);
1626 _mesa_swizzle_and_convert(tmp_row
, GL_FLOAT
, 4,
1627 tmp_row
, GL_FLOAT
, 4,
1628 map
, false, srcWidth
);
1629 _mesa_pack_float_rgba_row(dstFormat
, srcWidth
,
1630 (const GLfloat (*)[4])tmp_row
,
1632 dst_row
+= dstRowStride
;
1633 src_row
+= src_stride
;
1642 /** Stores an integer rgba texture
1644 * This function performs an integer texture storage operation by unpacking
1645 * the texture to 32-bit integers, and repacking it into the internal
1646 * format of the texture. This will work for any integer rgb texture
1647 * storage operation.
1650 texstore_rgba_integer(TEXSTORE_PARAMS
)
1652 GLuint i
, img
, row
, *tmp_row
;
1653 GLenum dst_type
, tmp_type
;
1654 const GLint src_stride
=
1655 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1656 int num_dst_components
;
1657 bool is_array
, normalized
;
1658 uint8_t *src_row
, *dst_row
;
1659 uint8_t swizzle
[4], rgba2base
[6], base2rgba
[6], rgba2dst
[4], dst2rgba
[4];
1661 tmp_row
= malloc(srcWidth
* 4 * sizeof(*tmp_row
));
1665 is_array
= _mesa_format_to_array(dstFormat
, &dst_type
, &num_dst_components
,
1666 rgba2dst
, &normalized
);
1668 assert(is_array
&& !normalized
);
1675 invert_swizzle(dst2rgba
, rgba2dst
);
1676 compute_component_mapping(GL_RGBA
, baseInternalFormat
, base2rgba
);
1677 compute_component_mapping(baseInternalFormat
, GL_RGBA
, rgba2base
);
1679 for (i
= 0; i
< 4; ++i
) {
1680 if (dst2rgba
[i
] == MESA_FORMAT_SWIZZLE_NONE
)
1681 swizzle
[i
] = MESA_FORMAT_SWIZZLE_NONE
;
1683 swizzle
[i
] = base2rgba
[rgba2base
[dst2rgba
[i
]]];
1686 if (_mesa_is_type_unsigned(srcType
)) {
1687 tmp_type
= GL_UNSIGNED_INT
;
1692 for (img
= 0; img
< srcDepth
; img
++) {
1693 dst_row
= dstSlices
[img
];
1694 src_row
= _mesa_image_address(dims
, srcPacking
, srcAddr
,
1695 srcWidth
, srcHeight
,
1698 for (row
= 0; row
< srcHeight
; row
++) {
1699 _mesa_unpack_color_span_uint(ctx
, srcWidth
, GL_RGBA
, tmp_row
,
1700 srcFormat
, srcType
, src_row
, srcPacking
);
1701 _mesa_swizzle_and_convert(dst_row
, dst_type
, num_dst_components
,
1702 tmp_row
, tmp_type
, 4,
1703 swizzle
, false, srcWidth
);
1704 dst_row
+= dstRowStride
;
1705 src_row
+= src_stride
;
1715 texstore_rgba(TEXSTORE_PARAMS
)
1717 static StoreTexImageFunc table
[MESA_FORMAT_COUNT
];
1718 static GLboolean initialized
= GL_FALSE
;
1721 memset(table
, 0, sizeof table
);
1723 table
[MESA_FORMAT_B5G6R5_UNORM
] = _mesa_texstore_rgb565
;
1724 table
[MESA_FORMAT_R5G6B5_UNORM
] = _mesa_texstore_rgb565
;
1725 table
[MESA_FORMAT_YCBCR
] = _mesa_texstore_ycbcr
;
1726 table
[MESA_FORMAT_YCBCR_REV
] = _mesa_texstore_ycbcr
;
1728 table
[MESA_FORMAT_B10G10R10A2_UINT
] = _mesa_texstore_argb2101010_uint
;
1729 table
[MESA_FORMAT_R10G10B10A2_UINT
] = _mesa_texstore_abgr2101010_uint
;
1731 initialized
= GL_TRUE
;
1734 if (table
[dstFormat
] && table
[dstFormat
](ctx
, dims
, baseInternalFormat
,
1735 dstFormat
, dstRowStride
, dstSlices
,
1736 srcWidth
, srcHeight
, srcDepth
,
1737 srcFormat
, srcType
, srcAddr
,
1742 if (texstore_swizzle(ctx
, dims
, baseInternalFormat
,
1744 dstRowStride
, dstSlices
,
1745 srcWidth
, srcHeight
, srcDepth
,
1746 srcFormat
, srcType
, srcAddr
, srcPacking
)) {
1750 if (_mesa_is_format_integer(dstFormat
)) {
1751 return texstore_rgba_integer(ctx
, dims
, baseInternalFormat
,
1752 dstFormat
, dstRowStride
, dstSlices
,
1753 srcWidth
, srcHeight
, srcDepth
,
1754 srcFormat
, srcType
, srcAddr
,
1756 } else if (_mesa_get_format_max_bits(dstFormat
) <= 8 &&
1757 !_mesa_is_format_signed(dstFormat
)) {
1758 return store_ubyte_texture(ctx
, dims
, baseInternalFormat
,
1760 dstRowStride
, dstSlices
,
1761 srcWidth
, srcHeight
, srcDepth
,
1762 srcFormat
, srcType
, srcAddr
, srcPacking
);
1764 return texstore_via_float(ctx
, dims
, baseInternalFormat
,
1765 dstFormat
, dstRowStride
, dstSlices
,
1766 srcWidth
, srcHeight
, srcDepth
,
1767 srcFormat
, srcType
, srcAddr
,
1773 _mesa_texstore_needs_transfer_ops(struct gl_context
*ctx
,
1774 GLenum baseInternalFormat
,
1775 mesa_format dstFormat
)
1779 /* There are different rules depending on the base format. */
1780 switch (baseInternalFormat
) {
1781 case GL_DEPTH_COMPONENT
:
1782 case GL_DEPTH_STENCIL
:
1783 return ctx
->Pixel
.DepthScale
!= 1.0f
||
1784 ctx
->Pixel
.DepthBias
!= 0.0f
;
1786 case GL_STENCIL_INDEX
:
1791 * Pixel transfer ops (scale, bias, table lookup) do not apply
1792 * to integer formats.
1794 dstType
= _mesa_get_format_datatype(dstFormat
);
1796 return dstType
!= GL_INT
&& dstType
!= GL_UNSIGNED_INT
&&
1797 ctx
->_ImageTransferState
;
1803 _mesa_texstore_can_use_memcpy(struct gl_context
*ctx
,
1804 GLenum baseInternalFormat
, mesa_format dstFormat
,
1805 GLenum srcFormat
, GLenum srcType
,
1806 const struct gl_pixelstore_attrib
*srcPacking
)
1808 if (_mesa_texstore_needs_transfer_ops(ctx
, baseInternalFormat
, dstFormat
)) {
1812 /* The base internal format and the base Mesa format must match. */
1813 if (baseInternalFormat
!= _mesa_get_format_base_format(dstFormat
)) {
1817 /* The Mesa format must match the input format and type. */
1818 if (!_mesa_format_matches_format_and_type(dstFormat
, srcFormat
, srcType
,
1819 srcPacking
->SwapBytes
)) {
1823 /* Depth texture data needs clamping in following cases:
1824 * - Floating point dstFormat with signed srcType: clamp to [0.0, 1.0].
1825 * - Fixed point dstFormat with signed srcType: clamp to [0, 2^n -1].
1827 * All the cases except one (float dstFormat with float srcType) are ruled
1828 * out by _mesa_format_matches_format_and_type() check above. Handle the
1829 * remaining case here.
1831 if ((baseInternalFormat
== GL_DEPTH_COMPONENT
||
1832 baseInternalFormat
== GL_DEPTH_STENCIL
) &&
1833 (srcType
== GL_FLOAT
||
1834 srcType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
)) {
1842 _mesa_texstore_memcpy(TEXSTORE_PARAMS
)
1844 if (!_mesa_texstore_can_use_memcpy(ctx
, baseInternalFormat
, dstFormat
,
1845 srcFormat
, srcType
, srcPacking
)) {
1849 memcpy_texture(ctx
, dims
,
1851 dstRowStride
, dstSlices
,
1852 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1853 srcAddr
, srcPacking
);
1857 * Store user data into texture memory.
1858 * Called via glTex[Sub]Image1/2/3D()
1859 * \return GL_TRUE for success, GL_FALSE for failure (out of memory).
1862 _mesa_texstore(TEXSTORE_PARAMS
)
1864 if (_mesa_texstore_memcpy(ctx
, dims
, baseInternalFormat
,
1866 dstRowStride
, dstSlices
,
1867 srcWidth
, srcHeight
, srcDepth
,
1868 srcFormat
, srcType
, srcAddr
, srcPacking
)) {
1872 if (_mesa_is_depth_or_stencil_format(baseInternalFormat
)) {
1873 return texstore_depth_stencil(ctx
, dims
, baseInternalFormat
,
1874 dstFormat
, dstRowStride
, dstSlices
,
1875 srcWidth
, srcHeight
, srcDepth
,
1876 srcFormat
, srcType
, srcAddr
, srcPacking
);
1877 } else if (_mesa_is_format_compressed(dstFormat
)) {
1878 return texstore_compressed(ctx
, dims
, baseInternalFormat
,
1879 dstFormat
, dstRowStride
, dstSlices
,
1880 srcWidth
, srcHeight
, srcDepth
,
1881 srcFormat
, srcType
, srcAddr
, srcPacking
);
1883 return texstore_rgba(ctx
, dims
, baseInternalFormat
,
1884 dstFormat
, dstRowStride
, dstSlices
,
1885 srcWidth
, srcHeight
, srcDepth
,
1886 srcFormat
, srcType
, srcAddr
, srcPacking
);
1892 * Normally, we'll only _write_ texel data to a texture when we map it.
1893 * But if the user is providing depth or stencil values and the texture
1894 * image is a combined depth/stencil format, we'll actually read from
1895 * the texture buffer too (in order to insert the depth or stencil values.
1896 * \param userFormat the user-provided image format
1897 * \param texFormat the destination texture format
1900 get_read_write_mode(GLenum userFormat
, mesa_format texFormat
)
1902 if ((userFormat
== GL_STENCIL_INDEX
|| userFormat
== GL_DEPTH_COMPONENT
)
1903 && _mesa_get_format_base_format(texFormat
) == GL_DEPTH_STENCIL
)
1904 return GL_MAP_READ_BIT
| GL_MAP_WRITE_BIT
;
1906 return GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_RANGE_BIT
;
1911 * Helper function for storing 1D, 2D, 3D whole and subimages into texture
1913 * The source of the image data may be user memory or a PBO. In the later
1914 * case, we'll map the PBO, copy from it, then unmap it.
1917 store_texsubimage(struct gl_context
*ctx
,
1918 struct gl_texture_image
*texImage
,
1919 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1920 GLint width
, GLint height
, GLint depth
,
1921 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1922 const struct gl_pixelstore_attrib
*packing
,
1926 const GLbitfield mapMode
= get_read_write_mode(format
, texImage
->TexFormat
);
1927 const GLenum target
= texImage
->TexObject
->Target
;
1928 GLboolean success
= GL_FALSE
;
1929 GLuint dims
, slice
, numSlices
= 1, sliceOffset
= 0;
1930 GLint srcImageStride
= 0;
1933 assert(xoffset
+ width
<= texImage
->Width
);
1934 assert(yoffset
+ height
<= texImage
->Height
);
1935 assert(zoffset
+ depth
<= texImage
->Depth
);
1941 case GL_TEXTURE_2D_ARRAY
:
1942 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1950 /* get pointer to src pixels (may be in a pbo which we'll map here) */
1951 src
= (const GLubyte
*)
1952 _mesa_validate_pbo_teximage(ctx
, dims
, width
, height
, depth
,
1953 format
, type
, pixels
, packing
, caller
);
1957 /* compute slice info (and do some sanity checks) */
1960 case GL_TEXTURE_RECTANGLE
:
1961 case GL_TEXTURE_CUBE_MAP
:
1962 case GL_TEXTURE_EXTERNAL_OES
:
1963 /* one image slice, nothing special needs to be done */
1966 assert(height
== 1);
1968 assert(yoffset
== 0);
1969 assert(zoffset
== 0);
1971 case GL_TEXTURE_1D_ARRAY
:
1973 assert(zoffset
== 0);
1975 sliceOffset
= yoffset
;
1978 srcImageStride
= _mesa_image_row_stride(packing
, width
, format
, type
);
1980 case GL_TEXTURE_2D_ARRAY
:
1982 sliceOffset
= zoffset
;
1985 srcImageStride
= _mesa_image_image_stride(packing
, width
, height
,
1989 /* we'll store 3D images as a series of slices */
1991 sliceOffset
= zoffset
;
1992 srcImageStride
= _mesa_image_image_stride(packing
, width
, height
,
1995 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1997 sliceOffset
= zoffset
;
1998 srcImageStride
= _mesa_image_image_stride(packing
, width
, height
,
2002 _mesa_warning(ctx
, "Unexpected target 0x%x in store_texsubimage()", target
);
2006 assert(numSlices
== 1 || srcImageStride
!= 0);
2008 for (slice
= 0; slice
< numSlices
; slice
++) {
2012 ctx
->Driver
.MapTextureImage(ctx
, texImage
,
2013 slice
+ sliceOffset
,
2014 xoffset
, yoffset
, width
, height
,
2015 mapMode
, &dstMap
, &dstRowStride
);
2017 /* Note: we're only storing a 2D (or 1D) slice at a time but we need
2018 * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is
2019 * used for 3D images.
2021 success
= _mesa_texstore(ctx
, dims
, texImage
->_BaseFormat
,
2022 texImage
->TexFormat
,
2025 width
, height
, 1, /* w, h, d */
2026 format
, type
, src
, packing
);
2028 ctx
->Driver
.UnmapTextureImage(ctx
, texImage
, slice
+ sliceOffset
);
2031 src
+= srcImageStride
;
2038 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "%s", caller
);
2040 _mesa_unmap_teximage_pbo(ctx
, packing
);
2046 * Fallback code for ctx->Driver.TexImage().
2047 * Basically, allocate storage for the texture image, then copy the
2048 * user's image into it.
2051 _mesa_store_teximage(struct gl_context
*ctx
,
2053 struct gl_texture_image
*texImage
,
2054 GLenum format
, GLenum type
, const GLvoid
*pixels
,
2055 const struct gl_pixelstore_attrib
*packing
)
2057 assert(dims
== 1 || dims
== 2 || dims
== 3);
2059 if (texImage
->Width
== 0 || texImage
->Height
== 0 || texImage
->Depth
== 0)
2062 /* allocate storage for texture data */
2063 if (!ctx
->Driver
.AllocTextureImageBuffer(ctx
, texImage
)) {
2064 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage%uD", dims
);
2068 store_texsubimage(ctx
, texImage
,
2069 0, 0, 0, texImage
->Width
, texImage
->Height
, texImage
->Depth
,
2070 format
, type
, pixels
, packing
, "glTexImage");
2075 * Fallback for Driver.TexSubImage().
2078 _mesa_store_texsubimage(struct gl_context
*ctx
, GLuint dims
,
2079 struct gl_texture_image
*texImage
,
2080 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2081 GLint width
, GLint height
, GLint depth
,
2082 GLenum format
, GLenum type
, const void *pixels
,
2083 const struct gl_pixelstore_attrib
*packing
)
2085 store_texsubimage(ctx
, texImage
,
2086 xoffset
, yoffset
, zoffset
, width
, height
, depth
,
2087 format
, type
, pixels
, packing
, "glTexSubImage");
2091 clear_image_to_zero(GLubyte
*dstMap
, GLint dstRowStride
,
2092 GLsizei width
, GLsizei height
,
2093 GLsizei clearValueSize
)
2097 for (y
= 0; y
< height
; y
++) {
2098 memset(dstMap
, 0, clearValueSize
* width
);
2099 dstMap
+= dstRowStride
;
2104 clear_image_to_value(GLubyte
*dstMap
, GLint dstRowStride
,
2105 GLsizei width
, GLsizei height
,
2106 const GLvoid
*clearValue
,
2107 GLsizei clearValueSize
)
2111 for (y
= 0; y
< height
; y
++) {
2112 for (x
= 0; x
< width
; x
++) {
2113 memcpy(dstMap
, clearValue
, clearValueSize
);
2114 dstMap
+= clearValueSize
;
2116 dstMap
+= dstRowStride
- clearValueSize
* width
;
2121 * Fallback for Driver.ClearTexSubImage().
2124 _mesa_store_cleartexsubimage(struct gl_context
*ctx
,
2125 struct gl_texture_image
*texImage
,
2126 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2127 GLsizei width
, GLsizei height
, GLsizei depth
,
2128 const GLvoid
*clearValue
)
2132 GLsizeiptr clearValueSize
;
2135 clearValueSize
= _mesa_get_format_bytes(texImage
->TexFormat
);
2137 for (z
= 0; z
< depth
; z
++) {
2138 ctx
->Driver
.MapTextureImage(ctx
, texImage
,
2139 z
+ zoffset
, xoffset
, yoffset
,
2142 &dstMap
, &dstRowStride
);
2143 if (dstMap
== NULL
) {
2144 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glClearTex*Image");
2149 clear_image_to_value(dstMap
, dstRowStride
,
2154 clear_image_to_zero(dstMap
, dstRowStride
,
2159 ctx
->Driver
.UnmapTextureImage(ctx
, texImage
, z
+ zoffset
);
2164 * Fallback for Driver.CompressedTexImage()
2167 _mesa_store_compressed_teximage(struct gl_context
*ctx
, GLuint dims
,
2168 struct gl_texture_image
*texImage
,
2169 GLsizei imageSize
, const GLvoid
*data
)
2171 /* only 2D and 3D compressed images are supported at this time */
2173 _mesa_problem(ctx
, "Unexpected glCompressedTexImage1D call");
2177 /* This is pretty simple, because unlike the general texstore path we don't
2178 * have to worry about the usual image unpacking or image transfer
2182 ASSERT(texImage
->Width
> 0);
2183 ASSERT(texImage
->Height
> 0);
2184 ASSERT(texImage
->Depth
> 0);
2186 /* allocate storage for texture data */
2187 if (!ctx
->Driver
.AllocTextureImageBuffer(ctx
, texImage
)) {
2188 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage%uD", dims
);
2192 _mesa_store_compressed_texsubimage(ctx
, dims
, texImage
,
2194 texImage
->Width
, texImage
->Height
, texImage
->Depth
,
2195 texImage
->TexFormat
,
2201 * Compute compressed_pixelstore parameters for copying compressed
2203 * \param dims number of texture image dimensions: 1, 2 or 3
2204 * \param texFormat the compressed texture format
2205 * \param width, height, depth size of image to copy
2206 * \param packing pixelstore parameters describing user-space image packing
2207 * \param store returns the compressed_pixelstore parameters
2210 _mesa_compute_compressed_pixelstore(GLuint dims
, mesa_format texFormat
,
2211 GLsizei width
, GLsizei height
,
2213 const struct gl_pixelstore_attrib
*packing
,
2214 struct compressed_pixelstore
*store
)
2218 _mesa_get_format_block_size(texFormat
, &bw
, &bh
);
2220 store
->SkipBytes
= 0;
2221 store
->TotalBytesPerRow
= store
->CopyBytesPerRow
=
2222 _mesa_format_row_stride(texFormat
, width
);
2223 store
->TotalRowsPerSlice
= store
->CopyRowsPerSlice
=
2224 (height
+ bh
- 1) / bh
;
2225 store
->CopySlices
= depth
;
2227 if (packing
->CompressedBlockWidth
&&
2228 packing
->CompressedBlockSize
) {
2230 bw
= packing
->CompressedBlockWidth
;
2232 if (packing
->RowLength
) {
2233 store
->TotalBytesPerRow
= packing
->CompressedBlockSize
*
2234 ((packing
->RowLength
+ bw
- 1) / bw
);
2237 store
->SkipBytes
+= packing
->SkipPixels
* packing
->CompressedBlockSize
/ bw
;
2240 if (dims
> 1 && packing
->CompressedBlockHeight
&&
2241 packing
->CompressedBlockSize
) {
2243 bh
= packing
->CompressedBlockHeight
;
2245 store
->SkipBytes
+= packing
->SkipRows
* store
->TotalBytesPerRow
/ bh
;
2246 store
->CopyRowsPerSlice
= (height
+ bh
- 1) / bh
; /* rows in blocks */
2248 if (packing
->ImageHeight
) {
2249 store
->TotalRowsPerSlice
= (packing
->ImageHeight
+ bh
- 1) / bh
;
2253 if (dims
> 2 && packing
->CompressedBlockDepth
&&
2254 packing
->CompressedBlockSize
) {
2256 int bd
= packing
->CompressedBlockDepth
;
2258 store
->SkipBytes
+= packing
->SkipImages
* store
->TotalBytesPerRow
*
2259 store
->TotalRowsPerSlice
/ bd
;
2265 * Fallback for Driver.CompressedTexSubImage()
2268 _mesa_store_compressed_texsubimage(struct gl_context
*ctx
, GLuint dims
,
2269 struct gl_texture_image
*texImage
,
2270 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2271 GLsizei width
, GLsizei height
, GLsizei depth
,
2273 GLsizei imageSize
, const GLvoid
*data
)
2275 struct compressed_pixelstore store
;
2282 _mesa_problem(ctx
, "Unexpected 1D compressed texsubimage call");
2286 _mesa_compute_compressed_pixelstore(dims
, texImage
->TexFormat
,
2287 width
, height
, depth
,
2288 &ctx
->Unpack
, &store
);
2290 /* get pointer to src pixels (may be in a pbo which we'll map here) */
2291 data
= _mesa_validate_pbo_compressed_teximage(ctx
, dims
, imageSize
, data
,
2293 "glCompressedTexSubImage");
2297 src
= (const GLubyte
*) data
+ store
.SkipBytes
;
2299 for (slice
= 0; slice
< store
.CopySlices
; slice
++) {
2300 /* Map dest texture buffer */
2301 ctx
->Driver
.MapTextureImage(ctx
, texImage
, slice
+ zoffset
,
2302 xoffset
, yoffset
, width
, height
,
2303 GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_RANGE_BIT
,
2304 &dstMap
, &dstRowStride
);
2308 /* copy rows of blocks */
2309 for (i
= 0; i
< store
.CopyRowsPerSlice
; i
++) {
2310 memcpy(dstMap
, src
, store
.CopyBytesPerRow
);
2311 dstMap
+= dstRowStride
;
2312 src
+= store
.TotalBytesPerRow
;
2315 ctx
->Driver
.UnmapTextureImage(ctx
, texImage
, slice
+ zoffset
);
2317 /* advance to next slice */
2318 src
+= store
.TotalBytesPerRow
* (store
.TotalRowsPerSlice
- store
.CopyRowsPerSlice
);
2321 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexSubImage%uD",
2326 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);