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(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS
,
33 4, 1, 1, 1, 4, 0, 1, 2, 3);
35 const mesa_array_format RGBA8_UBYTE
=
36 MESA_ARRAY_FORMAT(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS
,
37 1, 0, 0, 1, 4, 0, 1, 2, 3);
39 const mesa_array_format RGBA32_UINT
=
40 MESA_ARRAY_FORMAT(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS
,
41 4, 0, 0, 0, 4, 0, 1, 2, 3);
43 const mesa_array_format RGBA32_INT
=
44 MESA_ARRAY_FORMAT(MESA_ARRAY_FORMAT_BASE_FORMAT_RGBA_VARIANTS
,
45 4, 1, 0, 0, 4, 0, 1, 2, 3);
48 invert_swizzle(uint8_t dst
[4], const uint8_t src
[4])
52 dst
[0] = MESA_FORMAT_SWIZZLE_NONE
;
53 dst
[1] = MESA_FORMAT_SWIZZLE_NONE
;
54 dst
[2] = MESA_FORMAT_SWIZZLE_NONE
;
55 dst
[3] = MESA_FORMAT_SWIZZLE_NONE
;
57 for (i
= 0; i
< 4; ++i
)
58 for (j
= 0; j
< 4; ++j
)
59 if (src
[j
] == i
&& dst
[i
] == MESA_FORMAT_SWIZZLE_NONE
)
63 /* Takes a src to RGBA swizzle and applies a rebase swizzle to it. This
64 * is used when we need to rebase a format to match a different
65 * base internal format.
67 * The rebase swizzle can be NULL, which means that no rebase is necessary,
68 * in which case the src to RGBA swizzle is copied to the output without
71 * The resulting rebased swizzle and well as the input swizzles are
72 * all 4-element swizzles, but the rebase swizzle can be NULL if no rebase
76 compute_rebased_rgba_component_mapping(uint8_t *src2rgba
,
77 uint8_t *rebase_swizzle
,
78 uint8_t *rebased_src2rgba
)
83 for (i
= 0; i
< 4; i
++) {
84 if (rebase_swizzle
[i
] > MESA_FORMAT_SWIZZLE_W
)
85 rebased_src2rgba
[i
] = rebase_swizzle
[i
];
87 rebased_src2rgba
[i
] = src2rgba
[rebase_swizzle
[i
]];
90 /* No rebase needed, so src2rgba is all that we need */
91 memcpy(rebased_src2rgba
, src2rgba
, 4 * sizeof(uint8_t));
95 /* Computes the final swizzle transform to apply from src to dst in a
96 * conversion that might involve a rebase swizzle.
98 * This is used to compute the swizzle transform to apply in conversions
99 * between array formats where we have a src2rgba swizzle, a rgba2dst swizzle
100 * and possibly, a rebase swizzle.
102 * The final swizzle transform to apply (src2dst) when a rebase swizzle is
103 * involved is: src -> rgba -> base -> rgba -> dst
106 compute_src2dst_component_mapping(uint8_t *src2rgba
, uint8_t *rgba2dst
,
107 uint8_t *rebase_swizzle
, uint8_t *src2dst
)
111 if (!rebase_swizzle
) {
112 for (i
= 0; i
< 4; i
++) {
113 if (rgba2dst
[i
] > MESA_FORMAT_SWIZZLE_W
) {
114 src2dst
[i
] = rgba2dst
[i
];
116 src2dst
[i
] = src2rgba
[rgba2dst
[i
]];
120 for (i
= 0; i
< 4; i
++) {
121 if (rgba2dst
[i
] > MESA_FORMAT_SWIZZLE_W
) {
122 src2dst
[i
] = rgba2dst
[i
];
123 } else if (rebase_swizzle
[rgba2dst
[i
]] > MESA_FORMAT_SWIZZLE_W
) {
124 src2dst
[i
] = rebase_swizzle
[rgba2dst
[i
]];
126 src2dst
[i
] = src2rgba
[rebase_swizzle
[rgba2dst
[i
]]];
133 * This function is used by clients of _mesa_format_convert to obtain
134 * the rebase swizzle to use in a format conversion based on the base
137 * \param baseFormat the base internal format involved in the conversion.
138 * \param map the rebase swizzle to consider
140 * This function computes 'map' as rgba -> baseformat -> rgba and returns true
141 * if the resulting swizzle transform is not the identity transform (thus, a
142 * rebase is needed). If the function returns false then a rebase swizzle
143 * is not necessary and the value of 'map' is undefined. In this situation
144 * clients of _mesa_format_convert should pass NULL in the 'rebase_swizzle'
148 _mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat
, uint8_t *map
)
150 uint8_t rgba2base
[6], base2rgba
[6];
153 switch (baseFormat
) {
166 case GL_LUMINANCE_ALPHA
:
168 bool needRebase
= false;
169 _mesa_compute_component_mapping(GL_RGBA
, baseFormat
, rgba2base
);
170 _mesa_compute_component_mapping(baseFormat
, GL_RGBA
, base2rgba
);
171 for (i
= 0; i
< 4; i
++) {
172 if (base2rgba
[i
] > MESA_FORMAT_SWIZZLE_W
) {
173 map
[i
] = base2rgba
[i
];
175 map
[i
] = rgba2base
[base2rgba
[i
]];
183 unreachable("Unexpected base format");
189 * Special case conversion function to swap r/b channels from the source
190 * image to the dest image.
193 convert_ubyte_rgba_to_bgra(size_t width
, size_t height
,
194 const uint8_t *src
, size_t src_stride
,
195 uint8_t *dst
, size_t dst_stride
)
199 if (sizeof(void *) == 8 &&
200 src_stride
% 8 == 0 &&
201 dst_stride
% 8 == 0 &&
202 (GLsizeiptr
) src
% 8 == 0 &&
203 (GLsizeiptr
) dst
% 8 == 0) {
204 /* use 64-bit word to swizzle two 32-bit pixels. We need 8-byte
205 * alignment for src/dst addresses and strides.
207 for (row
= 0; row
< height
; row
++) {
208 const GLuint64
*s
= (const GLuint64
*) src
;
209 GLuint64
*d
= (GLuint64
*) dst
;
211 for (i
= 0; i
< width
/2; i
++) {
212 d
[i
] = ( (s
[i
] & 0xff00ff00ff00ff00) |
213 ((s
[i
] & 0xff000000ff) << 16) |
214 ((s
[i
] & 0xff000000ff0000) >> 16));
217 /* handle the case of odd widths */
218 const GLuint s
= ((const GLuint
*) src
)[width
- 1];
219 GLuint
*d
= (GLuint
*) dst
+ width
- 1;
220 *d
= ( (s
& 0xff00ff00) |
222 ((s
& 0xff0000) >> 16));
228 for (row
= 0; row
< height
; row
++) {
229 const GLuint
*s
= (const GLuint
*) src
;
230 GLuint
*d
= (GLuint
*) dst
;
232 for (i
= 0; i
< width
; i
++) {
233 d
[i
] = ( (s
[i
] & 0xff00ff00) |
234 ((s
[i
] & 0xff) << 16) |
235 ((s
[i
] & 0xff0000) >> 16));
245 * This can be used to convert between most color formats.
248 * - This function doesn't handle GL_COLOR_INDEX or YCBCR formats.
249 * - This function doesn't handle byte-swapping or transferOps, these should
250 * be handled by the caller.
252 * \param void_dst The address where converted color data will be stored.
253 * The caller must ensure that the buffer is large enough
254 * to hold the converted pixel data.
255 * \param dst_format The destination color format. It can be a mesa_format
256 * or a mesa_array_format represented as an uint32_t.
257 * \param dst_stride The stride of the destination format in bytes.
258 * \param void_src The address of the source color data to convert.
259 * \param src_format The source color format. It can be a mesa_format
260 * or a mesa_array_format represented as an uint32_t.
261 * \param src_stride The stride of the source format in bytes.
262 * \param width The width, in pixels, of the source image to convert.
263 * \param height The height, in pixels, of the source image to convert.
264 * \param rebase_swizzle A swizzle transform to apply during the conversion,
265 * typically used to match a different internal base
266 * format involved. NULL if no rebase transform is needed
267 * (i.e. the internal base format and the base format of
268 * the dst or the src -depending on whether we are doing
269 * an upload or a download respectively- are the same).
272 _mesa_format_convert(void *void_dst
, uint32_t dst_format
, size_t dst_stride
,
273 void *void_src
, uint32_t src_format
, size_t src_stride
,
274 size_t width
, size_t height
, uint8_t *rebase_swizzle
)
276 uint8_t *dst
= (uint8_t *)void_dst
;
277 uint8_t *src
= (uint8_t *)void_src
;
278 mesa_array_format src_array_format
, dst_array_format
;
279 bool src_format_is_mesa_array_format
, dst_format_is_mesa_array_format
;
280 uint8_t src2dst
[4], src2rgba
[4], rgba2dst
[4], dst2rgba
[4];
281 uint8_t rebased_src2rgba
[4];
282 enum mesa_array_format_datatype src_type
= 0, dst_type
= 0, common_type
;
283 bool normalized
, dst_integer
, src_integer
, is_signed
;
284 int src_num_channels
= 0, dst_num_channels
= 0;
285 uint8_t (*tmp_ubyte
)[4];
286 float (*tmp_float
)[4];
287 uint32_t (*tmp_uint
)[4];
291 if (_mesa_format_is_mesa_array_format(src_format
)) {
292 src_format_is_mesa_array_format
= true;
293 src_array_format
= src_format
;
295 assert(_mesa_is_format_color_format(src_format
));
296 src_format_is_mesa_array_format
= false;
297 src_array_format
= _mesa_format_to_array_format(src_format
);
300 if (_mesa_format_is_mesa_array_format(dst_format
)) {
301 dst_format_is_mesa_array_format
= true;
302 dst_array_format
= dst_format
;
304 assert(_mesa_is_format_color_format(dst_format
));
305 dst_format_is_mesa_array_format
= false;
306 dst_array_format
= _mesa_format_to_array_format(dst_format
);
309 /* First we see if we can implement the conversion with a direct pack
312 * In this case we want to be careful when we need to apply a swizzle to
313 * match an internal base format, since in these cases a simple pack/unpack
314 * to the dst format from the src format may not match the requirements
315 * of the internal base format. For now we decide to be safe and
316 * avoid this path in these scenarios but in the future we may want to
317 * enable it for specific combinations that are known to work.
319 if (!rebase_swizzle
) {
320 /* Do a direct memcpy where possible */
321 if ((dst_format_is_mesa_array_format
&&
322 src_format_is_mesa_array_format
&&
323 src_array_format
== dst_array_format
) ||
324 src_format
== dst_format
) {
325 int format_size
= _mesa_get_format_bytes(src_format
);
326 for (row
= 0; row
< height
; row
++) {
327 memcpy(dst
, src
, width
* format_size
);
334 /* Handle the cases where we can directly unpack */
335 if (!src_format_is_mesa_array_format
) {
336 if (dst_array_format
== RGBA32_FLOAT
) {
337 for (row
= 0; row
< height
; ++row
) {
338 _mesa_unpack_rgba_row(src_format
, width
,
339 src
, (float (*)[4])dst
);
344 } else if (dst_array_format
== RGBA8_UBYTE
) {
345 assert(!_mesa_is_format_integer_color(src_format
));
346 for (row
= 0; row
< height
; ++row
) {
347 _mesa_unpack_ubyte_rgba_row(src_format
, width
,
348 src
, (uint8_t (*)[4])dst
);
353 } else if (dst_array_format
== RGBA32_UINT
&&
354 _mesa_is_format_unsigned(src_format
)) {
355 assert(_mesa_is_format_integer_color(src_format
));
356 for (row
= 0; row
< height
; ++row
) {
357 _mesa_unpack_uint_rgba_row(src_format
, width
,
358 src
, (uint32_t (*)[4])dst
);
366 /* Handle the cases where we can directly pack */
367 if (!dst_format_is_mesa_array_format
) {
368 if (src_array_format
== RGBA32_FLOAT
) {
369 for (row
= 0; row
< height
; ++row
) {
370 _mesa_pack_float_rgba_row(dst_format
, width
,
371 (const float (*)[4])src
, dst
);
376 } else if (src_array_format
== RGBA8_UBYTE
) {
377 assert(!_mesa_is_format_integer_color(dst_format
));
379 if (dst_format
== MESA_FORMAT_B8G8R8A8_UNORM
) {
380 convert_ubyte_rgba_to_bgra(width
, height
, src
, src_stride
,
384 for (row
= 0; row
< height
; ++row
) {
385 _mesa_pack_ubyte_rgba_row(dst_format
, width
,
386 (const uint8_t (*)[4])src
, dst
);
392 } else if (src_array_format
== RGBA32_UINT
&&
393 _mesa_is_format_unsigned(dst_format
)) {
394 assert(_mesa_is_format_integer_color(dst_format
));
395 for (row
= 0; row
< height
; ++row
) {
396 _mesa_pack_uint_rgba_row(dst_format
, width
,
397 (const uint32_t (*)[4])src
, dst
);
406 /* Handle conversions between array formats */
408 if (src_array_format
) {
409 src_type
= _mesa_array_format_get_datatype(src_array_format
);
411 src_num_channels
= _mesa_array_format_get_num_channels(src_array_format
);
413 _mesa_array_format_get_swizzle(src_array_format
, src2rgba
);
415 normalized
= _mesa_array_format_is_normalized(src_array_format
);
418 if (dst_array_format
) {
419 dst_type
= _mesa_array_format_get_datatype(dst_array_format
);
421 dst_num_channels
= _mesa_array_format_get_num_channels(dst_array_format
);
423 _mesa_array_format_get_swizzle(dst_array_format
, dst2rgba
);
424 invert_swizzle(rgba2dst
, dst2rgba
);
426 normalized
|= _mesa_array_format_is_normalized(dst_array_format
);
429 if (src_array_format
&& dst_array_format
) {
430 assert(_mesa_array_format_is_normalized(src_array_format
) ==
431 _mesa_array_format_is_normalized(dst_array_format
));
433 compute_src2dst_component_mapping(src2rgba
, rgba2dst
, rebase_swizzle
,
436 for (row
= 0; row
< height
; ++row
) {
437 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
438 src
, src_type
, src_num_channels
,
439 src2dst
, normalized
, width
);
446 /* At this point, we're fresh out of fast-paths and we need to convert
447 * to float, uint32, or, if we're lucky, uint8.
452 if (src_array_format
) {
453 if (!_mesa_array_format_is_float(src_array_format
) &&
454 !_mesa_array_format_is_normalized(src_array_format
))
457 switch (_mesa_get_format_datatype(src_format
)) {
458 case GL_UNSIGNED_INT
:
465 /* If the destination format is signed but the source is unsigned, then we
466 * don't loose any data by converting to a signed intermediate format above
467 * and beyond the precision that we loose in the conversion itself. If the
468 * destination is unsigned then, by using an unsigned intermediate format,
469 * we make the conversion function that converts from the source to the
470 * intermediate format take care of truncating at zero. The exception here
471 * is if the intermediate format is float, in which case the first
472 * conversion will leave it signed and the second conversion will truncate
476 if (dst_array_format
) {
477 if (!_mesa_array_format_is_float(dst_array_format
) &&
478 !_mesa_array_format_is_normalized(dst_array_format
))
480 is_signed
= _mesa_array_format_is_signed(dst_array_format
);
481 bits
= 8 * _mesa_array_format_get_type_size(dst_array_format
);
483 switch (_mesa_get_format_datatype(dst_format
)) {
484 case GL_UNSIGNED_NORMALIZED
:
487 case GL_SIGNED_NORMALIZED
:
493 case GL_UNSIGNED_INT
:
502 bits
= _mesa_get_format_max_bits(dst_format
);
505 assert(src_integer
== dst_integer
);
507 if (src_integer
&& dst_integer
) {
508 tmp_uint
= malloc(width
* height
* sizeof(*tmp_uint
));
510 /* The [un]packing functions for unsigned datatypes treat the 32-bit
511 * integer array as signed for signed formats and as unsigned for
512 * unsigned formats. This is a bit of a problem if we ever convert from
513 * a signed to an unsigned format because the unsigned packing function
514 * doesn't know that the input is signed and will treat it as unsigned
515 * and not do the trunctation. The thing that saves us here is that all
516 * of the packed formats are unsigned, so we can just always use
517 * _mesa_swizzle_and_convert for signed formats, which is aware of the
518 * truncation problem.
520 common_type
= is_signed
? MESA_ARRAY_FORMAT_TYPE_INT
:
521 MESA_ARRAY_FORMAT_TYPE_UINT
;
522 if (src_array_format
) {
523 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
525 for (row
= 0; row
< height
; ++row
) {
526 _mesa_swizzle_and_convert(tmp_uint
+ row
* width
, common_type
, 4,
527 src
, src_type
, src_num_channels
,
528 rebased_src2rgba
, normalized
, width
);
532 for (row
= 0; row
< height
; ++row
) {
533 _mesa_unpack_uint_rgba_row(src_format
, width
,
534 src
, tmp_uint
+ row
* width
);
536 _mesa_swizzle_and_convert(tmp_uint
+ row
* width
, common_type
, 4,
537 tmp_uint
+ row
* width
, common_type
, 4,
538 rebase_swizzle
, false, width
);
543 /* At this point, we have already done the truncation if the source is
544 * signed but the destination is unsigned, so no need to force the
545 * _mesa_swizzle_and_convert path.
547 if (dst_format_is_mesa_array_format
) {
548 for (row
= 0; row
< height
; ++row
) {
549 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
550 tmp_uint
+ row
* width
, common_type
, 4,
551 rgba2dst
, normalized
, width
);
555 for (row
= 0; row
< height
; ++row
) {
556 _mesa_pack_uint_rgba_row(dst_format
, width
,
557 (const uint32_t (*)[4])tmp_uint
+ row
* width
, dst
);
563 } else if (is_signed
|| bits
> 8) {
564 tmp_float
= malloc(width
* height
* sizeof(*tmp_float
));
566 if (src_format_is_mesa_array_format
) {
567 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
569 for (row
= 0; row
< height
; ++row
) {
570 _mesa_swizzle_and_convert(tmp_float
+ row
* width
,
571 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
572 src
, src_type
, src_num_channels
,
573 rebased_src2rgba
, normalized
, width
);
577 for (row
= 0; row
< height
; ++row
) {
578 _mesa_unpack_rgba_row(src_format
, width
,
579 src
, tmp_float
+ row
* width
);
581 _mesa_swizzle_and_convert(tmp_float
+ row
* width
,
582 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
583 tmp_float
+ row
* width
,
584 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
585 rebase_swizzle
, normalized
, width
);
590 if (dst_format_is_mesa_array_format
) {
591 for (row
= 0; row
< height
; ++row
) {
592 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
593 tmp_float
+ row
* width
,
594 MESA_ARRAY_FORMAT_TYPE_FLOAT
, 4,
595 rgba2dst
, normalized
, width
);
599 for (row
= 0; row
< height
; ++row
) {
600 _mesa_pack_float_rgba_row(dst_format
, width
,
601 (const float (*)[4])tmp_float
+ row
* width
, dst
);
608 tmp_ubyte
= malloc(width
* height
* sizeof(*tmp_ubyte
));
610 if (src_format_is_mesa_array_format
) {
611 compute_rebased_rgba_component_mapping(src2rgba
, rebase_swizzle
,
613 for (row
= 0; row
< height
; ++row
) {
614 _mesa_swizzle_and_convert(tmp_ubyte
+ row
* width
,
615 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
616 src
, src_type
, src_num_channels
,
617 rebased_src2rgba
, normalized
, width
);
621 for (row
= 0; row
< height
; ++row
) {
622 _mesa_unpack_ubyte_rgba_row(src_format
, width
,
623 src
, tmp_ubyte
+ row
* width
);
625 _mesa_swizzle_and_convert(tmp_ubyte
+ row
* width
,
626 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
627 tmp_ubyte
+ row
* width
,
628 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
629 rebase_swizzle
, normalized
, width
);
634 if (dst_format_is_mesa_array_format
) {
635 for (row
= 0; row
< height
; ++row
) {
636 _mesa_swizzle_and_convert(dst
, dst_type
, dst_num_channels
,
637 tmp_ubyte
+ row
* width
,
638 MESA_ARRAY_FORMAT_TYPE_UBYTE
, 4,
639 rgba2dst
, normalized
, width
);
643 for (row
= 0; row
< height
; ++row
) {
644 _mesa_pack_ubyte_rgba_row(dst_format
, width
,
645 (const uint8_t (*)[4])tmp_ubyte
+ row
* width
, dst
);
654 static const uint8_t map_identity
[7] = { 0, 1, 2, 3, 4, 5, 6 };
655 #if UTIL_ARCH_BIG_ENDIAN
656 static const uint8_t map_3210
[7] = { 3, 2, 1, 0, 4, 5, 6 };
657 static const uint8_t map_1032
[7] = { 1, 0, 3, 2, 4, 5, 6 };
661 * Describes a format as an array format, if possible
663 * A helper function for figuring out if a (possibly packed) format is
664 * actually an array format and, if so, what the array parameters are.
666 * \param[in] format the mesa format
667 * \param[out] type the GL type of the array (GL_BYTE, etc.)
668 * \param[out] num_components the number of components in the array
669 * \param[out] swizzle a swizzle describing how to get from the
670 * given format to RGBA
671 * \param[out] normalized for integer formats, this represents whether
672 * the format is a normalized integer or a
674 * \return true if this format is an array format, false otherwise
677 _mesa_format_to_array(mesa_format format
, GLenum
*type
, int *num_components
,
678 uint8_t swizzle
[4], bool *normalized
)
681 GLuint format_components
;
682 uint8_t packed_swizzle
[4];
683 const uint8_t *endian
;
685 if (_mesa_is_format_compressed(format
))
688 *normalized
= !_mesa_is_format_integer(format
);
690 _mesa_uncompressed_format_to_type_and_comps(format
, type
, &format_components
);
692 switch (_mesa_get_format_layout(format
)) {
693 case MESA_FORMAT_LAYOUT_ARRAY
:
694 *num_components
= format_components
;
695 _mesa_get_format_swizzle(format
, swizzle
);
697 case MESA_FORMAT_LAYOUT_PACKED
:
699 case GL_UNSIGNED_BYTE
:
701 if (_mesa_get_format_max_bits(format
) != 8)
703 *num_components
= _mesa_get_format_bytes(format
);
704 switch (*num_components
) {
706 endian
= map_identity
;
709 #if UTIL_ARCH_LITTLE_ENDIAN
710 endian
= map_identity
;
716 #if UTIL_ARCH_LITTLE_ENDIAN
717 endian
= map_identity
;
723 endian
= map_identity
;
724 assert(!"Invalid number of components");
727 case GL_UNSIGNED_SHORT
:
730 if (_mesa_get_format_max_bits(format
) != 16)
732 *num_components
= _mesa_get_format_bytes(format
) / 2;
733 switch (*num_components
) {
735 endian
= map_identity
;
738 #if UTIL_ARCH_LITTLE_ENDIAN
739 endian
= map_identity
;
745 endian
= map_identity
;
746 assert(!"Invalid number of components");
749 case GL_UNSIGNED_INT
:
752 /* This isn't packed. At least not really. */
753 assert(format_components
== 1);
754 if (_mesa_get_format_max_bits(format
) != 32)
756 *num_components
= format_components
;
757 endian
= map_identity
;
763 _mesa_get_format_swizzle(format
, packed_swizzle
);
765 for (i
= 0; i
< 4; ++i
)
766 swizzle
[i
] = endian
[packed_swizzle
[i
]];
769 case MESA_FORMAT_LAYOUT_OTHER
:
776 * Attempts to perform the given swizzle-and-convert operation with memcpy
778 * This function determines if the given swizzle-and-convert operation can
779 * be done with a simple memcpy and, if so, does the memcpy. If not, it
780 * returns false and we fall back to the standard version below.
782 * The arguments are exactly the same as for _mesa_swizzle_and_convert
784 * \return true if it successfully performed the swizzle-and-convert
785 * operation with memcpy, false otherwise
788 swizzle_convert_try_memcpy(void *dst
,
789 enum mesa_array_format_datatype dst_type
,
790 int num_dst_channels
,
792 enum mesa_array_format_datatype src_type
,
793 int num_src_channels
,
794 const uint8_t swizzle
[4], bool normalized
, int count
)
798 if (src_type
!= dst_type
)
800 if (num_src_channels
!= num_dst_channels
)
803 for (i
= 0; i
< num_dst_channels
; ++i
)
804 if (swizzle
[i
] != i
&& swizzle
[i
] != MESA_FORMAT_SWIZZLE_NONE
)
807 memcpy(dst
, src
, count
* num_src_channels
*
808 _mesa_array_format_datatype_get_size(src_type
));
814 * Represents a single instance of the standard swizzle-and-convert loop
816 * Any swizzle-and-convert operation simply loops through the pixels and
817 * performs the transformation operation one pixel at a time. This macro
818 * embodies one instance of the conversion loop. This way we can do all
819 * control flow outside of the loop and allow the compiler to unroll
820 * everything inside the loop.
822 * Note: This loop is carefully crafted for performance. Be careful when
823 * changing it and run some benchmarks to ensure no performance regressions
826 * \param DST_TYPE the C datatype of the destination
827 * \param DST_CHANS the number of destination channels
828 * \param SRC_TYPE the C datatype of the source
829 * \param SRC_CHANS the number of source channels
830 * \param CONV an expression for converting from the source data,
831 * storred in the variable "src", to the destination
834 #define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \
837 for (s = 0; s < count; ++s) { \
838 for (j = 0; j < SRC_CHANS; ++j) { \
839 SRC_TYPE src = typed_src[j]; \
843 typed_dst[0] = tmp[swizzle_x]; \
844 if (DST_CHANS > 1) { \
845 typed_dst[1] = tmp[swizzle_y]; \
846 if (DST_CHANS > 2) { \
847 typed_dst[2] = tmp[swizzle_z]; \
848 if (DST_CHANS > 3) { \
849 typed_dst[3] = tmp[swizzle_w]; \
853 typed_src += SRC_CHANS; \
854 typed_dst += DST_CHANS; \
859 * Represents a single swizzle-and-convert operation
861 * This macro represents everything done in a single swizzle-and-convert
862 * operation. The actual work is done by the SWIZZLE_CONVERT_LOOP macro.
863 * This macro acts as a wrapper that uses a nested switch to ensure that
864 * all looping parameters get unrolled.
866 * This macro makes assumptions about variables etc. in the calling
867 * function. Changes to _mesa_swizzle_and_convert may require changes to
870 * \param DST_TYPE the C datatype of the destination
871 * \param SRC_TYPE the C datatype of the source
872 * \param CONV an expression for converting from the source data,
873 * storred in the variable "src", to the destination
876 #define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV) \
878 const uint8_t swizzle_x = swizzle[0]; \
879 const uint8_t swizzle_y = swizzle[1]; \
880 const uint8_t swizzle_z = swizzle[2]; \
881 const uint8_t swizzle_w = swizzle[3]; \
882 const SRC_TYPE *typed_src = void_src; \
883 DST_TYPE *typed_dst = void_dst; \
887 switch (num_dst_channels) { \
889 switch (num_src_channels) { \
891 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV); \
894 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV); \
897 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV); \
900 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV); \
905 switch (num_src_channels) { \
907 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV); \
910 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV); \
913 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV); \
916 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV); \
921 switch (num_src_channels) { \
923 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV); \
926 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV); \
929 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV); \
932 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV); \
937 switch (num_src_channels) { \
939 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV); \
942 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV); \
945 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV); \
948 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV); \
957 convert_float(void *void_dst
, int num_dst_channels
,
958 const void *void_src
, GLenum src_type
, int num_src_channels
,
959 const uint8_t swizzle
[4], bool normalized
, int count
)
961 const float one
= 1.0f
;
964 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
965 SWIZZLE_CONVERT(float, float, src
);
967 case MESA_ARRAY_FORMAT_TYPE_HALF
:
968 SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src
));
970 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
972 SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src
, 8));
974 SWIZZLE_CONVERT(float, uint8_t, src
);
977 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
979 SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src
, 8));
981 SWIZZLE_CONVERT(float, int8_t, src
);
984 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
986 SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src
, 16));
988 SWIZZLE_CONVERT(float, uint16_t, src
);
991 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
993 SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src
, 16));
995 SWIZZLE_CONVERT(float, int16_t, src
);
998 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1000 SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src
, 32));
1002 SWIZZLE_CONVERT(float, uint32_t, src
);
1005 case MESA_ARRAY_FORMAT_TYPE_INT
:
1007 SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src
, 32));
1009 SWIZZLE_CONVERT(float, int32_t, src
);
1013 assert(!"Invalid channel type combination");
1019 convert_half_float(void *void_dst
, int num_dst_channels
,
1020 const void *void_src
, GLenum src_type
, int num_src_channels
,
1021 const uint8_t swizzle
[4], bool normalized
, int count
)
1023 const uint16_t one
= _mesa_float_to_half(1.0f
);
1026 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1027 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src
));
1029 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1030 SWIZZLE_CONVERT(uint16_t, uint16_t, src
);
1032 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1034 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src
, 8));
1036 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src
));
1039 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1041 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src
, 8));
1043 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src
));
1046 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1048 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src
, 16));
1050 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src
));
1053 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1055 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src
, 16));
1057 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src
));
1060 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1062 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src
, 32));
1064 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src
));
1067 case MESA_ARRAY_FORMAT_TYPE_INT
:
1069 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src
, 32));
1071 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src
));
1075 assert(!"Invalid channel type combination");
1080 convert_ubyte(void *void_dst
, int num_dst_channels
,
1081 const void *void_src
, GLenum src_type
, int num_src_channels
,
1082 const uint8_t swizzle
[4], bool normalized
, int count
)
1084 const uint8_t one
= normalized
? UINT8_MAX
: 1;
1087 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1089 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src
, 8));
1091 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src
, 8));
1094 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1096 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src
, 8));
1098 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src
, 8));
1101 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1102 SWIZZLE_CONVERT(uint8_t, uint8_t, src
);
1104 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1106 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 8));
1108 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src
, 8));
1111 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1113 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src
, 16, 8));
1115 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src
, 8));
1118 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1120 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 8));
1122 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src
, 8));
1125 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1127 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src
, 32, 8));
1129 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src
, 8));
1132 case MESA_ARRAY_FORMAT_TYPE_INT
:
1134 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 8));
1136 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src
, 8));
1140 assert(!"Invalid channel type combination");
1146 convert_byte(void *void_dst
, int num_dst_channels
,
1147 const void *void_src
, GLenum src_type
, int num_src_channels
,
1148 const uint8_t swizzle
[4], bool normalized
, int count
)
1150 const int8_t one
= normalized
? INT8_MAX
: 1;
1153 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1155 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src
, 8));
1157 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src
, 8));
1160 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1162 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src
, 8));
1164 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src
, 8));
1167 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1169 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 8));
1171 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src
, 8));
1174 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1175 SWIZZLE_CONVERT(int8_t, int8_t, src
);
1177 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1179 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 8));
1181 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src
, 8));
1184 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1186 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src
, 16, 8));
1188 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src
, 8));
1191 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1193 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 8));
1195 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src
, 8));
1198 case MESA_ARRAY_FORMAT_TYPE_INT
:
1200 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src
, 32, 8));
1202 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src
, 8));
1206 assert(!"Invalid channel type combination");
1212 convert_ushort(void *void_dst
, int num_dst_channels
,
1213 const void *void_src
, GLenum src_type
, int num_src_channels
,
1214 const uint8_t swizzle
[4], bool normalized
, int count
)
1216 const uint16_t one
= normalized
? UINT16_MAX
: 1;
1219 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1221 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src
, 16));
1223 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src
, 16));
1226 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1228 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src
, 16));
1230 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src
, 16));
1233 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1235 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src
, 8, 16));
1237 SWIZZLE_CONVERT(uint16_t, uint8_t, src
);
1240 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1242 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 16));
1244 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src
, 16));
1247 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1248 SWIZZLE_CONVERT(uint16_t, uint16_t, src
);
1250 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1252 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 16));
1254 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src
, 16));
1257 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1259 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src
, 32, 16));
1261 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src
, 16));
1264 case MESA_ARRAY_FORMAT_TYPE_INT
:
1266 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 16));
1268 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src
, 16));
1272 assert(!"Invalid channel type combination");
1278 convert_short(void *void_dst
, int num_dst_channels
,
1279 const void *void_src
, GLenum src_type
, int num_src_channels
,
1280 const uint8_t swizzle
[4], bool normalized
, int count
)
1282 const int16_t one
= normalized
? INT16_MAX
: 1;
1285 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1287 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src
, 16));
1289 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src
, 16));
1292 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1294 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src
, 16));
1296 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src
, 16));
1299 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1301 SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 16));
1303 SWIZZLE_CONVERT(int16_t, uint8_t, src
);
1306 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1308 SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src
, 8, 16));
1310 SWIZZLE_CONVERT(int16_t, int8_t, src
);
1313 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1315 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 16));
1317 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src
, 16));
1320 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1321 SWIZZLE_CONVERT(int16_t, int16_t, src
);
1323 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1325 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 16));
1327 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src
, 16));
1330 case MESA_ARRAY_FORMAT_TYPE_INT
:
1332 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src
, 32, 16));
1334 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src
, 16));
1338 assert(!"Invalid channel type combination");
1343 convert_uint(void *void_dst
, int num_dst_channels
,
1344 const void *void_src
, GLenum src_type
, int num_src_channels
,
1345 const uint8_t swizzle
[4], bool normalized
, int count
)
1347 const uint32_t one
= normalized
? UINT32_MAX
: 1;
1350 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1352 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src
, 32));
1354 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src
, 32));
1357 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1359 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src
, 32));
1361 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src
, 32));
1364 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1366 SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src
, 8, 32));
1368 SWIZZLE_CONVERT(uint32_t, uint8_t, src
);
1371 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1373 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src
, 8, 32));
1375 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src
, 32));
1378 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1380 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src
, 16, 32));
1382 SWIZZLE_CONVERT(uint32_t, uint16_t, src
);
1385 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1387 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src
, 16, 32));
1389 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src
, 32));
1392 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1393 SWIZZLE_CONVERT(uint32_t, uint32_t, src
);
1395 case MESA_ARRAY_FORMAT_TYPE_INT
:
1397 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src
, 32, 32));
1399 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src
, 32));
1403 assert(!"Invalid channel type combination");
1409 convert_int(void *void_dst
, int num_dst_channels
,
1410 const void *void_src
, GLenum src_type
, int num_src_channels
,
1411 const uint8_t swizzle
[4], bool normalized
, int count
)
1413 const int32_t one
= normalized
? INT32_MAX
: 1;
1416 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1418 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src
, 32));
1420 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src
, 32));
1423 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1425 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src
, 32));
1427 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src
, 32));
1430 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1432 SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src
, 8, 32));
1434 SWIZZLE_CONVERT(int32_t, uint8_t, src
);
1437 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1439 SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src
, 8, 32));
1441 SWIZZLE_CONVERT(int32_t, int8_t, src
);
1444 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1446 SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src
, 16, 32));
1448 SWIZZLE_CONVERT(int32_t, uint16_t, src
);
1451 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1453 SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src
, 16, 32));
1455 SWIZZLE_CONVERT(int32_t, int16_t, src
);
1458 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1460 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src
, 32, 32));
1462 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src
, 32));
1465 case MESA_ARRAY_FORMAT_TYPE_INT
:
1466 SWIZZLE_CONVERT(int32_t, int32_t, src
);
1469 assert(!"Invalid channel type combination");
1475 * Convert between array-based color formats.
1477 * Most format conversion operations required by GL can be performed by
1478 * converting one channel at a time, shuffling the channels around, and
1479 * optionally filling missing channels with zeros and ones. This function
1480 * does just that in a general, yet efficient, way.
1482 * The swizzle parameter is an array of 4 numbers (see
1483 * _mesa_get_format_swizzle) that describes where each channel in the
1484 * destination should come from in the source. If swizzle[i] < 4 then it
1485 * means that dst[i] = CONVERT(src[swizzle[i]]). If swizzle[i] is
1486 * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding
1487 * dst[i] will be filled with the appropreate representation of zero or one
1490 * Under most circumstances, the source and destination images must be
1491 * different as no care is taken not to clobber one with the other.
1492 * However, if they have the same number of bits per pixel, it is safe to
1493 * do an in-place conversion.
1495 * \param[out] dst pointer to where the converted data should
1498 * \param[in] dst_type the destination GL type of the converted
1499 * data (GL_BYTE, etc.)
1501 * \param[in] num_dst_channels the number of channels in the converted
1504 * \param[in] src pointer to the source data
1506 * \param[in] src_type the GL type of the source data (GL_BYTE,
1509 * \param[in] num_src_channels the number of channels in the source data
1510 * (the number of channels total, not just
1513 * \param[in] swizzle describes how to get the destination data
1514 * from the source data.
1516 * \param[in] normalized for integer types, this indicates whether
1517 * the data should be considered as integers
1518 * or as normalized integers;
1520 * \param[in] count the number of pixels to convert
1523 _mesa_swizzle_and_convert(void *void_dst
, enum mesa_array_format_datatype dst_type
, int num_dst_channels
,
1524 const void *void_src
, enum mesa_array_format_datatype src_type
, int num_src_channels
,
1525 const uint8_t swizzle
[4], bool normalized
, int count
)
1527 if (swizzle_convert_try_memcpy(void_dst
, dst_type
, num_dst_channels
,
1528 void_src
, src_type
, num_src_channels
,
1529 swizzle
, normalized
, count
))
1533 case MESA_ARRAY_FORMAT_TYPE_FLOAT
:
1534 convert_float(void_dst
, num_dst_channels
, void_src
, src_type
,
1535 num_src_channels
, swizzle
, normalized
, count
);
1537 case MESA_ARRAY_FORMAT_TYPE_HALF
:
1538 convert_half_float(void_dst
, num_dst_channels
, void_src
, src_type
,
1539 num_src_channels
, swizzle
, normalized
, count
);
1541 case MESA_ARRAY_FORMAT_TYPE_UBYTE
:
1542 convert_ubyte(void_dst
, num_dst_channels
, void_src
, src_type
,
1543 num_src_channels
, swizzle
, normalized
, count
);
1545 case MESA_ARRAY_FORMAT_TYPE_BYTE
:
1546 convert_byte(void_dst
, num_dst_channels
, void_src
, src_type
,
1547 num_src_channels
, swizzle
, normalized
, count
);
1549 case MESA_ARRAY_FORMAT_TYPE_USHORT
:
1550 convert_ushort(void_dst
, num_dst_channels
, void_src
, src_type
,
1551 num_src_channels
, swizzle
, normalized
, count
);
1553 case MESA_ARRAY_FORMAT_TYPE_SHORT
:
1554 convert_short(void_dst
, num_dst_channels
, void_src
, src_type
,
1555 num_src_channels
, swizzle
, normalized
, count
);
1557 case MESA_ARRAY_FORMAT_TYPE_UINT
:
1558 convert_uint(void_dst
, num_dst_channels
, void_src
, src_type
,
1559 num_src_channels
, swizzle
, normalized
, count
);
1561 case MESA_ARRAY_FORMAT_TYPE_INT
:
1562 convert_int(void_dst
, num_dst_channels
, void_src
, src_type
,
1563 num_src_channels
, swizzle
, normalized
, count
);
1566 assert(!"Invalid channel type");