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.
26 #include "format_utils.h"
27 #include "glformats.h"
28 #include "format_pack.h"
29 #include "format_unpack.h"
31 const mesa_array_format RGBA32_FLOAT
=
32 MESA_ARRAY_FORMAT(4, 1, 1, 1, 4, 0, 1, 2, 3);
34 const mesa_array_format RGBA8_UBYTE
=
35 MESA_ARRAY_FORMAT(1, 0, 0, 1, 4, 0, 1, 2, 3);
37 const mesa_array_format RGBA32_UINT
=
38 MESA_ARRAY_FORMAT(4, 0, 0, 0, 4, 0, 1, 2, 3);
40 const mesa_array_format RGBA32_INT
=
41 MESA_ARRAY_FORMAT(4, 1, 0, 0, 4, 0, 1, 2, 3);
44 invert_swizzle(uint8_t dst
[4], const uint8_t src
[4])
48 dst
[0] = MESA_FORMAT_SWIZZLE_NONE
;
49 dst
[1] = MESA_FORMAT_SWIZZLE_NONE
;
50 dst
[2] = MESA_FORMAT_SWIZZLE_NONE
;
51 dst
[3] = MESA_FORMAT_SWIZZLE_NONE
;
53 for (i
= 0; i
< 4; ++i
)
54 for (j
= 0; j
< 4; ++j
)
55 if (src
[j
] == i
&& dst
[i
] == MESA_FORMAT_SWIZZLE_NONE
)
59 /* Takes a src to RGBA swizzle and applies a rebase swizzle to it. This
60 * is used when we need to rebase a format to match a different
61 * base internal format.
63 * The rebase swizzle can be NULL, which means that no rebase is necessary,
64 * in which case the src to RGBA swizzle is copied to the output without
67 * The resulting rebased swizzle and well as the input swizzles are
68 * all 4-element swizzles, but the rebase swizzle can be NULL if no rebase
72 compute_rebased_rgba_component_mapping(uint8_t *src2rgba
,
73 uint8_t *rebase_swizzle
,
74 uint8_t *rebased_src2rgba
)
79 for (i
= 0; i
< 4; i
++) {
80 if (rebase_swizzle
[i
] > MESA_FORMAT_SWIZZLE_W
)
81 rebased_src2rgba
[i
] = rebase_swizzle
[i
];
83 rebased_src2rgba
[i
] = src2rgba
[rebase_swizzle
[i
]];
86 /* No rebase needed, so src2rgba is all that we need */
87 memcpy(rebased_src2rgba
, src2rgba
, 4 * sizeof(uint8_t));
91 /* Computes the final swizzle transform to apply from src to dst in a
92 * conversion that might involve a rebase swizzle.
94 * This is used to compute the swizzle transform to apply in conversions
95 * between array formats where we have a src2rgba swizzle, a rgba2dst swizzle
96 * and possibly, a rebase swizzle.
98 * The final swizzle transform to apply (src2dst) when a rebase swizzle is
99 * involved is: src -> rgba -> base -> rgba -> dst
102 compute_src2dst_component_mapping(uint8_t *src2rgba
, uint8_t *rgba2dst
,
103 uint8_t *rebase_swizzle
, uint8_t *src2dst
)
107 if (!rebase_swizzle
) {
108 for (i
= 0; i
< 4; i
++) {
109 if (rgba2dst
[i
] > MESA_FORMAT_SWIZZLE_W
) {
110 src2dst
[i
] = rgba2dst
[i
];
112 src2dst
[i
] = src2rgba
[rgba2dst
[i
]];
116 for (i
= 0; i
< 4; i
++) {
117 if (rgba2dst
[i
] > MESA_FORMAT_SWIZZLE_W
) {
118 src2dst
[i
] = rgba2dst
[i
];
119 } else if (rebase_swizzle
[rgba2dst
[i
]] > MESA_FORMAT_SWIZZLE_W
) {
120 src2dst
[i
] = rebase_swizzle
[rgba2dst
[i
]];
122 src2dst
[i
] = src2rgba
[rebase_swizzle
[rgba2dst
[i
]]];
129 * This function is used by clients of _mesa_format_convert to obtain
130 * the rebase swizzle to use in a format conversion based on the base
133 * \param baseFormat the base internal format involved in the conversion.
134 * \param map the rebase swizzle to consider
136 * This function computes 'map' as rgba -> baseformat -> rgba and returns true
137 * if the resulting swizzle transform is not the identity transform (thus, a
138 * rebase is needed). If the function returns false then a rebase swizzle
139 * is not necessary and the value of 'map' is undefined. In this situation
140 * clients of _mesa_format_convert should pass NULL in the 'rebase_swizzle'
144 _mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat
, uint8_t *map
)
146 uint8_t rgba2base
[6], base2rgba
[6];
149 switch (baseFormat
) {
162 case GL_LUMINANCE_ALPHA
:
164 bool needRebase
= false;
165 _mesa_compute_component_mapping(GL_RGBA
, baseFormat
, rgba2base
);
166 _mesa_compute_component_mapping(baseFormat
, GL_RGBA
, base2rgba
);
167 for (i
= 0; i
< 4; i
++) {
168 if (base2rgba
[i
] > MESA_FORMAT_SWIZZLE_W
) {
169 map
[i
] = base2rgba
[i
];
171 map
[i
] = rgba2base
[base2rgba
[i
]];
179 unreachable("Unexpected base format");
185 * Special case conversion function to swap r/b channels from the source
186 * image to the dest image.
189 convert_ubyte_rgba_to_bgra(size_t width
, size_t height
,
190 const uint8_t *src
, size_t src_stride
,
191 uint8_t *dst
, size_t dst_stride
)
195 if (sizeof(void *) == 8 &&
196 src_stride
% 8 == 0 &&
197 dst_stride
% 8 == 0 &&
198 (GLsizeiptr
) src
% 8 == 0 &&
199 (GLsizeiptr
) dst
% 8 == 0) {
200 /* use 64-bit word to swizzle two 32-bit pixels. We need 8-byte
201 * alignment for src/dst addresses and strides.
203 for (row
= 0; row
< height
; row
++) {
204 const GLuint64
*s
= (const GLuint64
*) src
;
205 GLuint64
*d
= (GLuint64
*) dst
;
207 for (i
= 0; i
< width
/2; i
++) {
208 d
[i
] = ( (s
[i
] & 0xff00ff00ff00ff00) |
209 ((s
[i
] & 0xff000000ff) << 16) |
210 ((s
[i
] & 0xff000000ff0000) >> 16));
213 /* handle the case of odd widths */
214 const GLuint s
= ((const GLuint
*) src
)[width
- 1];
215 GLuint
*d
= (GLuint
*) dst
+ width
- 1;
216 *d
= ( (s
& 0xff00ff00) |
218 ((s
& 0xff0000) >> 16));
224 for (row
= 0; row
< height
; row
++) {
225 const GLuint
*s
= (const GLuint
*) src
;
226 GLuint
*d
= (GLuint
*) dst
;
228 for (i
= 0; i
< width
; i
++) {
229 d
[i
] = ( (s
[i
] & 0xff00ff00) |
230 ((s
[i
] & 0xff) << 16) |
231 ((s
[i
] & 0xff0000) >> 16));
241 * This can be used to convert between most color formats.
244 * - This function doesn't handle GL_COLOR_INDEX or YCBCR formats.
245 * - This function doesn't handle byte-swapping or transferOps, these should
246 * be handled by the caller.
248 * \param void_dst The address where converted color data will be stored.
249 * The caller must ensure that the buffer is large enough
250 * to hold the converted pixel data.
251 * \param dst_format The destination color format. It can be a mesa_format
252 * or a mesa_array_format represented as an uint32_t.
253 * \param dst_stride The stride of the destination format in bytes.
254 * \param void_src The address of the source color data to convert.
255 * \param src_format The source color format. It can be a mesa_format
256 * or a mesa_array_format represented as an uint32_t.
257 * \param src_stride The stride of the source format in bytes.
258 * \param width The width, in pixels, of the source image to convert.
259 * \param height The height, in pixels, of the source image to convert.
260 * \param rebase_swizzle A swizzle transform to apply during the conversion,
261 * typically used to match a different internal base
262 * format involved. NULL if no rebase transform is needed
263 * (i.e. the internal base format and the base format of
264 * the dst or the src -depending on whether we are doing
265 * an upload or a download respectively- are the same).
268 _mesa_format_convert(void *void_dst
, uint32_t dst_format
, size_t dst_stride
,
269 void *void_src
, uint32_t src_format
, size_t src_stride
,
270 size_t width
, size_t height
, uint8_t *rebase_swizzle
)
272 uint8_t *dst
= (uint8_t *)void_dst
;
273 uint8_t *src
= (uint8_t *)void_src
;
274 mesa_array_format src_array_format
, dst_array_format
;
275 bool src_format_is_mesa_array_format
, dst_format_is_mesa_array_format
;
276 uint8_t src2dst
[4], src2rgba
[4], rgba2dst
[4], dst2rgba
[4];
277 uint8_t rebased_src2rgba
[4];
278 enum mesa_array_format_datatype src_type
= 0, dst_type
= 0, common_type
;
279 bool normalized
, dst_integer
, src_integer
, is_signed
;
280 int src_num_channels
= 0, dst_num_channels
= 0;
281 uint8_t (*tmp_ubyte
)[4];
282 float (*tmp_float
)[4];
283 uint32_t (*tmp_uint
)[4];
287 if (_mesa_format_is_mesa_array_format(src_format
)) {
288 src_format_is_mesa_array_format
= true;
289 src_array_format
= src_format
;
291 assert(_mesa_is_format_color_format(src_format
));
292 src_format_is_mesa_array_format
= false;
293 src_array_format
= _mesa_format_to_array_format(src_format
);
296 if (_mesa_format_is_mesa_array_format(dst_format
)) {
297 dst_format_is_mesa_array_format
= true;
298 dst_array_format
= dst_format
;
300 assert(_mesa_is_format_color_format(dst_format
));
301 dst_format_is_mesa_array_format
= false;
302 dst_array_format
= _mesa_format_to_array_format(dst_format
);
305 /* First we see if we can implement the conversion with a direct pack
308 * In this case we want to be careful when we need to apply a swizzle to
309 * match an internal base format, since in these cases a simple pack/unpack
310 * to the dst format from the src format may not match the requirements
311 * of the internal base format. For now we decide to be safe and
312 * avoid this path in these scenarios but in the future we may want to
313 * enable it for specific combinations that are known to work.
315 if (!rebase_swizzle
) {
316 /* Do a direct memcpy where possible */
317 if ((dst_format_is_mesa_array_format
&&
318 src_format_is_mesa_array_format
&&
319 src_array_format
== dst_array_format
) ||
320 src_format
== dst_format
) {
321 int format_size
= _mesa_get_format_bytes(src_format
);
322 for (row
= 0; row
< height
; row
++) {
323 memcpy(dst
, src
, width
* format_size
);
330 /* Handle the cases where we can directly unpack */
331 if (!src_format_is_mesa_array_format
) {
332 if (dst_array_format
== RGBA32_FLOAT
) {
333 for (row
= 0; row
< height
; ++row
) {
334 _mesa_unpack_rgba_row(src_format
, width
,
335 src
, (float (*)[4])dst
);
340 } else if (dst_array_format
== RGBA8_UBYTE
) {
341 assert(!_mesa_is_format_integer_color(src_format
));
342 for (row
= 0; row
< height
; ++row
) {
343 _mesa_unpack_ubyte_rgba_row(src_format
, width
,
344 src
, (uint8_t (*)[4])dst
);
349 } else if (dst_array_format
== RGBA32_UINT
&&
350 _mesa_is_format_unsigned(src_format
)) {
351 assert(_mesa_is_format_integer_color(src_format
));
352 for (row
= 0; row
< height
; ++row
) {
353 _mesa_unpack_uint_rgba_row(src_format
, width
,
354 src
, (uint32_t (*)[4])dst
);
362 /* Handle the cases where we can directly pack */
363 if (!dst_format_is_mesa_array_format
) {
364 if (src_array_format
== RGBA32_FLOAT
) {
365 for (row
= 0; row
< height
; ++row
) {
366 _mesa_pack_float_rgba_row(dst_format
, width
,
367 (const float (*)[4])src
, dst
);
372 } else if (src_array_format
== RGBA8_UBYTE
) {
373 assert(!_mesa_is_format_integer_color(dst_format
));
375 if (dst_format
== MESA_FORMAT_B8G8R8A8_UNORM
) {
376 convert_ubyte_rgba_to_bgra(width
, height
, src
, src_stride
,
380 for (row
= 0; row
< height
; ++row
) {
381 _mesa_pack_ubyte_rgba_row(dst_format
, width
,
382 (const uint8_t (*)[4])src
, dst
);
388 } else if (src_array_format
== RGBA32_UINT
&&
389 _mesa_is_format_unsigned(dst_format
)) {
390 assert(_mesa_is_format_integer_color(dst_format
));
391 for (row
= 0; row
< height
; ++row
) {
392 _mesa_pack_uint_rgba_row(dst_format
, width
,
393 (const uint32_t (*)[4])src
, dst
);
402 /* Handle conversions between array formats */
404 if (src_array_format
) {
405 src_type
= _mesa_array_format_get_datatype(src_array_format
);
407 src_num_channels
= _mesa_array_format_get_num_channels(src_array_format
);
409 _mesa_array_format_get_swizzle(src_array_format
, src2rgba
);
411 normalized
= _mesa_array_format_is_normalized(src_array_format
);
414 if (dst_array_format
) {
415 dst_type
= _mesa_array_format_get_datatype(dst_array_format
);
417 dst_num_channels
= _mesa_array_format_get_num_channels(dst_array_format
);
419 _mesa_array_format_get_swizzle(dst_array_format
, dst2rgba
);
420 invert_swizzle(rgba2dst
, dst2rgba
);
422 normalized
|= _mesa_array_format_is_normalized(dst_array_format
);
425 if (src_array_format
&& dst_array_format
) {
426 assert(_mesa_array_format_is_normalized(src_array_format
) ==
427 _mesa_array_format_is_normalized(dst_array_format
));
429 compute_src2dst_component_mapping(src2rgba
, rgba2dst
, rebase_swizzle
,
432 for (row
= 0; row
< height
; ++row
) {
433 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
434 src
, src_type
, src_num_channels
,
435 src2dst
, normalized
, width
);
442 /* At this point, we're fresh out of fast-paths and we need to convert
443 * to float, uint32, or, if we're lucky, uint8.
448 if (src_array_format
) {
449 if (!_mesa_array_format_is_float(src_array_format
) &&
450 !_mesa_array_format_is_normalized(src_array_format
))
453 switch (_mesa_get_format_datatype(src_format
)) {
454 case GL_UNSIGNED_INT
:
461 /* If the destination format is signed but the source is unsigned, then we
462 * don't loose any data by converting to a signed intermediate format above
463 * and beyond the precision that we loose in the conversion itself. If the
464 * destination is unsigned then, by using an unsigned intermediate format,
465 * we make the conversion function that converts from the source to the
466 * intermediate format take care of truncating at zero. The exception here
467 * is if the intermediate format is float, in which case the first
468 * conversion will leave it signed and the second conversion will truncate
472 if (dst_array_format
) {
473 if (!_mesa_array_format_is_float(dst_array_format
) &&
474 !_mesa_array_format_is_normalized(dst_array_format
))
476 is_signed
= _mesa_array_format_is_signed(dst_array_format
);
477 bits
= 8 * _mesa_array_format_get_type_size(dst_array_format
);
479 switch (_mesa_get_format_datatype(dst_format
)) {
480 case GL_UNSIGNED_NORMALIZED
:
483 case GL_SIGNED_NORMALIZED
:
489 case GL_UNSIGNED_INT
:
498 bits
= _mesa_get_format_max_bits(dst_format
);
501 assert(src_integer
== dst_integer
);
503 if (src_integer
&& dst_integer
) {
504 tmp_uint
= malloc(width
* height
* sizeof(*tmp_uint
));
506 /* The [un]packing functions for unsigned datatypes treat the 32-bit
507 * integer array as signed for signed formats and as unsigned for
508 * unsigned formats. This is a bit of a problem if we ever convert from
509 * a signed to an unsigned format because the unsigned packing function
510 * doesn't know that the input is signed and will treat it as unsigned
511 * and not do the trunctation. The thing that saves us here is that all
512 * of the packed formats are unsigned, so we can just always use
513 * _mesa_swizzle_and_convert for signed formats, which is aware of the
514 * truncation problem.
516 common_type
= is_signed
? MESA_ARRAY_FORMAT_TYPE_INT
:
517 MESA_ARRAY_FORMAT_TYPE_UINT
;
518 if (src_array_format
) {
519 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
521 for (row
= 0; row
< height
; ++row
) {
522 _mesa_swizzle_and_convert(tmp_uint
+ row
* width
, common_type
, 4,
523 src
, src_type
, src_num_channels
,
524 rebased_src2rgba
, normalized
, width
);
528 for (row
= 0; row
< height
; ++row
) {
529 _mesa_unpack_uint_rgba_row(src_format
, width
,
530 src
, tmp_uint
+ row
* width
);
532 _mesa_swizzle_and_convert(tmp_uint
+ row
* width
, common_type
, 4,
533 tmp_uint
+ row
* width
, common_type
, 4,
534 rebase_swizzle
, false, width
);
539 /* At this point, we have already done the truncation if the source is
540 * signed but the destination is unsigned, so no need to force the
541 * _mesa_swizzle_and_convert path.
543 if (dst_format_is_mesa_array_format
) {
544 for (row
= 0; row
< height
; ++row
) {
545 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
546 tmp_uint
+ row
* width
, common_type
, 4,
547 rgba2dst
, normalized
, width
);
551 for (row
= 0; row
< height
; ++row
) {
552 _mesa_pack_uint_rgba_row(dst_format
, width
,
553 (const uint32_t (*)[4])tmp_uint
+ row
* width
, dst
);
559 } else if (is_signed
|| bits
> 8) {
560 tmp_float
= malloc(width
* height
* sizeof(*tmp_float
));
562 if (src_format_is_mesa_array_format
) {
563 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
565 for (row
= 0; row
< height
; ++row
) {
566 _mesa_swizzle_and_convert(tmp_float
+ row
* width
,
567 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
568 src
, src_type
, src_num_channels
,
569 rebased_src2rgba
, normalized
, width
);
573 for (row
= 0; row
< height
; ++row
) {
574 _mesa_unpack_rgba_row(src_format
, width
,
575 src
, tmp_float
+ row
* width
);
577 _mesa_swizzle_and_convert(tmp_float
+ row
* width
,
578 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
579 tmp_float
+ row
* width
,
580 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
581 rebase_swizzle
, normalized
, width
);
586 if (dst_format_is_mesa_array_format
) {
587 for (row
= 0; row
< height
; ++row
) {
588 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
589 tmp_float
+ row
* width
,
590 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
591 rgba2dst
, normalized
, width
);
595 for (row
= 0; row
< height
; ++row
) {
596 _mesa_pack_float_rgba_row(dst_format
, width
,
597 (const float (*)[4])tmp_float
+ row
* width
, dst
);
604 tmp_ubyte
= malloc(width
* height
* sizeof(*tmp_ubyte
));
606 if (src_format_is_mesa_array_format
) {
607 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
609 for (row
= 0; row
< height
; ++row
) {
610 _mesa_swizzle_and_convert(tmp_ubyte
+ row
* width
,
611 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
612 src
, src_type
, src_num_channels
,
613 rebased_src2rgba
, normalized
, width
);
617 for (row
= 0; row
< height
; ++row
) {
618 _mesa_unpack_ubyte_rgba_row(src_format
, width
,
619 src
, tmp_ubyte
+ row
* width
);
621 _mesa_swizzle_and_convert(tmp_ubyte
+ row
* width
,
622 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
623 tmp_ubyte
+ row
* width
,
624 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
625 rebase_swizzle
, normalized
, width
);
630 if (dst_format_is_mesa_array_format
) {
631 for (row
= 0; row
< height
; ++row
) {
632 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
633 tmp_ubyte
+ row
* width
,
634 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
635 rgba2dst
, normalized
, width
);
639 for (row
= 0; row
< height
; ++row
) {
640 _mesa_pack_ubyte_rgba_row(dst_format
, width
,
641 (const uint8_t (*)[4])tmp_ubyte
+ row
* width
, dst
);
650 static const uint8_t map_identity
[7] = { 0, 1, 2, 3, 4, 5, 6 };
651 static const uint8_t map_3210
[7] = { 3, 2, 1, 0, 4, 5, 6 };
652 static const uint8_t map_1032
[7] = { 1, 0, 3, 2, 4, 5, 6 };
655 * Describes a format as an array format, if possible
657 * A helper function for figuring out if a (possibly packed) format is
658 * actually an array format and, if so, what the array parameters are.
660 * \param[in] format the mesa format
661 * \param[out] type the GL type of the array (GL_BYTE, etc.)
662 * \param[out] num_components the number of components in the array
663 * \param[out] swizzle a swizzle describing how to get from the
664 * given format to RGBA
665 * \param[out] normalized for integer formats, this represents whether
666 * the format is a normalized integer or a
668 * \return true if this format is an array format, false otherwise
671 _mesa_format_to_array(mesa_format format
, GLenum
*type
, int *num_components
,
672 uint8_t swizzle
[4], bool *normalized
)
675 GLuint format_components
;
676 uint8_t packed_swizzle
[4];
677 const uint8_t *endian
;
679 if (_mesa_is_format_compressed(format
))
682 *normalized
= !_mesa_is_format_integer(format
);
684 _mesa_uncompressed_format_to_type_and_comps(format
, type
, &format_components
);
686 switch (_mesa_get_format_layout(format
)) {
687 case MESA_FORMAT_LAYOUT_ARRAY
:
688 *num_components
= format_components
;
689 _mesa_get_format_swizzle(format
, swizzle
);
691 case MESA_FORMAT_LAYOUT_PACKED
:
693 case GL_UNSIGNED_BYTE
:
695 if (_mesa_get_format_max_bits(format
) != 8)
697 *num_components
= _mesa_get_format_bytes(format
);
698 switch (*num_components
) {
700 endian
= map_identity
;
703 endian
= _mesa_little_endian() ? map_identity
: map_1032
;
706 endian
= _mesa_little_endian() ? map_identity
: map_3210
;
709 endian
= map_identity
;
710 assert(!"Invalid number of components");
713 case GL_UNSIGNED_SHORT
:
716 if (_mesa_get_format_max_bits(format
) != 16)
718 *num_components
= _mesa_get_format_bytes(format
) / 2;
719 switch (*num_components
) {
721 endian
= map_identity
;
724 endian
= _mesa_little_endian() ? map_identity
: map_1032
;
727 endian
= map_identity
;
728 assert(!"Invalid number of components");
731 case GL_UNSIGNED_INT
:
734 /* This isn't packed. At least not really. */
735 assert(format_components
== 1);
736 if (_mesa_get_format_max_bits(format
) != 32)
738 *num_components
= format_components
;
739 endian
= map_identity
;
745 _mesa_get_format_swizzle(format
, packed_swizzle
);
747 for (i
= 0; i
< 4; ++i
)
748 swizzle
[i
] = endian
[packed_swizzle
[i
]];
751 case MESA_FORMAT_LAYOUT_OTHER
:
758 * Attempts to perform the given swizzle-and-convert operation with memcpy
760 * This function determines if the given swizzle-and-convert operation can
761 * be done with a simple memcpy and, if so, does the memcpy. If not, it
762 * returns false and we fall back to the standard version below.
764 * The arguments are exactly the same as for _mesa_swizzle_and_convert
766 * \return true if it successfully performed the swizzle-and-convert
767 * operation with memcpy, false otherwise
770 swizzle_convert_try_memcpy(void *dst
,
771 enum mesa_array_format_datatype dst_type
,
772 int num_dst_channels
,
774 enum mesa_array_format_datatype src_type
,
775 int num_src_channels
,
776 const uint8_t swizzle
[4], bool normalized
, int count
)
780 if (src_type
!= dst_type
)
782 if (num_src_channels
!= num_dst_channels
)
785 for (i
= 0; i
< num_dst_channels
; ++i
)
786 if (swizzle
[i
] != i
&& swizzle
[i
] != MESA_FORMAT_SWIZZLE_NONE
)
789 memcpy(dst
, src
, count
* num_src_channels
*
790 _mesa_array_format_datatype_get_size(src_type
));
796 * Represents a single instance of the standard swizzle-and-convert loop
798 * Any swizzle-and-convert operation simply loops through the pixels and
799 * performs the transformation operation one pixel at a time. This macro
800 * embodies one instance of the conversion loop. This way we can do all
801 * control flow outside of the loop and allow the compiler to unroll
802 * everything inside the loop.
804 * Note: This loop is carefully crafted for performance. Be careful when
805 * changing it and run some benchmarks to ensure no performance regressions
808 * \param DST_TYPE the C datatype of the destination
809 * \param DST_CHANS the number of destination channels
810 * \param SRC_TYPE the C datatype of the source
811 * \param SRC_CHANS the number of source channels
812 * \param CONV an expression for converting from the source data,
813 * storred in the variable "src", to the destination
816 #define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \
819 for (s = 0; s < count; ++s) { \
820 for (j = 0; j < SRC_CHANS; ++j) { \
821 SRC_TYPE src = typed_src[j]; \
825 typed_dst[0] = tmp[swizzle_x]; \
826 if (DST_CHANS > 1) { \
827 typed_dst[1] = tmp[swizzle_y]; \
828 if (DST_CHANS > 2) { \
829 typed_dst[2] = tmp[swizzle_z]; \
830 if (DST_CHANS > 3) { \
831 typed_dst[3] = tmp[swizzle_w]; \
835 typed_src += SRC_CHANS; \
836 typed_dst += DST_CHANS; \
841 * Represents a single swizzle-and-convert operation
843 * This macro represents everything done in a single swizzle-and-convert
844 * operation. The actual work is done by the SWIZZLE_CONVERT_LOOP macro.
845 * This macro acts as a wrapper that uses a nested switch to ensure that
846 * all looping parameters get unrolled.
848 * This macro makes assumptions about variables etc. in the calling
849 * function. Changes to _mesa_swizzle_and_convert may require changes to
852 * \param DST_TYPE the C datatype of the destination
853 * \param SRC_TYPE the C datatype of the source
854 * \param CONV an expression for converting from the source data,
855 * storred in the variable "src", to the destination
858 #define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV) \
860 const uint8_t swizzle_x = swizzle[0]; \
861 const uint8_t swizzle_y = swizzle[1]; \
862 const uint8_t swizzle_z = swizzle[2]; \
863 const uint8_t swizzle_w = swizzle[3]; \
864 const SRC_TYPE *typed_src = void_src; \
865 DST_TYPE *typed_dst = void_dst; \
869 switch (num_dst_channels) { \
871 switch (num_src_channels) { \
873 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV); \
876 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV); \
879 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV); \
882 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV); \
887 switch (num_src_channels) { \
889 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV); \
892 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV); \
895 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV); \
898 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV); \
903 switch (num_src_channels) { \
905 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV); \
908 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV); \
911 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV); \
914 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV); \
919 switch (num_src_channels) { \
921 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV); \
924 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV); \
927 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV); \
930 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV); \
939 convert_float(void *void_dst
, int num_dst_channels
,
940 const void *void_src
, GLenum src_type
, int num_src_channels
,
941 const uint8_t swizzle
[4], bool normalized
, int count
)
943 const float one
= 1.0f
;
946 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
947 SWIZZLE_CONVERT(float, float, src
);
949 case MESA_ARRAY_FORMAT_TYPE_HALF
:
950 SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src
));
952 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
954 SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src
, 8));
956 SWIZZLE_CONVERT(float, uint8_t, src
);
959 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
961 SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src
, 8));
963 SWIZZLE_CONVERT(float, int8_t, src
);
966 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
968 SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src
, 16));
970 SWIZZLE_CONVERT(float, uint16_t, src
);
973 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
975 SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src
, 16));
977 SWIZZLE_CONVERT(float, int16_t, src
);
980 case MESA_ARRAY_FORMAT_TYPE_UINT
:
982 SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src
, 32));
984 SWIZZLE_CONVERT(float, uint32_t, src
);
987 case MESA_ARRAY_FORMAT_TYPE_INT
:
989 SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src
, 32));
991 SWIZZLE_CONVERT(float, int32_t, src
);
995 assert(!"Invalid channel type combination");
1001 convert_half_float(void *void_dst
, int num_dst_channels
,
1002 const void *void_src
, GLenum src_type
, int num_src_channels
,
1003 const uint8_t swizzle
[4], bool normalized
, int count
)
1005 const uint16_t one
= _mesa_float_to_half(1.0f
);
1008 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1009 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src
));
1011 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1012 SWIZZLE_CONVERT(uint16_t, uint16_t, src
);
1014 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1016 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src
, 8));
1018 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src
));
1021 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1023 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src
, 8));
1025 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src
));
1028 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1030 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src
, 16));
1032 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src
));
1035 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1037 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src
, 16));
1039 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src
));
1042 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1044 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src
, 32));
1046 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src
));
1049 case MESA_ARRAY_FORMAT_TYPE_INT
:
1051 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src
, 32));
1053 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src
));
1057 assert(!"Invalid channel type combination");
1062 convert_ubyte(void *void_dst
, int num_dst_channels
,
1063 const void *void_src
, GLenum src_type
, int num_src_channels
,
1064 const uint8_t swizzle
[4], bool normalized
, int count
)
1066 const uint8_t one
= normalized
? UINT8_MAX
: 1;
1069 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1071 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src
, 8));
1073 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src
, 8));
1076 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1078 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src
, 8));
1080 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src
, 8));
1083 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1084 SWIZZLE_CONVERT(uint8_t, uint8_t, src
);
1086 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1088 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 8));
1090 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src
, 8));
1093 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1095 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src
, 16, 8));
1097 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src
, 8));
1100 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1102 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 8));
1104 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src
, 8));
1107 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1109 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src
, 32, 8));
1111 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src
, 8));
1114 case MESA_ARRAY_FORMAT_TYPE_INT
:
1116 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 8));
1118 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src
, 8));
1122 assert(!"Invalid channel type combination");
1128 convert_byte(void *void_dst
, int num_dst_channels
,
1129 const void *void_src
, GLenum src_type
, int num_src_channels
,
1130 const uint8_t swizzle
[4], bool normalized
, int count
)
1132 const int8_t one
= normalized
? INT8_MAX
: 1;
1135 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1137 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src
, 8));
1139 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src
, 8));
1142 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1144 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src
, 8));
1146 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src
, 8));
1149 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1151 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 8));
1153 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src
, 8));
1156 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1157 SWIZZLE_CONVERT(int8_t, int8_t, src
);
1159 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1161 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 8));
1163 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src
, 8));
1166 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1168 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src
, 16, 8));
1170 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src
, 8));
1173 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1175 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 8));
1177 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src
, 8));
1180 case MESA_ARRAY_FORMAT_TYPE_INT
:
1182 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src
, 32, 8));
1184 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src
, 8));
1188 assert(!"Invalid channel type combination");
1194 convert_ushort(void *void_dst
, int num_dst_channels
,
1195 const void *void_src
, GLenum src_type
, int num_src_channels
,
1196 const uint8_t swizzle
[4], bool normalized
, int count
)
1198 const uint16_t one
= normalized
? UINT16_MAX
: 1;
1201 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1203 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src
, 16));
1205 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src
, 16));
1208 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1210 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src
, 16));
1212 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src
, 16));
1215 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1217 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src
, 8, 16));
1219 SWIZZLE_CONVERT(uint16_t, uint8_t, src
);
1222 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1224 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 16));
1226 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src
, 16));
1229 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1230 SWIZZLE_CONVERT(uint16_t, uint16_t, src
);
1232 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1234 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 16));
1236 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src
, 16));
1239 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1241 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src
, 32, 16));
1243 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src
, 16));
1246 case MESA_ARRAY_FORMAT_TYPE_INT
:
1248 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 16));
1250 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src
, 16));
1254 assert(!"Invalid channel type combination");
1260 convert_short(void *void_dst
, int num_dst_channels
,
1261 const void *void_src
, GLenum src_type
, int num_src_channels
,
1262 const uint8_t swizzle
[4], bool normalized
, int count
)
1264 const int16_t one
= normalized
? INT16_MAX
: 1;
1267 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1269 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src
, 16));
1271 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src
, 16));
1274 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1276 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src
, 16));
1278 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src
, 16));
1281 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1283 SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 16));
1285 SWIZZLE_CONVERT(int16_t, uint8_t, src
);
1288 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1290 SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src
, 8, 16));
1292 SWIZZLE_CONVERT(int16_t, int8_t, src
);
1295 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1297 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 16));
1299 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src
, 16));
1302 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1303 SWIZZLE_CONVERT(int16_t, int16_t, src
);
1305 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1307 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 16));
1309 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src
, 16));
1312 case MESA_ARRAY_FORMAT_TYPE_INT
:
1314 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src
, 32, 16));
1316 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src
, 16));
1320 assert(!"Invalid channel type combination");
1325 convert_uint(void *void_dst
, int num_dst_channels
,
1326 const void *void_src
, GLenum src_type
, int num_src_channels
,
1327 const uint8_t swizzle
[4], bool normalized
, int count
)
1329 const uint32_t one
= normalized
? UINT32_MAX
: 1;
1332 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1334 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src
, 32));
1336 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src
, 32));
1339 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1341 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src
, 32));
1343 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src
, 32));
1346 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1348 SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src
, 8, 32));
1350 SWIZZLE_CONVERT(uint32_t, uint8_t, src
);
1353 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1355 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 32));
1357 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src
, 32));
1360 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1362 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src
, 16, 32));
1364 SWIZZLE_CONVERT(uint32_t, uint16_t, src
);
1367 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1369 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 32));
1371 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src
, 32));
1374 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1375 SWIZZLE_CONVERT(uint32_t, uint32_t, src
);
1377 case MESA_ARRAY_FORMAT_TYPE_INT
:
1379 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 32));
1381 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src
, 32));
1385 assert(!"Invalid channel type combination");
1391 convert_int(void *void_dst
, int num_dst_channels
,
1392 const void *void_src
, GLenum src_type
, int num_src_channels
,
1393 const uint8_t swizzle
[4], bool normalized
, int count
)
1395 const int32_t one
= normalized
? INT32_MAX
: 1;
1398 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1400 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src
, 32));
1402 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src
, 32));
1405 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1407 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src
, 32));
1409 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src
, 32));
1412 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1414 SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 32));
1416 SWIZZLE_CONVERT(int32_t, uint8_t, src
);
1419 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1421 SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src
, 8, 32));
1423 SWIZZLE_CONVERT(int32_t, int8_t, src
);
1426 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1428 SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 32));
1430 SWIZZLE_CONVERT(int32_t, uint16_t, src
);
1433 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1435 SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src
, 16, 32));
1437 SWIZZLE_CONVERT(int32_t, int16_t, src
);
1440 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1442 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 32));
1444 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src
, 32));
1447 case MESA_ARRAY_FORMAT_TYPE_INT
:
1448 SWIZZLE_CONVERT(int32_t, int32_t, src
);
1451 assert(!"Invalid channel type combination");
1457 * Convert between array-based color formats.
1459 * Most format conversion operations required by GL can be performed by
1460 * converting one channel at a time, shuffling the channels around, and
1461 * optionally filling missing channels with zeros and ones. This function
1462 * does just that in a general, yet efficient, way.
1464 * The swizzle parameter is an array of 4 numbers (see
1465 * _mesa_get_format_swizzle) that describes where each channel in the
1466 * destination should come from in the source. If swizzle[i] < 4 then it
1467 * means that dst[i] = CONVERT(src[swizzle[i]]). If swizzle[i] is
1468 * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding
1469 * dst[i] will be filled with the appropreate representation of zero or one
1472 * Under most circumstances, the source and destination images must be
1473 * different as no care is taken not to clobber one with the other.
1474 * However, if they have the same number of bits per pixel, it is safe to
1475 * do an in-place conversion.
1477 * \param[out] dst pointer to where the converted data should
1480 * \param[in] dst_type the destination GL type of the converted
1481 * data (GL_BYTE, etc.)
1483 * \param[in] num_dst_channels the number of channels in the converted
1486 * \param[in] src pointer to the source data
1488 * \param[in] src_type the GL type of the source data (GL_BYTE,
1491 * \param[in] num_src_channels the number of channels in the source data
1492 * (the number of channels total, not just
1495 * \param[in] swizzle describes how to get the destination data
1496 * from the source data.
1498 * \param[in] normalized for integer types, this indicates whether
1499 * the data should be considered as integers
1500 * or as normalized integers;
1502 * \param[in] count the number of pixels to convert
1505 _mesa_swizzle_and_convert(void *void_dst
, enum mesa_array_format_datatype dst_type
, int num_dst_channels
,
1506 const void *void_src
, enum mesa_array_format_datatype src_type
, int num_src_channels
,
1507 const uint8_t swizzle
[4], bool normalized
, int count
)
1509 if (swizzle_convert_try_memcpy(void_dst
, dst_type
, num_dst_channels
,
1510 void_src
, src_type
, num_src_channels
,
1511 swizzle
, normalized
, count
))
1515 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1516 convert_float(void_dst
, num_dst_channels
, void_src
, src_type
,
1517 num_src_channels
, swizzle
, normalized
, count
);
1519 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1520 convert_half_float(void_dst
, num_dst_channels
, void_src
, src_type
,
1521 num_src_channels
, swizzle
, normalized
, count
);
1523 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1524 convert_ubyte(void_dst
, num_dst_channels
, void_src
, src_type
,
1525 num_src_channels
, swizzle
, normalized
, count
);
1527 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1528 convert_byte(void_dst
, num_dst_channels
, void_src
, src_type
,
1529 num_src_channels
, swizzle
, normalized
, count
);
1531 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1532 convert_ushort(void_dst
, num_dst_channels
, void_src
, src_type
,
1533 num_src_channels
, swizzle
, normalized
, count
);
1535 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1536 convert_short(void_dst
, num_dst_channels
, void_src
, src_type
,
1537 num_src_channels
, swizzle
, normalized
, count
);
1539 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1540 convert_uint(void_dst
, num_dst_channels
, void_src
, src_type
,
1541 num_src_channels
, swizzle
, normalized
, count
);
1543 case MESA_ARRAY_FORMAT_TYPE_INT
:
1544 convert_int(void_dst
, num_dst_channels
, void_src
, src_type
,
1545 num_src_channels
, swizzle
, normalized
, count
);
1548 assert(!"Invalid channel type");