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.
28 #include "format_utils.h"
29 #include "glformats.h"
30 #include "format_pack.h"
31 #include "format_unpack.h"
33 const mesa_array_format RGBA32_FLOAT
=
34 MESA_ARRAY_FORMAT(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS
,
35 4, 1, 1, 1, 4, 0, 1, 2, 3);
37 const mesa_array_format RGBA8_UBYTE
=
38 MESA_ARRAY_FORMAT(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS
,
39 1, 0, 0, 1, 4, 0, 1, 2, 3);
41 const mesa_array_format BGRA8_UBYTE
=
42 MESA_ARRAY_FORMAT(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS
,
43 1, 0, 0, 1, 4, 2, 1, 0, 3);
45 const mesa_array_format RGBA32_UINT
=
46 MESA_ARRAY_FORMAT(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS
,
47 4, 0, 0, 0, 4, 0, 1, 2, 3);
49 const mesa_array_format RGBA32_INT
=
50 MESA_ARRAY_FORMAT(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS
,
51 4, 1, 0, 0, 4, 0, 1, 2, 3);
54 invert_swizzle(uint8_t dst
[4], const uint8_t src
[4])
58 dst
[0] = MESA_FORMAT_SWIZZLE_NONE
;
59 dst
[1] = MESA_FORMAT_SWIZZLE_NONE
;
60 dst
[2] = MESA_FORMAT_SWIZZLE_NONE
;
61 dst
[3] = MESA_FORMAT_SWIZZLE_NONE
;
63 for (i
= 0; i
< 4; ++i
)
64 for (j
= 0; j
< 4; ++j
)
65 if (src
[j
] == i
&& dst
[i
] == MESA_FORMAT_SWIZZLE_NONE
)
69 /* Takes a src to RGBA swizzle and applies a rebase swizzle to it. This
70 * is used when we need to rebase a format to match a different
71 * base internal format.
73 * The rebase swizzle can be NULL, which means that no rebase is necessary,
74 * in which case the src to RGBA swizzle is copied to the output without
77 * The resulting rebased swizzle and well as the input swizzles are
78 * all 4-element swizzles, but the rebase swizzle can be NULL if no rebase
82 compute_rebased_rgba_component_mapping(uint8_t *src2rgba
,
83 uint8_t *rebase_swizzle
,
84 uint8_t *rebased_src2rgba
)
89 for (i
= 0; i
< 4; i
++) {
90 if (rebase_swizzle
[i
] > MESA_FORMAT_SWIZZLE_W
)
91 rebased_src2rgba
[i
] = rebase_swizzle
[i
];
93 rebased_src2rgba
[i
] = src2rgba
[rebase_swizzle
[i
]];
96 /* No rebase needed, so src2rgba is all that we need */
97 memcpy(rebased_src2rgba
, src2rgba
, 4 * sizeof(uint8_t));
101 /* Computes the final swizzle transform to apply from src to dst in a
102 * conversion that might involve a rebase swizzle.
104 * This is used to compute the swizzle transform to apply in conversions
105 * between array formats where we have a src2rgba swizzle, a rgba2dst swizzle
106 * and possibly, a rebase swizzle.
108 * The final swizzle transform to apply (src2dst) when a rebase swizzle is
109 * involved is: src -> rgba -> base -> rgba -> dst
112 compute_src2dst_component_mapping(uint8_t *src2rgba
, uint8_t *rgba2dst
,
113 uint8_t *rebase_swizzle
, uint8_t *src2dst
)
117 if (!rebase_swizzle
) {
118 for (i
= 0; i
< 4; i
++) {
119 if (rgba2dst
[i
] > MESA_FORMAT_SWIZZLE_W
) {
120 src2dst
[i
] = rgba2dst
[i
];
122 src2dst
[i
] = src2rgba
[rgba2dst
[i
]];
126 for (i
= 0; i
< 4; i
++) {
127 if (rgba2dst
[i
] > MESA_FORMAT_SWIZZLE_W
) {
128 src2dst
[i
] = rgba2dst
[i
];
129 } else if (rebase_swizzle
[rgba2dst
[i
]] > MESA_FORMAT_SWIZZLE_W
) {
130 src2dst
[i
] = rebase_swizzle
[rgba2dst
[i
]];
132 src2dst
[i
] = src2rgba
[rebase_swizzle
[rgba2dst
[i
]]];
139 * This function is used by clients of _mesa_format_convert to obtain
140 * the rebase swizzle to use in a format conversion based on the base
143 * \param baseFormat the base internal format involved in the conversion.
144 * \param map the rebase swizzle to consider
146 * This function computes 'map' as rgba -> baseformat -> rgba and returns true
147 * if the resulting swizzle transform is not the identity transform (thus, a
148 * rebase is needed). If the function returns false then a rebase swizzle
149 * is not necessary and the value of 'map' is undefined. In this situation
150 * clients of _mesa_format_convert should pass NULL in the 'rebase_swizzle'
154 _mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat
, uint8_t *map
)
156 uint8_t rgba2base
[6], base2rgba
[6];
159 switch (baseFormat
) {
172 case GL_LUMINANCE_ALPHA
:
174 bool needRebase
= false;
175 _mesa_compute_component_mapping(GL_RGBA
, baseFormat
, rgba2base
);
176 _mesa_compute_component_mapping(baseFormat
, GL_RGBA
, base2rgba
);
177 for (i
= 0; i
< 4; i
++) {
178 if (base2rgba
[i
] > MESA_FORMAT_SWIZZLE_W
) {
179 map
[i
] = base2rgba
[i
];
181 map
[i
] = rgba2base
[base2rgba
[i
]];
189 unreachable("Unexpected base format");
195 * Special case conversion function to swap r/b channels from the source
196 * image to the dest image.
199 convert_ubyte_rgba_to_bgra(size_t width
, size_t height
,
200 const uint8_t *src
, size_t src_stride
,
201 uint8_t *dst
, size_t dst_stride
)
205 if (sizeof(void *) == 8 &&
206 src_stride
% 8 == 0 &&
207 dst_stride
% 8 == 0 &&
208 (GLsizeiptr
) src
% 8 == 0 &&
209 (GLsizeiptr
) dst
% 8 == 0) {
210 /* use 64-bit word to swizzle two 32-bit pixels. We need 8-byte
211 * alignment for src/dst addresses and strides.
213 for (row
= 0; row
< height
; row
++) {
214 const GLuint64
*s
= (const GLuint64
*) src
;
215 GLuint64
*d
= (GLuint64
*) dst
;
217 for (i
= 0; i
< width
/2; i
++) {
218 d
[i
] = ( (s
[i
] & 0xff00ff00ff00ff00) |
219 ((s
[i
] & 0xff000000ff) << 16) |
220 ((s
[i
] & 0xff000000ff0000) >> 16));
223 /* handle the case of odd widths */
224 const GLuint s
= ((const GLuint
*) src
)[width
- 1];
225 GLuint
*d
= (GLuint
*) dst
+ width
- 1;
226 *d
= ( (s
& 0xff00ff00) |
228 ((s
& 0xff0000) >> 16));
234 for (row
= 0; row
< height
; row
++) {
235 const GLuint
*s
= (const GLuint
*) src
;
236 GLuint
*d
= (GLuint
*) dst
;
238 for (i
= 0; i
< width
; i
++) {
239 d
[i
] = ( (s
[i
] & 0xff00ff00) |
240 ((s
[i
] & 0xff) << 16) |
241 ((s
[i
] & 0xff0000) >> 16));
251 * This can be used to convert between most color formats.
254 * - This function doesn't handle GL_COLOR_INDEX or YCBCR formats.
255 * - This function doesn't handle byte-swapping or transferOps, these should
256 * be handled by the caller.
258 * \param void_dst The address where converted color data will be stored.
259 * The caller must ensure that the buffer is large enough
260 * to hold the converted pixel data.
261 * \param dst_format The destination color format. It can be a mesa_format
262 * or a mesa_array_format represented as an uint32_t.
263 * \param dst_stride The stride of the destination format in bytes.
264 * \param void_src The address of the source color data to convert.
265 * \param src_format The source color format. It can be a mesa_format
266 * or a mesa_array_format represented as an uint32_t.
267 * \param src_stride The stride of the source format in bytes.
268 * \param width The width, in pixels, of the source image to convert.
269 * \param height The height, in pixels, of the source image to convert.
270 * \param rebase_swizzle A swizzle transform to apply during the conversion,
271 * typically used to match a different internal base
272 * format involved. NULL if no rebase transform is needed
273 * (i.e. the internal base format and the base format of
274 * the dst or the src -depending on whether we are doing
275 * an upload or a download respectively- are the same).
278 _mesa_format_convert(void *void_dst
, uint32_t dst_format
, size_t dst_stride
,
279 void *void_src
, uint32_t src_format
, size_t src_stride
,
280 size_t width
, size_t height
, uint8_t *rebase_swizzle
)
282 uint8_t *dst
= (uint8_t *)void_dst
;
283 uint8_t *src
= (uint8_t *)void_src
;
284 mesa_array_format src_array_format
, dst_array_format
;
285 bool src_format_is_mesa_array_format
, dst_format_is_mesa_array_format
;
286 uint8_t src2dst
[4], src2rgba
[4], rgba2dst
[4], dst2rgba
[4];
287 uint8_t rebased_src2rgba
[4];
288 enum mesa_array_format_datatype src_type
= 0, dst_type
= 0, common_type
;
289 bool normalized
, dst_integer
, src_integer
, is_signed
;
290 int src_num_channels
= 0, dst_num_channels
= 0;
291 uint8_t (*tmp_ubyte
)[4];
292 float (*tmp_float
)[4];
293 uint32_t (*tmp_uint
)[4];
297 if (_mesa_format_is_mesa_array_format(src_format
)) {
298 src_format_is_mesa_array_format
= true;
299 src_array_format
= src_format
;
301 assert(_mesa_is_format_color_format(src_format
));
302 src_format_is_mesa_array_format
= false;
303 src_array_format
= _mesa_format_to_array_format(src_format
);
306 if (_mesa_format_is_mesa_array_format(dst_format
)) {
307 dst_format_is_mesa_array_format
= true;
308 dst_array_format
= dst_format
;
310 assert(_mesa_is_format_color_format(dst_format
));
311 dst_format_is_mesa_array_format
= false;
312 dst_array_format
= _mesa_format_to_array_format(dst_format
);
315 /* First we see if we can implement the conversion with a direct pack
318 * In this case we want to be careful when we need to apply a swizzle to
319 * match an internal base format, since in these cases a simple pack/unpack
320 * to the dst format from the src format may not match the requirements
321 * of the internal base format. For now we decide to be safe and
322 * avoid this path in these scenarios but in the future we may want to
323 * enable it for specific combinations that are known to work.
325 if (!rebase_swizzle
) {
326 /* Do a direct memcpy where possible */
327 if ((dst_format_is_mesa_array_format
&&
328 src_format_is_mesa_array_format
&&
329 src_array_format
== dst_array_format
) ||
330 src_format
== dst_format
) {
331 int format_size
= _mesa_get_format_bytes(src_format
);
332 for (row
= 0; row
< height
; row
++) {
333 memcpy(dst
, src
, width
* format_size
);
340 /* Handle the cases where we can directly unpack */
341 if (!src_format_is_mesa_array_format
) {
342 if (dst_array_format
== RGBA32_FLOAT
) {
343 for (row
= 0; row
< height
; ++row
) {
344 _mesa_unpack_rgba_row(src_format
, width
,
345 src
, (float (*)[4])dst
);
350 } else if (dst_array_format
== RGBA8_UBYTE
) {
351 assert(!_mesa_is_format_integer_color(src_format
));
352 for (row
= 0; row
< height
; ++row
) {
353 _mesa_unpack_ubyte_rgba_row(src_format
, width
,
354 src
, (uint8_t (*)[4])dst
);
359 } else if (dst_array_format
== BGRA8_UBYTE
&&
360 src_format
== MESA_FORMAT_R8G8B8A8_UNORM
) {
361 convert_ubyte_rgba_to_bgra(width
, height
, src
, src_stride
,
364 } else if (dst_array_format
== RGBA32_UINT
&&
365 _mesa_is_format_unsigned(src_format
)) {
366 assert(_mesa_is_format_integer_color(src_format
));
367 for (row
= 0; row
< height
; ++row
) {
368 _mesa_unpack_uint_rgba_row(src_format
, width
,
369 src
, (uint32_t (*)[4])dst
);
377 /* Handle the cases where we can directly pack */
378 if (!dst_format_is_mesa_array_format
) {
379 if (src_array_format
== RGBA32_FLOAT
) {
380 for (row
= 0; row
< height
; ++row
) {
381 _mesa_pack_float_rgba_row(dst_format
, width
,
382 (const float (*)[4])src
, dst
);
387 } else if (src_array_format
== RGBA8_UBYTE
) {
388 assert(!_mesa_is_format_integer_color(dst_format
));
390 if (dst_format
== MESA_FORMAT_B8G8R8A8_UNORM
) {
391 convert_ubyte_rgba_to_bgra(width
, height
, src
, src_stride
,
395 for (row
= 0; row
< height
; ++row
) {
396 _mesa_pack_ubyte_rgba_row(dst_format
, width
,
397 (const uint8_t (*)[4])src
, dst
);
403 } else if (src_array_format
== RGBA32_UINT
&&
404 _mesa_is_format_unsigned(dst_format
)) {
405 assert(_mesa_is_format_integer_color(dst_format
));
406 for (row
= 0; row
< height
; ++row
) {
407 _mesa_pack_uint_rgba_row(dst_format
, width
,
408 (const uint32_t (*)[4])src
, dst
);
417 /* Handle conversions between array formats */
419 if (src_array_format
) {
420 src_type
= _mesa_array_format_get_datatype(src_array_format
);
422 src_num_channels
= _mesa_array_format_get_num_channels(src_array_format
);
424 _mesa_array_format_get_swizzle(src_array_format
, src2rgba
);
426 normalized
= _mesa_array_format_is_normalized(src_array_format
);
429 if (dst_array_format
) {
430 dst_type
= _mesa_array_format_get_datatype(dst_array_format
);
432 dst_num_channels
= _mesa_array_format_get_num_channels(dst_array_format
);
434 _mesa_array_format_get_swizzle(dst_array_format
, dst2rgba
);
435 invert_swizzle(rgba2dst
, dst2rgba
);
437 normalized
|= _mesa_array_format_is_normalized(dst_array_format
);
440 if (src_array_format
&& dst_array_format
) {
441 assert(_mesa_array_format_is_normalized(src_array_format
) ==
442 _mesa_array_format_is_normalized(dst_array_format
));
444 compute_src2dst_component_mapping(src2rgba
, rgba2dst
, rebase_swizzle
,
447 for (row
= 0; row
< height
; ++row
) {
448 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
449 src
, src_type
, src_num_channels
,
450 src2dst
, normalized
, width
);
457 /* At this point, we're fresh out of fast-paths and we need to convert
458 * to float, uint32, or, if we're lucky, uint8.
463 if (src_array_format
) {
464 if (!_mesa_array_format_is_float(src_array_format
) &&
465 !_mesa_array_format_is_normalized(src_array_format
))
468 switch (_mesa_get_format_datatype(src_format
)) {
469 case GL_UNSIGNED_INT
:
476 /* If the destination format is signed but the source is unsigned, then we
477 * don't loose any data by converting to a signed intermediate format above
478 * and beyond the precision that we loose in the conversion itself. If the
479 * destination is unsigned then, by using an unsigned intermediate format,
480 * we make the conversion function that converts from the source to the
481 * intermediate format take care of truncating at zero. The exception here
482 * is if the intermediate format is float, in which case the first
483 * conversion will leave it signed and the second conversion will truncate
487 if (dst_array_format
) {
488 if (!_mesa_array_format_is_float(dst_array_format
) &&
489 !_mesa_array_format_is_normalized(dst_array_format
))
491 is_signed
= _mesa_array_format_is_signed(dst_array_format
);
492 bits
= 8 * _mesa_array_format_get_type_size(dst_array_format
);
494 switch (_mesa_get_format_datatype(dst_format
)) {
495 case GL_UNSIGNED_NORMALIZED
:
498 case GL_SIGNED_NORMALIZED
:
504 case GL_UNSIGNED_INT
:
513 bits
= _mesa_get_format_max_bits(dst_format
);
516 assert(src_integer
== dst_integer
);
518 if (src_integer
&& dst_integer
) {
519 tmp_uint
= malloc(width
* height
* sizeof(*tmp_uint
));
521 /* The [un]packing functions for unsigned datatypes treat the 32-bit
522 * integer array as signed for signed formats and as unsigned for
523 * unsigned formats. This is a bit of a problem if we ever convert from
524 * a signed to an unsigned format because the unsigned packing function
525 * doesn't know that the input is signed and will treat it as unsigned
526 * and not do the trunctation. The thing that saves us here is that all
527 * of the packed formats are unsigned, so we can just always use
528 * _mesa_swizzle_and_convert for signed formats, which is aware of the
529 * truncation problem.
531 common_type
= is_signed
? MESA_ARRAY_FORMAT_TYPE_INT
:
532 MESA_ARRAY_FORMAT_TYPE_UINT
;
533 if (src_array_format
) {
534 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
536 for (row
= 0; row
< height
; ++row
) {
537 _mesa_swizzle_and_convert(tmp_uint
+ row
* width
, common_type
, 4,
538 src
, src_type
, src_num_channels
,
539 rebased_src2rgba
, normalized
, width
);
543 for (row
= 0; row
< height
; ++row
) {
544 _mesa_unpack_uint_rgba_row(src_format
, width
,
545 src
, tmp_uint
+ row
* width
);
547 _mesa_swizzle_and_convert(tmp_uint
+ row
* width
, common_type
, 4,
548 tmp_uint
+ row
* width
, common_type
, 4,
549 rebase_swizzle
, false, width
);
554 /* At this point, we have already done the truncation if the source is
555 * signed but the destination is unsigned, so no need to force the
556 * _mesa_swizzle_and_convert path.
558 if (dst_format_is_mesa_array_format
) {
559 for (row
= 0; row
< height
; ++row
) {
560 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
561 tmp_uint
+ row
* width
, common_type
, 4,
562 rgba2dst
, normalized
, width
);
566 for (row
= 0; row
< height
; ++row
) {
567 _mesa_pack_uint_rgba_row(dst_format
, width
,
568 (const uint32_t (*)[4])tmp_uint
+ row
* width
, dst
);
574 } else if (is_signed
|| bits
> 8) {
575 tmp_float
= malloc(width
* height
* sizeof(*tmp_float
));
577 if (src_format_is_mesa_array_format
) {
578 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
580 for (row
= 0; row
< height
; ++row
) {
581 _mesa_swizzle_and_convert(tmp_float
+ row
* width
,
582 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
583 src
, src_type
, src_num_channels
,
584 rebased_src2rgba
, normalized
, width
);
588 for (row
= 0; row
< height
; ++row
) {
589 _mesa_unpack_rgba_row(src_format
, width
,
590 src
, tmp_float
+ row
* width
);
592 _mesa_swizzle_and_convert(tmp_float
+ row
* width
,
593 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
594 tmp_float
+ row
* width
,
595 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
596 rebase_swizzle
, normalized
, width
);
601 if (dst_format_is_mesa_array_format
) {
602 for (row
= 0; row
< height
; ++row
) {
603 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
604 tmp_float
+ row
* width
,
605 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
606 rgba2dst
, normalized
, width
);
610 for (row
= 0; row
< height
; ++row
) {
611 _mesa_pack_float_rgba_row(dst_format
, width
,
612 (const float (*)[4])tmp_float
+ row
* width
, dst
);
619 tmp_ubyte
= malloc(width
* height
* sizeof(*tmp_ubyte
));
621 if (src_format_is_mesa_array_format
) {
622 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
624 for (row
= 0; row
< height
; ++row
) {
625 _mesa_swizzle_and_convert(tmp_ubyte
+ row
* width
,
626 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
627 src
, src_type
, src_num_channels
,
628 rebased_src2rgba
, normalized
, width
);
632 for (row
= 0; row
< height
; ++row
) {
633 _mesa_unpack_ubyte_rgba_row(src_format
, width
,
634 src
, tmp_ubyte
+ row
* width
);
636 _mesa_swizzle_and_convert(tmp_ubyte
+ row
* width
,
637 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
638 tmp_ubyte
+ row
* width
,
639 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
640 rebase_swizzle
, normalized
, width
);
645 if (dst_format_is_mesa_array_format
) {
646 for (row
= 0; row
< height
; ++row
) {
647 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
648 tmp_ubyte
+ row
* width
,
649 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
650 rgba2dst
, normalized
, width
);
654 for (row
= 0; row
< height
; ++row
) {
655 _mesa_pack_ubyte_rgba_row(dst_format
, width
,
656 (const uint8_t (*)[4])tmp_ubyte
+ row
* width
, dst
);
665 static const uint8_t map_identity
[7] = { 0, 1, 2, 3, 4, 5, 6 };
666 #if UTIL_ARCH_BIG_ENDIAN
667 static const uint8_t map_3210
[7] = { 3, 2, 1, 0, 4, 5, 6 };
668 static const uint8_t map_1032
[7] = { 1, 0, 3, 2, 4, 5, 6 };
672 * Describes a format as an array format, if possible
674 * A helper function for figuring out if a (possibly packed) format is
675 * actually an array format and, if so, what the array parameters are.
677 * \param[in] format the mesa format
678 * \param[out] type the GL type of the array (GL_BYTE, etc.)
679 * \param[out] num_components the number of components in the array
680 * \param[out] swizzle a swizzle describing how to get from the
681 * given format to RGBA
682 * \param[out] normalized for integer formats, this represents whether
683 * the format is a normalized integer or a
685 * \return true if this format is an array format, false otherwise
688 _mesa_format_to_array(mesa_format format
, GLenum
*type
, int *num_components
,
689 uint8_t swizzle
[4], bool *normalized
)
692 GLuint format_components
;
693 uint8_t packed_swizzle
[4];
694 const uint8_t *endian
;
696 if (_mesa_is_format_compressed(format
))
699 *normalized
= !_mesa_is_format_integer(format
);
701 _mesa_uncompressed_format_to_type_and_comps(format
, type
, &format_components
);
703 switch (_mesa_get_format_layout(format
)) {
704 case MESA_FORMAT_LAYOUT_ARRAY
:
705 *num_components
= format_components
;
706 _mesa_get_format_swizzle(format
, swizzle
);
708 case MESA_FORMAT_LAYOUT_PACKED
:
710 case GL_UNSIGNED_BYTE
:
712 if (_mesa_get_format_max_bits(format
) != 8)
714 *num_components
= _mesa_get_format_bytes(format
);
715 switch (*num_components
) {
717 endian
= map_identity
;
720 #if UTIL_ARCH_LITTLE_ENDIAN
721 endian
= map_identity
;
727 #if UTIL_ARCH_LITTLE_ENDIAN
728 endian
= map_identity
;
734 endian
= map_identity
;
735 assert(!"Invalid number of components");
738 case GL_UNSIGNED_SHORT
:
741 if (_mesa_get_format_max_bits(format
) != 16)
743 *num_components
= _mesa_get_format_bytes(format
) / 2;
744 switch (*num_components
) {
746 endian
= map_identity
;
749 #if UTIL_ARCH_LITTLE_ENDIAN
750 endian
= map_identity
;
756 endian
= map_identity
;
757 assert(!"Invalid number of components");
760 case GL_UNSIGNED_INT
:
763 /* This isn't packed. At least not really. */
764 assert(format_components
== 1);
765 if (_mesa_get_format_max_bits(format
) != 32)
767 *num_components
= format_components
;
768 endian
= map_identity
;
774 _mesa_get_format_swizzle(format
, packed_swizzle
);
776 for (i
= 0; i
< 4; ++i
)
777 swizzle
[i
] = endian
[packed_swizzle
[i
]];
780 case MESA_FORMAT_LAYOUT_OTHER
:
787 * Attempts to perform the given swizzle-and-convert operation with memcpy
789 * This function determines if the given swizzle-and-convert operation can
790 * be done with a simple memcpy and, if so, does the memcpy. If not, it
791 * returns false and we fall back to the standard version below.
793 * The arguments are exactly the same as for _mesa_swizzle_and_convert
795 * \return true if it successfully performed the swizzle-and-convert
796 * operation with memcpy, false otherwise
799 swizzle_convert_try_memcpy(void *dst
,
800 enum mesa_array_format_datatype dst_type
,
801 int num_dst_channels
,
803 enum mesa_array_format_datatype src_type
,
804 int num_src_channels
,
805 const uint8_t swizzle
[4], bool normalized
, int count
)
809 if (src_type
!= dst_type
)
811 if (num_src_channels
!= num_dst_channels
)
814 for (i
= 0; i
< num_dst_channels
; ++i
)
815 if (swizzle
[i
] != i
&& swizzle
[i
] != MESA_FORMAT_SWIZZLE_NONE
)
818 memcpy(dst
, src
, count
* num_src_channels
*
819 _mesa_array_format_datatype_get_size(src_type
));
825 * Represents a single instance of the standard swizzle-and-convert loop
827 * Any swizzle-and-convert operation simply loops through the pixels and
828 * performs the transformation operation one pixel at a time. This macro
829 * embodies one instance of the conversion loop. This way we can do all
830 * control flow outside of the loop and allow the compiler to unroll
831 * everything inside the loop.
833 * Note: This loop is carefully crafted for performance. Be careful when
834 * changing it and run some benchmarks to ensure no performance regressions
837 * \param DST_TYPE the C datatype of the destination
838 * \param DST_CHANS the number of destination channels
839 * \param SRC_TYPE the C datatype of the source
840 * \param SRC_CHANS the number of source channels
841 * \param CONV an expression for converting from the source data,
842 * storred in the variable "src", to the destination
845 #define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \
848 for (s = 0; s < count; ++s) { \
849 for (j = 0; j < SRC_CHANS; ++j) { \
850 SRC_TYPE src = typed_src[j]; \
854 typed_dst[0] = tmp[swizzle_x]; \
855 if (DST_CHANS > 1) { \
856 typed_dst[1] = tmp[swizzle_y]; \
857 if (DST_CHANS > 2) { \
858 typed_dst[2] = tmp[swizzle_z]; \
859 if (DST_CHANS > 3) { \
860 typed_dst[3] = tmp[swizzle_w]; \
864 typed_src += SRC_CHANS; \
865 typed_dst += DST_CHANS; \
870 * Represents a single swizzle-and-convert operation
872 * This macro represents everything done in a single swizzle-and-convert
873 * operation. The actual work is done by the SWIZZLE_CONVERT_LOOP macro.
874 * This macro acts as a wrapper that uses a nested switch to ensure that
875 * all looping parameters get unrolled.
877 * This macro makes assumptions about variables etc. in the calling
878 * function. Changes to _mesa_swizzle_and_convert may require changes to
881 * \param DST_TYPE the C datatype of the destination
882 * \param SRC_TYPE the C datatype of the source
883 * \param CONV an expression for converting from the source data,
884 * storred in the variable "src", to the destination
887 #define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV) \
889 const uint8_t swizzle_x = swizzle[0]; \
890 const uint8_t swizzle_y = swizzle[1]; \
891 const uint8_t swizzle_z = swizzle[2]; \
892 const uint8_t swizzle_w = swizzle[3]; \
893 const SRC_TYPE *typed_src = void_src; \
894 DST_TYPE *typed_dst = void_dst; \
898 switch (num_dst_channels) { \
900 switch (num_src_channels) { \
902 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV); \
905 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV); \
908 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV); \
911 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV); \
916 switch (num_src_channels) { \
918 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV); \
921 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV); \
924 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV); \
927 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV); \
932 switch (num_src_channels) { \
934 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV); \
937 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV); \
940 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV); \
943 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV); \
948 switch (num_src_channels) { \
950 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV); \
953 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV); \
956 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV); \
959 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV); \
968 convert_float(void *void_dst
, int num_dst_channels
,
969 const void *void_src
, GLenum src_type
, int num_src_channels
,
970 const uint8_t swizzle
[4], bool normalized
, int count
)
972 const float one
= 1.0f
;
975 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
976 SWIZZLE_CONVERT(float, float, src
);
978 case MESA_ARRAY_FORMAT_TYPE_HALF
:
979 SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src
));
981 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
983 SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src
, 8));
985 SWIZZLE_CONVERT(float, uint8_t, src
);
988 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
990 SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src
, 8));
992 SWIZZLE_CONVERT(float, int8_t, src
);
995 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
997 SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src
, 16));
999 SWIZZLE_CONVERT(float, uint16_t, src
);
1002 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1004 SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src
, 16));
1006 SWIZZLE_CONVERT(float, int16_t, src
);
1009 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1011 SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src
, 32));
1013 SWIZZLE_CONVERT(float, uint32_t, src
);
1016 case MESA_ARRAY_FORMAT_TYPE_INT
:
1018 SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src
, 32));
1020 SWIZZLE_CONVERT(float, int32_t, src
);
1024 assert(!"Invalid channel type combination");
1030 convert_half_float(void *void_dst
, int num_dst_channels
,
1031 const void *void_src
, GLenum src_type
, int num_src_channels
,
1032 const uint8_t swizzle
[4], bool normalized
, int count
)
1034 const uint16_t one
= _mesa_float_to_half(1.0f
);
1037 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1038 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src
));
1040 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1041 SWIZZLE_CONVERT(uint16_t, uint16_t, src
);
1043 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1045 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src
, 8));
1047 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src
));
1050 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1052 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src
, 8));
1054 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src
));
1057 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1059 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src
, 16));
1061 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src
));
1064 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1066 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src
, 16));
1068 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src
));
1071 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1073 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src
, 32));
1075 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src
));
1078 case MESA_ARRAY_FORMAT_TYPE_INT
:
1080 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src
, 32));
1082 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src
));
1086 assert(!"Invalid channel type combination");
1091 convert_ubyte(void *void_dst
, int num_dst_channels
,
1092 const void *void_src
, GLenum src_type
, int num_src_channels
,
1093 const uint8_t swizzle
[4], bool normalized
, int count
)
1095 const uint8_t one
= normalized
? UINT8_MAX
: 1;
1098 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1100 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src
, 8));
1102 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src
, 8));
1105 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1107 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src
, 8));
1109 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src
, 8));
1112 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1113 SWIZZLE_CONVERT(uint8_t, uint8_t, src
);
1115 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1117 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 8));
1119 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src
, 8));
1122 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1124 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src
, 16, 8));
1126 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src
, 8));
1129 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1131 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 8));
1133 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src
, 8));
1136 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1138 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src
, 32, 8));
1140 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src
, 8));
1143 case MESA_ARRAY_FORMAT_TYPE_INT
:
1145 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 8));
1147 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src
, 8));
1151 assert(!"Invalid channel type combination");
1157 convert_byte(void *void_dst
, int num_dst_channels
,
1158 const void *void_src
, GLenum src_type
, int num_src_channels
,
1159 const uint8_t swizzle
[4], bool normalized
, int count
)
1161 const int8_t one
= normalized
? INT8_MAX
: 1;
1164 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1166 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src
, 8));
1168 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src
, 8));
1171 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1173 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src
, 8));
1175 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src
, 8));
1178 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1180 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 8));
1182 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src
, 8));
1185 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1186 SWIZZLE_CONVERT(int8_t, int8_t, src
);
1188 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1190 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 8));
1192 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src
, 8));
1195 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1197 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src
, 16, 8));
1199 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src
, 8));
1202 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1204 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 8));
1206 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src
, 8));
1209 case MESA_ARRAY_FORMAT_TYPE_INT
:
1211 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src
, 32, 8));
1213 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src
, 8));
1217 assert(!"Invalid channel type combination");
1223 convert_ushort(void *void_dst
, int num_dst_channels
,
1224 const void *void_src
, GLenum src_type
, int num_src_channels
,
1225 const uint8_t swizzle
[4], bool normalized
, int count
)
1227 const uint16_t one
= normalized
? UINT16_MAX
: 1;
1230 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1232 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src
, 16));
1234 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src
, 16));
1237 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1239 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src
, 16));
1241 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src
, 16));
1244 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1246 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src
, 8, 16));
1248 SWIZZLE_CONVERT(uint16_t, uint8_t, src
);
1251 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1253 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 16));
1255 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src
, 16));
1258 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1259 SWIZZLE_CONVERT(uint16_t, uint16_t, src
);
1261 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1263 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 16));
1265 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src
, 16));
1268 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1270 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src
, 32, 16));
1272 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src
, 16));
1275 case MESA_ARRAY_FORMAT_TYPE_INT
:
1277 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 16));
1279 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src
, 16));
1283 assert(!"Invalid channel type combination");
1289 convert_short(void *void_dst
, int num_dst_channels
,
1290 const void *void_src
, GLenum src_type
, int num_src_channels
,
1291 const uint8_t swizzle
[4], bool normalized
, int count
)
1293 const int16_t one
= normalized
? INT16_MAX
: 1;
1296 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1298 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src
, 16));
1300 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src
, 16));
1303 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1305 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src
, 16));
1307 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src
, 16));
1310 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1312 SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 16));
1314 SWIZZLE_CONVERT(int16_t, uint8_t, src
);
1317 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1319 SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src
, 8, 16));
1321 SWIZZLE_CONVERT(int16_t, int8_t, src
);
1324 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1326 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 16));
1328 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src
, 16));
1331 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1332 SWIZZLE_CONVERT(int16_t, int16_t, src
);
1334 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1336 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 16));
1338 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src
, 16));
1341 case MESA_ARRAY_FORMAT_TYPE_INT
:
1343 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src
, 32, 16));
1345 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src
, 16));
1349 assert(!"Invalid channel type combination");
1354 convert_uint(void *void_dst
, int num_dst_channels
,
1355 const void *void_src
, GLenum src_type
, int num_src_channels
,
1356 const uint8_t swizzle
[4], bool normalized
, int count
)
1358 const uint32_t one
= normalized
? UINT32_MAX
: 1;
1361 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1363 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src
, 32));
1365 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src
, 32));
1368 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1370 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src
, 32));
1372 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src
, 32));
1375 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1377 SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src
, 8, 32));
1379 SWIZZLE_CONVERT(uint32_t, uint8_t, src
);
1382 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1384 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 32));
1386 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src
, 32));
1389 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1391 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src
, 16, 32));
1393 SWIZZLE_CONVERT(uint32_t, uint16_t, src
);
1396 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1398 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 32));
1400 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src
, 32));
1403 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1404 SWIZZLE_CONVERT(uint32_t, uint32_t, src
);
1406 case MESA_ARRAY_FORMAT_TYPE_INT
:
1408 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 32));
1410 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src
, 32));
1414 assert(!"Invalid channel type combination");
1420 convert_int(void *void_dst
, int num_dst_channels
,
1421 const void *void_src
, GLenum src_type
, int num_src_channels
,
1422 const uint8_t swizzle
[4], bool normalized
, int count
)
1424 const int32_t one
= normalized
? INT32_MAX
: 1;
1427 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1429 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src
, 32));
1431 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src
, 32));
1434 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1436 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src
, 32));
1438 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src
, 32));
1441 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1443 SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 32));
1445 SWIZZLE_CONVERT(int32_t, uint8_t, src
);
1448 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1450 SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src
, 8, 32));
1452 SWIZZLE_CONVERT(int32_t, int8_t, src
);
1455 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1457 SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 32));
1459 SWIZZLE_CONVERT(int32_t, uint16_t, src
);
1462 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1464 SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src
, 16, 32));
1466 SWIZZLE_CONVERT(int32_t, int16_t, src
);
1469 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1471 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 32));
1473 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src
, 32));
1476 case MESA_ARRAY_FORMAT_TYPE_INT
:
1477 SWIZZLE_CONVERT(int32_t, int32_t, src
);
1480 assert(!"Invalid channel type combination");
1486 * Convert between array-based color formats.
1488 * Most format conversion operations required by GL can be performed by
1489 * converting one channel at a time, shuffling the channels around, and
1490 * optionally filling missing channels with zeros and ones. This function
1491 * does just that in a general, yet efficient, way.
1493 * The swizzle parameter is an array of 4 numbers (see
1494 * _mesa_get_format_swizzle) that describes where each channel in the
1495 * destination should come from in the source. If swizzle[i] < 4 then it
1496 * means that dst[i] = CONVERT(src[swizzle[i]]). If swizzle[i] is
1497 * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding
1498 * dst[i] will be filled with the appropreate representation of zero or one
1501 * Under most circumstances, the source and destination images must be
1502 * different as no care is taken not to clobber one with the other.
1503 * However, if they have the same number of bits per pixel, it is safe to
1504 * do an in-place conversion.
1506 * \param[out] dst pointer to where the converted data should
1509 * \param[in] dst_type the destination GL type of the converted
1510 * data (GL_BYTE, etc.)
1512 * \param[in] num_dst_channels the number of channels in the converted
1515 * \param[in] src pointer to the source data
1517 * \param[in] src_type the GL type of the source data (GL_BYTE,
1520 * \param[in] num_src_channels the number of channels in the source data
1521 * (the number of channels total, not just
1524 * \param[in] swizzle describes how to get the destination data
1525 * from the source data.
1527 * \param[in] normalized for integer types, this indicates whether
1528 * the data should be considered as integers
1529 * or as normalized integers;
1531 * \param[in] count the number of pixels to convert
1534 _mesa_swizzle_and_convert(void *void_dst
, enum mesa_array_format_datatype dst_type
, int num_dst_channels
,
1535 const void *void_src
, enum mesa_array_format_datatype src_type
, int num_src_channels
,
1536 const uint8_t swizzle
[4], bool normalized
, int count
)
1538 if (swizzle_convert_try_memcpy(void_dst
, dst_type
, num_dst_channels
,
1539 void_src
, src_type
, num_src_channels
,
1540 swizzle
, normalized
, count
))
1544 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1545 convert_float(void_dst
, num_dst_channels
, void_src
, src_type
,
1546 num_src_channels
, swizzle
, normalized
, count
);
1548 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1549 convert_half_float(void_dst
, num_dst_channels
, void_src
, src_type
,
1550 num_src_channels
, swizzle
, normalized
, count
);
1552 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1553 convert_ubyte(void_dst
, num_dst_channels
, void_src
, src_type
,
1554 num_src_channels
, swizzle
, normalized
, count
);
1556 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1557 convert_byte(void_dst
, num_dst_channels
, void_src
, src_type
,
1558 num_src_channels
, swizzle
, normalized
, count
);
1560 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1561 convert_ushort(void_dst
, num_dst_channels
, void_src
, src_type
,
1562 num_src_channels
, swizzle
, normalized
, count
);
1564 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1565 convert_short(void_dst
, num_dst_channels
, void_src
, src_type
,
1566 num_src_channels
, swizzle
, normalized
, count
);
1568 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1569 convert_uint(void_dst
, num_dst_channels
, void_src
, src_type
,
1570 num_src_channels
, swizzle
, normalized
, count
);
1572 case MESA_ARRAY_FORMAT_TYPE_INT
:
1573 convert_int(void_dst
, num_dst_channels
, void_src
, src_type
,
1574 num_src_channels
, swizzle
, normalized
, count
);
1577 assert(!"Invalid channel type");