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 a temporary (color) texture image with GLubyte components.
225 * Apply all needed pixel unpacking and pixel transfer operations.
226 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
227 * Suppose the user specifies GL_LUMINANCE as the internal texture format
228 * but the graphics hardware doesn't support luminance textures. So, we might
229 * use an RGB hardware format instead.
230 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
232 * \param ctx the rendering context
233 * \param dims image dimensions: 1, 2 or 3
234 * \param logicalBaseFormat basic texture derived from the user's
235 * internal texture format value
236 * \param textureBaseFormat the actual basic format of the texture
237 * \param srcWidth source image width
238 * \param srcHeight source image height
239 * \param srcDepth source image depth
240 * \param srcFormat source image format
241 * \param srcType source image type
242 * \param srcAddr source image address
243 * \param srcPacking source image pixel packing
244 * \return resulting image with format = textureBaseFormat and type = GLubyte.
247 _mesa_make_temp_ubyte_image(struct gl_context
*ctx
, GLuint dims
,
248 GLenum logicalBaseFormat
,
249 GLenum textureBaseFormat
,
250 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
251 GLenum srcFormat
, GLenum srcType
,
252 const GLvoid
*srcAddr
,
253 const struct gl_pixelstore_attrib
*srcPacking
)
255 GLuint transferOps
= ctx
->_ImageTransferState
;
256 const GLint components
= _mesa_components_in_format(logicalBaseFormat
);
258 GLubyte
*tempImage
, *dst
;
260 ASSERT(dims
>= 1 && dims
<= 3);
262 ASSERT(logicalBaseFormat
== GL_RGBA
||
263 logicalBaseFormat
== GL_RGB
||
264 logicalBaseFormat
== GL_RG
||
265 logicalBaseFormat
== GL_RED
||
266 logicalBaseFormat
== GL_LUMINANCE_ALPHA
||
267 logicalBaseFormat
== GL_LUMINANCE
||
268 logicalBaseFormat
== GL_ALPHA
||
269 logicalBaseFormat
== GL_INTENSITY
);
271 ASSERT(textureBaseFormat
== GL_RGBA
||
272 textureBaseFormat
== GL_RGB
||
273 textureBaseFormat
== GL_RG
||
274 textureBaseFormat
== GL_RED
||
275 textureBaseFormat
== GL_LUMINANCE_ALPHA
||
276 textureBaseFormat
== GL_LUMINANCE
||
277 textureBaseFormat
== GL_ALPHA
||
278 textureBaseFormat
== GL_INTENSITY
);
280 /* unpack and transfer the source image */
281 tempImage
= malloc(srcWidth
* srcHeight
* srcDepth
282 * components
* sizeof(GLubyte
));
288 for (img
= 0; img
< srcDepth
; img
++) {
289 const GLint srcStride
=
290 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
292 (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
296 for (row
= 0; row
< srcHeight
; row
++) {
297 _mesa_unpack_color_span_ubyte(ctx
, srcWidth
, logicalBaseFormat
, dst
,
298 srcFormat
, srcType
, src
, srcPacking
,
300 dst
+= srcWidth
* components
;
305 if (logicalBaseFormat
!= textureBaseFormat
) {
306 /* one more conversion step */
307 GLint texComponents
= _mesa_components_in_format(textureBaseFormat
);
308 GLint logComponents
= _mesa_components_in_format(logicalBaseFormat
);
313 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
314 ASSERT(textureBaseFormat
== GL_RGB
|| textureBaseFormat
== GL_RGBA
||
315 textureBaseFormat
== GL_LUMINANCE_ALPHA
);
317 /* The actual texture format should have at least as many components
318 * as the logical texture format.
320 ASSERT(texComponents
>= logComponents
);
322 newImage
= malloc(srcWidth
* srcHeight
* srcDepth
323 * texComponents
* sizeof(GLubyte
));
329 _mesa_compute_component_mapping(logicalBaseFormat
, textureBaseFormat
, map
);
331 n
= srcWidth
* srcHeight
* srcDepth
;
332 for (i
= 0; i
< n
; i
++) {
334 for (k
= 0; k
< texComponents
; k
++) {
337 newImage
[i
* texComponents
+ k
] = 0;
339 newImage
[i
* texComponents
+ k
] = 255;
341 newImage
[i
* texComponents
+ k
] = tempImage
[i
* logComponents
+ j
];
346 tempImage
= newImage
;
353 static const GLubyte map_identity
[6] = { 0, 1, 2, 3, ZERO
, ONE
};
354 static const GLubyte map_3210
[6] = { 3, 2, 1, 0, ZERO
, ONE
};
355 static const GLubyte map_1032
[6] = { 1, 0, 3, 2, ZERO
, ONE
};
359 * Teximage storage routine for when a simple memcpy will do.
360 * No pixel transfer operations or special texel encodings allowed.
361 * 1D, 2D and 3D images supported.
364 memcpy_texture(struct gl_context
*ctx
,
366 mesa_format dstFormat
,
369 GLint srcWidth
, GLint srcHeight
, GLint srcDepth
,
370 GLenum srcFormat
, GLenum srcType
,
371 const GLvoid
*srcAddr
,
372 const struct gl_pixelstore_attrib
*srcPacking
)
374 const GLint srcRowStride
= _mesa_image_row_stride(srcPacking
, srcWidth
,
376 const GLint srcImageStride
= _mesa_image_image_stride(srcPacking
,
377 srcWidth
, srcHeight
, srcFormat
, srcType
);
378 const GLubyte
*srcImage
= (const GLubyte
*) _mesa_image_address(dimensions
,
379 srcPacking
, srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, 0, 0, 0);
380 const GLuint texelBytes
= _mesa_get_format_bytes(dstFormat
);
381 const GLint bytesPerRow
= srcWidth
* texelBytes
;
383 if (dstRowStride
== srcRowStride
&&
384 dstRowStride
== bytesPerRow
) {
385 /* memcpy image by image */
387 for (img
= 0; img
< srcDepth
; img
++) {
388 GLubyte
*dstImage
= dstSlices
[img
];
389 memcpy(dstImage
, srcImage
, bytesPerRow
* srcHeight
);
390 srcImage
+= srcImageStride
;
394 /* memcpy row by row */
396 for (img
= 0; img
< srcDepth
; img
++) {
397 const GLubyte
*srcRow
= srcImage
;
398 GLubyte
*dstRow
= dstSlices
[img
];
399 for (row
= 0; row
< srcHeight
; row
++) {
400 memcpy(dstRow
, srcRow
, bytesPerRow
);
401 dstRow
+= dstRowStride
;
402 srcRow
+= srcRowStride
;
404 srcImage
+= srcImageStride
;
411 * Store a 32-bit integer or float depth component texture image.
414 _mesa_texstore_z32(TEXSTORE_PARAMS
)
416 const GLuint depthScale
= 0xffffffff;
419 ASSERT(dstFormat
== MESA_FORMAT_Z_UNORM32
||
420 dstFormat
== MESA_FORMAT_Z_FLOAT32
);
421 ASSERT(_mesa_get_format_bytes(dstFormat
) == sizeof(GLuint
));
423 if (dstFormat
== MESA_FORMAT_Z_UNORM32
)
424 dstType
= GL_UNSIGNED_INT
;
431 for (img
= 0; img
< srcDepth
; img
++) {
432 GLubyte
*dstRow
= dstSlices
[img
];
433 for (row
= 0; row
< srcHeight
; row
++) {
434 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
435 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
436 _mesa_unpack_depth_span(ctx
, srcWidth
,
438 depthScale
, srcType
, src
, srcPacking
);
439 dstRow
+= dstRowStride
;
448 * Store a 24-bit integer depth component texture image.
451 _mesa_texstore_x8_z24(TEXSTORE_PARAMS
)
453 const GLuint depthScale
= 0xffffff;
456 ASSERT(dstFormat
== MESA_FORMAT_Z24_UNORM_X8_UINT
);
461 for (img
= 0; img
< srcDepth
; img
++) {
462 GLubyte
*dstRow
= dstSlices
[img
];
463 for (row
= 0; row
< srcHeight
; row
++) {
464 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
465 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
466 _mesa_unpack_depth_span(ctx
, srcWidth
,
467 GL_UNSIGNED_INT
, (GLuint
*) dstRow
,
468 depthScale
, srcType
, src
, srcPacking
);
469 dstRow
+= dstRowStride
;
478 * Store a 24-bit integer depth component texture image.
481 _mesa_texstore_z24_x8(TEXSTORE_PARAMS
)
483 const GLuint depthScale
= 0xffffff;
486 ASSERT(dstFormat
== MESA_FORMAT_X8_UINT_Z24_UNORM
);
491 for (img
= 0; img
< srcDepth
; img
++) {
492 GLubyte
*dstRow
= dstSlices
[img
];
493 for (row
= 0; row
< srcHeight
; row
++) {
494 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
495 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
496 GLuint
*dst
= (GLuint
*) dstRow
;
498 _mesa_unpack_depth_span(ctx
, srcWidth
,
499 GL_UNSIGNED_INT
, dst
,
500 depthScale
, srcType
, src
, srcPacking
);
501 for (i
= 0; i
< srcWidth
; i
++)
503 dstRow
+= dstRowStride
;
512 * Store a 16-bit integer depth component texture image.
515 _mesa_texstore_z16(TEXSTORE_PARAMS
)
517 const GLuint depthScale
= 0xffff;
519 ASSERT(dstFormat
== MESA_FORMAT_Z_UNORM16
);
520 ASSERT(_mesa_get_format_bytes(dstFormat
) == sizeof(GLushort
));
525 for (img
= 0; img
< srcDepth
; img
++) {
526 GLubyte
*dstRow
= dstSlices
[img
];
527 for (row
= 0; row
< srcHeight
; row
++) {
528 const GLvoid
*src
= _mesa_image_address(dims
, srcPacking
,
529 srcAddr
, srcWidth
, srcHeight
, srcFormat
, srcType
, img
, row
, 0);
530 GLushort
*dst16
= (GLushort
*) dstRow
;
531 _mesa_unpack_depth_span(ctx
, srcWidth
,
532 GL_UNSIGNED_SHORT
, dst16
, depthScale
,
533 srcType
, src
, srcPacking
);
534 dstRow
+= dstRowStride
;
543 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
546 _mesa_texstore_ycbcr(TEXSTORE_PARAMS
)
548 const GLboolean littleEndian
= _mesa_little_endian();
550 (void) ctx
; (void) dims
; (void) baseInternalFormat
;
552 ASSERT((dstFormat
== MESA_FORMAT_YCBCR
) ||
553 (dstFormat
== MESA_FORMAT_YCBCR_REV
));
554 ASSERT(_mesa_get_format_bytes(dstFormat
) == 2);
555 ASSERT(ctx
->Extensions
.MESA_ycbcr_texture
);
556 ASSERT(srcFormat
== GL_YCBCR_MESA
);
557 ASSERT((srcType
== GL_UNSIGNED_SHORT_8_8_MESA
) ||
558 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
));
559 ASSERT(baseInternalFormat
== GL_YCBCR_MESA
);
561 /* always just memcpy since no pixel transfer ops apply */
562 memcpy_texture(ctx
, dims
,
564 dstRowStride
, dstSlices
,
565 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
566 srcAddr
, srcPacking
);
568 /* Check if we need byte swapping */
569 /* XXX the logic here _might_ be wrong */
570 if (srcPacking
->SwapBytes
^
571 (srcType
== GL_UNSIGNED_SHORT_8_8_REV_MESA
) ^
572 (dstFormat
== MESA_FORMAT_YCBCR_REV
) ^
575 for (img
= 0; img
< srcDepth
; img
++) {
576 GLubyte
*dstRow
= dstSlices
[img
];
577 for (row
= 0; row
< srcHeight
; row
++) {
578 _mesa_swap2((GLushort
*) dstRow
, srcWidth
);
579 dstRow
+= dstRowStride
;
588 * Store a combined depth/stencil texture image.
591 _mesa_texstore_z24_s8(TEXSTORE_PARAMS
)
593 const GLuint depthScale
= 0xffffff;
594 const GLint srcRowStride
595 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
597 GLuint
*depth
= malloc(srcWidth
* sizeof(GLuint
));
598 GLubyte
*stencil
= malloc(srcWidth
* sizeof(GLubyte
));
600 ASSERT(dstFormat
== MESA_FORMAT_S8_UINT_Z24_UNORM
);
601 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
||
602 srcFormat
== GL_DEPTH_COMPONENT
||
603 srcFormat
== GL_STENCIL_INDEX
);
604 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
||
605 srcType
== GL_UNSIGNED_INT_24_8_EXT
||
606 srcType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
608 if (!depth
|| !stencil
) {
614 /* In case we only upload depth we need to preserve the stencil */
615 for (img
= 0; img
< srcDepth
; img
++) {
616 GLuint
*dstRow
= (GLuint
*) dstSlices
[img
];
618 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
622 for (row
= 0; row
< srcHeight
; row
++) {
624 GLboolean keepdepth
= GL_FALSE
, keepstencil
= GL_FALSE
;
626 if (srcFormat
== GL_DEPTH_COMPONENT
) { /* preserve stencil */
627 keepstencil
= GL_TRUE
;
629 else if (srcFormat
== GL_STENCIL_INDEX
) { /* preserve depth */
633 if (keepdepth
== GL_FALSE
)
634 /* the 24 depth bits will be in the low position: */
635 _mesa_unpack_depth_span(ctx
, srcWidth
,
636 GL_UNSIGNED_INT
, /* dst type */
637 keepstencil
? depth
: dstRow
, /* dst addr */
639 srcType
, src
, srcPacking
);
641 if (keepstencil
== GL_FALSE
)
642 /* get the 8-bit stencil values */
643 _mesa_unpack_stencil_span(ctx
, srcWidth
,
644 GL_UNSIGNED_BYTE
, /* dst type */
645 stencil
, /* dst addr */
646 srcType
, src
, srcPacking
,
647 ctx
->_ImageTransferState
);
649 for (i
= 0; i
< srcWidth
; i
++) {
651 dstRow
[i
] = depth
[i
] << 8 | (dstRow
[i
] & 0x000000FF);
653 dstRow
[i
] = (dstRow
[i
] & 0xFFFFFF00) | (stencil
[i
] & 0xFF);
656 dstRow
+= dstRowStride
/ sizeof(GLuint
);
667 * Store a combined depth/stencil texture image.
670 _mesa_texstore_s8_z24(TEXSTORE_PARAMS
)
672 const GLuint depthScale
= 0xffffff;
673 const GLint srcRowStride
674 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
679 ASSERT(dstFormat
== MESA_FORMAT_Z24_UNORM_S8_UINT
);
680 ASSERT(srcFormat
== GL_DEPTH_STENCIL_EXT
||
681 srcFormat
== GL_DEPTH_COMPONENT
||
682 srcFormat
== GL_STENCIL_INDEX
);
683 ASSERT(srcFormat
!= GL_DEPTH_STENCIL_EXT
||
684 srcType
== GL_UNSIGNED_INT_24_8_EXT
||
685 srcType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
687 depth
= malloc(srcWidth
* sizeof(GLuint
));
688 stencil
= malloc(srcWidth
* sizeof(GLubyte
));
690 if (!depth
|| !stencil
) {
696 for (img
= 0; img
< srcDepth
; img
++) {
697 GLuint
*dstRow
= (GLuint
*) dstSlices
[img
];
699 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
703 for (row
= 0; row
< srcHeight
; row
++) {
705 GLboolean keepdepth
= GL_FALSE
, keepstencil
= GL_FALSE
;
707 if (srcFormat
== GL_DEPTH_COMPONENT
) { /* preserve stencil */
708 keepstencil
= GL_TRUE
;
710 else if (srcFormat
== GL_STENCIL_INDEX
) { /* preserve depth */
714 if (keepdepth
== GL_FALSE
)
715 /* the 24 depth bits will be in the low position: */
716 _mesa_unpack_depth_span(ctx
, srcWidth
,
717 GL_UNSIGNED_INT
, /* dst type */
718 keepstencil
? depth
: dstRow
, /* dst addr */
720 srcType
, src
, srcPacking
);
722 if (keepstencil
== GL_FALSE
)
723 /* get the 8-bit stencil values */
724 _mesa_unpack_stencil_span(ctx
, srcWidth
,
725 GL_UNSIGNED_BYTE
, /* dst type */
726 stencil
, /* dst addr */
727 srcType
, src
, srcPacking
,
728 ctx
->_ImageTransferState
);
730 /* merge stencil values into depth values */
731 for (i
= 0; i
< srcWidth
; i
++) {
733 dstRow
[i
] = depth
[i
] | (dstRow
[i
] & 0xFF000000);
735 dstRow
[i
] = (dstRow
[i
] & 0xFFFFFF) | (stencil
[i
] << 24);
739 dstRow
+= dstRowStride
/ sizeof(GLuint
);
751 * Store simple 8-bit/value stencil texture data.
754 _mesa_texstore_s8(TEXSTORE_PARAMS
)
756 ASSERT(dstFormat
== MESA_FORMAT_S_UINT8
);
757 ASSERT(srcFormat
== GL_STENCIL_INDEX
);
760 const GLint srcRowStride
761 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
763 GLubyte
*stencil
= malloc(srcWidth
* sizeof(GLubyte
));
768 for (img
= 0; img
< srcDepth
; img
++) {
769 GLubyte
*dstRow
= dstSlices
[img
];
771 = (const GLubyte
*) _mesa_image_address(dims
, srcPacking
, srcAddr
,
775 for (row
= 0; row
< srcHeight
; row
++) {
778 /* get the 8-bit stencil values */
779 _mesa_unpack_stencil_span(ctx
, srcWidth
,
780 GL_UNSIGNED_BYTE
, /* dst type */
781 stencil
, /* dst addr */
782 srcType
, src
, srcPacking
,
783 ctx
->_ImageTransferState
);
784 /* merge stencil values into depth values */
785 for (i
= 0; i
< srcWidth
; i
++)
786 dstRow
[i
] = stencil
[i
];
789 dstRow
+= dstRowStride
/ sizeof(GLubyte
);
801 _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS
)
804 const GLint srcRowStride
805 = _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
)
808 ASSERT(dstFormat
== MESA_FORMAT_Z32_FLOAT_S8X24_UINT
);
809 ASSERT(srcFormat
== GL_DEPTH_STENCIL
||
810 srcFormat
== GL_DEPTH_COMPONENT
||
811 srcFormat
== GL_STENCIL_INDEX
);
812 ASSERT(srcFormat
!= GL_DEPTH_STENCIL
||
813 srcType
== GL_UNSIGNED_INT_24_8
||
814 srcType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
);
816 /* In case we only upload depth we need to preserve the stencil */
817 for (img
= 0; img
< srcDepth
; img
++) {
818 uint64_t *dstRow
= (uint64_t *) dstSlices
[img
];
820 = (const uint64_t *) _mesa_image_address(dims
, srcPacking
, srcAddr
,
824 for (row
= 0; row
< srcHeight
; row
++) {
825 /* The unpack functions with:
826 * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
827 * only write their own dword, so the other dword (stencil
828 * or depth) is preserved. */
829 if (srcFormat
!= GL_STENCIL_INDEX
)
830 _mesa_unpack_depth_span(ctx
, srcWidth
,
831 GL_FLOAT_32_UNSIGNED_INT_24_8_REV
, /* dst type */
832 dstRow
, /* dst addr */
833 ~0U, srcType
, src
, srcPacking
);
835 if (srcFormat
!= GL_DEPTH_COMPONENT
)
836 _mesa_unpack_stencil_span(ctx
, srcWidth
,
837 GL_FLOAT_32_UNSIGNED_INT_24_8_REV
, /* dst type */
838 dstRow
, /* dst addr */
839 srcType
, src
, srcPacking
,
840 ctx
->_ImageTransferState
);
843 dstRow
+= dstRowStride
/ sizeof(uint64_t);
850 texstore_depth_stencil(TEXSTORE_PARAMS
)
852 static StoreTexImageFunc table
[MESA_FORMAT_COUNT
];
853 static GLboolean initialized
= GL_FALSE
;
856 memset(table
, 0, sizeof table
);
858 table
[MESA_FORMAT_S8_UINT_Z24_UNORM
] = _mesa_texstore_z24_s8
;
859 table
[MESA_FORMAT_Z24_UNORM_S8_UINT
] = _mesa_texstore_s8_z24
;
860 table
[MESA_FORMAT_Z_UNORM16
] = _mesa_texstore_z16
;
861 table
[MESA_FORMAT_Z24_UNORM_X8_UINT
] = _mesa_texstore_x8_z24
;
862 table
[MESA_FORMAT_X8_UINT_Z24_UNORM
] = _mesa_texstore_z24_x8
;
863 table
[MESA_FORMAT_Z_UNORM32
] = _mesa_texstore_z32
;
864 table
[MESA_FORMAT_S_UINT8
] = _mesa_texstore_s8
;
865 table
[MESA_FORMAT_Z_FLOAT32
] = _mesa_texstore_z32
;
866 table
[MESA_FORMAT_Z32_FLOAT_S8X24_UINT
] = _mesa_texstore_z32f_x24s8
;
868 initialized
= GL_TRUE
;
871 ASSERT(table
[dstFormat
]);
872 return table
[dstFormat
](ctx
, dims
, baseInternalFormat
,
873 dstFormat
, dstRowStride
, dstSlices
,
874 srcWidth
, srcHeight
, srcDepth
,
875 srcFormat
, srcType
, srcAddr
, srcPacking
);
879 texstore_compressed(TEXSTORE_PARAMS
)
881 static StoreTexImageFunc table
[MESA_FORMAT_COUNT
];
882 static GLboolean initialized
= GL_FALSE
;
885 memset(table
, 0, sizeof table
);
887 table
[MESA_FORMAT_SRGB_DXT1
] = _mesa_texstore_rgb_dxt1
;
888 table
[MESA_FORMAT_SRGBA_DXT1
] = _mesa_texstore_rgba_dxt1
;
889 table
[MESA_FORMAT_SRGBA_DXT3
] = _mesa_texstore_rgba_dxt3
;
890 table
[MESA_FORMAT_SRGBA_DXT5
] = _mesa_texstore_rgba_dxt5
;
891 table
[MESA_FORMAT_RGB_FXT1
] = _mesa_texstore_rgb_fxt1
;
892 table
[MESA_FORMAT_RGBA_FXT1
] = _mesa_texstore_rgba_fxt1
;
893 table
[MESA_FORMAT_RGB_DXT1
] = _mesa_texstore_rgb_dxt1
;
894 table
[MESA_FORMAT_RGBA_DXT1
] = _mesa_texstore_rgba_dxt1
;
895 table
[MESA_FORMAT_RGBA_DXT3
] = _mesa_texstore_rgba_dxt3
;
896 table
[MESA_FORMAT_RGBA_DXT5
] = _mesa_texstore_rgba_dxt5
;
897 table
[MESA_FORMAT_R_RGTC1_UNORM
] = _mesa_texstore_red_rgtc1
;
898 table
[MESA_FORMAT_R_RGTC1_SNORM
] = _mesa_texstore_signed_red_rgtc1
;
899 table
[MESA_FORMAT_RG_RGTC2_UNORM
] = _mesa_texstore_rg_rgtc2
;
900 table
[MESA_FORMAT_RG_RGTC2_SNORM
] = _mesa_texstore_signed_rg_rgtc2
;
901 table
[MESA_FORMAT_L_LATC1_UNORM
] = _mesa_texstore_red_rgtc1
;
902 table
[MESA_FORMAT_L_LATC1_SNORM
] = _mesa_texstore_signed_red_rgtc1
;
903 table
[MESA_FORMAT_LA_LATC2_UNORM
] = _mesa_texstore_rg_rgtc2
;
904 table
[MESA_FORMAT_LA_LATC2_SNORM
] = _mesa_texstore_signed_rg_rgtc2
;
905 table
[MESA_FORMAT_ETC1_RGB8
] = _mesa_texstore_etc1_rgb8
;
906 table
[MESA_FORMAT_ETC2_RGB8
] = _mesa_texstore_etc2_rgb8
;
907 table
[MESA_FORMAT_ETC2_SRGB8
] = _mesa_texstore_etc2_srgb8
;
908 table
[MESA_FORMAT_ETC2_RGBA8_EAC
] = _mesa_texstore_etc2_rgba8_eac
;
909 table
[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC
] = _mesa_texstore_etc2_srgb8_alpha8_eac
;
910 table
[MESA_FORMAT_ETC2_R11_EAC
] = _mesa_texstore_etc2_r11_eac
;
911 table
[MESA_FORMAT_ETC2_RG11_EAC
] = _mesa_texstore_etc2_rg11_eac
;
912 table
[MESA_FORMAT_ETC2_SIGNED_R11_EAC
] = _mesa_texstore_etc2_signed_r11_eac
;
913 table
[MESA_FORMAT_ETC2_SIGNED_RG11_EAC
] = _mesa_texstore_etc2_signed_rg11_eac
;
914 table
[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1
] =
915 _mesa_texstore_etc2_rgb8_punchthrough_alpha1
;
916 table
[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1
] =
917 _mesa_texstore_etc2_srgb8_punchthrough_alpha1
;
919 table
[MESA_FORMAT_BPTC_RGBA_UNORM
] =
920 _mesa_texstore_bptc_rgba_unorm
;
921 table
[MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM
] =
922 _mesa_texstore_bptc_rgba_unorm
;
923 table
[MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT
] =
924 _mesa_texstore_bptc_rgb_signed_float
;
925 table
[MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT
] =
926 _mesa_texstore_bptc_rgb_unsigned_float
;
928 initialized
= GL_TRUE
;
931 ASSERT(table
[dstFormat
]);
932 return table
[dstFormat
](ctx
, dims
, baseInternalFormat
,
933 dstFormat
, dstRowStride
, dstSlices
,
934 srcWidth
, srcHeight
, srcDepth
,
935 srcFormat
, srcType
, srcAddr
, srcPacking
);
939 texstore_rgba(TEXSTORE_PARAMS
)
941 void *tempImage
= NULL
;
942 int srcRowStride
, img
;
944 uint32_t srcMesaFormat
;
945 uint8_t rebaseSwizzle
[4];
948 /* We have to handle MESA_FORMAT_YCBCR manually because it is a special case
949 * and _mesa_format_convert does not support it. In this case the we only
950 * allow conversions between YCBCR formats and it is mostly a memcpy.
952 if (dstFormat
== MESA_FORMAT_YCBCR
|| dstFormat
== MESA_FORMAT_YCBCR_REV
) {
953 return _mesa_texstore_ycbcr(ctx
, dims
, baseInternalFormat
,
954 dstFormat
, dstRowStride
, dstSlices
,
955 srcWidth
, srcHeight
, srcDepth
,
956 srcFormat
, srcType
, srcAddr
,
960 /* We have to deal with GL_COLOR_INDEX manually because
961 * _mesa_format_convert does not handle this format. So what we do here is
962 * convert it to RGBA ubyte first and then convert from that to dst as usual.
964 if (srcFormat
== GL_COLOR_INDEX
) {
965 /* Notice that this will already handle byte swapping if necessary */
966 tempImage
= _mesa_make_temp_ubyte_image(ctx
, dims
,
969 srcWidth
, srcHeight
, srcDepth
,
970 srcFormat
, srcType
, srcAddr
,
975 /* Now we only have to adjust our src info for a conversion from
976 * the RGBA ubyte and then we continue as usual.
980 srcType
= GL_UNSIGNED_BYTE
;
981 } else if (srcPacking
->SwapBytes
) {
982 /* We have to handle byte-swapping scenarios before calling
983 * _mesa_format_convert
985 GLint swapSize
= _mesa_sizeof_packed_type(srcType
);
986 if (swapSize
== 2 || swapSize
== 4) {
987 int components
= _mesa_components_in_format(srcFormat
);
988 int elementCount
= srcWidth
* srcHeight
* components
;
989 tempImage
= malloc(elementCount
* swapSize
);
993 _mesa_swap2_copy(tempImage
, (GLushort
*) srcAddr
, elementCount
);
995 _mesa_swap4_copy(tempImage
, (GLuint
*) srcAddr
, elementCount
);
1001 _mesa_image_row_stride(srcPacking
, srcWidth
, srcFormat
, srcType
);
1004 _mesa_image_address(dims
, srcPacking
, srcAddr
, srcWidth
, srcHeight
,
1005 srcFormat
, srcType
, 0, 0, 0);
1007 srcMesaFormat
= _mesa_format_from_format_and_type(srcFormat
, srcType
);
1008 dstFormat
= _mesa_get_srgb_format_linear(dstFormat
);
1010 if (_mesa_get_format_base_format(dstFormat
) != baseInternalFormat
) {
1012 _mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat
,
1018 for (img
= 0; img
< srcDepth
; img
++) {
1019 _mesa_format_convert(dstSlices
[img
], dstFormat
, dstRowStride
,
1020 src
, srcMesaFormat
, srcRowStride
,
1021 srcWidth
, srcHeight
,
1022 needRebase
? rebaseSwizzle
: NULL
);
1023 src
+= srcHeight
* srcRowStride
;
1032 _mesa_texstore_needs_transfer_ops(struct gl_context
*ctx
,
1033 GLenum baseInternalFormat
,
1034 mesa_format dstFormat
)
1038 /* There are different rules depending on the base format. */
1039 switch (baseInternalFormat
) {
1040 case GL_DEPTH_COMPONENT
:
1041 case GL_DEPTH_STENCIL
:
1042 return ctx
->Pixel
.DepthScale
!= 1.0f
||
1043 ctx
->Pixel
.DepthBias
!= 0.0f
;
1045 case GL_STENCIL_INDEX
:
1050 * Pixel transfer ops (scale, bias, table lookup) do not apply
1051 * to integer formats.
1053 dstType
= _mesa_get_format_datatype(dstFormat
);
1055 return dstType
!= GL_INT
&& dstType
!= GL_UNSIGNED_INT
&&
1056 ctx
->_ImageTransferState
;
1062 _mesa_texstore_can_use_memcpy(struct gl_context
*ctx
,
1063 GLenum baseInternalFormat
, mesa_format dstFormat
,
1064 GLenum srcFormat
, GLenum srcType
,
1065 const struct gl_pixelstore_attrib
*srcPacking
)
1067 if (_mesa_texstore_needs_transfer_ops(ctx
, baseInternalFormat
, dstFormat
)) {
1071 /* The base internal format and the base Mesa format must match. */
1072 if (baseInternalFormat
!= _mesa_get_format_base_format(dstFormat
)) {
1076 /* The Mesa format must match the input format and type. */
1077 if (!_mesa_format_matches_format_and_type(dstFormat
, srcFormat
, srcType
,
1078 srcPacking
->SwapBytes
)) {
1082 /* Depth texture data needs clamping in following cases:
1083 * - Floating point dstFormat with signed srcType: clamp to [0.0, 1.0].
1084 * - Fixed point dstFormat with signed srcType: clamp to [0, 2^n -1].
1086 * All the cases except one (float dstFormat with float srcType) are ruled
1087 * out by _mesa_format_matches_format_and_type() check above. Handle the
1088 * remaining case here.
1090 if ((baseInternalFormat
== GL_DEPTH_COMPONENT
||
1091 baseInternalFormat
== GL_DEPTH_STENCIL
) &&
1092 (srcType
== GL_FLOAT
||
1093 srcType
== GL_FLOAT_32_UNSIGNED_INT_24_8_REV
)) {
1101 _mesa_texstore_memcpy(TEXSTORE_PARAMS
)
1103 if (!_mesa_texstore_can_use_memcpy(ctx
, baseInternalFormat
, dstFormat
,
1104 srcFormat
, srcType
, srcPacking
)) {
1108 memcpy_texture(ctx
, dims
,
1110 dstRowStride
, dstSlices
,
1111 srcWidth
, srcHeight
, srcDepth
, srcFormat
, srcType
,
1112 srcAddr
, srcPacking
);
1116 * Store user data into texture memory.
1117 * Called via glTex[Sub]Image1/2/3D()
1118 * \return GL_TRUE for success, GL_FALSE for failure (out of memory).
1121 _mesa_texstore(TEXSTORE_PARAMS
)
1123 if (_mesa_texstore_memcpy(ctx
, dims
, baseInternalFormat
,
1125 dstRowStride
, dstSlices
,
1126 srcWidth
, srcHeight
, srcDepth
,
1127 srcFormat
, srcType
, srcAddr
, srcPacking
)) {
1131 if (_mesa_is_depth_or_stencil_format(baseInternalFormat
)) {
1132 return texstore_depth_stencil(ctx
, dims
, baseInternalFormat
,
1133 dstFormat
, dstRowStride
, dstSlices
,
1134 srcWidth
, srcHeight
, srcDepth
,
1135 srcFormat
, srcType
, srcAddr
, srcPacking
);
1136 } else if (_mesa_is_format_compressed(dstFormat
)) {
1137 return texstore_compressed(ctx
, dims
, baseInternalFormat
,
1138 dstFormat
, dstRowStride
, dstSlices
,
1139 srcWidth
, srcHeight
, srcDepth
,
1140 srcFormat
, srcType
, srcAddr
, srcPacking
);
1142 return texstore_rgba(ctx
, dims
, baseInternalFormat
,
1143 dstFormat
, dstRowStride
, dstSlices
,
1144 srcWidth
, srcHeight
, srcDepth
,
1145 srcFormat
, srcType
, srcAddr
, srcPacking
);
1151 * Normally, we'll only _write_ texel data to a texture when we map it.
1152 * But if the user is providing depth or stencil values and the texture
1153 * image is a combined depth/stencil format, we'll actually read from
1154 * the texture buffer too (in order to insert the depth or stencil values.
1155 * \param userFormat the user-provided image format
1156 * \param texFormat the destination texture format
1159 get_read_write_mode(GLenum userFormat
, mesa_format texFormat
)
1161 if ((userFormat
== GL_STENCIL_INDEX
|| userFormat
== GL_DEPTH_COMPONENT
)
1162 && _mesa_get_format_base_format(texFormat
) == GL_DEPTH_STENCIL
)
1163 return GL_MAP_READ_BIT
| GL_MAP_WRITE_BIT
;
1165 return GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_RANGE_BIT
;
1170 * Helper function for storing 1D, 2D, 3D whole and subimages into texture
1172 * The source of the image data may be user memory or a PBO. In the later
1173 * case, we'll map the PBO, copy from it, then unmap it.
1176 store_texsubimage(struct gl_context
*ctx
,
1177 struct gl_texture_image
*texImage
,
1178 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1179 GLint width
, GLint height
, GLint depth
,
1180 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1181 const struct gl_pixelstore_attrib
*packing
,
1185 const GLbitfield mapMode
= get_read_write_mode(format
, texImage
->TexFormat
);
1186 const GLenum target
= texImage
->TexObject
->Target
;
1187 GLboolean success
= GL_FALSE
;
1188 GLuint dims
, slice
, numSlices
= 1, sliceOffset
= 0;
1189 GLint srcImageStride
= 0;
1192 assert(xoffset
+ width
<= texImage
->Width
);
1193 assert(yoffset
+ height
<= texImage
->Height
);
1194 assert(zoffset
+ depth
<= texImage
->Depth
);
1200 case GL_TEXTURE_2D_ARRAY
:
1201 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1209 /* get pointer to src pixels (may be in a pbo which we'll map here) */
1210 src
= (const GLubyte
*)
1211 _mesa_validate_pbo_teximage(ctx
, dims
, width
, height
, depth
,
1212 format
, type
, pixels
, packing
, caller
);
1216 /* compute slice info (and do some sanity checks) */
1219 case GL_TEXTURE_RECTANGLE
:
1220 case GL_TEXTURE_CUBE_MAP
:
1221 case GL_TEXTURE_EXTERNAL_OES
:
1222 /* one image slice, nothing special needs to be done */
1225 assert(height
== 1);
1227 assert(yoffset
== 0);
1228 assert(zoffset
== 0);
1230 case GL_TEXTURE_1D_ARRAY
:
1232 assert(zoffset
== 0);
1234 sliceOffset
= yoffset
;
1237 srcImageStride
= _mesa_image_row_stride(packing
, width
, format
, type
);
1239 case GL_TEXTURE_2D_ARRAY
:
1241 sliceOffset
= zoffset
;
1244 srcImageStride
= _mesa_image_image_stride(packing
, width
, height
,
1248 /* we'll store 3D images as a series of slices */
1250 sliceOffset
= zoffset
;
1251 srcImageStride
= _mesa_image_image_stride(packing
, width
, height
,
1254 case GL_TEXTURE_CUBE_MAP_ARRAY
:
1256 sliceOffset
= zoffset
;
1257 srcImageStride
= _mesa_image_image_stride(packing
, width
, height
,
1261 _mesa_warning(ctx
, "Unexpected target 0x%x in store_texsubimage()", target
);
1265 assert(numSlices
== 1 || srcImageStride
!= 0);
1267 for (slice
= 0; slice
< numSlices
; slice
++) {
1271 ctx
->Driver
.MapTextureImage(ctx
, texImage
,
1272 slice
+ sliceOffset
,
1273 xoffset
, yoffset
, width
, height
,
1274 mapMode
, &dstMap
, &dstRowStride
);
1276 /* Note: we're only storing a 2D (or 1D) slice at a time but we need
1277 * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is
1278 * used for 3D images.
1280 success
= _mesa_texstore(ctx
, dims
, texImage
->_BaseFormat
,
1281 texImage
->TexFormat
,
1284 width
, height
, 1, /* w, h, d */
1285 format
, type
, src
, packing
);
1287 ctx
->Driver
.UnmapTextureImage(ctx
, texImage
, slice
+ sliceOffset
);
1290 src
+= srcImageStride
;
1297 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "%s", caller
);
1299 _mesa_unmap_teximage_pbo(ctx
, packing
);
1305 * Fallback code for ctx->Driver.TexImage().
1306 * Basically, allocate storage for the texture image, then copy the
1307 * user's image into it.
1310 _mesa_store_teximage(struct gl_context
*ctx
,
1312 struct gl_texture_image
*texImage
,
1313 GLenum format
, GLenum type
, const GLvoid
*pixels
,
1314 const struct gl_pixelstore_attrib
*packing
)
1316 assert(dims
== 1 || dims
== 2 || dims
== 3);
1318 if (texImage
->Width
== 0 || texImage
->Height
== 0 || texImage
->Depth
== 0)
1321 /* allocate storage for texture data */
1322 if (!ctx
->Driver
.AllocTextureImageBuffer(ctx
, texImage
)) {
1323 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage%uD", dims
);
1327 store_texsubimage(ctx
, texImage
,
1328 0, 0, 0, texImage
->Width
, texImage
->Height
, texImage
->Depth
,
1329 format
, type
, pixels
, packing
, "glTexImage");
1334 * Fallback for Driver.TexSubImage().
1337 _mesa_store_texsubimage(struct gl_context
*ctx
, GLuint dims
,
1338 struct gl_texture_image
*texImage
,
1339 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1340 GLint width
, GLint height
, GLint depth
,
1341 GLenum format
, GLenum type
, const void *pixels
,
1342 const struct gl_pixelstore_attrib
*packing
)
1344 store_texsubimage(ctx
, texImage
,
1345 xoffset
, yoffset
, zoffset
, width
, height
, depth
,
1346 format
, type
, pixels
, packing
, "glTexSubImage");
1350 clear_image_to_zero(GLubyte
*dstMap
, GLint dstRowStride
,
1351 GLsizei width
, GLsizei height
,
1352 GLsizei clearValueSize
)
1356 for (y
= 0; y
< height
; y
++) {
1357 memset(dstMap
, 0, clearValueSize
* width
);
1358 dstMap
+= dstRowStride
;
1363 clear_image_to_value(GLubyte
*dstMap
, GLint dstRowStride
,
1364 GLsizei width
, GLsizei height
,
1365 const GLvoid
*clearValue
,
1366 GLsizei clearValueSize
)
1370 for (y
= 0; y
< height
; y
++) {
1371 for (x
= 0; x
< width
; x
++) {
1372 memcpy(dstMap
, clearValue
, clearValueSize
);
1373 dstMap
+= clearValueSize
;
1375 dstMap
+= dstRowStride
- clearValueSize
* width
;
1380 * Fallback for Driver.ClearTexSubImage().
1383 _mesa_store_cleartexsubimage(struct gl_context
*ctx
,
1384 struct gl_texture_image
*texImage
,
1385 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1386 GLsizei width
, GLsizei height
, GLsizei depth
,
1387 const GLvoid
*clearValue
)
1391 GLsizeiptr clearValueSize
;
1394 clearValueSize
= _mesa_get_format_bytes(texImage
->TexFormat
);
1396 for (z
= 0; z
< depth
; z
++) {
1397 ctx
->Driver
.MapTextureImage(ctx
, texImage
,
1398 z
+ zoffset
, xoffset
, yoffset
,
1401 &dstMap
, &dstRowStride
);
1402 if (dstMap
== NULL
) {
1403 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glClearTex*Image");
1408 clear_image_to_value(dstMap
, dstRowStride
,
1413 clear_image_to_zero(dstMap
, dstRowStride
,
1418 ctx
->Driver
.UnmapTextureImage(ctx
, texImage
, z
+ zoffset
);
1423 * Fallback for Driver.CompressedTexImage()
1426 _mesa_store_compressed_teximage(struct gl_context
*ctx
, GLuint dims
,
1427 struct gl_texture_image
*texImage
,
1428 GLsizei imageSize
, const GLvoid
*data
)
1430 /* only 2D and 3D compressed images are supported at this time */
1432 _mesa_problem(ctx
, "Unexpected glCompressedTexImage1D call");
1436 /* This is pretty simple, because unlike the general texstore path we don't
1437 * have to worry about the usual image unpacking or image transfer
1441 ASSERT(texImage
->Width
> 0);
1442 ASSERT(texImage
->Height
> 0);
1443 ASSERT(texImage
->Depth
> 0);
1445 /* allocate storage for texture data */
1446 if (!ctx
->Driver
.AllocTextureImageBuffer(ctx
, texImage
)) {
1447 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexImage%uD", dims
);
1451 _mesa_store_compressed_texsubimage(ctx
, dims
, texImage
,
1453 texImage
->Width
, texImage
->Height
, texImage
->Depth
,
1454 texImage
->TexFormat
,
1460 * Compute compressed_pixelstore parameters for copying compressed
1462 * \param dims number of texture image dimensions: 1, 2 or 3
1463 * \param texFormat the compressed texture format
1464 * \param width, height, depth size of image to copy
1465 * \param packing pixelstore parameters describing user-space image packing
1466 * \param store returns the compressed_pixelstore parameters
1469 _mesa_compute_compressed_pixelstore(GLuint dims
, mesa_format texFormat
,
1470 GLsizei width
, GLsizei height
,
1472 const struct gl_pixelstore_attrib
*packing
,
1473 struct compressed_pixelstore
*store
)
1477 _mesa_get_format_block_size(texFormat
, &bw
, &bh
);
1479 store
->SkipBytes
= 0;
1480 store
->TotalBytesPerRow
= store
->CopyBytesPerRow
=
1481 _mesa_format_row_stride(texFormat
, width
);
1482 store
->TotalRowsPerSlice
= store
->CopyRowsPerSlice
=
1483 (height
+ bh
- 1) / bh
;
1484 store
->CopySlices
= depth
;
1486 if (packing
->CompressedBlockWidth
&&
1487 packing
->CompressedBlockSize
) {
1489 bw
= packing
->CompressedBlockWidth
;
1491 if (packing
->RowLength
) {
1492 store
->TotalBytesPerRow
= packing
->CompressedBlockSize
*
1493 ((packing
->RowLength
+ bw
- 1) / bw
);
1496 store
->SkipBytes
+= packing
->SkipPixels
* packing
->CompressedBlockSize
/ bw
;
1499 if (dims
> 1 && packing
->CompressedBlockHeight
&&
1500 packing
->CompressedBlockSize
) {
1502 bh
= packing
->CompressedBlockHeight
;
1504 store
->SkipBytes
+= packing
->SkipRows
* store
->TotalBytesPerRow
/ bh
;
1505 store
->CopyRowsPerSlice
= (height
+ bh
- 1) / bh
; /* rows in blocks */
1507 if (packing
->ImageHeight
) {
1508 store
->TotalRowsPerSlice
= (packing
->ImageHeight
+ bh
- 1) / bh
;
1512 if (dims
> 2 && packing
->CompressedBlockDepth
&&
1513 packing
->CompressedBlockSize
) {
1515 int bd
= packing
->CompressedBlockDepth
;
1517 store
->SkipBytes
+= packing
->SkipImages
* store
->TotalBytesPerRow
*
1518 store
->TotalRowsPerSlice
/ bd
;
1524 * Fallback for Driver.CompressedTexSubImage()
1527 _mesa_store_compressed_texsubimage(struct gl_context
*ctx
, GLuint dims
,
1528 struct gl_texture_image
*texImage
,
1529 GLint xoffset
, GLint yoffset
, GLint zoffset
,
1530 GLsizei width
, GLsizei height
, GLsizei depth
,
1532 GLsizei imageSize
, const GLvoid
*data
)
1534 struct compressed_pixelstore store
;
1541 _mesa_problem(ctx
, "Unexpected 1D compressed texsubimage call");
1545 _mesa_compute_compressed_pixelstore(dims
, texImage
->TexFormat
,
1546 width
, height
, depth
,
1547 &ctx
->Unpack
, &store
);
1549 /* get pointer to src pixels (may be in a pbo which we'll map here) */
1550 data
= _mesa_validate_pbo_compressed_teximage(ctx
, dims
, imageSize
, data
,
1552 "glCompressedTexSubImage");
1556 src
= (const GLubyte
*) data
+ store
.SkipBytes
;
1558 for (slice
= 0; slice
< store
.CopySlices
; slice
++) {
1559 /* Map dest texture buffer */
1560 ctx
->Driver
.MapTextureImage(ctx
, texImage
, slice
+ zoffset
,
1561 xoffset
, yoffset
, width
, height
,
1562 GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_RANGE_BIT
,
1563 &dstMap
, &dstRowStride
);
1567 /* copy rows of blocks */
1568 for (i
= 0; i
< store
.CopyRowsPerSlice
; i
++) {
1569 memcpy(dstMap
, src
, store
.CopyBytesPerRow
);
1570 dstMap
+= dstRowStride
;
1571 src
+= store
.TotalBytesPerRow
;
1574 ctx
->Driver
.UnmapTextureImage(ctx
, texImage
, slice
+ zoffset
);
1576 /* advance to next slice */
1577 src
+= store
.TotalBytesPerRow
* (store
.TotalRowsPerSlice
- store
.CopyRowsPerSlice
);
1580 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glCompressedTexSubImage%uD",
1585 _mesa_unmap_teximage_pbo(ctx
, &ctx
->Unpack
);