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");
184 * Special case conversion function to swap r/b channels from the source
185 * image to the dest image.
188 convert_ubyte_rgba_to_bgra(size_t width
, size_t height
,
189 const uint8_t *src
, size_t src_stride
,
190 uint8_t *dst
, size_t dst_stride
)
194 if (sizeof(void *) == 8 &&
195 src_stride
% 8 == 0 &&
196 dst_stride
% 8 == 0 &&
197 (GLsizeiptr
) src
% 8 == 0 &&
198 (GLsizeiptr
) dst
% 8 == 0) {
199 /* use 64-bit word to swizzle two 32-bit pixels. We need 8-byte
200 * alignment for src/dst addresses and strides.
202 for (row
= 0; row
< height
; row
++) {
203 const GLuint64
*s
= (const GLuint64
*) src
;
204 GLuint64
*d
= (GLuint64
*) dst
;
206 for (i
= 0; i
< width
/2; i
++) {
207 d
[i
] = ( (s
[i
] & 0xff00ff00ff00ff00) |
208 ((s
[i
] & 0xff000000ff) << 16) |
209 ((s
[i
] & 0xff000000ff0000) >> 16));
212 /* handle the case of odd widths */
213 const GLuint s
= ((const GLuint
*) src
)[width
- 1];
214 GLuint
*d
= (GLuint
*) dst
+ width
- 1;
215 *d
= ( (s
& 0xff00ff00) |
217 ((s
& 0xff0000) >> 16));
223 for (row
= 0; row
< height
; row
++) {
224 const GLuint
*s
= (const GLuint
*) src
;
225 GLuint
*d
= (GLuint
*) dst
;
227 for (i
= 0; i
< width
; i
++) {
228 d
[i
] = ( (s
[i
] & 0xff00ff00) |
229 ((s
[i
] & 0xff) << 16) |
230 ((s
[i
] & 0xff0000) >> 16));
240 * This can be used to convert between most color formats.
243 * - This function doesn't handle GL_COLOR_INDEX or YCBCR formats.
244 * - This function doesn't handle byte-swapping or transferOps, these should
245 * be handled by the caller.
247 * \param void_dst The address where converted color data will be stored.
248 * The caller must ensure that the buffer is large enough
249 * to hold the converted pixel data.
250 * \param dst_format The destination color format. It can be a mesa_format
251 * or a mesa_array_format represented as an uint32_t.
252 * \param dst_stride The stride of the destination format in bytes.
253 * \param void_src The address of the source color data to convert.
254 * \param src_format The source color format. It can be a mesa_format
255 * or a mesa_array_format represented as an uint32_t.
256 * \param src_stride The stride of the source format in bytes.
257 * \param width The width, in pixels, of the source image to convert.
258 * \param height The height, in pixels, of the source image to convert.
259 * \param rebase_swizzle A swizzle transform to apply during the conversion,
260 * typically used to match a different internal base
261 * format involved. NULL if no rebase transform is needed
262 * (i.e. the internal base format and the base format of
263 * the dst or the src -depending on whether we are doing
264 * an upload or a download respectively- are the same).
267 _mesa_format_convert(void *void_dst
, uint32_t dst_format
, size_t dst_stride
,
268 void *void_src
, uint32_t src_format
, size_t src_stride
,
269 size_t width
, size_t height
, uint8_t *rebase_swizzle
)
271 uint8_t *dst
= (uint8_t *)void_dst
;
272 uint8_t *src
= (uint8_t *)void_src
;
273 mesa_array_format src_array_format
, dst_array_format
;
274 bool src_format_is_mesa_array_format
, dst_format_is_mesa_array_format
;
275 uint8_t src2dst
[4], src2rgba
[4], rgba2dst
[4], dst2rgba
[4];
276 uint8_t rebased_src2rgba
[4];
277 enum mesa_array_format_datatype src_type
= 0, dst_type
= 0, common_type
;
278 bool normalized
, dst_integer
, src_integer
, is_signed
;
279 int src_num_channels
= 0, dst_num_channels
= 0;
280 uint8_t (*tmp_ubyte
)[4];
281 float (*tmp_float
)[4];
282 uint32_t (*tmp_uint
)[4];
286 if (_mesa_format_is_mesa_array_format(src_format
)) {
287 src_format_is_mesa_array_format
= true;
288 src_array_format
= src_format
;
290 assert(_mesa_is_format_color_format(src_format
));
291 src_format_is_mesa_array_format
= false;
292 src_array_format
= _mesa_format_to_array_format(src_format
);
295 if (_mesa_format_is_mesa_array_format(dst_format
)) {
296 dst_format_is_mesa_array_format
= true;
297 dst_array_format
= dst_format
;
299 assert(_mesa_is_format_color_format(dst_format
));
300 dst_format_is_mesa_array_format
= false;
301 dst_array_format
= _mesa_format_to_array_format(dst_format
);
304 /* First we see if we can implement the conversion with a direct pack
307 * In this case we want to be careful when we need to apply a swizzle to
308 * match an internal base format, since in these cases a simple pack/unpack
309 * to the dst format from the src format may not match the requirements
310 * of the internal base format. For now we decide to be safe and
311 * avoid this path in these scenarios but in the future we may want to
312 * enable it for specific combinations that are known to work.
314 if (!rebase_swizzle
) {
315 /* Handle the cases where we can directly unpack */
316 if (!src_format_is_mesa_array_format
) {
317 if (dst_array_format
== RGBA32_FLOAT
) {
318 for (row
= 0; row
< height
; ++row
) {
319 _mesa_unpack_rgba_row(src_format
, width
,
320 src
, (float (*)[4])dst
);
325 } else if (dst_array_format
== RGBA8_UBYTE
) {
326 assert(!_mesa_is_format_integer_color(src_format
));
327 for (row
= 0; row
< height
; ++row
) {
328 _mesa_unpack_ubyte_rgba_row(src_format
, width
,
329 src
, (uint8_t (*)[4])dst
);
334 } else if (dst_array_format
== RGBA32_UINT
&&
335 _mesa_is_format_unsigned(src_format
)) {
336 assert(_mesa_is_format_integer_color(src_format
));
337 for (row
= 0; row
< height
; ++row
) {
338 _mesa_unpack_uint_rgba_row(src_format
, width
,
339 src
, (uint32_t (*)[4])dst
);
347 /* Handle the cases where we can directly pack */
348 if (!dst_format_is_mesa_array_format
) {
349 if (src_array_format
== RGBA32_FLOAT
) {
350 for (row
= 0; row
< height
; ++row
) {
351 _mesa_pack_float_rgba_row(dst_format
, width
,
352 (const float (*)[4])src
, dst
);
357 } else if (src_array_format
== RGBA8_UBYTE
) {
358 assert(!_mesa_is_format_integer_color(dst_format
));
360 if (dst_format
== MESA_FORMAT_B8G8R8A8_UNORM
) {
361 convert_ubyte_rgba_to_bgra(width
, height
, src
, src_stride
,
365 for (row
= 0; row
< height
; ++row
) {
366 _mesa_pack_ubyte_rgba_row(dst_format
, width
,
367 (const uint8_t (*)[4])src
, dst
);
373 } else if (src_array_format
== RGBA32_UINT
&&
374 _mesa_is_format_unsigned(dst_format
)) {
375 assert(_mesa_is_format_integer_color(dst_format
));
376 for (row
= 0; row
< height
; ++row
) {
377 _mesa_pack_uint_rgba_row(dst_format
, width
,
378 (const uint32_t (*)[4])src
, dst
);
387 /* Handle conversions between array formats */
389 if (src_array_format
) {
390 src_type
= _mesa_array_format_get_datatype(src_array_format
);
392 src_num_channels
= _mesa_array_format_get_num_channels(src_array_format
);
394 _mesa_array_format_get_swizzle(src_array_format
, src2rgba
);
396 normalized
= _mesa_array_format_is_normalized(src_array_format
);
399 if (dst_array_format
) {
400 dst_type
= _mesa_array_format_get_datatype(dst_array_format
);
402 dst_num_channels
= _mesa_array_format_get_num_channels(dst_array_format
);
404 _mesa_array_format_get_swizzle(dst_array_format
, dst2rgba
);
405 invert_swizzle(rgba2dst
, dst2rgba
);
407 normalized
|= _mesa_array_format_is_normalized(dst_array_format
);
410 if (src_array_format
&& dst_array_format
) {
411 assert(_mesa_array_format_is_normalized(src_array_format
) ==
412 _mesa_array_format_is_normalized(dst_array_format
));
414 compute_src2dst_component_mapping(src2rgba
, rgba2dst
, rebase_swizzle
,
417 for (row
= 0; row
< height
; ++row
) {
418 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
419 src
, src_type
, src_num_channels
,
420 src2dst
, normalized
, width
);
427 /* At this point, we're fresh out of fast-paths and we need to convert
428 * to float, uint32, or, if we're lucky, uint8.
433 if (src_array_format
) {
434 if (!_mesa_array_format_is_float(src_array_format
) &&
435 !_mesa_array_format_is_normalized(src_array_format
))
438 switch (_mesa_get_format_datatype(src_format
)) {
439 case GL_UNSIGNED_INT
:
446 /* If the destination format is signed but the source is unsigned, then we
447 * don't loose any data by converting to a signed intermediate format above
448 * and beyond the precision that we loose in the conversion itself. If the
449 * destination is unsigned then, by using an unsigned intermediate format,
450 * we make the conversion function that converts from the source to the
451 * intermediate format take care of truncating at zero. The exception here
452 * is if the intermediate format is float, in which case the first
453 * conversion will leave it signed and the second conversion will truncate
457 if (dst_array_format
) {
458 if (!_mesa_array_format_is_float(dst_array_format
) &&
459 !_mesa_array_format_is_normalized(dst_array_format
))
461 is_signed
= _mesa_array_format_is_signed(dst_array_format
);
462 bits
= 8 * _mesa_array_format_get_type_size(dst_array_format
);
464 switch (_mesa_get_format_datatype(dst_format
)) {
465 case GL_UNSIGNED_NORMALIZED
:
468 case GL_SIGNED_NORMALIZED
:
474 case GL_UNSIGNED_INT
:
483 bits
= _mesa_get_format_max_bits(dst_format
);
486 assert(src_integer
== dst_integer
);
488 if (src_integer
&& dst_integer
) {
489 tmp_uint
= malloc(width
* height
* sizeof(*tmp_uint
));
491 /* The [un]packing functions for unsigned datatypes treat the 32-bit
492 * integer array as signed for signed formats and as unsigned for
493 * unsigned formats. This is a bit of a problem if we ever convert from
494 * a signed to an unsigned format because the unsigned packing function
495 * doesn't know that the input is signed and will treat it as unsigned
496 * and not do the trunctation. The thing that saves us here is that all
497 * of the packed formats are unsigned, so we can just always use
498 * _mesa_swizzle_and_convert for signed formats, which is aware of the
499 * truncation problem.
501 common_type
= is_signed
? MESA_ARRAY_FORMAT_TYPE_INT
:
502 MESA_ARRAY_FORMAT_TYPE_UINT
;
503 if (src_array_format
) {
504 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
506 for (row
= 0; row
< height
; ++row
) {
507 _mesa_swizzle_and_convert(tmp_uint
+ row
* width
, common_type
, 4,
508 src
, src_type
, src_num_channels
,
509 rebased_src2rgba
, normalized
, width
);
513 for (row
= 0; row
< height
; ++row
) {
514 _mesa_unpack_uint_rgba_row(src_format
, width
,
515 src
, tmp_uint
+ row
* width
);
517 _mesa_swizzle_and_convert(tmp_uint
+ row
* width
, common_type
, 4,
518 tmp_uint
+ row
* width
, common_type
, 4,
519 rebase_swizzle
, false, width
);
524 /* At this point, we have already done the truncation if the source is
525 * signed but the destination is unsigned, so no need to force the
526 * _mesa_swizzle_and_convert path.
528 if (dst_format_is_mesa_array_format
) {
529 for (row
= 0; row
< height
; ++row
) {
530 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
531 tmp_uint
+ row
* width
, common_type
, 4,
532 rgba2dst
, normalized
, width
);
536 for (row
= 0; row
< height
; ++row
) {
537 _mesa_pack_uint_rgba_row(dst_format
, width
,
538 (const uint32_t (*)[4])tmp_uint
+ row
* width
, dst
);
544 } else if (is_signed
|| bits
> 8) {
545 tmp_float
= malloc(width
* height
* sizeof(*tmp_float
));
547 if (src_format_is_mesa_array_format
) {
548 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
550 for (row
= 0; row
< height
; ++row
) {
551 _mesa_swizzle_and_convert(tmp_float
+ row
* width
,
552 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
553 src
, src_type
, src_num_channels
,
554 rebased_src2rgba
, normalized
, width
);
558 for (row
= 0; row
< height
; ++row
) {
559 _mesa_unpack_rgba_row(src_format
, width
,
560 src
, tmp_float
+ row
* width
);
562 _mesa_swizzle_and_convert(tmp_float
+ row
* width
,
563 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
564 tmp_float
+ row
* width
,
565 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
566 rebase_swizzle
, normalized
, width
);
571 if (dst_format_is_mesa_array_format
) {
572 for (row
= 0; row
< height
; ++row
) {
573 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
574 tmp_float
+ row
* width
,
575 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
576 rgba2dst
, normalized
, width
);
580 for (row
= 0; row
< height
; ++row
) {
581 _mesa_pack_float_rgba_row(dst_format
, width
,
582 (const float (*)[4])tmp_float
+ row
* width
, dst
);
589 tmp_ubyte
= malloc(width
* height
* sizeof(*tmp_ubyte
));
591 if (src_format_is_mesa_array_format
) {
592 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
594 for (row
= 0; row
< height
; ++row
) {
595 _mesa_swizzle_and_convert(tmp_ubyte
+ row
* width
,
596 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
597 src
, src_type
, src_num_channels
,
598 rebased_src2rgba
, normalized
, width
);
602 for (row
= 0; row
< height
; ++row
) {
603 _mesa_unpack_ubyte_rgba_row(src_format
, width
,
604 src
, tmp_ubyte
+ row
* width
);
606 _mesa_swizzle_and_convert(tmp_ubyte
+ row
* width
,
607 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
608 tmp_ubyte
+ row
* width
,
609 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
610 rebase_swizzle
, normalized
, width
);
615 if (dst_format_is_mesa_array_format
) {
616 for (row
= 0; row
< height
; ++row
) {
617 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
618 tmp_ubyte
+ row
* width
,
619 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
620 rgba2dst
, normalized
, width
);
624 for (row
= 0; row
< height
; ++row
) {
625 _mesa_pack_ubyte_rgba_row(dst_format
, width
,
626 (const uint8_t (*)[4])tmp_ubyte
+ row
* width
, dst
);
635 static const uint8_t map_identity
[7] = { 0, 1, 2, 3, 4, 5, 6 };
636 static const uint8_t map_3210
[7] = { 3, 2, 1, 0, 4, 5, 6 };
637 static const uint8_t map_1032
[7] = { 1, 0, 3, 2, 4, 5, 6 };
640 * Describes a format as an array format, if possible
642 * A helper function for figuring out if a (possibly packed) format is
643 * actually an array format and, if so, what the array parameters are.
645 * \param[in] format the mesa format
646 * \param[out] type the GL type of the array (GL_BYTE, etc.)
647 * \param[out] num_components the number of components in the array
648 * \param[out] swizzle a swizzle describing how to get from the
649 * given format to RGBA
650 * \param[out] normalized for integer formats, this represents whether
651 * the format is a normalized integer or a
653 * \return true if this format is an array format, false otherwise
656 _mesa_format_to_array(mesa_format format
, GLenum
*type
, int *num_components
,
657 uint8_t swizzle
[4], bool *normalized
)
660 GLuint format_components
;
661 uint8_t packed_swizzle
[4];
662 const uint8_t *endian
;
664 if (_mesa_is_format_compressed(format
))
667 *normalized
= !_mesa_is_format_integer(format
);
669 _mesa_uncompressed_format_to_type_and_comps(format
, type
, &format_components
);
671 switch (_mesa_get_format_layout(format
)) {
672 case MESA_FORMAT_LAYOUT_ARRAY
:
673 *num_components
= format_components
;
674 _mesa_get_format_swizzle(format
, swizzle
);
676 case MESA_FORMAT_LAYOUT_PACKED
:
678 case GL_UNSIGNED_BYTE
:
680 if (_mesa_get_format_max_bits(format
) != 8)
682 *num_components
= _mesa_get_format_bytes(format
);
683 switch (*num_components
) {
685 endian
= map_identity
;
688 endian
= _mesa_little_endian() ? map_identity
: map_1032
;
691 endian
= _mesa_little_endian() ? map_identity
: map_3210
;
694 endian
= map_identity
;
695 assert(!"Invalid number of components");
698 case GL_UNSIGNED_SHORT
:
701 if (_mesa_get_format_max_bits(format
) != 16)
703 *num_components
= _mesa_get_format_bytes(format
) / 2;
704 switch (*num_components
) {
706 endian
= map_identity
;
709 endian
= _mesa_little_endian() ? map_identity
: map_1032
;
712 endian
= map_identity
;
713 assert(!"Invalid number of components");
716 case GL_UNSIGNED_INT
:
719 /* This isn't packed. At least not really. */
720 assert(format_components
== 1);
721 if (_mesa_get_format_max_bits(format
) != 32)
723 *num_components
= format_components
;
724 endian
= map_identity
;
730 _mesa_get_format_swizzle(format
, packed_swizzle
);
732 for (i
= 0; i
< 4; ++i
)
733 swizzle
[i
] = endian
[packed_swizzle
[i
]];
736 case MESA_FORMAT_LAYOUT_OTHER
:
743 * Attempts to perform the given swizzle-and-convert operation with memcpy
745 * This function determines if the given swizzle-and-convert operation can
746 * be done with a simple memcpy and, if so, does the memcpy. If not, it
747 * returns false and we fall back to the standard version below.
749 * The arguments are exactly the same as for _mesa_swizzle_and_convert
751 * \return true if it successfully performed the swizzle-and-convert
752 * operation with memcpy, false otherwise
755 swizzle_convert_try_memcpy(void *dst
,
756 enum mesa_array_format_datatype dst_type
,
757 int num_dst_channels
,
759 enum mesa_array_format_datatype src_type
,
760 int num_src_channels
,
761 const uint8_t swizzle
[4], bool normalized
, int count
)
765 if (src_type
!= dst_type
)
767 if (num_src_channels
!= num_dst_channels
)
770 for (i
= 0; i
< num_dst_channels
; ++i
)
771 if (swizzle
[i
] != i
&& swizzle
[i
] != MESA_FORMAT_SWIZZLE_NONE
)
774 memcpy(dst
, src
, count
* num_src_channels
*
775 _mesa_array_format_datatype_get_size(src_type
));
781 * Represents a single instance of the standard swizzle-and-convert loop
783 * Any swizzle-and-convert operation simply loops through the pixels and
784 * performs the transformation operation one pixel at a time. This macro
785 * embodies one instance of the conversion loop. This way we can do all
786 * control flow outside of the loop and allow the compiler to unroll
787 * everything inside the loop.
789 * Note: This loop is carefully crafted for performance. Be careful when
790 * changing it and run some benchmarks to ensure no performance regressions
793 * \param DST_TYPE the C datatype of the destination
794 * \param DST_CHANS the number of destination channels
795 * \param SRC_TYPE the C datatype of the source
796 * \param SRC_CHANS the number of source channels
797 * \param CONV an expression for converting from the source data,
798 * storred in the variable "src", to the destination
801 #define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \
804 for (s = 0; s < count; ++s) { \
805 for (j = 0; j < SRC_CHANS; ++j) { \
806 SRC_TYPE src = typed_src[j]; \
810 typed_dst[0] = tmp[swizzle_x]; \
811 if (DST_CHANS > 1) { \
812 typed_dst[1] = tmp[swizzle_y]; \
813 if (DST_CHANS > 2) { \
814 typed_dst[2] = tmp[swizzle_z]; \
815 if (DST_CHANS > 3) { \
816 typed_dst[3] = tmp[swizzle_w]; \
820 typed_src += SRC_CHANS; \
821 typed_dst += DST_CHANS; \
826 * Represents a single swizzle-and-convert operation
828 * This macro represents everything done in a single swizzle-and-convert
829 * operation. The actual work is done by the SWIZZLE_CONVERT_LOOP macro.
830 * This macro acts as a wrapper that uses a nested switch to ensure that
831 * all looping parameters get unrolled.
833 * This macro makes assumptions about variables etc. in the calling
834 * function. Changes to _mesa_swizzle_and_convert may require changes to
837 * \param DST_TYPE the C datatype of the destination
838 * \param SRC_TYPE the C datatype of the source
839 * \param CONV an expression for converting from the source data,
840 * storred in the variable "src", to the destination
843 #define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV) \
845 const uint8_t swizzle_x = swizzle[0]; \
846 const uint8_t swizzle_y = swizzle[1]; \
847 const uint8_t swizzle_z = swizzle[2]; \
848 const uint8_t swizzle_w = swizzle[3]; \
849 const SRC_TYPE *typed_src = void_src; \
850 DST_TYPE *typed_dst = void_dst; \
854 switch (num_dst_channels) { \
856 switch (num_src_channels) { \
858 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV); \
861 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV); \
864 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV); \
867 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV); \
872 switch (num_src_channels) { \
874 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV); \
877 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV); \
880 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV); \
883 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV); \
888 switch (num_src_channels) { \
890 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV); \
893 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV); \
896 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV); \
899 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV); \
904 switch (num_src_channels) { \
906 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV); \
909 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV); \
912 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV); \
915 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV); \
924 convert_float(void *void_dst
, int num_dst_channels
,
925 const void *void_src
, GLenum src_type
, int num_src_channels
,
926 const uint8_t swizzle
[4], bool normalized
, int count
)
928 const float one
= 1.0f
;
931 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
932 SWIZZLE_CONVERT(float, float, src
);
934 case MESA_ARRAY_FORMAT_TYPE_HALF
:
935 SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src
));
937 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
939 SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src
, 8));
941 SWIZZLE_CONVERT(float, uint8_t, src
);
944 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
946 SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src
, 8));
948 SWIZZLE_CONVERT(float, int8_t, src
);
951 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
953 SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src
, 16));
955 SWIZZLE_CONVERT(float, uint16_t, src
);
958 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
960 SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src
, 16));
962 SWIZZLE_CONVERT(float, int16_t, src
);
965 case MESA_ARRAY_FORMAT_TYPE_UINT
:
967 SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src
, 32));
969 SWIZZLE_CONVERT(float, uint32_t, src
);
972 case MESA_ARRAY_FORMAT_TYPE_INT
:
974 SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src
, 32));
976 SWIZZLE_CONVERT(float, int32_t, src
);
980 assert(!"Invalid channel type combination");
986 convert_half_float(void *void_dst
, int num_dst_channels
,
987 const void *void_src
, GLenum src_type
, int num_src_channels
,
988 const uint8_t swizzle
[4], bool normalized
, int count
)
990 const uint16_t one
= _mesa_float_to_half(1.0f
);
993 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
994 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src
));
996 case MESA_ARRAY_FORMAT_TYPE_HALF
:
997 SWIZZLE_CONVERT(uint16_t, uint16_t, src
);
999 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1001 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src
, 8));
1003 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src
));
1006 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1008 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src
, 8));
1010 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src
));
1013 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1015 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src
, 16));
1017 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src
));
1020 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1022 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src
, 16));
1024 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src
));
1027 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1029 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src
, 32));
1031 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src
));
1034 case MESA_ARRAY_FORMAT_TYPE_INT
:
1036 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src
, 32));
1038 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src
));
1042 assert(!"Invalid channel type combination");
1047 convert_ubyte(void *void_dst
, int num_dst_channels
,
1048 const void *void_src
, GLenum src_type
, int num_src_channels
,
1049 const uint8_t swizzle
[4], bool normalized
, int count
)
1051 const uint8_t one
= normalized
? UINT8_MAX
: 1;
1054 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1056 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src
, 8));
1058 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src
, 8));
1061 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1063 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src
, 8));
1065 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src
, 8));
1068 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1069 SWIZZLE_CONVERT(uint8_t, uint8_t, src
);
1071 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1073 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 8));
1075 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src
, 8));
1078 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1080 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src
, 16, 8));
1082 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src
, 8));
1085 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1087 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 8));
1089 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src
, 8));
1092 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1094 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src
, 32, 8));
1096 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src
, 8));
1099 case MESA_ARRAY_FORMAT_TYPE_INT
:
1101 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 8));
1103 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src
, 8));
1107 assert(!"Invalid channel type combination");
1113 convert_byte(void *void_dst
, int num_dst_channels
,
1114 const void *void_src
, GLenum src_type
, int num_src_channels
,
1115 const uint8_t swizzle
[4], bool normalized
, int count
)
1117 const int8_t one
= normalized
? INT8_MAX
: 1;
1120 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1122 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src
, 8));
1124 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src
, 8));
1127 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1129 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src
, 8));
1131 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src
, 8));
1134 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1136 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 8));
1138 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src
, 8));
1141 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1142 SWIZZLE_CONVERT(int8_t, int8_t, src
);
1144 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1146 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 8));
1148 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src
, 8));
1151 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1153 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src
, 16, 8));
1155 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src
, 8));
1158 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1160 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 8));
1162 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src
, 8));
1165 case MESA_ARRAY_FORMAT_TYPE_INT
:
1167 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src
, 32, 8));
1169 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src
, 8));
1173 assert(!"Invalid channel type combination");
1179 convert_ushort(void *void_dst
, int num_dst_channels
,
1180 const void *void_src
, GLenum src_type
, int num_src_channels
,
1181 const uint8_t swizzle
[4], bool normalized
, int count
)
1183 const uint16_t one
= normalized
? UINT16_MAX
: 1;
1186 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1188 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src
, 16));
1190 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src
, 16));
1193 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1195 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src
, 16));
1197 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src
, 16));
1200 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1202 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src
, 8, 16));
1204 SWIZZLE_CONVERT(uint16_t, uint8_t, src
);
1207 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1209 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 16));
1211 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src
, 16));
1214 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1215 SWIZZLE_CONVERT(uint16_t, uint16_t, src
);
1217 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1219 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 16));
1221 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src
, 16));
1224 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1226 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src
, 32, 16));
1228 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src
, 16));
1231 case MESA_ARRAY_FORMAT_TYPE_INT
:
1233 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 16));
1235 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src
, 16));
1239 assert(!"Invalid channel type combination");
1245 convert_short(void *void_dst
, int num_dst_channels
,
1246 const void *void_src
, GLenum src_type
, int num_src_channels
,
1247 const uint8_t swizzle
[4], bool normalized
, int count
)
1249 const int16_t one
= normalized
? INT16_MAX
: 1;
1252 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1254 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src
, 16));
1256 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src
, 16));
1259 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1261 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src
, 16));
1263 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src
, 16));
1266 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1268 SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 16));
1270 SWIZZLE_CONVERT(int16_t, uint8_t, src
);
1273 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1275 SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src
, 8, 16));
1277 SWIZZLE_CONVERT(int16_t, int8_t, src
);
1280 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1282 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 16));
1284 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src
, 16));
1287 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1288 SWIZZLE_CONVERT(int16_t, int16_t, src
);
1290 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1292 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 16));
1294 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src
, 16));
1297 case MESA_ARRAY_FORMAT_TYPE_INT
:
1299 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src
, 32, 16));
1301 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src
, 16));
1305 assert(!"Invalid channel type combination");
1310 convert_uint(void *void_dst
, int num_dst_channels
,
1311 const void *void_src
, GLenum src_type
, int num_src_channels
,
1312 const uint8_t swizzle
[4], bool normalized
, int count
)
1314 const uint32_t one
= normalized
? UINT32_MAX
: 1;
1317 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1319 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src
, 32));
1321 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src
, 32));
1324 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1326 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src
, 32));
1328 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src
, 32));
1331 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1333 SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src
, 8, 32));
1335 SWIZZLE_CONVERT(uint32_t, uint8_t, src
);
1338 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1340 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 32));
1342 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src
, 32));
1345 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1347 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src
, 16, 32));
1349 SWIZZLE_CONVERT(uint32_t, uint16_t, src
);
1352 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1354 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 32));
1356 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src
, 32));
1359 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1360 SWIZZLE_CONVERT(uint32_t, uint32_t, src
);
1362 case MESA_ARRAY_FORMAT_TYPE_INT
:
1364 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 32));
1366 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src
, 32));
1370 assert(!"Invalid channel type combination");
1376 convert_int(void *void_dst
, int num_dst_channels
,
1377 const void *void_src
, GLenum src_type
, int num_src_channels
,
1378 const uint8_t swizzle
[4], bool normalized
, int count
)
1380 const int32_t one
= normalized
? INT32_MAX
: 1;
1383 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1385 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src
, 32));
1387 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src
, 32));
1390 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1392 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src
, 32));
1394 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src
, 32));
1397 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1399 SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 32));
1401 SWIZZLE_CONVERT(int32_t, uint8_t, src
);
1404 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1406 SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src
, 8, 32));
1408 SWIZZLE_CONVERT(int32_t, int8_t, src
);
1411 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1413 SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 32));
1415 SWIZZLE_CONVERT(int32_t, uint16_t, src
);
1418 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1420 SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src
, 16, 32));
1422 SWIZZLE_CONVERT(int32_t, int16_t, src
);
1425 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1427 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 32));
1429 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src
, 32));
1432 case MESA_ARRAY_FORMAT_TYPE_INT
:
1433 SWIZZLE_CONVERT(int32_t, int32_t, src
);
1436 assert(!"Invalid channel type combination");
1442 * Convert between array-based color formats.
1444 * Most format conversion operations required by GL can be performed by
1445 * converting one channel at a time, shuffling the channels around, and
1446 * optionally filling missing channels with zeros and ones. This function
1447 * does just that in a general, yet efficient, way.
1449 * The swizzle parameter is an array of 4 numbers (see
1450 * _mesa_get_format_swizzle) that describes where each channel in the
1451 * destination should come from in the source. If swizzle[i] < 4 then it
1452 * means that dst[i] = CONVERT(src[swizzle[i]]). If swizzle[i] is
1453 * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding
1454 * dst[i] will be filled with the appropreate representation of zero or one
1457 * Under most circumstances, the source and destination images must be
1458 * different as no care is taken not to clobber one with the other.
1459 * However, if they have the same number of bits per pixel, it is safe to
1460 * do an in-place conversion.
1462 * \param[out] dst pointer to where the converted data should
1465 * \param[in] dst_type the destination GL type of the converted
1466 * data (GL_BYTE, etc.)
1468 * \param[in] num_dst_channels the number of channels in the converted
1471 * \param[in] src pointer to the source data
1473 * \param[in] src_type the GL type of the source data (GL_BYTE,
1476 * \param[in] num_src_channels the number of channels in the source data
1477 * (the number of channels total, not just
1480 * \param[in] swizzle describes how to get the destination data
1481 * from the source data.
1483 * \param[in] normalized for integer types, this indicates whether
1484 * the data should be considered as integers
1485 * or as normalized integers;
1487 * \param[in] count the number of pixels to convert
1490 _mesa_swizzle_and_convert(void *void_dst
, enum mesa_array_format_datatype dst_type
, int num_dst_channels
,
1491 const void *void_src
, enum mesa_array_format_datatype src_type
, int num_src_channels
,
1492 const uint8_t swizzle
[4], bool normalized
, int count
)
1494 if (swizzle_convert_try_memcpy(void_dst
, dst_type
, num_dst_channels
,
1495 void_src
, src_type
, num_src_channels
,
1496 swizzle
, normalized
, count
))
1500 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1501 convert_float(void_dst
, num_dst_channels
, void_src
, src_type
,
1502 num_src_channels
, swizzle
, normalized
, count
);
1504 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1505 convert_half_float(void_dst
, num_dst_channels
, void_src
, src_type
,
1506 num_src_channels
, swizzle
, normalized
, count
);
1508 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1509 convert_ubyte(void_dst
, num_dst_channels
, void_src
, src_type
,
1510 num_src_channels
, swizzle
, normalized
, count
);
1512 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1513 convert_byte(void_dst
, num_dst_channels
, void_src
, src_type
,
1514 num_src_channels
, swizzle
, normalized
, count
);
1516 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1517 convert_ushort(void_dst
, num_dst_channels
, void_src
, src_type
,
1518 num_src_channels
, swizzle
, normalized
, count
);
1520 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1521 convert_short(void_dst
, num_dst_channels
, void_src
, src_type
,
1522 num_src_channels
, swizzle
, normalized
, count
);
1524 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1525 convert_uint(void_dst
, num_dst_channels
, void_src
, src_type
,
1526 num_src_channels
, swizzle
, normalized
, count
);
1528 case MESA_ARRAY_FORMAT_TYPE_INT
:
1529 convert_int(void_dst
, num_dst_channels
, void_src
, src_type
,
1530 num_src_channels
, swizzle
, normalized
, count
);
1533 assert(!"Invalid channel type");