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
);
93 * Make a temporary (color) texture image with GLfloat components.
94 * Apply all needed pixel unpacking and pixel transfer operations.
95 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
96 * Suppose the user specifies GL_LUMINANCE as the internal texture format
97 * but the graphics hardware doesn't support luminance textures. So, we might
98 * use an RGB hardware format instead.
99 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
101 * \param ctx the rendering context
102 * \param dims image dimensions: 1, 2 or 3
103 * \param logicalBaseFormat basic texture derived from the user's
104 * internal texture format value
105 * \param textureBaseFormat the actual basic format of the texture
106 * \param srcWidth source image width
107 * \param srcHeight source image height
108 * \param srcDepth source image depth
109 * \param srcFormat source image format
110 * \param srcType source image type
111 * \param srcAddr source image address
112 * \param srcPacking source image pixel packing
113 * \return resulting image with format = textureBaseFormat and type = GLfloat.
116 _mesa_make_temp_float_image(struct gl_context
*ctx
, GLuint dims
,
117 GLenum logicalBaseFormat
,
118 GLenum textureBaseFormat
,
119 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
120 GLenum srcFormat
, GLenum srcType
,
121 const GLvoid
*srcAddr
,
122 const struct gl_pixelstore_attrib
*srcPacking
,
123 GLbitfield transferOps
)
126 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
127 const GLint srcStride
=
128 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
132 ASSERT(dims
>= 1 && dims
<= 3);
134 ASSERT(logicalBaseFormat
== GL_RGBA
||
135 logicalBaseFormat
== GL_RGB
||
136 logicalBaseFormat
== GL_RG
||
137 logicalBaseFormat
== GL_RED
||
138 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
139 logicalBaseFormat
== GL_LUMINANCE
||
140 logicalBaseFormat
== GL_ALPHA
||
141 logicalBaseFormat
== GL_INTENSITY
||
142 logicalBaseFormat
== GL_DEPTH_COMPONENT
);
144 ASSERT(textureBaseFormat
== GL_RGBA
||
145 textureBaseFormat
== GL_RGB
||
146 textureBaseFormat
== GL_RG
||
147 textureBaseFormat
== GL_RED
||
148 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
149 textureBaseFormat
== GL_LUMINANCE
||
150 textureBaseFormat
== GL_ALPHA
||
151 textureBaseFormat
== GL_INTENSITY
||
152 textureBaseFormat
== GL_DEPTH_COMPONENT
);
154 tempImage
= malloc(srcWidth
* srcHeight
* srcDepth
155 * components
* sizeof(GLfloat
));
160 for (img
= 0; img
< srcDepth
; img
++) {
162 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
166 for (row
= 0; row
< srcHeight
; row
++) {
167 _mesa_unpack_color_span_float(ctx
, srcWidth
, logicalBaseFormat
,
168 dst
, srcFormat
, srcType
, src
,
169 srcPacking
, transferOps
);
170 dst
+= srcWidth
* components
;
175 if (logicalBaseFormat
!= textureBaseFormat
) {
177 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
178 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
183 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
184 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
185 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
187 /* The actual texture format should have at least as many components
188 * as the logical texture format.
190 ASSERT(texComponents
>= logComponents
);
192 newImage
= malloc(srcWidth
* srcHeight
* srcDepth
193 * texComponents
* sizeof(GLfloat
));
199 _mesa_compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
201 n
= srcWidth
* srcHeight
* srcDepth
;
202 for (i
= 0; i
< n
; i
++) {
204 for (k
= 0; k
< texComponents
; k
++) {
207 newImage
[i
* texComponents
+ k
] = 0.0F
;
209 newImage
[i
* texComponents
+ k
] = 1.0F
;
211 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
216 tempImage
= newImage
;
224 * Make temporary image with uint pixel values. Used for unsigned
225 * integer-valued textures.
228 make_temp_uint_image(struct gl_context
*ctx
, GLuint dims
,
229 GLenum logicalBaseFormat
,
230 GLenum textureBaseFormat
,
231 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
232 GLenum srcFormat
, GLenum srcType
,
233 const GLvoid
*srcAddr
,
234 const struct gl_pixelstore_attrib
*srcPacking
)
237 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
238 const GLint srcStride
=
239 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
243 ASSERT(dims
>= 1 && dims
<= 3);
245 ASSERT(logicalBaseFormat
== GL_RGBA
||
246 logicalBaseFormat
== GL_RGB
||
247 logicalBaseFormat
== GL_RG
||
248 logicalBaseFormat
== GL_RED
||
249 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
250 logicalBaseFormat
== GL_LUMINANCE
||
251 logicalBaseFormat
== GL_INTENSITY
||
252 logicalBaseFormat
== GL_ALPHA
);
254 ASSERT(textureBaseFormat
== GL_RGBA
||
255 textureBaseFormat
== GL_RGB
||
256 textureBaseFormat
== GL_RG
||
257 textureBaseFormat
== GL_RED
||
258 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
259 textureBaseFormat
== GL_LUMINANCE
||
260 textureBaseFormat
== GL_INTENSITY
||
261 textureBaseFormat
== GL_ALPHA
);
263 tempImage
= malloc(srcWidth
* srcHeight
* srcDepth
264 * components
* sizeof(GLuint
));
269 for (img
= 0; img
< srcDepth
; img
++) {
271 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
275 for (row
= 0; row
< srcHeight
; row
++) {
276 _mesa_unpack_color_span_uint(ctx
, srcWidth
, logicalBaseFormat
,
277 dst
, srcFormat
, srcType
, src
,
279 dst
+= srcWidth
* components
;
284 if (logicalBaseFormat
!= textureBaseFormat
) {
286 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
287 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
292 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
293 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
294 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
296 /* The actual texture format should have at least as many components
297 * as the logical texture format.
299 ASSERT(texComponents
>= logComponents
);
301 newImage
= malloc(srcWidth
* srcHeight
* srcDepth
302 * texComponents
* sizeof(GLuint
));
308 _mesa_compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
310 n
= srcWidth
* srcHeight
* srcDepth
;
311 for (i
= 0; i
< n
; i
++) {
313 for (k
= 0; k
< texComponents
; k
++) {
316 newImage
[i
* texComponents
+ k
] = 0;
318 newImage
[i
* texComponents
+ k
] = 1;
320 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
325 tempImage
= newImage
;
334 * Make a temporary (color) texture image with GLubyte components.
335 * Apply all needed pixel unpacking and pixel transfer operations.
336 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
337 * Suppose the user specifies GL_LUMINANCE as the internal texture format
338 * but the graphics hardware doesn't support luminance textures. So, we might
339 * use an RGB hardware format instead.
340 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
342 * \param ctx the rendering context
343 * \param dims image dimensions: 1, 2 or 3
344 * \param logicalBaseFormat basic texture derived from the user's
345 * internal texture format value
346 * \param textureBaseFormat the actual basic format of the texture
347 * \param srcWidth source image width
348 * \param srcHeight source image height
349 * \param srcDepth source image depth
350 * \param srcFormat source image format
351 * \param srcType source image type
352 * \param srcAddr source image address
353 * \param srcPacking source image pixel packing
354 * \return resulting image with format = textureBaseFormat and type = GLubyte.
357 _mesa_make_temp_ubyte_image(struct gl_context
*ctx
, GLuint dims
,
358 GLenum logicalBaseFormat
,
359 GLenum textureBaseFormat
,
360 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
361 GLenum srcFormat
, GLenum srcType
,
362 const GLvoid
*srcAddr
,
363 const struct gl_pixelstore_attrib
*srcPacking
)
365 GLuint transferOps
= ctx
->_ImageTransferState
;
366 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
368 GLubyte
*tempImage
, *dst
;
370 ASSERT(dims
>= 1 && dims
<= 3);
372 ASSERT(logicalBaseFormat
== GL_RGBA
||
373 logicalBaseFormat
== GL_RGB
||
374 logicalBaseFormat
== GL_RG
||
375 logicalBaseFormat
== GL_RED
||
376 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
377 logicalBaseFormat
== GL_LUMINANCE
||
378 logicalBaseFormat
== GL_ALPHA
||
379 logicalBaseFormat
== GL_INTENSITY
);
381 ASSERT(textureBaseFormat
== GL_RGBA
||
382 textureBaseFormat
== GL_RGB
||
383 textureBaseFormat
== GL_RG
||
384 textureBaseFormat
== GL_RED
||
385 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
386 textureBaseFormat
== GL_LUMINANCE
||
387 textureBaseFormat
== GL_ALPHA
||
388 textureBaseFormat
== GL_INTENSITY
);
390 /* unpack and transfer the source image */
391 tempImage
= malloc(srcWidth
* srcHeight
* srcDepth
392 * components
* sizeof(GLubyte
));
398 for (img
= 0; img
< srcDepth
; img
++) {
399 const GLint srcStride
=
400 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
402 (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
406 for (row
= 0; row
< srcHeight
; row
++) {
407 _mesa_unpack_color_span_ubyte(ctx
, srcWidth
, logicalBaseFormat
, dst
,
408 srcFormat
, srcType
, src
, srcPacking
,
410 dst
+= srcWidth
* components
;
415 if (logicalBaseFormat
!= textureBaseFormat
) {
416 /* one more conversion step */
417 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
418 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
423 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
424 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
425 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
427 /* The actual texture format should have at least as many components
428 * as the logical texture format.
430 ASSERT(texComponents
>= logComponents
);
432 newImage
= malloc(srcWidth
* srcHeight
* srcDepth
433 * texComponents
* sizeof(GLubyte
));
439 _mesa_compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
441 n
= srcWidth
* srcHeight
* srcDepth
;
442 for (i
= 0; i
< n
; i
++) {
444 for (k
= 0; k
< texComponents
; k
++) {
447 newImage
[i
* texComponents
+ k
] = 0;
449 newImage
[i
* texComponents
+ k
] = 255;
451 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
456 tempImage
= newImage
;
463 static const GLubyte map_identity
[6] = { 0, 1, 2, 3, ZERO
, ONE
};
464 static const GLubyte map_3210
[6] = { 3, 2, 1, 0, ZERO
, ONE
};
465 static const GLubyte map_1032
[6] = { 1, 0, 3, 2, ZERO
, ONE
};
469 * Teximage storage routine for when a simple memcpy will do.
470 * No pixel transfer operations or special texel encodings allowed.
471 * 1D, 2D and 3D images supported.
474 memcpy_texture(struct gl_context
*ctx
,
476 mesa_format dstFormat
,
479 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
480 GLenum srcFormat
, GLenum srcType
,
481 const GLvoid
*srcAddr
,
482 const struct gl_pixelstore_attrib
*srcPacking
)
484 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
486 const GLint srcImageStride
= _mesa_image_image_stride(srcPacking
,
487 srcWidth
, srcHeight
, srcFormat
, srcType
);
488 const GLubyte
*srcImage
= (const GLubyte
*) _mesa_image_address(dimensions
,
489 srcPacking
, srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, 0, 0, 0);
490 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
491 const GLint bytesPerRow
= srcWidth
* texelBytes
;
493 if (dstRowStride
== srcRowStride
&&
494 dstRowStride
== bytesPerRow
) {
495 /* memcpy image by image */
497 for (img
= 0; img
< srcDepth
; img
++) {
498 GLubyte
*dstImage
= dstSlices
[img
];
499 memcpy(dstImage
, srcImage
, bytesPerRow
* srcHeight
);
500 srcImage
+= srcImageStride
;
504 /* memcpy row by row */
506 for (img
= 0; img
< srcDepth
; img
++) {
507 const GLubyte
*srcRow
= srcImage
;
508 GLubyte
*dstRow
= dstSlices
[img
];
509 for (row
= 0; row
< srcHeight
; row
++) {
510 memcpy(dstRow
, srcRow
, bytesPerRow
);
511 dstRow
+= dstRowStride
;
512 srcRow
+= srcRowStride
;
514 srcImage
+= srcImageStride
;
521 * General-case function for storing a color texture images with
522 * components that can be represented with ubytes. Example destination
523 * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565.
526 store_ubyte_texture(TEXSTORE_PARAMS
)
528 const GLint srcRowStride
= srcWidth
* 4 * sizeof(GLubyte
);
529 GLubyte
*tempImage
, *src
;
532 tempImage
= _mesa_make_temp_ubyte_image(ctx
, dims
,
535 srcWidth
, srcHeight
, srcDepth
,
536 srcFormat
, srcType
, srcAddr
,
541 /* This way we will use the RGB versions of the packing functions and it
542 * will work for both RGB and sRGB textures*/
543 dstFormat
= _mesa_get_srgb_format_linear(dstFormat
);
546 for (img
= 0; img
< srcDepth
; img
++) {
547 _mesa_pack_ubyte_rgba_rect(dstFormat
, srcWidth
, srcHeight
,
549 dstSlices
[img
], dstRowStride
);
550 src
+= srcHeight
* srcRowStride
;
561 * Store a 32-bit integer or float depth component texture image.
564 _mesa_texstore_z32(TEXSTORE_PARAMS
)
566 const GLuint depthScale
= 0xffffffff;
569 ASSERT(dstFormat
== MESA_FORMAT_Z_UNORM32
||
570 dstFormat
== MESA_FORMAT_Z_FLOAT32
);
571 ASSERT(_mesa_get_format_bytes(dstFormat
) == sizeof(GLuint
));
573 if (dstFormat
== MESA_FORMAT_Z_UNORM32
)
574 dstType
= GL_UNSIGNED_INT
;
581 for (img
= 0; img
< srcDepth
; img
++) {
582 GLubyte
*dstRow
= dstSlices
[img
];
583 for (row
= 0; row
< srcHeight
; row
++) {
584 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
585 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
586 _mesa_unpack_depth_span(ctx
, srcWidth
,
588 depthScale
, srcType
, src
, srcPacking
);
589 dstRow
+= dstRowStride
;
598 * Store a 24-bit integer depth component texture image.
601 _mesa_texstore_x8_z24(TEXSTORE_PARAMS
)
603 const GLuint depthScale
= 0xffffff;
606 ASSERT(dstFormat
== MESA_FORMAT_Z24_UNORM_X8_UINT
);
611 for (img
= 0; img
< srcDepth
; img
++) {
612 GLubyte
*dstRow
= dstSlices
[img
];
613 for (row
= 0; row
< srcHeight
; row
++) {
614 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
615 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
616 _mesa_unpack_depth_span(ctx
, srcWidth
,
617 GL_UNSIGNED_INT
, (GLuint
*) dstRow
,
618 depthScale
, srcType
, src
, srcPacking
);
619 dstRow
+= dstRowStride
;
628 * Store a 24-bit integer depth component texture image.
631 _mesa_texstore_z24_x8(TEXSTORE_PARAMS
)
633 const GLuint depthScale
= 0xffffff;
636 ASSERT(dstFormat
== MESA_FORMAT_X8_UINT_Z24_UNORM
);
641 for (img
= 0; img
< srcDepth
; img
++) {
642 GLubyte
*dstRow
= dstSlices
[img
];
643 for (row
= 0; row
< srcHeight
; row
++) {
644 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
645 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
646 GLuint
*dst
= (GLuint
*) dstRow
;
648 _mesa_unpack_depth_span(ctx
, srcWidth
,
649 GL_UNSIGNED_INT
, dst
,
650 depthScale
, srcType
, src
, srcPacking
);
651 for (i
= 0; i
< srcWidth
; i
++)
653 dstRow
+= dstRowStride
;
662 * Store a 16-bit integer depth component texture image.
665 _mesa_texstore_z16(TEXSTORE_PARAMS
)
667 const GLuint depthScale
= 0xffff;
669 ASSERT(dstFormat
== MESA_FORMAT_Z_UNORM16
);
670 ASSERT(_mesa_get_format_bytes(dstFormat
) == sizeof(GLushort
));
675 for (img
= 0; img
< srcDepth
; img
++) {
676 GLubyte
*dstRow
= dstSlices
[img
];
677 for (row
= 0; row
< srcHeight
; row
++) {
678 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
679 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
680 GLushort
*dst16
= (GLushort
*) dstRow
;
681 _mesa_unpack_depth_span(ctx
, srcWidth
,
682 GL_UNSIGNED_SHORT
, dst16
, depthScale
,
683 srcType
, src
, srcPacking
);
684 dstRow
+= dstRowStride
;
693 * Store an rgb565 or rgb565_rev texture image.
696 _mesa_texstore_rgb565(TEXSTORE_PARAMS
)
698 ASSERT(dstFormat
== MESA_FORMAT_B5G6R5_UNORM
||
699 dstFormat
== MESA_FORMAT_R5G6B5_UNORM
);
700 ASSERT(_mesa_get_format_bytes(dstFormat
) == 2);
702 if (!ctx
->_ImageTransferState
&&
703 !srcPacking
->SwapBytes
&&
704 baseInternalFormat
== GL_RGB
&&
705 srcFormat
== GL_RGB
&&
706 srcType
== GL_UNSIGNED_BYTE
&&
708 /* do optimized tex store */
709 const GLint srcRowStride
=
710 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
711 const GLubyte
*src
= (const GLubyte
*)
712 _mesa_image_address(dims
, srcPacking
, srcAddr
, srcWidth
, srcHeight
,
713 srcFormat
, srcType
, 0, 0, 0);
714 GLubyte
*dst
= dstSlices
[0];
716 for (row
= 0; row
< srcHeight
; row
++) {
717 const GLubyte
*srcUB
= (const GLubyte
*) src
;
718 GLushort
*dstUS
= (GLushort
*) dst
;
719 /* check for byteswapped format */
720 if (dstFormat
== MESA_FORMAT_B5G6R5_UNORM
) {
721 for (col
= 0; col
< srcWidth
; col
++) {
722 dstUS
[col
] = PACK_COLOR_565( srcUB
[0], srcUB
[1], srcUB
[2] );
727 for (col
= 0; col
< srcWidth
; col
++) {
728 dstUS
[col
] = PACK_COLOR_565( srcUB
[2], srcUB
[1], srcUB
[0] );
743 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
746 _mesa_texstore_ycbcr(TEXSTORE_PARAMS
)
748 const GLboolean littleEndian
= _mesa_little_endian();
750 (void) ctx
; (void) dims
; (void) baseInternalFormat
;
752 ASSERT((dstFormat
== MESA_FORMAT_YCBCR
) ||
753 (dstFormat
== MESA_FORMAT_YCBCR_REV
));
754 ASSERT(_mesa_get_format_bytes(dstFormat
) == 2);
755 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
756 ASSERT(srcFormat
== GL_YCBCR_MESA
);
757 ASSERT((srcType
== GL_UNSIGNED_SHORT_8_8_MESA
) ||
758 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
));
759 ASSERT(baseInternalFormat
== GL_YCBCR_MESA
);
761 /* always just memcpy since no pixel transfer ops apply */
762 memcpy_texture(ctx
, dims
,
764 dstRowStride
, dstSlices
,
765 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
766 srcAddr
, srcPacking
);
768 /* Check if we need byte swapping */
769 /* XXX the logic here _might_ be wrong */
770 if (srcPacking
->SwapBytes
^
771 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ^
772 (dstFormat
== MESA_FORMAT_YCBCR_REV
) ^
775 for (img
= 0; img
< srcDepth
; img
++) {
776 GLubyte
*dstRow
= dstSlices
[img
];
777 for (row
= 0; row
< srcHeight
; row
++) {
778 _mesa_swap2((GLushort
*) dstRow
, srcWidth
);
779 dstRow
+= dstRowStride
;
788 * Store a combined depth/stencil texture image.
791 _mesa_texstore_z24_s8(TEXSTORE_PARAMS
)
793 const GLuint depthScale
= 0xffffff;
794 const GLint srcRowStride
795 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
797 GLuint
*depth
= malloc(srcWidth
* sizeof(GLuint
));
798 GLubyte
*stencil
= malloc(srcWidth
* sizeof(GLubyte
));
800 ASSERT(dstFormat
== MESA_FORMAT_S8_UINT_Z24_UNORM
);
801 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
||
802 srcFormat
== GL_DEPTH_COMPONENT
||
803 srcFormat
== GL_STENCIL_INDEX
);
804 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
||
805 srcType
== GL_UNSIGNED_INT_24_8_EXT
||
806 srcType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
808 if (!depth
|| !stencil
) {
814 /* In case we only upload depth we need to preserve the stencil */
815 for (img
= 0; img
< srcDepth
; img
++) {
816 GLuint
*dstRow
= (GLuint
*) dstSlices
[img
];
818 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
822 for (row
= 0; row
< srcHeight
; row
++) {
824 GLboolean keepdepth
= GL_FALSE
, keepstencil
= GL_FALSE
;
826 if (srcFormat
== GL_DEPTH_COMPONENT
) { /* preserve stencil */
827 keepstencil
= GL_TRUE
;
829 else if (srcFormat
== GL_STENCIL_INDEX
) { /* preserve depth */
833 if (keepdepth
== GL_FALSE
)
834 /* the 24 depth bits will be in the low position: */
835 _mesa_unpack_depth_span(ctx
, srcWidth
,
836 GL_UNSIGNED_INT
, /* dst type */
837 keepstencil
? depth
: dstRow
, /* dst addr */
839 srcType
, src
, srcPacking
);
841 if (keepstencil
== GL_FALSE
)
842 /* get the 8-bit stencil values */
843 _mesa_unpack_stencil_span(ctx
, srcWidth
,
844 GL_UNSIGNED_BYTE
, /* dst type */
845 stencil
, /* dst addr */
846 srcType
, src
, srcPacking
,
847 ctx
->_ImageTransferState
);
849 for (i
= 0; i
< srcWidth
; i
++) {
851 dstRow
[i
] = depth
[i
] << 8 | (dstRow
[i
] & 0x000000FF);
853 dstRow
[i
] = (dstRow
[i
] & 0xFFFFFF00) | (stencil
[i
] & 0xFF);
856 dstRow
+= dstRowStride
/ sizeof(GLuint
);
867 * Store a combined depth/stencil texture image.
870 _mesa_texstore_s8_z24(TEXSTORE_PARAMS
)
872 const GLuint depthScale
= 0xffffff;
873 const GLint srcRowStride
874 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
879 ASSERT(dstFormat
== MESA_FORMAT_Z24_UNORM_S8_UINT
);
880 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
||
881 srcFormat
== GL_DEPTH_COMPONENT
||
882 srcFormat
== GL_STENCIL_INDEX
);
883 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
||
884 srcType
== GL_UNSIGNED_INT_24_8_EXT
||
885 srcType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
887 depth
= malloc(srcWidth
* sizeof(GLuint
));
888 stencil
= malloc(srcWidth
* sizeof(GLubyte
));
890 if (!depth
|| !stencil
) {
896 for (img
= 0; img
< srcDepth
; img
++) {
897 GLuint
*dstRow
= (GLuint
*) dstSlices
[img
];
899 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
903 for (row
= 0; row
< srcHeight
; row
++) {
905 GLboolean keepdepth
= GL_FALSE
, keepstencil
= GL_FALSE
;
907 if (srcFormat
== GL_DEPTH_COMPONENT
) { /* preserve stencil */
908 keepstencil
= GL_TRUE
;
910 else if (srcFormat
== GL_STENCIL_INDEX
) { /* preserve depth */
914 if (keepdepth
== GL_FALSE
)
915 /* the 24 depth bits will be in the low position: */
916 _mesa_unpack_depth_span(ctx
, srcWidth
,
917 GL_UNSIGNED_INT
, /* dst type */
918 keepstencil
? depth
: dstRow
, /* dst addr */
920 srcType
, src
, srcPacking
);
922 if (keepstencil
== GL_FALSE
)
923 /* get the 8-bit stencil values */
924 _mesa_unpack_stencil_span(ctx
, srcWidth
,
925 GL_UNSIGNED_BYTE
, /* dst type */
926 stencil
, /* dst addr */
927 srcType
, src
, srcPacking
,
928 ctx
->_ImageTransferState
);
930 /* merge stencil values into depth values */
931 for (i
= 0; i
< srcWidth
; i
++) {
933 dstRow
[i
] = depth
[i
] | (dstRow
[i
] & 0xFF000000);
935 dstRow
[i
] = (dstRow
[i
] & 0xFFFFFF) | (stencil
[i
] << 24);
939 dstRow
+= dstRowStride
/ sizeof(GLuint
);
951 * Store simple 8-bit/value stencil texture data.
954 _mesa_texstore_s8(TEXSTORE_PARAMS
)
956 ASSERT(dstFormat
== MESA_FORMAT_S_UINT8
);
957 ASSERT(srcFormat
== GL_STENCIL_INDEX
);
960 const GLint srcRowStride
961 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
963 GLubyte
*stencil
= malloc(srcWidth
* sizeof(GLubyte
));
968 for (img
= 0; img
< srcDepth
; img
++) {
969 GLubyte
*dstRow
= dstSlices
[img
];
971 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
975 for (row
= 0; row
< srcHeight
; row
++) {
978 /* get the 8-bit stencil values */
979 _mesa_unpack_stencil_span(ctx
, srcWidth
,
980 GL_UNSIGNED_BYTE
, /* dst type */
981 stencil
, /* dst addr */
982 srcType
, src
, srcPacking
,
983 ctx
->_ImageTransferState
);
984 /* merge stencil values into depth values */
985 for (i
= 0; i
< srcWidth
; i
++)
986 dstRow
[i
] = stencil
[i
];
989 dstRow
+= dstRowStride
/ sizeof(GLubyte
);
1001 _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS
)
1004 const GLint srcRowStride
1005 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
1008 ASSERT(dstFormat
== MESA_FORMAT_Z32_FLOAT_S8X24_UINT
);
1009 ASSERT(srcFormat
== GL_DEPTH_STENCIL
||
1010 srcFormat
== GL_DEPTH_COMPONENT
||
1011 srcFormat
== GL_STENCIL_INDEX
);
1012 ASSERT(srcFormat
!= GL_DEPTH_STENCIL
||
1013 srcType
== GL_UNSIGNED_INT_24_8
||
1014 srcType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
1016 /* In case we only upload depth we need to preserve the stencil */
1017 for (img
= 0; img
< srcDepth
; img
++) {
1018 uint64_t *dstRow
= (uint64_t *) dstSlices
[img
];
1020 = (const uint64_t *) _mesa_image_address(dims
, srcPacking
, srcAddr
,
1021 srcWidth
, srcHeight
,
1024 for (row
= 0; row
< srcHeight
; row
++) {
1025 /* The unpack functions with:
1026 * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
1027 * only write their own dword, so the other dword (stencil
1028 * or depth) is preserved. */
1029 if (srcFormat
!= GL_STENCIL_INDEX
)
1030 _mesa_unpack_depth_span(ctx
, srcWidth
,
1031 GL_FLOAT_32_UNSIGNED_INT_24_8_REV
, /* dst type */
1032 dstRow
, /* dst addr */
1033 ~0U, srcType
, src
, srcPacking
);
1035 if (srcFormat
!= GL_DEPTH_COMPONENT
)
1036 _mesa_unpack_stencil_span(ctx
, srcWidth
,
1037 GL_FLOAT_32_UNSIGNED_INT_24_8_REV
, /* dst type */
1038 dstRow
, /* dst addr */
1039 srcType
, src
, srcPacking
,
1040 ctx
->_ImageTransferState
);
1042 src
+= srcRowStride
;
1043 dstRow
+= dstRowStride
/ sizeof(uint64_t);
1050 _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS
)
1052 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1054 ASSERT(dstFormat
== MESA_FORMAT_B10G10R10A2_UINT
);
1055 ASSERT(_mesa_get_format_bytes(dstFormat
) == 4);
1059 const GLuint
*tempImage
= make_temp_uint_image(ctx
, dims
,
1062 srcWidth
, srcHeight
,
1063 srcDepth
, srcFormat
,
1066 const GLuint
*src
= tempImage
;
1067 GLint img
, row
, col
;
1068 GLboolean is_unsigned
= _mesa_is_type_unsigned(srcType
);
1071 for (img
= 0; img
< srcDepth
; img
++) {
1072 GLubyte
*dstRow
= dstSlices
[img
];
1074 for (row
= 0; row
< srcHeight
; row
++) {
1075 GLuint
*dstUI
= (GLuint
*) dstRow
;
1077 for (col
= 0; col
< srcWidth
; col
++) {
1079 r
= MIN2(src
[RCOMP
], 0x3ff);
1080 g
= MIN2(src
[GCOMP
], 0x3ff);
1081 b
= MIN2(src
[BCOMP
], 0x3ff);
1082 a
= MIN2(src
[ACOMP
], 0x003);
1083 dstUI
[col
] = (a
<< 30) | (r
<< 20) | (g
<< 10) | (b
);
1087 for (col
= 0; col
< srcWidth
; col
++) {
1089 r
= CLAMP((GLint
) src
[RCOMP
], 0, 0x3ff);
1090 g
= CLAMP((GLint
) src
[GCOMP
], 0, 0x3ff);
1091 b
= CLAMP((GLint
) src
[BCOMP
], 0, 0x3ff);
1092 a
= CLAMP((GLint
) src
[ACOMP
], 0, 0x003);
1093 dstUI
[col
] = (a
<< 30) | (r
<< 20) | (g
<< 10) | (b
);
1097 dstRow
+= dstRowStride
;
1100 free((void *) tempImage
);
1106 _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS
)
1108 const GLenum baseFormat
= _mesa_get_format_base_format(dstFormat
);
1110 ASSERT(dstFormat
== MESA_FORMAT_R10G10B10A2_UINT
);
1111 ASSERT(_mesa_get_format_bytes(dstFormat
) == 4);
1115 const GLuint
*tempImage
= make_temp_uint_image(ctx
, dims
,
1118 srcWidth
, srcHeight
,
1119 srcDepth
, srcFormat
,
1122 const GLuint
*src
= tempImage
;
1123 GLint img
, row
, col
;
1124 GLboolean is_unsigned
= _mesa_is_type_unsigned(srcType
);
1127 for (img
= 0; img
< srcDepth
; img
++) {
1128 GLubyte
*dstRow
= dstSlices
[img
];
1130 for (row
= 0; row
< srcHeight
; row
++) {
1131 GLuint
*dstUI
= (GLuint
*) dstRow
;
1133 for (col
= 0; col
< srcWidth
; col
++) {
1135 r
= MIN2(src
[RCOMP
], 0x3ff);
1136 g
= MIN2(src
[GCOMP
], 0x3ff);
1137 b
= MIN2(src
[BCOMP
], 0x3ff);
1138 a
= MIN2(src
[ACOMP
], 0x003);
1139 dstUI
[col
] = (a
<< 30) | (b
<< 20) | (g
<< 10) | (r
);
1143 for (col
= 0; col
< srcWidth
; col
++) {
1145 r
= CLAMP((GLint
) src
[RCOMP
], 0, 0x3ff);
1146 g
= CLAMP((GLint
) src
[GCOMP
], 0, 0x3ff);
1147 b
= CLAMP((GLint
) src
[BCOMP
], 0, 0x3ff);
1148 a
= CLAMP((GLint
) src
[ACOMP
], 0, 0x003);
1149 dstUI
[col
] = (a
<< 30) | (b
<< 20) | (g
<< 10) | (r
);
1153 dstRow
+= dstRowStride
;
1156 free((void *) tempImage
);
1163 texstore_depth_stencil(TEXSTORE_PARAMS
)
1165 static StoreTexImageFunc table
[MESA_FORMAT_COUNT
];
1166 static GLboolean initialized
= GL_FALSE
;
1169 memset(table
, 0, sizeof table
);
1171 table
[MESA_FORMAT_S8_UINT_Z24_UNORM
] = _mesa_texstore_z24_s8
;
1172 table
[MESA_FORMAT_Z24_UNORM_S8_UINT
] = _mesa_texstore_s8_z24
;
1173 table
[MESA_FORMAT_Z_UNORM16
] = _mesa_texstore_z16
;
1174 table
[MESA_FORMAT_Z24_UNORM_X8_UINT
] = _mesa_texstore_x8_z24
;
1175 table
[MESA_FORMAT_X8_UINT_Z24_UNORM
] = _mesa_texstore_z24_x8
;
1176 table
[MESA_FORMAT_Z_UNORM32
] = _mesa_texstore_z32
;
1177 table
[MESA_FORMAT_S_UINT8
] = _mesa_texstore_s8
;
1178 table
[MESA_FORMAT_Z_FLOAT32
] = _mesa_texstore_z32
;
1179 table
[MESA_FORMAT_Z32_FLOAT_S8X24_UINT
] = _mesa_texstore_z32f_x24s8
;
1181 initialized
= GL_TRUE
;
1184 ASSERT(table
[dstFormat
]);
1185 return table
[dstFormat
](ctx
, dims
, baseInternalFormat
,
1186 dstFormat
, dstRowStride
, dstSlices
,
1187 srcWidth
, srcHeight
, srcDepth
,
1188 srcFormat
, srcType
, srcAddr
, srcPacking
);
1192 texstore_compressed(TEXSTORE_PARAMS
)
1194 static StoreTexImageFunc table
[MESA_FORMAT_COUNT
];
1195 static GLboolean initialized
= GL_FALSE
;
1198 memset(table
, 0, sizeof table
);
1200 table
[MESA_FORMAT_SRGB_DXT1
] = _mesa_texstore_rgb_dxt1
;
1201 table
[MESA_FORMAT_SRGBA_DXT1
] = _mesa_texstore_rgba_dxt1
;
1202 table
[MESA_FORMAT_SRGBA_DXT3
] = _mesa_texstore_rgba_dxt3
;
1203 table
[MESA_FORMAT_SRGBA_DXT5
] = _mesa_texstore_rgba_dxt5
;
1204 table
[MESA_FORMAT_RGB_FXT1
] = _mesa_texstore_rgb_fxt1
;
1205 table
[MESA_FORMAT_RGBA_FXT1
] = _mesa_texstore_rgba_fxt1
;
1206 table
[MESA_FORMAT_RGB_DXT1
] = _mesa_texstore_rgb_dxt1
;
1207 table
[MESA_FORMAT_RGBA_DXT1
] = _mesa_texstore_rgba_dxt1
;
1208 table
[MESA_FORMAT_RGBA_DXT3
] = _mesa_texstore_rgba_dxt3
;
1209 table
[MESA_FORMAT_RGBA_DXT5
] = _mesa_texstore_rgba_dxt5
;
1210 table
[MESA_FORMAT_R_RGTC1_UNORM
] = _mesa_texstore_red_rgtc1
;
1211 table
[MESA_FORMAT_R_RGTC1_SNORM
] = _mesa_texstore_signed_red_rgtc1
;
1212 table
[MESA_FORMAT_RG_RGTC2_UNORM
] = _mesa_texstore_rg_rgtc2
;
1213 table
[MESA_FORMAT_RG_RGTC2_SNORM
] = _mesa_texstore_signed_rg_rgtc2
;
1214 table
[MESA_FORMAT_L_LATC1_UNORM
] = _mesa_texstore_red_rgtc1
;
1215 table
[MESA_FORMAT_L_LATC1_SNORM
] = _mesa_texstore_signed_red_rgtc1
;
1216 table
[MESA_FORMAT_LA_LATC2_UNORM
] = _mesa_texstore_rg_rgtc2
;
1217 table
[MESA_FORMAT_LA_LATC2_SNORM
] = _mesa_texstore_signed_rg_rgtc2
;
1218 table
[MESA_FORMAT_ETC1_RGB8
] = _mesa_texstore_etc1_rgb8
;
1219 table
[MESA_FORMAT_ETC2_RGB8
] = _mesa_texstore_etc2_rgb8
;
1220 table
[MESA_FORMAT_ETC2_SRGB8
] = _mesa_texstore_etc2_srgb8
;
1221 table
[MESA_FORMAT_ETC2_RGBA8_EAC
] = _mesa_texstore_etc2_rgba8_eac
;
1222 table
[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC
] = _mesa_texstore_etc2_srgb8_alpha8_eac
;
1223 table
[MESA_FORMAT_ETC2_R11_EAC
] = _mesa_texstore_etc2_r11_eac
;
1224 table
[MESA_FORMAT_ETC2_RG11_EAC
] = _mesa_texstore_etc2_rg11_eac
;
1225 table
[MESA_FORMAT_ETC2_SIGNED_R11_EAC
] = _mesa_texstore_etc2_signed_r11_eac
;
1226 table
[MESA_FORMAT_ETC2_SIGNED_RG11_EAC
] = _mesa_texstore_etc2_signed_rg11_eac
;
1227 table
[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1
] =
1228 _mesa_texstore_etc2_rgb8_punchthrough_alpha1
;
1229 table
[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1
] =
1230 _mesa_texstore_etc2_srgb8_punchthrough_alpha1
;
1232 table
[MESA_FORMAT_BPTC_RGBA_UNORM
] =
1233 _mesa_texstore_bptc_rgba_unorm
;
1234 table
[MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM
] =
1235 _mesa_texstore_bptc_rgba_unorm
;
1236 table
[MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT
] =
1237 _mesa_texstore_bptc_rgb_signed_float
;
1238 table
[MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT
] =
1239 _mesa_texstore_bptc_rgb_unsigned_float
;
1241 initialized
= GL_TRUE
;
1244 ASSERT(table
[dstFormat
]);
1245 return table
[dstFormat
](ctx
, dims
, baseInternalFormat
,
1246 dstFormat
, dstRowStride
, dstSlices
,
1247 srcWidth
, srcHeight
, srcDepth
,
1248 srcFormat
, srcType
, srcAddr
, srcPacking
);
1252 invert_swizzle(uint8_t dst
[4], const uint8_t src
[4])
1256 dst
[0] = MESA_FORMAT_SWIZZLE_NONE
;
1257 dst
[1] = MESA_FORMAT_SWIZZLE_NONE
;
1258 dst
[2] = MESA_FORMAT_SWIZZLE_NONE
;
1259 dst
[3] = MESA_FORMAT_SWIZZLE_NONE
;
1261 for (i
= 0; i
< 4; ++i
)
1262 for (j
= 0; j
< 4; ++j
)
1263 if (src
[j
] == i
&& dst
[i
] == MESA_FORMAT_SWIZZLE_NONE
)
1267 /** Store a texture by per-channel conversions and swizzling.
1269 * This function attempts to perform a texstore operation by doing simple
1270 * per-channel conversions and swizzling. This covers a huge chunk of the
1271 * texture storage operations that anyone cares about. If this function is
1272 * incapable of performing the operation, it bails and returns GL_FALSE.
1275 texstore_swizzle(TEXSTORE_PARAMS
)
1277 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
1278 srcFormat
, srcType
);
1279 const GLint srcImageStride
= _mesa_image_image_stride(srcPacking
,
1280 srcWidth
, srcHeight
, srcFormat
, srcType
);
1281 const GLubyte
*srcImage
= (const GLubyte
*) _mesa_image_address(dims
,
1282 srcPacking
, srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, 0, 0, 0);
1283 const int src_components
= _mesa_components_in_format(srcFormat
);
1285 GLubyte swizzle
[4], rgba2base
[6], base2src
[6], rgba2dst
[4], dst2rgba
[4];
1286 const GLubyte
*swap
;
1289 bool is_array
, normalized
, need_swap
;
1291 const GLubyte
*src_row
;
1294 is_array
= _mesa_format_to_array(dstFormat
, &dst_type
, &dst_components
,
1295 rgba2dst
, &normalized
);
1300 if (srcFormat
== GL_COLOR_INDEX
)
1303 if (_mesa_texstore_needs_transfer_ops(ctx
, baseInternalFormat
, dstFormat
))
1308 case GL_UNSIGNED_BYTE
:
1310 case GL_UNSIGNED_SHORT
:
1312 case GL_UNSIGNED_INT
:
1314 /* If wa have to swap bytes in a multi-byte datatype, that means
1315 * we're not doing an array conversion anymore */
1316 if (srcPacking
->SwapBytes
)
1320 case GL_UNSIGNED_INT_8_8_8_8
:
1321 need_swap
= srcPacking
->SwapBytes
;
1322 if (_mesa_little_endian())
1323 need_swap
= !need_swap
;
1324 srcType
= GL_UNSIGNED_BYTE
;
1326 case GL_UNSIGNED_INT_8_8_8_8_REV
:
1327 need_swap
= srcPacking
->SwapBytes
;
1328 if (!_mesa_little_endian())
1329 need_swap
= !need_swap
;
1330 srcType
= GL_UNSIGNED_BYTE
;
1335 swap
= need_swap
? map_3210
: map_identity
;
1337 _mesa_compute_component_mapping(srcFormat
, baseInternalFormat
, base2src
);
1338 _mesa_compute_component_mapping(baseInternalFormat
, GL_RGBA
, rgba2base
);
1339 invert_swizzle(dst2rgba
, rgba2dst
);
1341 for (i
= 0; i
< 4; i
++) {
1342 if (dst2rgba
[i
] == MESA_FORMAT_SWIZZLE_NONE
)
1343 swizzle
[i
] = MESA_FORMAT_SWIZZLE_NONE
;
1345 swizzle
[i
] = swap
[base2src
[rgba2base
[dst2rgba
[i
]]]];
1348 /* Is it normalized? */
1349 normalized
|= !_mesa_is_enum_format_integer(srcFormat
);
1351 for (img
= 0; img
< srcDepth
; img
++) {
1352 if (dstRowStride
== srcWidth
* dst_components
&&
1353 srcRowStride
== srcWidth
* src_components
) {
1354 _mesa_swizzle_and_convert(dstSlices
[img
], dst_type
, dst_components
,
1355 srcImage
, srcType
, src_components
,
1356 swizzle
, normalized
, srcWidth
* srcHeight
);
1359 dst_row
= dstSlices
[img
];
1360 for (row
= 0; row
< srcHeight
; row
++) {
1361 _mesa_swizzle_and_convert(dst_row
, dst_type
, dst_components
,
1362 src_row
, srcType
, src_components
,
1363 swizzle
, normalized
, srcWidth
);
1364 dst_row
+= dstRowStride
;
1365 src_row
+= srcRowStride
;
1368 srcImage
+= srcImageStride
;
1375 /** Stores a texture by converting float and then to the texture format
1377 * This function performs a texstore operation by converting to float,
1378 * applying pixel transfer ops, and then converting to the texture's
1379 * internal format using pixel store functions. This function will work
1380 * for any rgb or srgb textore format.
1383 texstore_via_float(TEXSTORE_PARAMS
)
1386 const GLint src_stride
=
1387 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1390 uint8_t *src_row
, *dst_row
, map
[4], rgba2base
[6], base2rgba
[6];
1392 tmp_row
= malloc(srcWidth
* 4 * sizeof(*tmp_row
));
1396 /* The GL spec (4.0, compatibility profile) only specifies srgb
1397 * conversion as something that is done in the sampler during the
1398 * filtering process before the colors are handed to the shader.
1399 * Furthermore, the flowchart (Figure 3.7 in the 4.0 compatibility spec)
1400 * does not list RGB <-> sRGB conversions anywhere. Therefore, we just
1401 * treat sRGB formats the same as RGB formats for the purposes of
1402 * texture upload and transfer ops.
1404 dstFormat
= _mesa_get_srgb_format_linear(dstFormat
);
1406 need_convert
= false;
1407 if (baseInternalFormat
!= _mesa_get_format_base_format(dstFormat
)) {
1408 _mesa_compute_component_mapping(GL_RGBA
, baseInternalFormat
, base2rgba
);
1409 _mesa_compute_component_mapping(baseInternalFormat
, GL_RGBA
, rgba2base
);
1410 for (i
= 0; i
< 4; ++i
) {
1411 map
[i
] = base2rgba
[rgba2base
[i
]];
1413 need_convert
= true;
1417 for (img
= 0; img
< srcDepth
; img
++) {
1418 dst_row
= dstSlices
[img
];
1419 src_row
= _mesa_image_address(dims
, srcPacking
, srcAddr
,
1420 srcWidth
, srcHeight
,
1423 for (row
= 0; row
< srcHeight
; row
++) {
1424 _mesa_unpack_color_span_float(ctx
, srcWidth
, GL_RGBA
, tmp_row
,
1425 srcFormat
, srcType
, src_row
,
1426 srcPacking
, ctx
->_ImageTransferState
);
1428 _mesa_swizzle_and_convert(tmp_row
, GL_FLOAT
, 4,
1429 tmp_row
, GL_FLOAT
, 4,
1430 map
, false, srcWidth
);
1431 _mesa_pack_float_rgba_row(dstFormat
, srcWidth
,
1432 (const GLfloat (*)[4])tmp_row
,
1434 dst_row
+= dstRowStride
;
1435 src_row
+= src_stride
;
1444 /** Stores an integer rgba texture
1446 * This function performs an integer texture storage operation by unpacking
1447 * the texture to 32-bit integers, and repacking it into the internal
1448 * format of the texture. This will work for any integer rgb texture
1449 * storage operation.
1452 texstore_rgba_integer(TEXSTORE_PARAMS
)
1454 GLuint i
, img
, row
, *tmp_row
;
1455 GLenum dst_type
, tmp_type
;
1456 const GLint src_stride
=
1457 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1458 int num_dst_components
;
1459 bool is_array
, normalized
;
1460 uint8_t *src_row
, *dst_row
;
1461 uint8_t swizzle
[4], rgba2base
[6], base2rgba
[6], rgba2dst
[4], dst2rgba
[4];
1463 tmp_row
= malloc(srcWidth
* 4 * sizeof(*tmp_row
));
1467 is_array
= _mesa_format_to_array(dstFormat
, &dst_type
, &num_dst_components
,
1468 rgba2dst
, &normalized
);
1470 assert(is_array
&& !normalized
);
1477 invert_swizzle(dst2rgba
, rgba2dst
);
1478 _mesa_compute_component_mapping(GL_RGBA
, baseInternalFormat
, base2rgba
);
1479 _mesa_compute_component_mapping(baseInternalFormat
, GL_RGBA
, rgba2base
);
1481 for (i
= 0; i
< 4; ++i
) {
1482 if (dst2rgba
[i
] == MESA_FORMAT_SWIZZLE_NONE
)
1483 swizzle
[i
] = MESA_FORMAT_SWIZZLE_NONE
;
1485 swizzle
[i
] = base2rgba
[rgba2base
[dst2rgba
[i
]]];
1488 if (_mesa_is_type_unsigned(srcType
)) {
1489 tmp_type
= GL_UNSIGNED_INT
;
1494 for (img
= 0; img
< srcDepth
; img
++) {
1495 dst_row
= dstSlices
[img
];
1496 src_row
= _mesa_image_address(dims
, srcPacking
, srcAddr
,
1497 srcWidth
, srcHeight
,
1500 for (row
= 0; row
< srcHeight
; row
++) {
1501 _mesa_unpack_color_span_uint(ctx
, srcWidth
, GL_RGBA
, tmp_row
,
1502 srcFormat
, srcType
, src_row
, srcPacking
);
1503 _mesa_swizzle_and_convert(dst_row
, dst_type
, num_dst_components
,
1504 tmp_row
, tmp_type
, 4,
1505 swizzle
, false, srcWidth
);
1506 dst_row
+= dstRowStride
;
1507 src_row
+= src_stride
;
1517 texstore_rgba(TEXSTORE_PARAMS
)
1519 static StoreTexImageFunc table
[MESA_FORMAT_COUNT
];
1520 static GLboolean initialized
= GL_FALSE
;
1523 memset(table
, 0, sizeof table
);
1525 table
[MESA_FORMAT_B5G6R5_UNORM
] = _mesa_texstore_rgb565
;
1526 table
[MESA_FORMAT_R5G6B5_UNORM
] = _mesa_texstore_rgb565
;
1527 table
[MESA_FORMAT_YCBCR
] = _mesa_texstore_ycbcr
;
1528 table
[MESA_FORMAT_YCBCR_REV
] = _mesa_texstore_ycbcr
;
1530 table
[MESA_FORMAT_B10G10R10A2_UINT
] = _mesa_texstore_argb2101010_uint
;
1531 table
[MESA_FORMAT_R10G10B10A2_UINT
] = _mesa_texstore_abgr2101010_uint
;
1533 initialized
= GL_TRUE
;
1536 if (table
[dstFormat
] && table
[dstFormat
](ctx
, dims
, baseInternalFormat
,
1537 dstFormat
, dstRowStride
, dstSlices
,
1538 srcWidth
, srcHeight
, srcDepth
,
1539 srcFormat
, srcType
, srcAddr
,
1544 if (texstore_swizzle(ctx
, dims
, baseInternalFormat
,
1546 dstRowStride
, dstSlices
,
1547 srcWidth
, srcHeight
, srcDepth
,
1548 srcFormat
, srcType
, srcAddr
, srcPacking
)) {
1552 if (_mesa_is_format_integer(dstFormat
)) {
1553 return texstore_rgba_integer(ctx
, dims
, baseInternalFormat
,
1554 dstFormat
, dstRowStride
, dstSlices
,
1555 srcWidth
, srcHeight
, srcDepth
,
1556 srcFormat
, srcType
, srcAddr
,
1558 } else if (_mesa_get_format_max_bits(dstFormat
) <= 8 &&
1559 !_mesa_is_format_signed(dstFormat
)) {
1560 return store_ubyte_texture(ctx
, dims
, baseInternalFormat
,
1562 dstRowStride
, dstSlices
,
1563 srcWidth
, srcHeight
, srcDepth
,
1564 srcFormat
, srcType
, srcAddr
, srcPacking
);
1566 return texstore_via_float(ctx
, dims
, baseInternalFormat
,
1567 dstFormat
, dstRowStride
, dstSlices
,
1568 srcWidth
, srcHeight
, srcDepth
,
1569 srcFormat
, srcType
, srcAddr
,
1575 _mesa_texstore_needs_transfer_ops(struct gl_context
*ctx
,
1576 GLenum baseInternalFormat
,
1577 mesa_format dstFormat
)
1581 /* There are different rules depending on the base format. */
1582 switch (baseInternalFormat
) {
1583 case GL_DEPTH_COMPONENT
:
1584 case GL_DEPTH_STENCIL
:
1585 return ctx
->Pixel
.DepthScale
!= 1.0f
||
1586 ctx
->Pixel
.DepthBias
!= 0.0f
;
1588 case GL_STENCIL_INDEX
:
1593 * Pixel transfer ops (scale, bias, table lookup) do not apply
1594 * to integer formats.
1596 dstType
= _mesa_get_format_datatype(dstFormat
);
1598 return dstType
!= GL_INT
&& dstType
!= GL_UNSIGNED_INT
&&
1599 ctx
->_ImageTransferState
;
1605 _mesa_texstore_can_use_memcpy(struct gl_context
*ctx
,
1606 GLenum baseInternalFormat
, mesa_format dstFormat
,
1607 GLenum srcFormat
, GLenum srcType
,
1608 const struct gl_pixelstore_attrib
*srcPacking
)
1610 if (_mesa_texstore_needs_transfer_ops(ctx
, baseInternalFormat
, dstFormat
)) {
1614 /* The base internal format and the base Mesa format must match. */
1615 if (baseInternalFormat
!= _mesa_get_format_base_format(dstFormat
)) {
1619 /* The Mesa format must match the input format and type. */
1620 if (!_mesa_format_matches_format_and_type(dstFormat
, srcFormat
, srcType
,
1621 srcPacking
->SwapBytes
)) {
1625 /* Depth texture data needs clamping in following cases:
1626 * - Floating point dstFormat with signed srcType: clamp to [0.0, 1.0].
1627 * - Fixed point dstFormat with signed srcType: clamp to [0, 2^n -1].
1629 * All the cases except one (float dstFormat with float srcType) are ruled
1630 * out by _mesa_format_matches_format_and_type() check above. Handle the
1631 * remaining case here.
1633 if ((baseInternalFormat
== GL_DEPTH_COMPONENT
||
1634 baseInternalFormat
== GL_DEPTH_STENCIL
) &&
1635 (srcType
== GL_FLOAT
||
1636 srcType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
)) {
1644 _mesa_texstore_memcpy(TEXSTORE_PARAMS
)
1646 if (!_mesa_texstore_can_use_memcpy(ctx
, baseInternalFormat
, dstFormat
,
1647 srcFormat
, srcType
, srcPacking
)) {
1651 memcpy_texture(ctx
, dims
,
1653 dstRowStride
, dstSlices
,
1654 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1655 srcAddr
, srcPacking
);
1659 * Store user data into texture memory.
1660 * Called via glTex[Sub]Image1/2/3D()
1661 * \return GL_TRUE for success, GL_FALSE for failure (out of memory).
1664 _mesa_texstore(TEXSTORE_PARAMS
)
1666 if (_mesa_texstore_memcpy(ctx
, dims
, baseInternalFormat
,
1668 dstRowStride
, dstSlices
,
1669 srcWidth
, srcHeight
, srcDepth
,
1670 srcFormat
, srcType
, srcAddr
, srcPacking
)) {
1674 if (_mesa_is_depth_or_stencil_format(baseInternalFormat
)) {
1675 return texstore_depth_stencil(ctx
, dims
, baseInternalFormat
,
1676 dstFormat
, dstRowStride
, dstSlices
,
1677 srcWidth
, srcHeight
, srcDepth
,
1678 srcFormat
, srcType
, srcAddr
, srcPacking
);
1679 } else if (_mesa_is_format_compressed(dstFormat
)) {
1680 return texstore_compressed(ctx
, dims
, baseInternalFormat
,
1681 dstFormat
, dstRowStride
, dstSlices
,
1682 srcWidth
, srcHeight
, srcDepth
,
1683 srcFormat
, srcType
, srcAddr
, srcPacking
);
1685 return texstore_rgba(ctx
, dims
, baseInternalFormat
,
1686 dstFormat
, dstRowStride
, dstSlices
,
1687 srcWidth
, srcHeight
, srcDepth
,
1688 srcFormat
, srcType
, srcAddr
, srcPacking
);
1694 * Normally, we'll only _write_ texel data to a texture when we map it.
1695 * But if the user is providing depth or stencil values and the texture
1696 * image is a combined depth/stencil format, we'll actually read from
1697 * the texture buffer too (in order to insert the depth or stencil values.
1698 * \param userFormat the user-provided image format
1699 * \param texFormat the destination texture format
1702 get_read_write_mode(GLenum userFormat
, mesa_format texFormat
)
1704 if ((userFormat
== GL_STENCIL_INDEX
|| userFormat
== GL_DEPTH_COMPONENT
)
1705 && _mesa_get_format_base_format(texFormat
) == GL_DEPTH_STENCIL
)
1706 return GL_MAP_READ_BIT
| GL_MAP_WRITE_BIT
;
1708 return GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_RANGE_BIT
;
1713 * Helper function for storing 1D, 2D, 3D whole and subimages into texture
1715 * The source of the image data may be user memory or a PBO. In the later
1716 * case, we'll map the PBO, copy from it, then unmap it.
1719 store_texsubimage(struct gl_context
*ctx
,
1720 struct gl_texture_image
*texImage
,
1721 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1722 GLint width
, GLint height
, GLint depth
,
1723 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1724 const struct gl_pixelstore_attrib
*packing
,
1728 const GLbitfield mapMode
= get_read_write_mode(format
, texImage
->TexFormat
);
1729 const GLenum target
= texImage
->TexObject
->Target
;
1730 GLboolean success
= GL_FALSE
;
1731 GLuint dims
, slice
, numSlices
= 1, sliceOffset
= 0;
1732 GLint srcImageStride
= 0;
1735 assert(xoffset
+ width
<= texImage
->Width
);
1736 assert(yoffset
+ height
<= texImage
->Height
);
1737 assert(zoffset
+ depth
<= texImage
->Depth
);
1743 case GL_TEXTURE_2D_ARRAY
:
1744 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1752 /* get pointer to src pixels (may be in a pbo which we'll map here) */
1753 src
= (const GLubyte
*)
1754 _mesa_validate_pbo_teximage(ctx
, dims
, width
, height
, depth
,
1755 format
, type
, pixels
, packing
, caller
);
1759 /* compute slice info (and do some sanity checks) */
1762 case GL_TEXTURE_RECTANGLE
:
1763 case GL_TEXTURE_CUBE_MAP
:
1764 case GL_TEXTURE_EXTERNAL_OES
:
1765 /* one image slice, nothing special needs to be done */
1768 assert(height
== 1);
1770 assert(yoffset
== 0);
1771 assert(zoffset
== 0);
1773 case GL_TEXTURE_1D_ARRAY
:
1775 assert(zoffset
== 0);
1777 sliceOffset
= yoffset
;
1780 srcImageStride
= _mesa_image_row_stride(packing
, width
, format
, type
);
1782 case GL_TEXTURE_2D_ARRAY
:
1784 sliceOffset
= zoffset
;
1787 srcImageStride
= _mesa_image_image_stride(packing
, width
, height
,
1791 /* we'll store 3D images as a series of slices */
1793 sliceOffset
= zoffset
;
1794 srcImageStride
= _mesa_image_image_stride(packing
, width
, height
,
1797 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1799 sliceOffset
= zoffset
;
1800 srcImageStride
= _mesa_image_image_stride(packing
, width
, height
,
1804 _mesa_warning(ctx
, "Unexpected target 0x%x in store_texsubimage()", target
);
1808 assert(numSlices
== 1 || srcImageStride
!= 0);
1810 for (slice
= 0; slice
< numSlices
; slice
++) {
1814 ctx
->Driver
.MapTextureImage(ctx
, texImage
,
1815 slice
+ sliceOffset
,
1816 xoffset
, yoffset
, width
, height
,
1817 mapMode
, &dstMap
, &dstRowStride
);
1819 /* Note: we're only storing a 2D (or 1D) slice at a time but we need
1820 * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is
1821 * used for 3D images.
1823 success
= _mesa_texstore(ctx
, dims
, texImage
->_BaseFormat
,
1824 texImage
->TexFormat
,
1827 width
, height
, 1, /* w, h, d */
1828 format
, type
, src
, packing
);
1830 ctx
->Driver
.UnmapTextureImage(ctx
, texImage
, slice
+ sliceOffset
);
1833 src
+= srcImageStride
;
1840 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "%s", caller
);
1842 _mesa_unmap_teximage_pbo(ctx
, packing
);
1848 * Fallback code for ctx->Driver.TexImage().
1849 * Basically, allocate storage for the texture image, then copy the
1850 * user's image into it.
1853 _mesa_store_teximage(struct gl_context
*ctx
,
1855 struct gl_texture_image
*texImage
,
1856 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1857 const struct gl_pixelstore_attrib
*packing
)
1859 assert(dims
== 1 || dims
== 2 || dims
== 3);
1861 if (texImage
->Width
== 0 || texImage
->Height
== 0 || texImage
->Depth
== 0)
1864 /* allocate storage for texture data */
1865 if (!ctx
->Driver
.AllocTextureImageBuffer(ctx
, texImage
)) {
1866 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage%uD", dims
);
1870 store_texsubimage(ctx
, texImage
,
1871 0, 0, 0, texImage
->Width
, texImage
->Height
, texImage
->Depth
,
1872 format
, type
, pixels
, packing
, "glTexImage");
1877 * Fallback for Driver.TexSubImage().
1880 _mesa_store_texsubimage(struct gl_context
*ctx
, GLuint dims
,
1881 struct gl_texture_image
*texImage
,
1882 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1883 GLint width
, GLint height
, GLint depth
,
1884 GLenum format
, GLenum type
, const void *pixels
,
1885 const struct gl_pixelstore_attrib
*packing
)
1887 store_texsubimage(ctx
, texImage
,
1888 xoffset
, yoffset
, zoffset
, width
, height
, depth
,
1889 format
, type
, pixels
, packing
, "glTexSubImage");
1893 clear_image_to_zero(GLubyte
*dstMap
, GLint dstRowStride
,
1894 GLsizei width
, GLsizei height
,
1895 GLsizei clearValueSize
)
1899 for (y
= 0; y
< height
; y
++) {
1900 memset(dstMap
, 0, clearValueSize
* width
);
1901 dstMap
+= dstRowStride
;
1906 clear_image_to_value(GLubyte
*dstMap
, GLint dstRowStride
,
1907 GLsizei width
, GLsizei height
,
1908 const GLvoid
*clearValue
,
1909 GLsizei clearValueSize
)
1913 for (y
= 0; y
< height
; y
++) {
1914 for (x
= 0; x
< width
; x
++) {
1915 memcpy(dstMap
, clearValue
, clearValueSize
);
1916 dstMap
+= clearValueSize
;
1918 dstMap
+= dstRowStride
- clearValueSize
* width
;
1923 * Fallback for Driver.ClearTexSubImage().
1926 _mesa_store_cleartexsubimage(struct gl_context
*ctx
,
1927 struct gl_texture_image
*texImage
,
1928 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1929 GLsizei width
, GLsizei height
, GLsizei depth
,
1930 const GLvoid
*clearValue
)
1934 GLsizeiptr clearValueSize
;
1937 clearValueSize
= _mesa_get_format_bytes(texImage
->TexFormat
);
1939 for (z
= 0; z
< depth
; z
++) {
1940 ctx
->Driver
.MapTextureImage(ctx
, texImage
,
1941 z
+ zoffset
, xoffset
, yoffset
,
1944 &dstMap
, &dstRowStride
);
1945 if (dstMap
== NULL
) {
1946 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glClearTex*Image");
1951 clear_image_to_value(dstMap
, dstRowStride
,
1956 clear_image_to_zero(dstMap
, dstRowStride
,
1961 ctx
->Driver
.UnmapTextureImage(ctx
, texImage
, z
+ zoffset
);
1966 * Fallback for Driver.CompressedTexImage()
1969 _mesa_store_compressed_teximage(struct gl_context
*ctx
, GLuint dims
,
1970 struct gl_texture_image
*texImage
,
1971 GLsizei imageSize
, const GLvoid
*data
)
1973 /* only 2D and 3D compressed images are supported at this time */
1975 _mesa_problem(ctx
, "Unexpected glCompressedTexImage1D call");
1979 /* This is pretty simple, because unlike the general texstore path we don't
1980 * have to worry about the usual image unpacking or image transfer
1984 ASSERT(texImage
->Width
> 0);
1985 ASSERT(texImage
->Height
> 0);
1986 ASSERT(texImage
->Depth
> 0);
1988 /* allocate storage for texture data */
1989 if (!ctx
->Driver
.AllocTextureImageBuffer(ctx
, texImage
)) {
1990 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage%uD", dims
);
1994 _mesa_store_compressed_texsubimage(ctx
, dims
, texImage
,
1996 texImage
->Width
, texImage
->Height
, texImage
->Depth
,
1997 texImage
->TexFormat
,
2003 * Compute compressed_pixelstore parameters for copying compressed
2005 * \param dims number of texture image dimensions: 1, 2 or 3
2006 * \param texFormat the compressed texture format
2007 * \param width, height, depth size of image to copy
2008 * \param packing pixelstore parameters describing user-space image packing
2009 * \param store returns the compressed_pixelstore parameters
2012 _mesa_compute_compressed_pixelstore(GLuint dims
, mesa_format texFormat
,
2013 GLsizei width
, GLsizei height
,
2015 const struct gl_pixelstore_attrib
*packing
,
2016 struct compressed_pixelstore
*store
)
2020 _mesa_get_format_block_size(texFormat
, &bw
, &bh
);
2022 store
->SkipBytes
= 0;
2023 store
->TotalBytesPerRow
= store
->CopyBytesPerRow
=
2024 _mesa_format_row_stride(texFormat
, width
);
2025 store
->TotalRowsPerSlice
= store
->CopyRowsPerSlice
=
2026 (height
+ bh
- 1) / bh
;
2027 store
->CopySlices
= depth
;
2029 if (packing
->CompressedBlockWidth
&&
2030 packing
->CompressedBlockSize
) {
2032 bw
= packing
->CompressedBlockWidth
;
2034 if (packing
->RowLength
) {
2035 store
->TotalBytesPerRow
= packing
->CompressedBlockSize
*
2036 ((packing
->RowLength
+ bw
- 1) / bw
);
2039 store
->SkipBytes
+= packing
->SkipPixels
* packing
->CompressedBlockSize
/ bw
;
2042 if (dims
> 1 && packing
->CompressedBlockHeight
&&
2043 packing
->CompressedBlockSize
) {
2045 bh
= packing
->CompressedBlockHeight
;
2047 store
->SkipBytes
+= packing
->SkipRows
* store
->TotalBytesPerRow
/ bh
;
2048 store
->CopyRowsPerSlice
= (height
+ bh
- 1) / bh
; /* rows in blocks */
2050 if (packing
->ImageHeight
) {
2051 store
->TotalRowsPerSlice
= (packing
->ImageHeight
+ bh
- 1) / bh
;
2055 if (dims
> 2 && packing
->CompressedBlockDepth
&&
2056 packing
->CompressedBlockSize
) {
2058 int bd
= packing
->CompressedBlockDepth
;
2060 store
->SkipBytes
+= packing
->SkipImages
* store
->TotalBytesPerRow
*
2061 store
->TotalRowsPerSlice
/ bd
;
2067 * Fallback for Driver.CompressedTexSubImage()
2070 _mesa_store_compressed_texsubimage(struct gl_context
*ctx
, GLuint dims
,
2071 struct gl_texture_image
*texImage
,
2072 GLint xoffset
, GLint yoffset
, GLint zoffset
,
2073 GLsizei width
, GLsizei height
, GLsizei depth
,
2075 GLsizei imageSize
, const GLvoid
*data
)
2077 struct compressed_pixelstore store
;
2084 _mesa_problem(ctx
, "Unexpected 1D compressed texsubimage call");
2088 _mesa_compute_compressed_pixelstore(dims
, texImage
->TexFormat
,
2089 width
, height
, depth
,
2090 &ctx
->Unpack
, &store
);
2092 /* get pointer to src pixels (may be in a pbo which we'll map here) */
2093 data
= _mesa_validate_pbo_compressed_teximage(ctx
, dims
, imageSize
, data
,
2095 "glCompressedTexSubImage");
2099 src
= (const GLubyte
*) data
+ store
.SkipBytes
;
2101 for (slice
= 0; slice
< store
.CopySlices
; slice
++) {
2102 /* Map dest texture buffer */
2103 ctx
->Driver
.MapTextureImage(ctx
, texImage
, slice
+ zoffset
,
2104 xoffset
, yoffset
, width
, height
,
2105 GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_RANGE_BIT
,
2106 &dstMap
, &dstRowStride
);
2110 /* copy rows of blocks */
2111 for (i
= 0; i
< store
.CopyRowsPerSlice
; i
++) {
2112 memcpy(dstMap
, src
, store
.CopyBytesPerRow
);
2113 dstMap
+= dstRowStride
;
2114 src
+= store
.TotalBytesPerRow
;
2117 ctx
->Driver
.UnmapTextureImage(ctx
, texImage
, slice
+ zoffset
);
2119 /* advance to next slice */
2120 src
+= store
.TotalBytesPerRow
* (store
.TotalRowsPerSlice
- store
.CopyRowsPerSlice
);
2123 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexSubImage%uD",
2128 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);