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 RGBA32_FLOAT
=
31 MESA_ARRAY_FORMAT(4, 1, 1, 1, 4, 0, 1, 2, 3);
33 const mesa_array_format RGBA8_UBYTE
=
34 MESA_ARRAY_FORMAT(1, 0, 0, 1, 4, 0, 1, 2, 3);
36 const mesa_array_format RGBA32_UINT
=
37 MESA_ARRAY_FORMAT(4, 0, 0, 0, 4, 0, 1, 2, 3);
39 const mesa_array_format RGBA32_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
)
58 /* Takes a src to RGBA swizzle and applies a rebase swizzle to it. This
59 * is used when we need to rebase a format to match a different
60 * base internal format.
62 * The rebase swizzle can be NULL, which means that no rebase is necessary,
63 * in which case the src to RGBA swizzle is copied to the output without
66 * The resulting rebased swizzle and well as the input swizzles are
67 * all 4-element swizzles, but the rebase swizzle can be NULL if no rebase
71 compute_rebased_rgba_component_mapping(uint8_t *src2rgba
,
72 uint8_t *rebase_swizzle
,
73 uint8_t *rebased_src2rgba
)
78 for (i
= 0; i
< 4; i
++) {
79 if (rebase_swizzle
[i
] > MESA_FORMAT_SWIZZLE_W
)
80 rebased_src2rgba
[i
] = rebase_swizzle
[i
];
82 rebased_src2rgba
[i
] = src2rgba
[rebase_swizzle
[i
]];
85 /* No rebase needed, so src2rgba is all that we need */
86 memcpy(rebased_src2rgba
, src2rgba
, 4 * sizeof(uint8_t));
90 /* Computes the final swizzle transform to apply from src to dst in a
91 * conversion that might involve a rebase swizzle.
93 * This is used to compute the swizzle transform to apply in conversions
94 * between array formats where we have a src2rgba swizzle, a rgba2dst swizzle
95 * and possibly, a rebase swizzle.
97 * The final swizzle transform to apply (src2dst) when a rebase swizzle is
98 * involved is: src -> rgba -> base -> rgba -> dst
101 compute_src2dst_component_mapping(uint8_t *src2rgba
, uint8_t *rgba2dst
,
102 uint8_t *rebase_swizzle
, uint8_t *src2dst
)
106 if (!rebase_swizzle
) {
107 for (i
= 0; i
< 4; i
++) {
108 if (rgba2dst
[i
] > MESA_FORMAT_SWIZZLE_W
) {
109 src2dst
[i
] = rgba2dst
[i
];
111 src2dst
[i
] = src2rgba
[rgba2dst
[i
]];
115 for (i
= 0; i
< 4; i
++) {
116 if (rgba2dst
[i
] > MESA_FORMAT_SWIZZLE_W
) {
117 src2dst
[i
] = rgba2dst
[i
];
118 } else if (rebase_swizzle
[rgba2dst
[i
]] > MESA_FORMAT_SWIZZLE_W
) {
119 src2dst
[i
] = rebase_swizzle
[rgba2dst
[i
]];
121 src2dst
[i
] = src2rgba
[rebase_swizzle
[rgba2dst
[i
]]];
128 * This function is used by clients of _mesa_format_convert to obtain
129 * the rebase swizzle to use in a format conversion based on the base
132 * \param baseFormat the base internal format involved in the conversion.
133 * \param map the rebase swizzle to consider
135 * This function computes 'map' as rgba -> baseformat -> rgba and returns true
136 * if the resulting swizzle transform is not the identity transform (thus, a
137 * rebase is needed). If the function returns false then a rebase swizzle
138 * is not necessary and the value of 'map' is undefined. In this situation
139 * clients of _mesa_format_convert should pass NULL in the 'rebase_swizzle'
143 _mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat
, uint8_t *map
)
145 uint8_t rgba2base
[6], base2rgba
[6];
148 switch (baseFormat
) {
161 case GL_LUMINANCE_ALPHA
:
163 bool needRebase
= false;
164 _mesa_compute_component_mapping(GL_RGBA
, baseFormat
, rgba2base
);
165 _mesa_compute_component_mapping(baseFormat
, GL_RGBA
, base2rgba
);
166 for (i
= 0; i
< 4; i
++) {
167 if (base2rgba
[i
] > MESA_FORMAT_SWIZZLE_W
) {
168 map
[i
] = base2rgba
[i
];
170 map
[i
] = rgba2base
[base2rgba
[i
]];
178 unreachable("Unexpected base format");
183 * This can be used to convert between most color formats.
186 * - This function doesn't handle GL_COLOR_INDEX or YCBCR formats.
187 * - This function doesn't handle byte-swapping or transferOps, these should
188 * be handled by the caller.
190 * \param void_dst The address where converted color data will be stored.
191 * The caller must ensure that the buffer is large enough
192 * to hold the converted pixel data.
193 * \param dst_format The destination color format. It can be a mesa_format
194 * or a mesa_array_format represented as an uint32_t.
195 * \param dst_stride The stride of the destination format in bytes.
196 * \param void_src The address of the source color data to convert.
197 * \param src_format The source color format. It can be a mesa_format
198 * or a mesa_array_format represented as an uint32_t.
199 * \param src_stride The stride of the source format in bytes.
200 * \param width The width, in pixels, of the source image to convert.
201 * \param height The height, in pixels, of the source image to convert.
202 * \param rebase_swizzle A swizzle transform to apply during the conversion,
203 * typically used to match a different internal base
204 * format involved. NULL if no rebase transform is needed
205 * (i.e. the internal base format and the base format of
206 * the dst or the src -depending on whether we are doing
207 * an upload or a download respectively- are the same).
210 _mesa_format_convert(void *void_dst
, uint32_t dst_format
, size_t dst_stride
,
211 void *void_src
, uint32_t src_format
, size_t src_stride
,
212 size_t width
, size_t height
, uint8_t *rebase_swizzle
)
214 uint8_t *dst
= (uint8_t *)void_dst
;
215 uint8_t *src
= (uint8_t *)void_src
;
216 mesa_array_format src_array_format
, dst_array_format
;
217 bool src_format_is_mesa_array_format
, dst_format_is_mesa_array_format
;
218 uint8_t src2dst
[4], src2rgba
[4], rgba2dst
[4], dst2rgba
[4];
219 uint8_t rebased_src2rgba
[4];
220 enum mesa_array_format_datatype src_type
= 0, dst_type
= 0, common_type
;
221 bool normalized
, dst_integer
, src_integer
, is_signed
;
222 int src_num_channels
= 0, dst_num_channels
= 0;
223 uint8_t (*tmp_ubyte
)[4];
224 float (*tmp_float
)[4];
225 uint32_t (*tmp_uint
)[4];
229 if (_mesa_format_is_mesa_array_format(src_format
)) {
230 src_format_is_mesa_array_format
= true;
231 src_array_format
= src_format
;
233 assert(_mesa_is_format_color_format(src_format
));
234 src_format_is_mesa_array_format
= false;
235 src_array_format
= _mesa_format_to_array_format(src_format
);
238 if (_mesa_format_is_mesa_array_format(dst_format
)) {
239 dst_format_is_mesa_array_format
= true;
240 dst_array_format
= dst_format
;
242 assert(_mesa_is_format_color_format(dst_format
));
243 dst_format_is_mesa_array_format
= false;
244 dst_array_format
= _mesa_format_to_array_format(dst_format
);
247 /* First we see if we can implement the conversion with a direct pack
250 * In this case we want to be careful when we need to apply a swizzle to
251 * match an internal base format, since in these cases a simple pack/unpack
252 * to the dst format from the src format may not match the requirements
253 * of the internal base format. For now we decide to be safe and
254 * avoid this path in these scenarios but in the future we may want to
255 * enable it for specific combinations that are known to work.
257 if (!rebase_swizzle
) {
258 /* Handle the cases where we can directly unpack */
259 if (!src_format_is_mesa_array_format
) {
260 if (dst_array_format
== RGBA32_FLOAT
) {
261 for (row
= 0; row
< height
; ++row
) {
262 _mesa_unpack_rgba_row(src_format
, width
,
263 src
, (float (*)[4])dst
);
268 } else if (dst_array_format
== RGBA8_UBYTE
) {
269 assert(!_mesa_is_format_integer_color(src_format
));
270 for (row
= 0; row
< height
; ++row
) {
271 _mesa_unpack_ubyte_rgba_row(src_format
, width
,
272 src
, (uint8_t (*)[4])dst
);
277 } else if (dst_array_format
== RGBA32_UINT
&&
278 _mesa_is_format_unsigned(src_format
)) {
279 assert(_mesa_is_format_integer_color(src_format
));
280 for (row
= 0; row
< height
; ++row
) {
281 _mesa_unpack_uint_rgba_row(src_format
, width
,
282 src
, (uint32_t (*)[4])dst
);
290 /* Handle the cases where we can directly pack */
291 if (!dst_format_is_mesa_array_format
) {
292 if (src_array_format
== RGBA32_FLOAT
) {
293 for (row
= 0; row
< height
; ++row
) {
294 _mesa_pack_float_rgba_row(dst_format
, width
,
295 (const float (*)[4])src
, dst
);
300 } else if (src_array_format
== RGBA8_UBYTE
) {
301 assert(!_mesa_is_format_integer_color(dst_format
));
302 for (row
= 0; row
< height
; ++row
) {
303 _mesa_pack_ubyte_rgba_row(dst_format
, width
,
304 (const uint8_t (*)[4])src
, dst
);
309 } else if (src_array_format
== RGBA32_UINT
&&
310 _mesa_is_format_unsigned(dst_format
)) {
311 assert(_mesa_is_format_integer_color(dst_format
));
312 for (row
= 0; row
< height
; ++row
) {
313 _mesa_pack_uint_rgba_row(dst_format
, width
,
314 (const uint32_t (*)[4])src
, dst
);
323 /* Handle conversions between array formats */
325 if (src_array_format
) {
326 src_type
= _mesa_array_format_get_datatype(src_array_format
);
328 src_num_channels
= _mesa_array_format_get_num_channels(src_array_format
);
330 _mesa_array_format_get_swizzle(src_array_format
, src2rgba
);
332 normalized
= _mesa_array_format_is_normalized(src_array_format
);
335 if (dst_array_format
) {
336 dst_type
= _mesa_array_format_get_datatype(dst_array_format
);
338 dst_num_channels
= _mesa_array_format_get_num_channels(dst_array_format
);
340 _mesa_array_format_get_swizzle(dst_array_format
, dst2rgba
);
341 invert_swizzle(rgba2dst
, dst2rgba
);
343 normalized
|= _mesa_array_format_is_normalized(dst_array_format
);
346 if (src_array_format
&& dst_array_format
) {
347 assert(_mesa_array_format_is_normalized(src_array_format
) ==
348 _mesa_array_format_is_normalized(dst_array_format
));
350 compute_src2dst_component_mapping(src2rgba
, rgba2dst
, rebase_swizzle
,
353 for (row
= 0; row
< height
; ++row
) {
354 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
355 src
, src_type
, src_num_channels
,
356 src2dst
, normalized
, width
);
363 /* At this point, we're fresh out of fast-paths and we need to convert
364 * to float, uint32, or, if we're lucky, uint8.
369 if (src_array_format
) {
370 if (!_mesa_array_format_is_float(src_array_format
) &&
371 !_mesa_array_format_is_normalized(src_array_format
))
374 switch (_mesa_get_format_datatype(src_format
)) {
375 case GL_UNSIGNED_INT
:
382 /* If the destination format is signed but the source is unsigned, then we
383 * don't loose any data by converting to a signed intermediate format above
384 * and beyond the precision that we loose in the conversion itself. If the
385 * destination is unsigned then, by using an unsigned intermediate format,
386 * we make the conversion function that converts from the source to the
387 * intermediate format take care of truncating at zero. The exception here
388 * is if the intermediate format is float, in which case the first
389 * conversion will leave it signed and the second conversion will truncate
393 if (dst_array_format
) {
394 if (!_mesa_array_format_is_float(dst_array_format
) &&
395 !_mesa_array_format_is_normalized(dst_array_format
))
397 is_signed
= _mesa_array_format_is_signed(dst_array_format
);
398 bits
= 8 * _mesa_array_format_get_type_size(dst_array_format
);
400 switch (_mesa_get_format_datatype(dst_format
)) {
401 case GL_UNSIGNED_NORMALIZED
:
404 case GL_SIGNED_NORMALIZED
:
410 case GL_UNSIGNED_INT
:
419 bits
= _mesa_get_format_max_bits(dst_format
);
422 assert(src_integer
== dst_integer
);
424 if (src_integer
&& dst_integer
) {
425 tmp_uint
= malloc(width
* height
* sizeof(*tmp_uint
));
427 /* The [un]packing functions for unsigned datatypes treat the 32-bit
428 * integer array as signed for signed formats and as unsigned for
429 * unsigned formats. This is a bit of a problem if we ever convert from
430 * a signed to an unsigned format because the unsigned packing function
431 * doesn't know that the input is signed and will treat it as unsigned
432 * and not do the trunctation. The thing that saves us here is that all
433 * of the packed formats are unsigned, so we can just always use
434 * _mesa_swizzle_and_convert for signed formats, which is aware of the
435 * truncation problem.
437 common_type
= is_signed
? MESA_ARRAY_FORMAT_TYPE_INT
:
438 MESA_ARRAY_FORMAT_TYPE_UINT
;
439 if (src_array_format
) {
440 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
442 for (row
= 0; row
< height
; ++row
) {
443 _mesa_swizzle_and_convert(tmp_uint
+ row
* width
, common_type
, 4,
444 src
, src_type
, src_num_channels
,
445 rebased_src2rgba
, normalized
, width
);
449 for (row
= 0; row
< height
; ++row
) {
450 _mesa_unpack_uint_rgba_row(src_format
, width
,
451 src
, tmp_uint
+ row
* width
);
453 _mesa_swizzle_and_convert(tmp_uint
+ row
* width
, common_type
, 4,
454 tmp_uint
+ row
* width
, common_type
, 4,
455 rebase_swizzle
, false, width
);
460 /* At this point, we have already done the truncation if the source is
461 * signed but the destination is unsigned, so no need to force the
462 * _mesa_swizzle_and_convert path.
464 if (dst_format_is_mesa_array_format
) {
465 for (row
= 0; row
< height
; ++row
) {
466 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
467 tmp_uint
+ row
* width
, common_type
, 4,
468 rgba2dst
, normalized
, width
);
472 for (row
= 0; row
< height
; ++row
) {
473 _mesa_pack_uint_rgba_row(dst_format
, width
,
474 (const uint32_t (*)[4])tmp_uint
+ row
* width
, dst
);
480 } else if (is_signed
|| bits
> 8) {
481 tmp_float
= malloc(width
* height
* sizeof(*tmp_float
));
483 if (src_format_is_mesa_array_format
) {
484 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
486 for (row
= 0; row
< height
; ++row
) {
487 _mesa_swizzle_and_convert(tmp_float
+ row
* width
,
488 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
489 src
, src_type
, src_num_channels
,
490 rebased_src2rgba
, normalized
, width
);
494 for (row
= 0; row
< height
; ++row
) {
495 _mesa_unpack_rgba_row(src_format
, width
,
496 src
, tmp_float
+ row
* width
);
498 _mesa_swizzle_and_convert(tmp_float
+ row
* width
,
499 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
500 tmp_float
+ row
* width
,
501 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
502 rebase_swizzle
, normalized
, width
);
507 if (dst_format_is_mesa_array_format
) {
508 for (row
= 0; row
< height
; ++row
) {
509 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
510 tmp_float
+ row
* width
,
511 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
512 rgba2dst
, normalized
, width
);
516 for (row
= 0; row
< height
; ++row
) {
517 _mesa_pack_float_rgba_row(dst_format
, width
,
518 (const float (*)[4])tmp_float
+ row
* width
, dst
);
525 tmp_ubyte
= malloc(width
* height
* sizeof(*tmp_ubyte
));
527 if (src_format_is_mesa_array_format
) {
528 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
530 for (row
= 0; row
< height
; ++row
) {
531 _mesa_swizzle_and_convert(tmp_ubyte
+ row
* width
,
532 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
533 src
, src_type
, src_num_channels
,
534 rebased_src2rgba
, normalized
, width
);
538 for (row
= 0; row
< height
; ++row
) {
539 _mesa_unpack_ubyte_rgba_row(src_format
, width
,
540 src
, tmp_ubyte
+ row
* width
);
542 _mesa_swizzle_and_convert(tmp_ubyte
+ row
* width
,
543 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
544 tmp_ubyte
+ row
* width
,
545 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
546 rebase_swizzle
, normalized
, width
);
551 if (dst_format_is_mesa_array_format
) {
552 for (row
= 0; row
< height
; ++row
) {
553 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
554 tmp_ubyte
+ row
* width
,
555 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
556 rgba2dst
, normalized
, width
);
560 for (row
= 0; row
< height
; ++row
) {
561 _mesa_pack_ubyte_rgba_row(dst_format
, width
,
562 (const uint8_t (*)[4])tmp_ubyte
+ row
* width
, dst
);
571 static const uint8_t map_identity
[7] = { 0, 1, 2, 3, 4, 5, 6 };
572 static const uint8_t map_3210
[7] = { 3, 2, 1, 0, 4, 5, 6 };
573 static const uint8_t map_1032
[7] = { 1, 0, 3, 2, 4, 5, 6 };
576 * Describes a format as an array format, if possible
578 * A helper function for figuring out if a (possibly packed) format is
579 * actually an array format and, if so, what the array parameters are.
581 * \param[in] format the mesa format
582 * \param[out] type the GL type of the array (GL_BYTE, etc.)
583 * \param[out] num_components the number of components in the array
584 * \param[out] swizzle a swizzle describing how to get from the
585 * given format to RGBA
586 * \param[out] normalized for integer formats, this represents whether
587 * the format is a normalized integer or a
589 * \return true if this format is an array format, false otherwise
592 _mesa_format_to_array(mesa_format format
, GLenum
*type
, int *num_components
,
593 uint8_t swizzle
[4], bool *normalized
)
596 GLuint format_components
;
597 uint8_t packed_swizzle
[4];
598 const uint8_t *endian
;
600 if (_mesa_is_format_compressed(format
))
603 *normalized
= !_mesa_is_format_integer(format
);
605 _mesa_format_to_type_and_comps(format
, type
, &format_components
);
607 switch (_mesa_get_format_layout(format
)) {
608 case MESA_FORMAT_LAYOUT_ARRAY
:
609 *num_components
= format_components
;
610 _mesa_get_format_swizzle(format
, swizzle
);
612 case MESA_FORMAT_LAYOUT_PACKED
:
614 case GL_UNSIGNED_BYTE
:
616 if (_mesa_get_format_max_bits(format
) != 8)
618 *num_components
= _mesa_get_format_bytes(format
);
619 switch (*num_components
) {
621 endian
= map_identity
;
624 endian
= _mesa_little_endian() ? map_identity
: map_1032
;
627 endian
= _mesa_little_endian() ? map_identity
: map_3210
;
630 endian
= map_identity
;
631 assert(!"Invalid number of components");
634 case GL_UNSIGNED_SHORT
:
637 if (_mesa_get_format_max_bits(format
) != 16)
639 *num_components
= _mesa_get_format_bytes(format
) / 2;
640 switch (*num_components
) {
642 endian
= map_identity
;
645 endian
= _mesa_little_endian() ? map_identity
: map_1032
;
648 endian
= map_identity
;
649 assert(!"Invalid number of components");
652 case GL_UNSIGNED_INT
:
655 /* This isn't packed. At least not really. */
656 assert(format_components
== 1);
657 if (_mesa_get_format_max_bits(format
) != 32)
659 *num_components
= format_components
;
660 endian
= map_identity
;
666 _mesa_get_format_swizzle(format
, packed_swizzle
);
668 for (i
= 0; i
< 4; ++i
)
669 swizzle
[i
] = endian
[packed_swizzle
[i
]];
672 case MESA_FORMAT_LAYOUT_OTHER
:
679 * Attempts to perform the given swizzle-and-convert operation with memcpy
681 * This function determines if the given swizzle-and-convert operation can
682 * be done with a simple memcpy and, if so, does the memcpy. If not, it
683 * returns false and we fall back to the standard version below.
685 * The arguments are exactly the same as for _mesa_swizzle_and_convert
687 * \return true if it successfully performed the swizzle-and-convert
688 * operation with memcpy, false otherwise
691 swizzle_convert_try_memcpy(void *dst
,
692 enum mesa_array_format_datatype dst_type
,
693 int num_dst_channels
,
695 enum mesa_array_format_datatype src_type
,
696 int num_src_channels
,
697 const uint8_t swizzle
[4], bool normalized
, int count
)
701 if (src_type
!= dst_type
)
703 if (num_src_channels
!= num_dst_channels
)
706 for (i
= 0; i
< num_dst_channels
; ++i
)
707 if (swizzle
[i
] != i
&& swizzle
[i
] != MESA_FORMAT_SWIZZLE_NONE
)
710 memcpy(dst
, src
, count
* num_src_channels
*
711 _mesa_array_format_datatype_get_size(src_type
));
717 * Represents a single instance of the standard swizzle-and-convert loop
719 * Any swizzle-and-convert operation simply loops through the pixels and
720 * performs the transformation operation one pixel at a time. This macro
721 * embodies one instance of the conversion loop. This way we can do all
722 * control flow outside of the loop and allow the compiler to unroll
723 * everything inside the loop.
725 * Note: This loop is carefully crafted for performance. Be careful when
726 * changing it and run some benchmarks to ensure no performance regressions
729 * \param DST_TYPE the C datatype of the destination
730 * \param DST_CHANS the number of destination channels
731 * \param SRC_TYPE the C datatype of the source
732 * \param SRC_CHANS the number of source channels
733 * \param CONV an expression for converting from the source data,
734 * storred in the variable "src", to the destination
737 #define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \
740 for (s = 0; s < count; ++s) { \
741 for (j = 0; j < SRC_CHANS; ++j) { \
742 SRC_TYPE src = typed_src[j]; \
746 typed_dst[0] = tmp[swizzle_x]; \
747 if (DST_CHANS > 1) { \
748 typed_dst[1] = tmp[swizzle_y]; \
749 if (DST_CHANS > 2) { \
750 typed_dst[2] = tmp[swizzle_z]; \
751 if (DST_CHANS > 3) { \
752 typed_dst[3] = tmp[swizzle_w]; \
756 typed_src += SRC_CHANS; \
757 typed_dst += DST_CHANS; \
762 * Represents a single swizzle-and-convert operation
764 * This macro represents everything done in a single swizzle-and-convert
765 * operation. The actual work is done by the SWIZZLE_CONVERT_LOOP macro.
766 * This macro acts as a wrapper that uses a nested switch to ensure that
767 * all looping parameters get unrolled.
769 * This macro makes assumptions about variables etc. in the calling
770 * function. Changes to _mesa_swizzle_and_convert may require changes to
773 * \param DST_TYPE the C datatype of the destination
774 * \param SRC_TYPE the C datatype of the source
775 * \param CONV an expression for converting from the source data,
776 * storred in the variable "src", to the destination
779 #define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV) \
781 const uint8_t swizzle_x = swizzle[0]; \
782 const uint8_t swizzle_y = swizzle[1]; \
783 const uint8_t swizzle_z = swizzle[2]; \
784 const uint8_t swizzle_w = swizzle[3]; \
785 const SRC_TYPE *typed_src = void_src; \
786 DST_TYPE *typed_dst = void_dst; \
790 switch (num_dst_channels) { \
792 switch (num_src_channels) { \
794 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV); \
797 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV); \
800 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV); \
803 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV); \
808 switch (num_src_channels) { \
810 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV); \
813 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV); \
816 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV); \
819 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV); \
824 switch (num_src_channels) { \
826 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV); \
829 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV); \
832 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV); \
835 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV); \
840 switch (num_src_channels) { \
842 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV); \
845 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV); \
848 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV); \
851 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV); \
860 convert_float(void *void_dst
, int num_dst_channels
,
861 const void *void_src
, GLenum src_type
, int num_src_channels
,
862 const uint8_t swizzle
[4], bool normalized
, int count
)
864 const float one
= 1.0f
;
867 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
868 SWIZZLE_CONVERT(float, float, src
);
870 case MESA_ARRAY_FORMAT_TYPE_HALF
:
871 SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src
));
873 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
875 SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src
, 8));
877 SWIZZLE_CONVERT(float, uint8_t, src
);
880 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
882 SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src
, 8));
884 SWIZZLE_CONVERT(float, int8_t, src
);
887 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
889 SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src
, 16));
891 SWIZZLE_CONVERT(float, uint16_t, src
);
894 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
896 SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src
, 16));
898 SWIZZLE_CONVERT(float, int16_t, src
);
901 case MESA_ARRAY_FORMAT_TYPE_UINT
:
903 SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src
, 32));
905 SWIZZLE_CONVERT(float, uint32_t, src
);
908 case MESA_ARRAY_FORMAT_TYPE_INT
:
910 SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src
, 32));
912 SWIZZLE_CONVERT(float, int32_t, src
);
916 assert(!"Invalid channel type combination");
922 convert_half_float(void *void_dst
, int num_dst_channels
,
923 const void *void_src
, GLenum src_type
, int num_src_channels
,
924 const uint8_t swizzle
[4], bool normalized
, int count
)
926 const uint16_t one
= _mesa_float_to_half(1.0f
);
929 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
930 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src
));
932 case MESA_ARRAY_FORMAT_TYPE_HALF
:
933 SWIZZLE_CONVERT(uint16_t, uint16_t, src
);
935 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
937 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src
, 8));
939 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src
));
942 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
944 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src
, 8));
946 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src
));
949 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
951 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src
, 16));
953 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src
));
956 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
958 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src
, 16));
960 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src
));
963 case MESA_ARRAY_FORMAT_TYPE_UINT
:
965 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src
, 32));
967 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src
));
970 case MESA_ARRAY_FORMAT_TYPE_INT
:
972 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src
, 32));
974 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src
));
978 assert(!"Invalid channel type combination");
983 convert_ubyte(void *void_dst
, int num_dst_channels
,
984 const void *void_src
, GLenum src_type
, int num_src_channels
,
985 const uint8_t swizzle
[4], bool normalized
, int count
)
987 const uint8_t one
= normalized
? UINT8_MAX
: 1;
990 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
992 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src
, 8));
994 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src
, 8));
997 case MESA_ARRAY_FORMAT_TYPE_HALF
:
999 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src
, 8));
1001 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src
, 8));
1004 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1005 SWIZZLE_CONVERT(uint8_t, uint8_t, src
);
1007 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1009 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 8));
1011 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src
, 8));
1014 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1016 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src
, 16, 8));
1018 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src
, 8));
1021 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1023 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 8));
1025 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src
, 8));
1028 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1030 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src
, 32, 8));
1032 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src
, 8));
1035 case MESA_ARRAY_FORMAT_TYPE_INT
:
1037 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 8));
1039 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src
, 8));
1043 assert(!"Invalid channel type combination");
1049 convert_byte(void *void_dst
, int num_dst_channels
,
1050 const void *void_src
, GLenum src_type
, int num_src_channels
,
1051 const uint8_t swizzle
[4], bool normalized
, int count
)
1053 const int8_t one
= normalized
? INT8_MAX
: 1;
1056 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1058 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src
, 8));
1060 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src
, 8));
1063 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1065 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src
, 8));
1067 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src
, 8));
1070 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1072 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 8));
1074 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src
, 8));
1077 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1078 SWIZZLE_CONVERT(int8_t, int8_t, src
);
1080 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1082 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 8));
1084 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src
, 8));
1087 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1089 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src
, 16, 8));
1091 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src
, 8));
1094 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1096 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 8));
1098 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src
, 8));
1101 case MESA_ARRAY_FORMAT_TYPE_INT
:
1103 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src
, 32, 8));
1105 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src
, 8));
1109 assert(!"Invalid channel type combination");
1115 convert_ushort(void *void_dst
, int num_dst_channels
,
1116 const void *void_src
, GLenum src_type
, int num_src_channels
,
1117 const uint8_t swizzle
[4], bool normalized
, int count
)
1119 const uint16_t one
= normalized
? UINT16_MAX
: 1;
1122 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1124 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src
, 16));
1126 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src
, 16));
1129 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1131 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src
, 16));
1133 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src
, 16));
1136 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1138 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src
, 8, 16));
1140 SWIZZLE_CONVERT(uint16_t, uint8_t, src
);
1143 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1145 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 16));
1147 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src
, 16));
1150 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1151 SWIZZLE_CONVERT(uint16_t, uint16_t, src
);
1153 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1155 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 16));
1157 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src
, 16));
1160 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1162 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src
, 32, 16));
1164 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src
, 16));
1167 case MESA_ARRAY_FORMAT_TYPE_INT
:
1169 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 16));
1171 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src
, 16));
1175 assert(!"Invalid channel type combination");
1181 convert_short(void *void_dst
, int num_dst_channels
,
1182 const void *void_src
, GLenum src_type
, int num_src_channels
,
1183 const uint8_t swizzle
[4], bool normalized
, int count
)
1185 const int16_t one
= normalized
? INT16_MAX
: 1;
1188 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1190 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src
, 16));
1192 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src
, 16));
1195 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1197 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src
, 16));
1199 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src
, 16));
1202 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1204 SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 16));
1206 SWIZZLE_CONVERT(int16_t, uint8_t, src
);
1209 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1211 SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src
, 8, 16));
1213 SWIZZLE_CONVERT(int16_t, int8_t, src
);
1216 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1218 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 16));
1220 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src
, 16));
1223 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1224 SWIZZLE_CONVERT(int16_t, int16_t, src
);
1226 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1228 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 16));
1230 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src
, 16));
1233 case MESA_ARRAY_FORMAT_TYPE_INT
:
1235 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src
, 32, 16));
1237 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src
, 16));
1241 assert(!"Invalid channel type combination");
1246 convert_uint(void *void_dst
, int num_dst_channels
,
1247 const void *void_src
, GLenum src_type
, int num_src_channels
,
1248 const uint8_t swizzle
[4], bool normalized
, int count
)
1250 const uint32_t one
= normalized
? UINT32_MAX
: 1;
1253 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1255 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src
, 32));
1257 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src
, 32));
1260 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1262 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src
, 32));
1264 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src
, 32));
1267 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1269 SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src
, 8, 32));
1271 SWIZZLE_CONVERT(uint32_t, uint8_t, src
);
1274 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1276 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 32));
1278 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src
, 32));
1281 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1283 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src
, 16, 32));
1285 SWIZZLE_CONVERT(uint32_t, uint16_t, src
);
1288 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1290 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 32));
1292 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src
, 32));
1295 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1296 SWIZZLE_CONVERT(uint32_t, uint32_t, src
);
1298 case MESA_ARRAY_FORMAT_TYPE_INT
:
1300 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 32));
1302 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src
, 32));
1306 assert(!"Invalid channel type combination");
1312 convert_int(void *void_dst
, int num_dst_channels
,
1313 const void *void_src
, GLenum src_type
, int num_src_channels
,
1314 const uint8_t swizzle
[4], bool normalized
, int count
)
1316 const int32_t one
= normalized
? INT32_MAX
: 1;
1319 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1321 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src
, 32));
1323 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src
, 32));
1326 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1328 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src
, 32));
1330 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src
, 32));
1333 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1335 SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 32));
1337 SWIZZLE_CONVERT(int32_t, uint8_t, src
);
1340 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1342 SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src
, 8, 32));
1344 SWIZZLE_CONVERT(int32_t, int8_t, src
);
1347 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1349 SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 32));
1351 SWIZZLE_CONVERT(int32_t, uint16_t, src
);
1354 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1356 SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src
, 16, 32));
1358 SWIZZLE_CONVERT(int32_t, int16_t, src
);
1361 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1363 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 32));
1365 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src
, 32));
1368 case MESA_ARRAY_FORMAT_TYPE_INT
:
1369 SWIZZLE_CONVERT(int32_t, int32_t, src
);
1372 assert(!"Invalid channel type combination");
1378 * Convert between array-based color formats.
1380 * Most format conversion operations required by GL can be performed by
1381 * converting one channel at a time, shuffling the channels around, and
1382 * optionally filling missing channels with zeros and ones. This function
1383 * does just that in a general, yet efficient, way.
1385 * The swizzle parameter is an array of 4 numbers (see
1386 * _mesa_get_format_swizzle) that describes where each channel in the
1387 * destination should come from in the source. If swizzle[i] < 4 then it
1388 * means that dst[i] = CONVERT(src[swizzle[i]]). If swizzle[i] is
1389 * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding
1390 * dst[i] will be filled with the appropreate representation of zero or one
1393 * Under most circumstances, the source and destination images must be
1394 * different as no care is taken not to clobber one with the other.
1395 * However, if they have the same number of bits per pixel, it is safe to
1396 * do an in-place conversion.
1398 * \param[out] dst pointer to where the converted data should
1401 * \param[in] dst_type the destination GL type of the converted
1402 * data (GL_BYTE, etc.)
1404 * \param[in] num_dst_channels the number of channels in the converted
1407 * \param[in] src pointer to the source data
1409 * \param[in] src_type the GL type of the source data (GL_BYTE,
1412 * \param[in] num_src_channels the number of channels in the source data
1413 * (the number of channels total, not just
1416 * \param[in] swizzle describes how to get the destination data
1417 * from the source data.
1419 * \param[in] normalized for integer types, this indicates whether
1420 * the data should be considered as integers
1421 * or as normalized integers;
1423 * \param[in] count the number of pixels to convert
1426 _mesa_swizzle_and_convert(void *void_dst
, enum mesa_array_format_datatype dst_type
, int num_dst_channels
,
1427 const void *void_src
, enum mesa_array_format_datatype src_type
, int num_src_channels
,
1428 const uint8_t swizzle
[4], bool normalized
, int count
)
1430 if (swizzle_convert_try_memcpy(void_dst
, dst_type
, num_dst_channels
,
1431 void_src
, src_type
, num_src_channels
,
1432 swizzle
, normalized
, count
))
1436 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1437 convert_float(void_dst
, num_dst_channels
, void_src
, src_type
,
1438 num_src_channels
, swizzle
, normalized
, count
);
1440 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1441 convert_half_float(void_dst
, num_dst_channels
, void_src
, src_type
,
1442 num_src_channels
, swizzle
, normalized
, count
);
1444 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1445 convert_ubyte(void_dst
, num_dst_channels
, void_src
, src_type
,
1446 num_src_channels
, swizzle
, normalized
, count
);
1448 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1449 convert_byte(void_dst
, num_dst_channels
, void_src
, src_type
,
1450 num_src_channels
, swizzle
, normalized
, count
);
1452 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1453 convert_ushort(void_dst
, num_dst_channels
, void_src
, src_type
,
1454 num_src_channels
, swizzle
, normalized
, count
);
1456 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1457 convert_short(void_dst
, num_dst_channels
, void_src
, src_type
,
1458 num_src_channels
, swizzle
, normalized
, count
);
1460 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1461 convert_uint(void_dst
, num_dst_channels
, void_src
, src_type
,
1462 num_src_channels
, swizzle
, normalized
, count
);
1464 case MESA_ARRAY_FORMAT_TYPE_INT
:
1465 convert_int(void_dst
, num_dst_channels
, void_src
, src_type
,
1466 num_src_channels
, swizzle
, normalized
, count
);
1469 assert(!"Invalid channel type");