2 * Mesa 3-D graphics library
4 * Copyright (C) 2014 Intel Corporation All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
25 #include "format_utils.h"
26 #include "glformats.h"
27 #include "format_pack.h"
28 #include "format_unpack.h"
30 const mesa_array_format RGBA8888_FLOAT
=
31 MESA_ARRAY_FORMAT(4, 1, 1, 1, 4, 0, 1, 2, 3);
33 const mesa_array_format RGBA8888_UBYTE
=
34 MESA_ARRAY_FORMAT(1, 0, 0, 1, 4, 0, 1, 2, 3);
36 const mesa_array_format RGBA8888_UINT
=
37 MESA_ARRAY_FORMAT(4, 0, 0, 0, 4, 0, 1, 2, 3);
39 const mesa_array_format RGBA8888_INT
=
40 MESA_ARRAY_FORMAT(4, 1, 0, 0, 4, 0, 1, 2, 3);
43 invert_swizzle(uint8_t dst
[4], const uint8_t src
[4])
47 dst
[0] = MESA_FORMAT_SWIZZLE_NONE
;
48 dst
[1] = MESA_FORMAT_SWIZZLE_NONE
;
49 dst
[2] = MESA_FORMAT_SWIZZLE_NONE
;
50 dst
[3] = MESA_FORMAT_SWIZZLE_NONE
;
52 for (i
= 0; i
< 4; ++i
)
53 for (j
= 0; j
< 4; ++j
)
54 if (src
[j
] == i
&& dst
[i
] == MESA_FORMAT_SWIZZLE_NONE
)
59 gl_type_for_array_format_datatype(enum mesa_array_format_datatype type
)
62 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
63 return GL_UNSIGNED_BYTE
;
64 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
65 return GL_UNSIGNED_SHORT
;
66 case MESA_ARRAY_FORMAT_TYPE_UINT
:
67 return GL_UNSIGNED_INT
;
68 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
70 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
72 case MESA_ARRAY_FORMAT_TYPE_INT
:
74 case MESA_ARRAY_FORMAT_TYPE_HALF
:
76 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
79 assert(!"Invalid datatype");
84 /* Takes a src to RGBA swizzle and applies a rebase swizzle to it. This
85 * is used when we need to rebase a format to match a different
86 * base internal format.
88 * The rebase swizzle can be NULL, which means that no rebase is necessary,
89 * in which case the src to RGBA swizzle is copied to the output without
92 * The resulting rebased swizzle and well as the input swizzles are
93 * all 4-element swizzles, but the rebase swizzle can be NULL if no rebase
97 compute_rebased_rgba_component_mapping(uint8_t *src2rgba
,
98 uint8_t *rebase_swizzle
,
99 uint8_t *rebased_src2rgba
)
103 if (rebase_swizzle
) {
104 for (i
= 0; i
< 4; i
++) {
105 if (rebase_swizzle
[i
] > MESA_FORMAT_SWIZZLE_W
)
106 rebased_src2rgba
[i
] = rebase_swizzle
[i
];
108 rebased_src2rgba
[i
] = src2rgba
[rebase_swizzle
[i
]];
111 /* No rebase needed, so src2rgba is all that we need */
112 memcpy(rebased_src2rgba
, src2rgba
, 4 * sizeof(uint8_t));
116 /* Computes the final swizzle transform to apply from src to dst in a
117 * conversion that might involve a rebase swizzle.
119 * This is used to compute the swizzle transform to apply in conversions
120 * between array formats where we have a src2rgba swizzle, a rgba2dst swizzle
121 * and possibly, a rebase swizzle.
123 * The final swizzle transform to apply (src2dst) when a rebase swizzle is
124 * involved is: src -> rgba -> base -> rgba -> dst
127 compute_src2dst_component_mapping(uint8_t *src2rgba
, uint8_t *rgba2dst
,
128 uint8_t *rebase_swizzle
, uint8_t *src2dst
)
132 if (!rebase_swizzle
) {
133 for (i
= 0; i
< 4; i
++) {
134 if (rgba2dst
[i
] > MESA_FORMAT_SWIZZLE_W
) {
135 src2dst
[i
] = rgba2dst
[i
];
137 src2dst
[i
] = src2rgba
[rgba2dst
[i
]];
141 for (i
= 0; i
< 4; i
++) {
142 if (rgba2dst
[i
] > MESA_FORMAT_SWIZZLE_W
) {
143 src2dst
[i
] = rgba2dst
[i
];
144 } else if (rebase_swizzle
[rgba2dst
[i
]] > MESA_FORMAT_SWIZZLE_W
) {
145 src2dst
[i
] = rebase_swizzle
[rgba2dst
[i
]];
147 src2dst
[i
] = src2rgba
[rebase_swizzle
[rgba2dst
[i
]]];
154 * This can be used to convert between most color formats.
157 * - This function doesn't handle GL_COLOR_INDEX or YCBCR formats.
158 * - This function doesn't handle byte-swapping or transferOps, these should
159 * be handled by the caller.
161 * \param void_dst The address where converted color data will be stored.
162 * The caller must ensure that the buffer is large enough
163 * to hold the converted pixel data.
164 * \param dst_format The destination color format. It can be a mesa_format
165 * or a mesa_array_format represented as an uint32_t.
166 * \param dst_stride The stride of the destination format in bytes.
167 * \param void_src The address of the source color data to convert.
168 * \param src_format The source color format. It can be a mesa_format
169 * or a mesa_array_format represented as an uint32_t.
170 * \param src_stride The stride of the source format in bytes.
171 * \param width The width, in pixels, of the source image to convert.
172 * \param height The height, in pixels, of the source image to convert.
173 * \param rebase_swizzle A swizzle transform to apply during the conversion,
174 * typically used to match a different internal base
175 * format involved. NULL if no rebase transform is needed
176 * (i.e. the internal base format and the base format of
177 * the dst or the src -depending on whether we are doing
178 * an upload or a download respectively- are the same).
181 _mesa_format_convert(void *void_dst
, uint32_t dst_format
, size_t dst_stride
,
182 void *void_src
, uint32_t src_format
, size_t src_stride
,
183 size_t width
, size_t height
, uint8_t *rebase_swizzle
)
185 uint8_t *dst
= (uint8_t *)void_dst
;
186 uint8_t *src
= (uint8_t *)void_src
;
187 mesa_array_format src_array_format
, dst_array_format
;
188 bool src_format_is_mesa_array_format
, dst_format_is_mesa_array_format
;
189 uint8_t src2dst
[4], src2rgba
[4], rgba2dst
[4], dst2rgba
[4];
190 uint8_t rebased_src2rgba
[4];
191 GLenum src_gl_type
, dst_gl_type
, common_gl_type
;
192 bool normalized
, dst_integer
, src_integer
, is_signed
;
193 int src_num_channels
= 0, dst_num_channels
= 0;
194 uint8_t (*tmp_ubyte
)[4];
195 float (*tmp_float
)[4];
196 uint32_t (*tmp_uint
)[4];
200 if (_mesa_format_is_mesa_array_format(src_format
)) {
201 src_format_is_mesa_array_format
= true;
202 src_array_format
= src_format
;
204 assert(_mesa_is_format_color_format(src_format
));
205 src_format_is_mesa_array_format
= false;
206 src_array_format
= _mesa_format_to_array_format(src_format
);
209 if (_mesa_format_is_mesa_array_format(dst_format
)) {
210 dst_format_is_mesa_array_format
= true;
211 dst_array_format
= dst_format
;
213 assert(_mesa_is_format_color_format(dst_format
));
214 dst_format_is_mesa_array_format
= false;
215 dst_array_format
= _mesa_format_to_array_format(dst_format
);
218 /* First we see if we can implement the conversion with a direct pack
221 * In this case we want to be careful when we need to apply a swizzle to
222 * match an internal base format, since in these cases a simple pack/unpack
223 * to the dst format from the src format may not match the requirements
224 * of the internal base format. For now we decide to be safe and
225 * avoid this path in these scenarios but in the future we may want to
226 * enable it for specific combinations that are known to work.
228 if (!rebase_swizzle
) {
229 /* Handle the cases where we can directly unpack */
230 if (!src_format_is_mesa_array_format
) {
231 if (dst_array_format
== RGBA8888_FLOAT
) {
232 for (row
= 0; row
< height
; ++row
) {
233 _mesa_unpack_rgba_row(src_format
, width
,
234 src
, (float (*)[4])dst
);
239 } else if (dst_array_format
== RGBA8888_UBYTE
) {
240 assert(!_mesa_is_format_integer_color(src_format
));
241 for (row
= 0; row
< height
; ++row
) {
242 _mesa_unpack_ubyte_rgba_row(src_format
, width
,
243 src
, (uint8_t (*)[4])dst
);
248 } else if (dst_array_format
== RGBA8888_UINT
&&
249 _mesa_is_format_unsigned(src_format
)) {
250 assert(_mesa_is_format_integer_color(src_format
));
251 for (row
= 0; row
< height
; ++row
) {
252 _mesa_unpack_uint_rgba_row(src_format
, width
,
253 src
, (uint32_t (*)[4])dst
);
261 /* Handle the cases where we can directly pack */
262 if (!dst_format_is_mesa_array_format
) {
263 if (src_array_format
== RGBA8888_FLOAT
) {
264 for (row
= 0; row
< height
; ++row
) {
265 _mesa_pack_float_rgba_row(dst_format
, width
,
266 (const float (*)[4])src
, dst
);
271 } else if (src_array_format
== RGBA8888_UBYTE
) {
272 assert(!_mesa_is_format_integer_color(dst_format
));
273 for (row
= 0; row
< height
; ++row
) {
274 _mesa_pack_ubyte_rgba_row(dst_format
, width
,
275 (const uint8_t (*)[4])src
, dst
);
280 } else if (src_array_format
== RGBA8888_UINT
&&
281 _mesa_is_format_unsigned(dst_format
)) {
282 assert(_mesa_is_format_integer_color(dst_format
));
283 for (row
= 0; row
< height
; ++row
) {
284 _mesa_pack_uint_rgba_row(dst_format
, width
,
285 (const uint32_t (*)[4])src
, dst
);
294 /* Handle conversions between array formats */
296 if (src_array_format
) {
297 enum mesa_array_format_datatype datatype
=
298 _mesa_array_format_get_datatype(src_array_format
);
299 src_gl_type
= gl_type_for_array_format_datatype(datatype
);
301 src_num_channels
= _mesa_array_format_get_num_channels(src_array_format
);
303 _mesa_array_format_get_swizzle(src_array_format
, src2rgba
);
305 normalized
= _mesa_array_format_is_normalized(src_array_format
);
308 if (dst_array_format
) {
309 enum mesa_array_format_datatype datatype
=
310 _mesa_array_format_get_datatype(dst_array_format
);
311 dst_gl_type
= gl_type_for_array_format_datatype(datatype
);
313 dst_num_channels
= _mesa_array_format_get_num_channels(dst_array_format
);
315 _mesa_array_format_get_swizzle(dst_array_format
, dst2rgba
);
316 invert_swizzle(rgba2dst
, dst2rgba
);
318 normalized
|= _mesa_array_format_is_normalized(dst_array_format
);
321 if (src_array_format
&& dst_array_format
) {
322 assert(_mesa_array_format_is_normalized(src_array_format
) ==
323 _mesa_array_format_is_normalized(dst_array_format
));
325 compute_src2dst_component_mapping(src2rgba
, rgba2dst
, rebase_swizzle
,
328 for (row
= 0; row
< height
; ++row
) {
329 _mesa_swizzle_and_convert(dst
, dst_gl_type
, dst_num_channels
,
330 src
, src_gl_type
, src_num_channels
,
331 src2dst
, normalized
, width
);
338 /* At this point, we're fresh out of fast-paths and we need to convert
339 * to float, uint32, or, if we're lucky, uint8.
344 if (src_array_format
) {
345 if (!_mesa_array_format_is_float(src_array_format
) &&
346 !_mesa_array_format_is_normalized(src_array_format
))
349 switch (_mesa_get_format_datatype(src_format
)) {
350 case GL_UNSIGNED_INT
:
357 /* If the destination format is signed but the source is unsigned, then we
358 * don't loose any data by converting to a signed intermediate format above
359 * and beyond the precision that we loose in the conversion itself. If the
360 * destination is unsigned then, by using an unsigned intermediate format,
361 * we make the conversion function that converts from the source to the
362 * intermediate format take care of truncating at zero. The exception here
363 * is if the intermediate format is float, in which case the first
364 * conversion will leave it signed and the second conversion will truncate
368 if (dst_array_format
) {
369 if (!_mesa_array_format_is_float(dst_array_format
) &&
370 !_mesa_array_format_is_normalized(dst_array_format
))
372 is_signed
= _mesa_array_format_is_signed(dst_array_format
);
373 bits
= 8 * _mesa_array_format_get_type_size(dst_array_format
);
375 switch (_mesa_get_format_datatype(dst_format
)) {
376 case GL_UNSIGNED_NORMALIZED
:
379 case GL_SIGNED_NORMALIZED
:
385 case GL_UNSIGNED_INT
:
394 bits
= _mesa_get_format_max_bits(dst_format
);
397 assert(src_integer
== dst_integer
);
399 if (src_integer
&& dst_integer
) {
400 tmp_uint
= malloc(width
* height
* sizeof(*tmp_uint
));
402 /* The [un]packing functions for unsigned datatypes treat the 32-bit
403 * integer array as signed for signed formats and as unsigned for
404 * unsigned formats. This is a bit of a problem if we ever convert from
405 * a signed to an unsigned format because the unsigned packing function
406 * doesn't know that the input is signed and will treat it as unsigned
407 * and not do the trunctation. The thing that saves us here is that all
408 * of the packed formats are unsigned, so we can just always use
409 * _mesa_swizzle_and_convert for signed formats, which is aware of the
410 * truncation problem.
412 common_gl_type
= is_signed
? GL_INT
: GL_UNSIGNED_INT
;
413 if (src_array_format
) {
414 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
416 for (row
= 0; row
< height
; ++row
) {
417 _mesa_swizzle_and_convert(tmp_uint
+ row
* width
, common_gl_type
, 4,
418 src
, src_gl_type
, src_num_channels
,
419 rebased_src2rgba
, normalized
, width
);
423 for (row
= 0; row
< height
; ++row
) {
424 _mesa_unpack_uint_rgba_row(src_format
, width
,
425 src
, tmp_uint
+ row
* width
);
427 _mesa_swizzle_and_convert(tmp_uint
+ row
* width
, common_gl_type
, 4,
428 tmp_uint
+ row
* width
, common_gl_type
, 4,
429 rebase_swizzle
, false, width
);
434 /* At this point, we have already done the truncation if the source is
435 * signed but the destination is unsigned, so no need to force the
436 * _mesa_swizzle_and_convert path.
438 if (dst_format_is_mesa_array_format
) {
439 for (row
= 0; row
< height
; ++row
) {
440 _mesa_swizzle_and_convert(dst
, dst_gl_type
, dst_num_channels
,
441 tmp_uint
+ row
* width
, common_gl_type
, 4,
442 rgba2dst
, normalized
, width
);
446 for (row
= 0; row
< height
; ++row
) {
447 _mesa_pack_uint_rgba_row(dst_format
, width
,
448 (const uint32_t (*)[4])tmp_uint
+ row
* width
, dst
);
454 } else if (is_signed
|| bits
> 8) {
455 tmp_float
= malloc(width
* height
* sizeof(*tmp_float
));
457 if (src_format_is_mesa_array_format
) {
458 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
460 for (row
= 0; row
< height
; ++row
) {
461 _mesa_swizzle_and_convert(tmp_float
+ row
* width
, GL_FLOAT
, 4,
462 src
, src_gl_type
, src_num_channels
,
463 rebased_src2rgba
, normalized
, width
);
467 for (row
= 0; row
< height
; ++row
) {
468 _mesa_unpack_rgba_row(src_format
, width
,
469 src
, tmp_float
+ row
* width
);
471 _mesa_swizzle_and_convert(tmp_float
+ row
* width
, GL_FLOAT
, 4,
472 tmp_float
+ row
* width
, GL_FLOAT
, 4,
473 rebase_swizzle
, false, width
);
478 if (dst_format_is_mesa_array_format
) {
479 for (row
= 0; row
< height
; ++row
) {
480 _mesa_swizzle_and_convert(dst
, dst_gl_type
, dst_num_channels
,
481 tmp_float
+ row
* width
, GL_FLOAT
, 4,
482 rgba2dst
, normalized
, width
);
486 for (row
= 0; row
< height
; ++row
) {
487 _mesa_pack_float_rgba_row(dst_format
, width
,
488 (const float (*)[4])tmp_float
+ row
* width
, dst
);
495 tmp_ubyte
= malloc(width
* height
* sizeof(*tmp_ubyte
));
497 if (src_format_is_mesa_array_format
) {
498 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
500 for (row
= 0; row
< height
; ++row
) {
501 _mesa_swizzle_and_convert(tmp_ubyte
+ row
* width
, GL_UNSIGNED_BYTE
, 4,
502 src
, src_gl_type
, src_num_channels
,
503 rebased_src2rgba
, normalized
, width
);
507 for (row
= 0; row
< height
; ++row
) {
508 _mesa_unpack_ubyte_rgba_row(src_format
, width
,
509 src
, tmp_ubyte
+ row
* width
);
511 _mesa_swizzle_and_convert(tmp_ubyte
+ row
* width
, GL_UNSIGNED_BYTE
, 4,
512 tmp_ubyte
+ row
* width
, GL_UNSIGNED_BYTE
, 4,
513 rebase_swizzle
, false, width
);
518 if (dst_format_is_mesa_array_format
) {
519 for (row
= 0; row
< height
; ++row
) {
520 _mesa_swizzle_and_convert(dst
, dst_gl_type
, dst_num_channels
,
521 tmp_ubyte
+ row
* width
, GL_UNSIGNED_BYTE
, 4,
522 rgba2dst
, normalized
, width
);
526 for (row
= 0; row
< height
; ++row
) {
527 _mesa_pack_ubyte_rgba_row(dst_format
, width
,
528 (const uint8_t (*)[4])tmp_ubyte
+ row
* width
, dst
);
537 static const uint8_t map_identity
[7] = { 0, 1, 2, 3, 4, 5, 6 };
538 static const uint8_t map_3210
[7] = { 3, 2, 1, 0, 4, 5, 6 };
539 static const uint8_t map_1032
[7] = { 1, 0, 3, 2, 4, 5, 6 };
542 * Describes a format as an array format, if possible
544 * A helper function for figuring out if a (possibly packed) format is
545 * actually an array format and, if so, what the array parameters are.
547 * \param[in] format the mesa format
548 * \param[out] type the GL type of the array (GL_BYTE, etc.)
549 * \param[out] num_components the number of components in the array
550 * \param[out] swizzle a swizzle describing how to get from the
551 * given format to RGBA
552 * \param[out] normalized for integer formats, this represents whether
553 * the format is a normalized integer or a
555 * \return true if this format is an array format, false otherwise
558 _mesa_format_to_array(mesa_format format
, GLenum
*type
, int *num_components
,
559 uint8_t swizzle
[4], bool *normalized
)
562 GLuint format_components
;
563 uint8_t packed_swizzle
[4];
564 const uint8_t *endian
;
566 if (_mesa_is_format_compressed(format
))
569 *normalized
= !_mesa_is_format_integer(format
);
571 _mesa_format_to_type_and_comps(format
, type
, &format_components
);
573 switch (_mesa_get_format_layout(format
)) {
574 case MESA_FORMAT_LAYOUT_ARRAY
:
575 *num_components
= format_components
;
576 _mesa_get_format_swizzle(format
, swizzle
);
578 case MESA_FORMAT_LAYOUT_PACKED
:
580 case GL_UNSIGNED_BYTE
:
582 if (_mesa_get_format_max_bits(format
) != 8)
584 *num_components
= _mesa_get_format_bytes(format
);
585 switch (*num_components
) {
587 endian
= map_identity
;
590 endian
= _mesa_little_endian() ? map_identity
: map_1032
;
593 endian
= _mesa_little_endian() ? map_identity
: map_3210
;
596 endian
= map_identity
;
597 assert(!"Invalid number of components");
600 case GL_UNSIGNED_SHORT
:
603 if (_mesa_get_format_max_bits(format
) != 16)
605 *num_components
= _mesa_get_format_bytes(format
) / 2;
606 switch (*num_components
) {
608 endian
= map_identity
;
611 endian
= _mesa_little_endian() ? map_identity
: map_1032
;
614 endian
= map_identity
;
615 assert(!"Invalid number of components");
618 case GL_UNSIGNED_INT
:
621 /* This isn't packed. At least not really. */
622 assert(format_components
== 1);
623 if (_mesa_get_format_max_bits(format
) != 32)
625 *num_components
= format_components
;
626 endian
= map_identity
;
632 _mesa_get_format_swizzle(format
, packed_swizzle
);
634 for (i
= 0; i
< 4; ++i
)
635 swizzle
[i
] = endian
[packed_swizzle
[i
]];
638 case MESA_FORMAT_LAYOUT_OTHER
:
645 * Attempts to perform the given swizzle-and-convert operation with memcpy
647 * This function determines if the given swizzle-and-convert operation can
648 * be done with a simple memcpy and, if so, does the memcpy. If not, it
649 * returns false and we fall back to the standard version below.
651 * The arguments are exactly the same as for _mesa_swizzle_and_convert
653 * \return true if it successfully performed the swizzle-and-convert
654 * operation with memcpy, false otherwise
657 swizzle_convert_try_memcpy(void *dst
, GLenum dst_type
, int num_dst_channels
,
658 const void *src
, GLenum src_type
, int num_src_channels
,
659 const uint8_t swizzle
[4], bool normalized
, int count
)
663 if (src_type
!= dst_type
)
665 if (num_src_channels
!= num_dst_channels
)
668 for (i
= 0; i
< num_dst_channels
; ++i
)
669 if (swizzle
[i
] != i
&& swizzle
[i
] != MESA_FORMAT_SWIZZLE_NONE
)
672 memcpy(dst
, src
, count
* num_src_channels
* _mesa_sizeof_type(src_type
));
678 * Represents a single instance of the standard swizzle-and-convert loop
680 * Any swizzle-and-convert operation simply loops through the pixels and
681 * performs the transformation operation one pixel at a time. This macro
682 * embodies one instance of the conversion loop. This way we can do all
683 * control flow outside of the loop and allow the compiler to unroll
684 * everything inside the loop.
686 * Note: This loop is carefully crafted for performance. Be careful when
687 * changing it and run some benchmarks to ensure no performance regressions
690 * \param DST_TYPE the C datatype of the destination
691 * \param DST_CHANS the number of destination channels
692 * \param SRC_TYPE the C datatype of the source
693 * \param SRC_CHANS the number of source channels
694 * \param CONV an expression for converting from the source data,
695 * storred in the variable "src", to the destination
698 #define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \
701 for (s = 0; s < count; ++s) { \
702 for (j = 0; j < SRC_CHANS; ++j) { \
703 SRC_TYPE src = typed_src[j]; \
707 typed_dst[0] = tmp[swizzle_x]; \
708 if (DST_CHANS > 1) { \
709 typed_dst[1] = tmp[swizzle_y]; \
710 if (DST_CHANS > 2) { \
711 typed_dst[2] = tmp[swizzle_z]; \
712 if (DST_CHANS > 3) { \
713 typed_dst[3] = tmp[swizzle_w]; \
717 typed_src += SRC_CHANS; \
718 typed_dst += DST_CHANS; \
723 * Represents a single swizzle-and-convert operation
725 * This macro represents everything done in a single swizzle-and-convert
726 * operation. The actual work is done by the SWIZZLE_CONVERT_LOOP macro.
727 * This macro acts as a wrapper that uses a nested switch to ensure that
728 * all looping parameters get unrolled.
730 * This macro makes assumptions about variables etc. in the calling
731 * function. Changes to _mesa_swizzle_and_convert may require changes to
734 * \param DST_TYPE the C datatype of the destination
735 * \param SRC_TYPE the C datatype of the source
736 * \param CONV an expression for converting from the source data,
737 * storred in the variable "src", to the destination
740 #define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV) \
742 const uint8_t swizzle_x = swizzle[0]; \
743 const uint8_t swizzle_y = swizzle[1]; \
744 const uint8_t swizzle_z = swizzle[2]; \
745 const uint8_t swizzle_w = swizzle[3]; \
746 const SRC_TYPE *typed_src = void_src; \
747 DST_TYPE *typed_dst = void_dst; \
751 switch (num_dst_channels) { \
753 switch (num_src_channels) { \
755 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV); \
758 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV); \
761 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV); \
764 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV); \
769 switch (num_src_channels) { \
771 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV); \
774 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV); \
777 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV); \
780 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV); \
785 switch (num_src_channels) { \
787 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV); \
790 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV); \
793 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV); \
796 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV); \
801 switch (num_src_channels) { \
803 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV); \
806 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV); \
809 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV); \
812 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV); \
821 convert_float(void *void_dst
, int num_dst_channels
,
822 const void *void_src
, GLenum src_type
, int num_src_channels
,
823 const uint8_t swizzle
[4], bool normalized
, int count
)
825 const float one
= 1.0f
;
829 SWIZZLE_CONVERT(float, float, src
);
832 SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src
));
834 case GL_UNSIGNED_BYTE
:
836 SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src
, 8));
838 SWIZZLE_CONVERT(float, uint8_t, src
);
843 SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src
, 8));
845 SWIZZLE_CONVERT(float, int8_t, src
);
848 case GL_UNSIGNED_SHORT
:
850 SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src
, 16));
852 SWIZZLE_CONVERT(float, uint16_t, src
);
857 SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src
, 16));
859 SWIZZLE_CONVERT(float, int16_t, src
);
862 case GL_UNSIGNED_INT
:
864 SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src
, 32));
866 SWIZZLE_CONVERT(float, uint32_t, src
);
871 SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src
, 32));
873 SWIZZLE_CONVERT(float, int32_t, src
);
877 assert(!"Invalid channel type combination");
883 convert_half_float(void *void_dst
, int num_dst_channels
,
884 const void *void_src
, GLenum src_type
, int num_src_channels
,
885 const uint8_t swizzle
[4], bool normalized
, int count
)
887 const uint16_t one
= _mesa_float_to_half(1.0f
);
891 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src
));
894 SWIZZLE_CONVERT(uint16_t, uint16_t, src
);
896 case GL_UNSIGNED_BYTE
:
898 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src
, 8));
900 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src
));
905 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src
, 8));
907 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src
));
910 case GL_UNSIGNED_SHORT
:
912 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src
, 16));
914 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src
));
919 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src
, 16));
921 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src
));
924 case GL_UNSIGNED_INT
:
926 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src
, 32));
928 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src
));
933 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src
, 32));
935 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src
));
939 assert(!"Invalid channel type combination");
944 convert_ubyte(void *void_dst
, int num_dst_channels
,
945 const void *void_src
, GLenum src_type
, int num_src_channels
,
946 const uint8_t swizzle
[4], bool normalized
, int count
)
948 const uint8_t one
= normalized
? UINT8_MAX
: 1;
953 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src
, 8));
955 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src
, 8));
960 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src
, 8));
962 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src
, 8));
965 case GL_UNSIGNED_BYTE
:
966 SWIZZLE_CONVERT(uint8_t, uint8_t, src
);
970 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 8));
972 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src
, 8));
975 case GL_UNSIGNED_SHORT
:
977 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src
, 16, 8));
979 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src
, 8));
984 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 8));
986 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src
, 8));
989 case GL_UNSIGNED_INT
:
991 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src
, 32, 8));
993 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src
, 8));
998 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 8));
1000 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src
, 8));
1004 assert(!"Invalid channel type combination");
1010 convert_byte(void *void_dst
, int num_dst_channels
,
1011 const void *void_src
, GLenum src_type
, int num_src_channels
,
1012 const uint8_t swizzle
[4], bool normalized
, int count
)
1014 const int8_t one
= normalized
? INT8_MAX
: 1;
1019 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src
, 8));
1021 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src
, 8));
1026 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src
, 8));
1028 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src
, 8));
1031 case GL_UNSIGNED_BYTE
:
1033 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 8));
1035 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src
, 8));
1039 SWIZZLE_CONVERT(int8_t, int8_t, src
);
1041 case GL_UNSIGNED_SHORT
:
1043 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 8));
1045 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src
, 8));
1050 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src
, 16, 8));
1052 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src
, 8));
1055 case GL_UNSIGNED_INT
:
1057 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 8));
1059 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src
, 8));
1064 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src
, 32, 8));
1066 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src
, 8));
1070 assert(!"Invalid channel type combination");
1076 convert_ushort(void *void_dst
, int num_dst_channels
,
1077 const void *void_src
, GLenum src_type
, int num_src_channels
,
1078 const uint8_t swizzle
[4], bool normalized
, int count
)
1080 const uint16_t one
= normalized
? UINT16_MAX
: 1;
1085 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src
, 16));
1087 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src
, 16));
1092 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src
, 16));
1094 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src
, 16));
1097 case GL_UNSIGNED_BYTE
:
1099 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src
, 8, 16));
1101 SWIZZLE_CONVERT(uint16_t, uint8_t, src
);
1106 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 16));
1108 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src
, 16));
1111 case GL_UNSIGNED_SHORT
:
1112 SWIZZLE_CONVERT(uint16_t, uint16_t, src
);
1116 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 16));
1118 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src
, 16));
1121 case GL_UNSIGNED_INT
:
1123 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src
, 32, 16));
1125 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src
, 16));
1130 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 16));
1132 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src
, 16));
1136 assert(!"Invalid channel type combination");
1142 convert_short(void *void_dst
, int num_dst_channels
,
1143 const void *void_src
, GLenum src_type
, int num_src_channels
,
1144 const uint8_t swizzle
[4], bool normalized
, int count
)
1146 const int16_t one
= normalized
? INT16_MAX
: 1;
1151 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src
, 16));
1153 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src
, 16));
1158 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src
, 16));
1160 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src
, 16));
1163 case GL_UNSIGNED_BYTE
:
1165 SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 16));
1167 SWIZZLE_CONVERT(int16_t, uint8_t, src
);
1172 SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src
, 8, 16));
1174 SWIZZLE_CONVERT(int16_t, int8_t, src
);
1177 case GL_UNSIGNED_SHORT
:
1179 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 16));
1181 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src
, 16));
1185 SWIZZLE_CONVERT(int16_t, int16_t, src
);
1187 case GL_UNSIGNED_INT
:
1189 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 16));
1191 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src
, 16));
1196 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src
, 32, 16));
1198 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src
, 16));
1202 assert(!"Invalid channel type combination");
1207 convert_uint(void *void_dst
, int num_dst_channels
,
1208 const void *void_src
, GLenum src_type
, int num_src_channels
,
1209 const uint8_t swizzle
[4], bool normalized
, int count
)
1211 const uint32_t one
= normalized
? UINT32_MAX
: 1;
1216 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src
, 32));
1218 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src
, 32));
1223 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src
, 32));
1225 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src
, 32));
1228 case GL_UNSIGNED_BYTE
:
1230 SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src
, 8, 32));
1232 SWIZZLE_CONVERT(uint32_t, uint8_t, src
);
1237 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 32));
1239 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src
, 32));
1242 case GL_UNSIGNED_SHORT
:
1244 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src
, 16, 32));
1246 SWIZZLE_CONVERT(uint32_t, uint16_t, src
);
1251 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 32));
1253 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src
, 32));
1256 case GL_UNSIGNED_INT
:
1257 SWIZZLE_CONVERT(uint32_t, uint32_t, src
);
1261 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 32));
1263 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src
, 32));
1267 assert(!"Invalid channel type combination");
1273 convert_int(void *void_dst
, int num_dst_channels
,
1274 const void *void_src
, GLenum src_type
, int num_src_channels
,
1275 const uint8_t swizzle
[4], bool normalized
, int count
)
1277 const int32_t one
= normalized
? INT32_MAX
: 1;
1282 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src
, 32));
1284 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src
, 32));
1289 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src
, 32));
1291 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src
, 32));
1294 case GL_UNSIGNED_BYTE
:
1296 SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 32));
1298 SWIZZLE_CONVERT(int32_t, uint8_t, src
);
1303 SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src
, 8, 32));
1305 SWIZZLE_CONVERT(int32_t, int8_t, src
);
1308 case GL_UNSIGNED_SHORT
:
1310 SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 32));
1312 SWIZZLE_CONVERT(int32_t, uint16_t, src
);
1317 SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src
, 16, 32));
1319 SWIZZLE_CONVERT(int32_t, int16_t, src
);
1322 case GL_UNSIGNED_INT
:
1324 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 32));
1326 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src
, 32));
1330 SWIZZLE_CONVERT(int32_t, int32_t, src
);
1333 assert(!"Invalid channel type combination");
1339 * Convert between array-based color formats.
1341 * Most format conversion operations required by GL can be performed by
1342 * converting one channel at a time, shuffling the channels around, and
1343 * optionally filling missing channels with zeros and ones. This function
1344 * does just that in a general, yet efficient, way.
1346 * The swizzle parameter is an array of 4 numbers (see
1347 * _mesa_get_format_swizzle) that describes where each channel in the
1348 * destination should come from in the source. If swizzle[i] < 4 then it
1349 * means that dst[i] = CONVERT(src[swizzle[i]]). If swizzle[i] is
1350 * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding
1351 * dst[i] will be filled with the appropreate representation of zero or one
1354 * Under most circumstances, the source and destination images must be
1355 * different as no care is taken not to clobber one with the other.
1356 * However, if they have the same number of bits per pixel, it is safe to
1357 * do an in-place conversion.
1359 * \param[out] dst pointer to where the converted data should
1362 * \param[in] dst_type the destination GL type of the converted
1363 * data (GL_BYTE, etc.)
1365 * \param[in] num_dst_channels the number of channels in the converted
1368 * \param[in] src pointer to the source data
1370 * \param[in] src_type the GL type of the source data (GL_BYTE,
1373 * \param[in] num_src_channels the number of channels in the source data
1374 * (the number of channels total, not just
1377 * \param[in] swizzle describes how to get the destination data
1378 * from the source data.
1380 * \param[in] normalized for integer types, this indicates whether
1381 * the data should be considered as integers
1382 * or as normalized integers;
1384 * \param[in] count the number of pixels to convert
1387 _mesa_swizzle_and_convert(void *void_dst
, GLenum dst_type
, int num_dst_channels
,
1388 const void *void_src
, GLenum src_type
, int num_src_channels
,
1389 const uint8_t swizzle
[4], bool normalized
, int count
)
1391 if (swizzle_convert_try_memcpy(void_dst
, dst_type
, num_dst_channels
,
1392 void_src
, src_type
, num_src_channels
,
1393 swizzle
, normalized
, count
))
1398 convert_float(void_dst
, num_dst_channels
, void_src
, src_type
,
1399 num_src_channels
, swizzle
, normalized
, count
);
1402 convert_half_float(void_dst
, num_dst_channels
, void_src
, src_type
,
1403 num_src_channels
, swizzle
, normalized
, count
);
1405 case GL_UNSIGNED_BYTE
:
1406 convert_ubyte(void_dst
, num_dst_channels
, void_src
, src_type
,
1407 num_src_channels
, swizzle
, normalized
, count
);
1410 convert_byte(void_dst
, num_dst_channels
, void_src
, src_type
,
1411 num_src_channels
, swizzle
, normalized
, count
);
1413 case GL_UNSIGNED_SHORT
:
1414 convert_ushort(void_dst
, num_dst_channels
, void_src
, src_type
,
1415 num_src_channels
, swizzle
, normalized
, count
);
1418 convert_short(void_dst
, num_dst_channels
, void_src
, src_type
,
1419 num_src_channels
, swizzle
, normalized
, count
);
1421 case GL_UNSIGNED_INT
:
1422 convert_uint(void_dst
, num_dst_channels
, void_src
, src_type
,
1423 num_src_channels
, swizzle
, normalized
, count
);
1426 convert_int(void_dst
, num_dst_channels
, void_src
, src_type
,
1427 num_src_channels
, swizzle
, normalized
, count
);
1430 assert(!"Invalid channel type");