Merge remote-tracking branch 'mesa-public/master' into vulkan
[mesa.git] / src / mesa / main / format_utils.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2014 Intel Corporation All Rights Reserved.
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
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.
23 */
24
25 #include "format_utils.h"
26 #include "glformats.h"
27 #include "format_pack.h"
28 #include "format_unpack.h"
29
30 const mesa_array_format RGBA32_FLOAT =
31 MESA_ARRAY_FORMAT(4, 1, 1, 1, 4, 0, 1, 2, 3);
32
33 const mesa_array_format RGBA8_UBYTE =
34 MESA_ARRAY_FORMAT(1, 0, 0, 1, 4, 0, 1, 2, 3);
35
36 const mesa_array_format RGBA32_UINT =
37 MESA_ARRAY_FORMAT(4, 0, 0, 0, 4, 0, 1, 2, 3);
38
39 const mesa_array_format RGBA32_INT =
40 MESA_ARRAY_FORMAT(4, 1, 0, 0, 4, 0, 1, 2, 3);
41
42 static void
43 invert_swizzle(uint8_t dst[4], const uint8_t src[4])
44 {
45 int i, j;
46
47 dst[0] = MESA_FORMAT_SWIZZLE_NONE;
48 dst[1] = MESA_FORMAT_SWIZZLE_NONE;
49 dst[2] = MESA_FORMAT_SWIZZLE_NONE;
50 dst[3] = MESA_FORMAT_SWIZZLE_NONE;
51
52 for (i = 0; i < 4; ++i)
53 for (j = 0; j < 4; ++j)
54 if (src[j] == i && dst[i] == MESA_FORMAT_SWIZZLE_NONE)
55 dst[i] = j;
56 }
57
58 /* Takes a src to RGBA swizzle and applies a rebase swizzle to it. This
59 * is used when we need to rebase a format to match a different
60 * base internal format.
61 *
62 * The rebase swizzle can be NULL, which means that no rebase is necessary,
63 * in which case the src to RGBA swizzle is copied to the output without
64 * changes.
65 *
66 * The resulting rebased swizzle and well as the input swizzles are
67 * all 4-element swizzles, but the rebase swizzle can be NULL if no rebase
68 * is necessary.
69 */
70 static void
71 compute_rebased_rgba_component_mapping(uint8_t *src2rgba,
72 uint8_t *rebase_swizzle,
73 uint8_t *rebased_src2rgba)
74 {
75 int i;
76
77 if (rebase_swizzle) {
78 for (i = 0; i < 4; i++) {
79 if (rebase_swizzle[i] > MESA_FORMAT_SWIZZLE_W)
80 rebased_src2rgba[i] = rebase_swizzle[i];
81 else
82 rebased_src2rgba[i] = src2rgba[rebase_swizzle[i]];
83 }
84 } else {
85 /* No rebase needed, so src2rgba is all that we need */
86 memcpy(rebased_src2rgba, src2rgba, 4 * sizeof(uint8_t));
87 }
88 }
89
90 /* Computes the final swizzle transform to apply from src to dst in a
91 * conversion that might involve a rebase swizzle.
92 *
93 * This is used to compute the swizzle transform to apply in conversions
94 * between array formats where we have a src2rgba swizzle, a rgba2dst swizzle
95 * and possibly, a rebase swizzle.
96 *
97 * The final swizzle transform to apply (src2dst) when a rebase swizzle is
98 * involved is: src -> rgba -> base -> rgba -> dst
99 */
100 static void
101 compute_src2dst_component_mapping(uint8_t *src2rgba, uint8_t *rgba2dst,
102 uint8_t *rebase_swizzle, uint8_t *src2dst)
103 {
104 int i;
105
106 if (!rebase_swizzle) {
107 for (i = 0; i < 4; i++) {
108 if (rgba2dst[i] > MESA_FORMAT_SWIZZLE_W) {
109 src2dst[i] = rgba2dst[i];
110 } else {
111 src2dst[i] = src2rgba[rgba2dst[i]];
112 }
113 }
114 } else {
115 for (i = 0; i < 4; i++) {
116 if (rgba2dst[i] > MESA_FORMAT_SWIZZLE_W) {
117 src2dst[i] = rgba2dst[i];
118 } else if (rebase_swizzle[rgba2dst[i]] > MESA_FORMAT_SWIZZLE_W) {
119 src2dst[i] = rebase_swizzle[rgba2dst[i]];
120 } else {
121 src2dst[i] = src2rgba[rebase_swizzle[rgba2dst[i]]];
122 }
123 }
124 }
125 }
126
127 /**
128 * This function is used by clients of _mesa_format_convert to obtain
129 * the rebase swizzle to use in a format conversion based on the base
130 * format involved.
131 *
132 * \param baseFormat the base internal format involved in the conversion.
133 * \param map the rebase swizzle to consider
134 *
135 * This function computes 'map' as rgba -> baseformat -> rgba and returns true
136 * if the resulting swizzle transform is not the identity transform (thus, a
137 * rebase is needed). If the function returns false then a rebase swizzle
138 * is not necessary and the value of 'map' is undefined. In this situation
139 * clients of _mesa_format_convert should pass NULL in the 'rebase_swizzle'
140 * parameter.
141 */
142 bool
143 _mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat, uint8_t *map)
144 {
145 uint8_t rgba2base[6], base2rgba[6];
146 int i;
147
148 switch (baseFormat) {
149 case GL_ALPHA:
150 case GL_RED:
151 case GL_GREEN:
152 case GL_BLUE:
153 case GL_RG:
154 case GL_RGB:
155 case GL_BGR:
156 case GL_RGBA:
157 case GL_BGRA:
158 case GL_ABGR_EXT:
159 case GL_LUMINANCE:
160 case GL_INTENSITY:
161 case GL_LUMINANCE_ALPHA:
162 {
163 bool needRebase = false;
164 _mesa_compute_component_mapping(GL_RGBA, baseFormat, rgba2base);
165 _mesa_compute_component_mapping(baseFormat, GL_RGBA, base2rgba);
166 for (i = 0; i < 4; i++) {
167 if (base2rgba[i] > MESA_FORMAT_SWIZZLE_W) {
168 map[i] = base2rgba[i];
169 } else {
170 map[i] = rgba2base[base2rgba[i]];
171 }
172 if (map[i] != i)
173 needRebase = true;
174 }
175 return needRebase;
176 }
177 default:
178 unreachable("Unexpected base format");
179 }
180 }
181
182 /**
183 * This can be used to convert between most color formats.
184 *
185 * Limitations:
186 * - This function doesn't handle GL_COLOR_INDEX or YCBCR formats.
187 * - This function doesn't handle byte-swapping or transferOps, these should
188 * be handled by the caller.
189 *
190 * \param void_dst The address where converted color data will be stored.
191 * The caller must ensure that the buffer is large enough
192 * to hold the converted pixel data.
193 * \param dst_format The destination color format. It can be a mesa_format
194 * or a mesa_array_format represented as an uint32_t.
195 * \param dst_stride The stride of the destination format in bytes.
196 * \param void_src The address of the source color data to convert.
197 * \param src_format The source color format. It can be a mesa_format
198 * or a mesa_array_format represented as an uint32_t.
199 * \param src_stride The stride of the source format in bytes.
200 * \param width The width, in pixels, of the source image to convert.
201 * \param height The height, in pixels, of the source image to convert.
202 * \param rebase_swizzle A swizzle transform to apply during the conversion,
203 * typically used to match a different internal base
204 * format involved. NULL if no rebase transform is needed
205 * (i.e. the internal base format and the base format of
206 * the dst or the src -depending on whether we are doing
207 * an upload or a download respectively- are the same).
208 */
209 void
210 _mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride,
211 void *void_src, uint32_t src_format, size_t src_stride,
212 size_t width, size_t height, uint8_t *rebase_swizzle)
213 {
214 uint8_t *dst = (uint8_t *)void_dst;
215 uint8_t *src = (uint8_t *)void_src;
216 mesa_array_format src_array_format, dst_array_format;
217 bool src_format_is_mesa_array_format, dst_format_is_mesa_array_format;
218 uint8_t src2dst[4], src2rgba[4], rgba2dst[4], dst2rgba[4];
219 uint8_t rebased_src2rgba[4];
220 enum mesa_array_format_datatype src_type = 0, dst_type = 0, common_type;
221 bool normalized, dst_integer, src_integer, is_signed;
222 int src_num_channels = 0, dst_num_channels = 0;
223 uint8_t (*tmp_ubyte)[4];
224 float (*tmp_float)[4];
225 uint32_t (*tmp_uint)[4];
226 int bits;
227 size_t row;
228
229 if (_mesa_format_is_mesa_array_format(src_format)) {
230 src_format_is_mesa_array_format = true;
231 src_array_format = src_format;
232 } else {
233 assert(_mesa_is_format_color_format(src_format));
234 src_format_is_mesa_array_format = false;
235 src_array_format = _mesa_format_to_array_format(src_format);
236 }
237
238 if (_mesa_format_is_mesa_array_format(dst_format)) {
239 dst_format_is_mesa_array_format = true;
240 dst_array_format = dst_format;
241 } else {
242 assert(_mesa_is_format_color_format(dst_format));
243 dst_format_is_mesa_array_format = false;
244 dst_array_format = _mesa_format_to_array_format(dst_format);
245 }
246
247 /* First we see if we can implement the conversion with a direct pack
248 * or unpack.
249 *
250 * In this case we want to be careful when we need to apply a swizzle to
251 * match an internal base format, since in these cases a simple pack/unpack
252 * to the dst format from the src format may not match the requirements
253 * of the internal base format. For now we decide to be safe and
254 * avoid this path in these scenarios but in the future we may want to
255 * enable it for specific combinations that are known to work.
256 */
257 if (!rebase_swizzle) {
258 /* Handle the cases where we can directly unpack */
259 if (!src_format_is_mesa_array_format) {
260 if (dst_array_format == RGBA32_FLOAT) {
261 for (row = 0; row < height; ++row) {
262 _mesa_unpack_rgba_row(src_format, width,
263 src, (float (*)[4])dst);
264 src += src_stride;
265 dst += dst_stride;
266 }
267 return;
268 } else if (dst_array_format == RGBA8_UBYTE) {
269 assert(!_mesa_is_format_integer_color(src_format));
270 for (row = 0; row < height; ++row) {
271 _mesa_unpack_ubyte_rgba_row(src_format, width,
272 src, (uint8_t (*)[4])dst);
273 src += src_stride;
274 dst += dst_stride;
275 }
276 return;
277 } else if (dst_array_format == RGBA32_UINT &&
278 _mesa_is_format_unsigned(src_format)) {
279 assert(_mesa_is_format_integer_color(src_format));
280 for (row = 0; row < height; ++row) {
281 _mesa_unpack_uint_rgba_row(src_format, width,
282 src, (uint32_t (*)[4])dst);
283 src += src_stride;
284 dst += dst_stride;
285 }
286 return;
287 }
288 }
289
290 /* Handle the cases where we can directly pack */
291 if (!dst_format_is_mesa_array_format) {
292 if (src_array_format == RGBA32_FLOAT) {
293 for (row = 0; row < height; ++row) {
294 _mesa_pack_float_rgba_row(dst_format, width,
295 (const float (*)[4])src, dst);
296 src += src_stride;
297 dst += dst_stride;
298 }
299 return;
300 } else if (src_array_format == RGBA8_UBYTE) {
301 assert(!_mesa_is_format_integer_color(dst_format));
302 for (row = 0; row < height; ++row) {
303 _mesa_pack_ubyte_rgba_row(dst_format, width,
304 (const uint8_t (*)[4])src, dst);
305 src += src_stride;
306 dst += dst_stride;
307 }
308 return;
309 } else if (src_array_format == RGBA32_UINT &&
310 _mesa_is_format_unsigned(dst_format)) {
311 assert(_mesa_is_format_integer_color(dst_format));
312 for (row = 0; row < height; ++row) {
313 _mesa_pack_uint_rgba_row(dst_format, width,
314 (const uint32_t (*)[4])src, dst);
315 src += src_stride;
316 dst += dst_stride;
317 }
318 return;
319 }
320 }
321 }
322
323 /* Handle conversions between array formats */
324 normalized = false;
325 if (src_array_format) {
326 src_type = _mesa_array_format_get_datatype(src_array_format);
327
328 src_num_channels = _mesa_array_format_get_num_channels(src_array_format);
329
330 _mesa_array_format_get_swizzle(src_array_format, src2rgba);
331
332 normalized = _mesa_array_format_is_normalized(src_array_format);
333 }
334
335 if (dst_array_format) {
336 dst_type = _mesa_array_format_get_datatype(dst_array_format);
337
338 dst_num_channels = _mesa_array_format_get_num_channels(dst_array_format);
339
340 _mesa_array_format_get_swizzle(dst_array_format, dst2rgba);
341 invert_swizzle(rgba2dst, dst2rgba);
342
343 normalized |= _mesa_array_format_is_normalized(dst_array_format);
344 }
345
346 if (src_array_format && dst_array_format) {
347 assert(_mesa_array_format_is_normalized(src_array_format) ==
348 _mesa_array_format_is_normalized(dst_array_format));
349
350 compute_src2dst_component_mapping(src2rgba, rgba2dst, rebase_swizzle,
351 src2dst);
352
353 for (row = 0; row < height; ++row) {
354 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels,
355 src, src_type, src_num_channels,
356 src2dst, normalized, width);
357 src += src_stride;
358 dst += dst_stride;
359 }
360 return;
361 }
362
363 /* At this point, we're fresh out of fast-paths and we need to convert
364 * to float, uint32, or, if we're lucky, uint8.
365 */
366 dst_integer = false;
367 src_integer = false;
368
369 if (src_array_format) {
370 if (!_mesa_array_format_is_float(src_array_format) &&
371 !_mesa_array_format_is_normalized(src_array_format))
372 src_integer = true;
373 } else {
374 switch (_mesa_get_format_datatype(src_format)) {
375 case GL_UNSIGNED_INT:
376 case GL_INT:
377 src_integer = true;
378 break;
379 }
380 }
381
382 /* If the destination format is signed but the source is unsigned, then we
383 * don't loose any data by converting to a signed intermediate format above
384 * and beyond the precision that we loose in the conversion itself. If the
385 * destination is unsigned then, by using an unsigned intermediate format,
386 * we make the conversion function that converts from the source to the
387 * intermediate format take care of truncating at zero. The exception here
388 * is if the intermediate format is float, in which case the first
389 * conversion will leave it signed and the second conversion will truncate
390 * at zero.
391 */
392 is_signed = false;
393 if (dst_array_format) {
394 if (!_mesa_array_format_is_float(dst_array_format) &&
395 !_mesa_array_format_is_normalized(dst_array_format))
396 dst_integer = true;
397 is_signed = _mesa_array_format_is_signed(dst_array_format);
398 bits = 8 * _mesa_array_format_get_type_size(dst_array_format);
399 } else {
400 switch (_mesa_get_format_datatype(dst_format)) {
401 case GL_UNSIGNED_NORMALIZED:
402 is_signed = false;
403 break;
404 case GL_SIGNED_NORMALIZED:
405 is_signed = true;
406 break;
407 case GL_FLOAT:
408 is_signed = true;
409 break;
410 case GL_UNSIGNED_INT:
411 is_signed = false;
412 dst_integer = true;
413 break;
414 case GL_INT:
415 is_signed = true;
416 dst_integer = true;
417 break;
418 }
419 bits = _mesa_get_format_max_bits(dst_format);
420 }
421
422 assert(src_integer == dst_integer);
423
424 if (src_integer && dst_integer) {
425 tmp_uint = malloc(width * height * sizeof(*tmp_uint));
426
427 /* The [un]packing functions for unsigned datatypes treat the 32-bit
428 * integer array as signed for signed formats and as unsigned for
429 * unsigned formats. This is a bit of a problem if we ever convert from
430 * a signed to an unsigned format because the unsigned packing function
431 * doesn't know that the input is signed and will treat it as unsigned
432 * and not do the trunctation. The thing that saves us here is that all
433 * of the packed formats are unsigned, so we can just always use
434 * _mesa_swizzle_and_convert for signed formats, which is aware of the
435 * truncation problem.
436 */
437 common_type = is_signed ? MESA_ARRAY_FORMAT_TYPE_INT :
438 MESA_ARRAY_FORMAT_TYPE_UINT;
439 if (src_array_format) {
440 compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle,
441 rebased_src2rgba);
442 for (row = 0; row < height; ++row) {
443 _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4,
444 src, src_type, src_num_channels,
445 rebased_src2rgba, normalized, width);
446 src += src_stride;
447 }
448 } else {
449 for (row = 0; row < height; ++row) {
450 _mesa_unpack_uint_rgba_row(src_format, width,
451 src, tmp_uint + row * width);
452 if (rebase_swizzle)
453 _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4,
454 tmp_uint + row * width, common_type, 4,
455 rebase_swizzle, false, width);
456 src += src_stride;
457 }
458 }
459
460 /* At this point, we have already done the truncation if the source is
461 * signed but the destination is unsigned, so no need to force the
462 * _mesa_swizzle_and_convert path.
463 */
464 if (dst_format_is_mesa_array_format) {
465 for (row = 0; row < height; ++row) {
466 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels,
467 tmp_uint + row * width, common_type, 4,
468 rgba2dst, normalized, width);
469 dst += dst_stride;
470 }
471 } else {
472 for (row = 0; row < height; ++row) {
473 _mesa_pack_uint_rgba_row(dst_format, width,
474 (const uint32_t (*)[4])tmp_uint + row * width, dst);
475 dst += dst_stride;
476 }
477 }
478
479 free(tmp_uint);
480 } else if (is_signed || bits > 8) {
481 tmp_float = malloc(width * height * sizeof(*tmp_float));
482
483 if (src_format_is_mesa_array_format) {
484 compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle,
485 rebased_src2rgba);
486 for (row = 0; row < height; ++row) {
487 _mesa_swizzle_and_convert(tmp_float + row * width,
488 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4,
489 src, src_type, src_num_channels,
490 rebased_src2rgba, normalized, width);
491 src += src_stride;
492 }
493 } else {
494 for (row = 0; row < height; ++row) {
495 _mesa_unpack_rgba_row(src_format, width,
496 src, tmp_float + row * width);
497 if (rebase_swizzle)
498 _mesa_swizzle_and_convert(tmp_float + row * width,
499 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4,
500 tmp_float + row * width,
501 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4,
502 rebase_swizzle, normalized, width);
503 src += src_stride;
504 }
505 }
506
507 if (dst_format_is_mesa_array_format) {
508 for (row = 0; row < height; ++row) {
509 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels,
510 tmp_float + row * width,
511 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4,
512 rgba2dst, normalized, width);
513 dst += dst_stride;
514 }
515 } else {
516 for (row = 0; row < height; ++row) {
517 _mesa_pack_float_rgba_row(dst_format, width,
518 (const float (*)[4])tmp_float + row * width, dst);
519 dst += dst_stride;
520 }
521 }
522
523 free(tmp_float);
524 } else {
525 tmp_ubyte = malloc(width * height * sizeof(*tmp_ubyte));
526
527 if (src_format_is_mesa_array_format) {
528 compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle,
529 rebased_src2rgba);
530 for (row = 0; row < height; ++row) {
531 _mesa_swizzle_and_convert(tmp_ubyte + row * width,
532 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4,
533 src, src_type, src_num_channels,
534 rebased_src2rgba, normalized, width);
535 src += src_stride;
536 }
537 } else {
538 for (row = 0; row < height; ++row) {
539 _mesa_unpack_ubyte_rgba_row(src_format, width,
540 src, tmp_ubyte + row * width);
541 if (rebase_swizzle)
542 _mesa_swizzle_and_convert(tmp_ubyte + row * width,
543 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4,
544 tmp_ubyte + row * width,
545 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4,
546 rebase_swizzle, normalized, width);
547 src += src_stride;
548 }
549 }
550
551 if (dst_format_is_mesa_array_format) {
552 for (row = 0; row < height; ++row) {
553 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels,
554 tmp_ubyte + row * width,
555 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4,
556 rgba2dst, normalized, width);
557 dst += dst_stride;
558 }
559 } else {
560 for (row = 0; row < height; ++row) {
561 _mesa_pack_ubyte_rgba_row(dst_format, width,
562 (const uint8_t (*)[4])tmp_ubyte + row * width, dst);
563 dst += dst_stride;
564 }
565 }
566
567 free(tmp_ubyte);
568 }
569 }
570
571 static const uint8_t map_identity[7] = { 0, 1, 2, 3, 4, 5, 6 };
572 static const uint8_t map_3210[7] = { 3, 2, 1, 0, 4, 5, 6 };
573 static const uint8_t map_1032[7] = { 1, 0, 3, 2, 4, 5, 6 };
574
575 /**
576 * Describes a format as an array format, if possible
577 *
578 * A helper function for figuring out if a (possibly packed) format is
579 * actually an array format and, if so, what the array parameters are.
580 *
581 * \param[in] format the mesa format
582 * \param[out] type the GL type of the array (GL_BYTE, etc.)
583 * \param[out] num_components the number of components in the array
584 * \param[out] swizzle a swizzle describing how to get from the
585 * given format to RGBA
586 * \param[out] normalized for integer formats, this represents whether
587 * the format is a normalized integer or a
588 * regular integer
589 * \return true if this format is an array format, false otherwise
590 */
591 bool
592 _mesa_format_to_array(mesa_format format, GLenum *type, int *num_components,
593 uint8_t swizzle[4], bool *normalized)
594 {
595 int i;
596 GLuint format_components;
597 uint8_t packed_swizzle[4];
598 const uint8_t *endian;
599
600 if (_mesa_is_format_compressed(format))
601 return false;
602
603 *normalized = !_mesa_is_format_integer(format);
604
605 _mesa_uncompressed_format_to_type_and_comps(format, type, &format_components);
606
607 switch (_mesa_get_format_layout(format)) {
608 case MESA_FORMAT_LAYOUT_ARRAY:
609 *num_components = format_components;
610 _mesa_get_format_swizzle(format, swizzle);
611 return true;
612 case MESA_FORMAT_LAYOUT_PACKED:
613 switch (*type) {
614 case GL_UNSIGNED_BYTE:
615 case GL_BYTE:
616 if (_mesa_get_format_max_bits(format) != 8)
617 return false;
618 *num_components = _mesa_get_format_bytes(format);
619 switch (*num_components) {
620 case 1:
621 endian = map_identity;
622 break;
623 case 2:
624 endian = _mesa_little_endian() ? map_identity : map_1032;
625 break;
626 case 4:
627 endian = _mesa_little_endian() ? map_identity : map_3210;
628 break;
629 default:
630 endian = map_identity;
631 assert(!"Invalid number of components");
632 }
633 break;
634 case GL_UNSIGNED_SHORT:
635 case GL_SHORT:
636 case GL_HALF_FLOAT:
637 if (_mesa_get_format_max_bits(format) != 16)
638 return false;
639 *num_components = _mesa_get_format_bytes(format) / 2;
640 switch (*num_components) {
641 case 1:
642 endian = map_identity;
643 break;
644 case 2:
645 endian = _mesa_little_endian() ? map_identity : map_1032;
646 break;
647 default:
648 endian = map_identity;
649 assert(!"Invalid number of components");
650 }
651 break;
652 case GL_UNSIGNED_INT:
653 case GL_INT:
654 case GL_FLOAT:
655 /* This isn't packed. At least not really. */
656 assert(format_components == 1);
657 if (_mesa_get_format_max_bits(format) != 32)
658 return false;
659 *num_components = format_components;
660 endian = map_identity;
661 break;
662 default:
663 return false;
664 }
665
666 _mesa_get_format_swizzle(format, packed_swizzle);
667
668 for (i = 0; i < 4; ++i)
669 swizzle[i] = endian[packed_swizzle[i]];
670
671 return true;
672 case MESA_FORMAT_LAYOUT_OTHER:
673 default:
674 return false;
675 }
676 }
677
678 /**
679 * Attempts to perform the given swizzle-and-convert operation with memcpy
680 *
681 * This function determines if the given swizzle-and-convert operation can
682 * be done with a simple memcpy and, if so, does the memcpy. If not, it
683 * returns false and we fall back to the standard version below.
684 *
685 * The arguments are exactly the same as for _mesa_swizzle_and_convert
686 *
687 * \return true if it successfully performed the swizzle-and-convert
688 * operation with memcpy, false otherwise
689 */
690 static bool
691 swizzle_convert_try_memcpy(void *dst,
692 enum mesa_array_format_datatype dst_type,
693 int num_dst_channels,
694 const void *src,
695 enum mesa_array_format_datatype src_type,
696 int num_src_channels,
697 const uint8_t swizzle[4], bool normalized, int count)
698 {
699 int i;
700
701 if (src_type != dst_type)
702 return false;
703 if (num_src_channels != num_dst_channels)
704 return false;
705
706 for (i = 0; i < num_dst_channels; ++i)
707 if (swizzle[i] != i && swizzle[i] != MESA_FORMAT_SWIZZLE_NONE)
708 return false;
709
710 memcpy(dst, src, count * num_src_channels *
711 _mesa_array_format_datatype_get_size(src_type));
712
713 return true;
714 }
715
716 /**
717 * Represents a single instance of the standard swizzle-and-convert loop
718 *
719 * Any swizzle-and-convert operation simply loops through the pixels and
720 * performs the transformation operation one pixel at a time. This macro
721 * embodies one instance of the conversion loop. This way we can do all
722 * control flow outside of the loop and allow the compiler to unroll
723 * everything inside the loop.
724 *
725 * Note: This loop is carefully crafted for performance. Be careful when
726 * changing it and run some benchmarks to ensure no performance regressions
727 * if you do.
728 *
729 * \param DST_TYPE the C datatype of the destination
730 * \param DST_CHANS the number of destination channels
731 * \param SRC_TYPE the C datatype of the source
732 * \param SRC_CHANS the number of source channels
733 * \param CONV an expression for converting from the source data,
734 * storred in the variable "src", to the destination
735 * format
736 */
737 #define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \
738 do { \
739 int s, j; \
740 for (s = 0; s < count; ++s) { \
741 for (j = 0; j < SRC_CHANS; ++j) { \
742 SRC_TYPE src = typed_src[j]; \
743 tmp[j] = CONV; \
744 } \
745 \
746 typed_dst[0] = tmp[swizzle_x]; \
747 if (DST_CHANS > 1) { \
748 typed_dst[1] = tmp[swizzle_y]; \
749 if (DST_CHANS > 2) { \
750 typed_dst[2] = tmp[swizzle_z]; \
751 if (DST_CHANS > 3) { \
752 typed_dst[3] = tmp[swizzle_w]; \
753 } \
754 } \
755 } \
756 typed_src += SRC_CHANS; \
757 typed_dst += DST_CHANS; \
758 } \
759 } while (0)
760
761 /**
762 * Represents a single swizzle-and-convert operation
763 *
764 * This macro represents everything done in a single swizzle-and-convert
765 * operation. The actual work is done by the SWIZZLE_CONVERT_LOOP macro.
766 * This macro acts as a wrapper that uses a nested switch to ensure that
767 * all looping parameters get unrolled.
768 *
769 * This macro makes assumptions about variables etc. in the calling
770 * function. Changes to _mesa_swizzle_and_convert may require changes to
771 * this macro.
772 *
773 * \param DST_TYPE the C datatype of the destination
774 * \param SRC_TYPE the C datatype of the source
775 * \param CONV an expression for converting from the source data,
776 * storred in the variable "src", to the destination
777 * format
778 */
779 #define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV) \
780 do { \
781 const uint8_t swizzle_x = swizzle[0]; \
782 const uint8_t swizzle_y = swizzle[1]; \
783 const uint8_t swizzle_z = swizzle[2]; \
784 const uint8_t swizzle_w = swizzle[3]; \
785 const SRC_TYPE *typed_src = void_src; \
786 DST_TYPE *typed_dst = void_dst; \
787 DST_TYPE tmp[7]; \
788 tmp[4] = 0; \
789 tmp[5] = one; \
790 switch (num_dst_channels) { \
791 case 1: \
792 switch (num_src_channels) { \
793 case 1: \
794 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV); \
795 break; \
796 case 2: \
797 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV); \
798 break; \
799 case 3: \
800 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV); \
801 break; \
802 case 4: \
803 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV); \
804 break; \
805 } \
806 break; \
807 case 2: \
808 switch (num_src_channels) { \
809 case 1: \
810 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV); \
811 break; \
812 case 2: \
813 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV); \
814 break; \
815 case 3: \
816 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV); \
817 break; \
818 case 4: \
819 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV); \
820 break; \
821 } \
822 break; \
823 case 3: \
824 switch (num_src_channels) { \
825 case 1: \
826 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV); \
827 break; \
828 case 2: \
829 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV); \
830 break; \
831 case 3: \
832 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV); \
833 break; \
834 case 4: \
835 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV); \
836 break; \
837 } \
838 break; \
839 case 4: \
840 switch (num_src_channels) { \
841 case 1: \
842 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV); \
843 break; \
844 case 2: \
845 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV); \
846 break; \
847 case 3: \
848 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV); \
849 break; \
850 case 4: \
851 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV); \
852 break; \
853 } \
854 break; \
855 } \
856 } while (0)
857
858
859 static void
860 convert_float(void *void_dst, int num_dst_channels,
861 const void *void_src, GLenum src_type, int num_src_channels,
862 const uint8_t swizzle[4], bool normalized, int count)
863 {
864 const float one = 1.0f;
865
866 switch (src_type) {
867 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
868 SWIZZLE_CONVERT(float, float, src);
869 break;
870 case MESA_ARRAY_FORMAT_TYPE_HALF:
871 SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src));
872 break;
873 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
874 if (normalized) {
875 SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src, 8));
876 } else {
877 SWIZZLE_CONVERT(float, uint8_t, src);
878 }
879 break;
880 case MESA_ARRAY_FORMAT_TYPE_BYTE:
881 if (normalized) {
882 SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src, 8));
883 } else {
884 SWIZZLE_CONVERT(float, int8_t, src);
885 }
886 break;
887 case MESA_ARRAY_FORMAT_TYPE_USHORT:
888 if (normalized) {
889 SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src, 16));
890 } else {
891 SWIZZLE_CONVERT(float, uint16_t, src);
892 }
893 break;
894 case MESA_ARRAY_FORMAT_TYPE_SHORT:
895 if (normalized) {
896 SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src, 16));
897 } else {
898 SWIZZLE_CONVERT(float, int16_t, src);
899 }
900 break;
901 case MESA_ARRAY_FORMAT_TYPE_UINT:
902 if (normalized) {
903 SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src, 32));
904 } else {
905 SWIZZLE_CONVERT(float, uint32_t, src);
906 }
907 break;
908 case MESA_ARRAY_FORMAT_TYPE_INT:
909 if (normalized) {
910 SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src, 32));
911 } else {
912 SWIZZLE_CONVERT(float, int32_t, src);
913 }
914 break;
915 default:
916 assert(!"Invalid channel type combination");
917 }
918 }
919
920
921 static void
922 convert_half_float(void *void_dst, int num_dst_channels,
923 const void *void_src, GLenum src_type, int num_src_channels,
924 const uint8_t swizzle[4], bool normalized, int count)
925 {
926 const uint16_t one = _mesa_float_to_half(1.0f);
927
928 switch (src_type) {
929 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
930 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src));
931 break;
932 case MESA_ARRAY_FORMAT_TYPE_HALF:
933 SWIZZLE_CONVERT(uint16_t, uint16_t, src);
934 break;
935 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
936 if (normalized) {
937 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src, 8));
938 } else {
939 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src));
940 }
941 break;
942 case MESA_ARRAY_FORMAT_TYPE_BYTE:
943 if (normalized) {
944 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src, 8));
945 } else {
946 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src));
947 }
948 break;
949 case MESA_ARRAY_FORMAT_TYPE_USHORT:
950 if (normalized) {
951 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src, 16));
952 } else {
953 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src));
954 }
955 break;
956 case MESA_ARRAY_FORMAT_TYPE_SHORT:
957 if (normalized) {
958 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src, 16));
959 } else {
960 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src));
961 }
962 break;
963 case MESA_ARRAY_FORMAT_TYPE_UINT:
964 if (normalized) {
965 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src, 32));
966 } else {
967 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src));
968 }
969 break;
970 case MESA_ARRAY_FORMAT_TYPE_INT:
971 if (normalized) {
972 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src, 32));
973 } else {
974 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src));
975 }
976 break;
977 default:
978 assert(!"Invalid channel type combination");
979 }
980 }
981
982 static void
983 convert_ubyte(void *void_dst, int num_dst_channels,
984 const void *void_src, GLenum src_type, int num_src_channels,
985 const uint8_t swizzle[4], bool normalized, int count)
986 {
987 const uint8_t one = normalized ? UINT8_MAX : 1;
988
989 switch (src_type) {
990 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
991 if (normalized) {
992 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src, 8));
993 } else {
994 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src, 8));
995 }
996 break;
997 case MESA_ARRAY_FORMAT_TYPE_HALF:
998 if (normalized) {
999 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src, 8));
1000 } else {
1001 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src, 8));
1002 }
1003 break;
1004 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1005 SWIZZLE_CONVERT(uint8_t, uint8_t, src);
1006 break;
1007 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1008 if (normalized) {
1009 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src, 8, 8));
1010 } else {
1011 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src, 8));
1012 }
1013 break;
1014 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1015 if (normalized) {
1016 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 8));
1017 } else {
1018 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src, 8));
1019 }
1020 break;
1021 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1022 if (normalized) {
1023 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src, 16, 8));
1024 } else {
1025 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src, 8));
1026 }
1027 break;
1028 case MESA_ARRAY_FORMAT_TYPE_UINT:
1029 if (normalized) {
1030 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 8));
1031 } else {
1032 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src, 8));
1033 }
1034 break;
1035 case MESA_ARRAY_FORMAT_TYPE_INT:
1036 if (normalized) {
1037 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src, 32, 8));
1038 } else {
1039 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src, 8));
1040 }
1041 break;
1042 default:
1043 assert(!"Invalid channel type combination");
1044 }
1045 }
1046
1047
1048 static void
1049 convert_byte(void *void_dst, int num_dst_channels,
1050 const void *void_src, GLenum src_type, int num_src_channels,
1051 const uint8_t swizzle[4], bool normalized, int count)
1052 {
1053 const int8_t one = normalized ? INT8_MAX : 1;
1054
1055 switch (src_type) {
1056 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1057 if (normalized) {
1058 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src, 8));
1059 } else {
1060 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src, 8));
1061 }
1062 break;
1063 case MESA_ARRAY_FORMAT_TYPE_HALF:
1064 if (normalized) {
1065 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src, 8));
1066 } else {
1067 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src, 8));
1068 }
1069 break;
1070 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1071 if (normalized) {
1072 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 8));
1073 } else {
1074 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src, 8));
1075 }
1076 break;
1077 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1078 SWIZZLE_CONVERT(int8_t, int8_t, src);
1079 break;
1080 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1081 if (normalized) {
1082 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 8));
1083 } else {
1084 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src, 8));
1085 }
1086 break;
1087 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1088 if (normalized) {
1089 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src, 16, 8));
1090 } else {
1091 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src, 8));
1092 }
1093 break;
1094 case MESA_ARRAY_FORMAT_TYPE_UINT:
1095 if (normalized) {
1096 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 8));
1097 } else {
1098 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src, 8));
1099 }
1100 break;
1101 case MESA_ARRAY_FORMAT_TYPE_INT:
1102 if (normalized) {
1103 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src, 32, 8));
1104 } else {
1105 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src, 8));
1106 }
1107 break;
1108 default:
1109 assert(!"Invalid channel type combination");
1110 }
1111 }
1112
1113
1114 static void
1115 convert_ushort(void *void_dst, int num_dst_channels,
1116 const void *void_src, GLenum src_type, int num_src_channels,
1117 const uint8_t swizzle[4], bool normalized, int count)
1118 {
1119 const uint16_t one = normalized ? UINT16_MAX : 1;
1120
1121 switch (src_type) {
1122 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1123 if (normalized) {
1124 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src, 16));
1125 } else {
1126 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src, 16));
1127 }
1128 break;
1129 case MESA_ARRAY_FORMAT_TYPE_HALF:
1130 if (normalized) {
1131 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src, 16));
1132 } else {
1133 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src, 16));
1134 }
1135 break;
1136 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1137 if (normalized) {
1138 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 16));
1139 } else {
1140 SWIZZLE_CONVERT(uint16_t, uint8_t, src);
1141 }
1142 break;
1143 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1144 if (normalized) {
1145 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src, 8, 16));
1146 } else {
1147 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src, 16));
1148 }
1149 break;
1150 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1151 SWIZZLE_CONVERT(uint16_t, uint16_t, src);
1152 break;
1153 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1154 if (normalized) {
1155 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src, 16, 16));
1156 } else {
1157 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src, 16));
1158 }
1159 break;
1160 case MESA_ARRAY_FORMAT_TYPE_UINT:
1161 if (normalized) {
1162 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 16));
1163 } else {
1164 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src, 16));
1165 }
1166 break;
1167 case MESA_ARRAY_FORMAT_TYPE_INT:
1168 if (normalized) {
1169 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src, 32, 16));
1170 } else {
1171 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src, 16));
1172 }
1173 break;
1174 default:
1175 assert(!"Invalid channel type combination");
1176 }
1177 }
1178
1179
1180 static void
1181 convert_short(void *void_dst, int num_dst_channels,
1182 const void *void_src, GLenum src_type, int num_src_channels,
1183 const uint8_t swizzle[4], bool normalized, int count)
1184 {
1185 const int16_t one = normalized ? INT16_MAX : 1;
1186
1187 switch (src_type) {
1188 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1189 if (normalized) {
1190 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src, 16));
1191 } else {
1192 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src, 16));
1193 }
1194 break;
1195 case MESA_ARRAY_FORMAT_TYPE_HALF:
1196 if (normalized) {
1197 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src, 16));
1198 } else {
1199 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src, 16));
1200 }
1201 break;
1202 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1203 if (normalized) {
1204 SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 16));
1205 } else {
1206 SWIZZLE_CONVERT(int16_t, uint8_t, src);
1207 }
1208 break;
1209 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1210 if (normalized) {
1211 SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src, 8, 16));
1212 } else {
1213 SWIZZLE_CONVERT(int16_t, int8_t, src);
1214 }
1215 break;
1216 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1217 if (normalized) {
1218 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 16));
1219 } else {
1220 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src, 16));
1221 }
1222 break;
1223 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1224 SWIZZLE_CONVERT(int16_t, int16_t, src);
1225 break;
1226 case MESA_ARRAY_FORMAT_TYPE_UINT:
1227 if (normalized) {
1228 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 16));
1229 } else {
1230 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src, 16));
1231 }
1232 break;
1233 case MESA_ARRAY_FORMAT_TYPE_INT:
1234 if (normalized) {
1235 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src, 32, 16));
1236 } else {
1237 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src, 16));
1238 }
1239 break;
1240 default:
1241 assert(!"Invalid channel type combination");
1242 }
1243 }
1244
1245 static void
1246 convert_uint(void *void_dst, int num_dst_channels,
1247 const void *void_src, GLenum src_type, int num_src_channels,
1248 const uint8_t swizzle[4], bool normalized, int count)
1249 {
1250 const uint32_t one = normalized ? UINT32_MAX : 1;
1251
1252 switch (src_type) {
1253 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1254 if (normalized) {
1255 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src, 32));
1256 } else {
1257 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src, 32));
1258 }
1259 break;
1260 case MESA_ARRAY_FORMAT_TYPE_HALF:
1261 if (normalized) {
1262 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src, 32));
1263 } else {
1264 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src, 32));
1265 }
1266 break;
1267 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1268 if (normalized) {
1269 SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 32));
1270 } else {
1271 SWIZZLE_CONVERT(uint32_t, uint8_t, src);
1272 }
1273 break;
1274 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1275 if (normalized) {
1276 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src, 8, 32));
1277 } else {
1278 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src, 32));
1279 }
1280 break;
1281 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1282 if (normalized) {
1283 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 32));
1284 } else {
1285 SWIZZLE_CONVERT(uint32_t, uint16_t, src);
1286 }
1287 break;
1288 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1289 if (normalized) {
1290 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src, 16, 32));
1291 } else {
1292 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src, 32));
1293 }
1294 break;
1295 case MESA_ARRAY_FORMAT_TYPE_UINT:
1296 SWIZZLE_CONVERT(uint32_t, uint32_t, src);
1297 break;
1298 case MESA_ARRAY_FORMAT_TYPE_INT:
1299 if (normalized) {
1300 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src, 32, 32));
1301 } else {
1302 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src, 32));
1303 }
1304 break;
1305 default:
1306 assert(!"Invalid channel type combination");
1307 }
1308 }
1309
1310
1311 static void
1312 convert_int(void *void_dst, int num_dst_channels,
1313 const void *void_src, GLenum src_type, int num_src_channels,
1314 const uint8_t swizzle[4], bool normalized, int count)
1315 {
1316 const int32_t one = normalized ? INT32_MAX : 1;
1317
1318 switch (src_type) {
1319 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1320 if (normalized) {
1321 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src, 32));
1322 } else {
1323 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src, 32));
1324 }
1325 break;
1326 case MESA_ARRAY_FORMAT_TYPE_HALF:
1327 if (normalized) {
1328 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src, 32));
1329 } else {
1330 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src, 32));
1331 }
1332 break;
1333 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1334 if (normalized) {
1335 SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 32));
1336 } else {
1337 SWIZZLE_CONVERT(int32_t, uint8_t, src);
1338 }
1339 break;
1340 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1341 if (normalized) {
1342 SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src, 8, 32));
1343 } else {
1344 SWIZZLE_CONVERT(int32_t, int8_t, src);
1345 }
1346 break;
1347 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1348 if (normalized) {
1349 SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 32));
1350 } else {
1351 SWIZZLE_CONVERT(int32_t, uint16_t, src);
1352 }
1353 break;
1354 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1355 if (normalized) {
1356 SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src, 16, 32));
1357 } else {
1358 SWIZZLE_CONVERT(int32_t, int16_t, src);
1359 }
1360 break;
1361 case MESA_ARRAY_FORMAT_TYPE_UINT:
1362 if (normalized) {
1363 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 32));
1364 } else {
1365 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src, 32));
1366 }
1367 break;
1368 case MESA_ARRAY_FORMAT_TYPE_INT:
1369 SWIZZLE_CONVERT(int32_t, int32_t, src);
1370 break;
1371 default:
1372 assert(!"Invalid channel type combination");
1373 }
1374 }
1375
1376
1377 /**
1378 * Convert between array-based color formats.
1379 *
1380 * Most format conversion operations required by GL can be performed by
1381 * converting one channel at a time, shuffling the channels around, and
1382 * optionally filling missing channels with zeros and ones. This function
1383 * does just that in a general, yet efficient, way.
1384 *
1385 * The swizzle parameter is an array of 4 numbers (see
1386 * _mesa_get_format_swizzle) that describes where each channel in the
1387 * destination should come from in the source. If swizzle[i] < 4 then it
1388 * means that dst[i] = CONVERT(src[swizzle[i]]). If swizzle[i] is
1389 * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding
1390 * dst[i] will be filled with the appropreate representation of zero or one
1391 * respectively.
1392 *
1393 * Under most circumstances, the source and destination images must be
1394 * different as no care is taken not to clobber one with the other.
1395 * However, if they have the same number of bits per pixel, it is safe to
1396 * do an in-place conversion.
1397 *
1398 * \param[out] dst pointer to where the converted data should
1399 * be stored
1400 *
1401 * \param[in] dst_type the destination GL type of the converted
1402 * data (GL_BYTE, etc.)
1403 *
1404 * \param[in] num_dst_channels the number of channels in the converted
1405 * data
1406 *
1407 * \param[in] src pointer to the source data
1408 *
1409 * \param[in] src_type the GL type of the source data (GL_BYTE,
1410 * etc.)
1411 *
1412 * \param[in] num_src_channels the number of channels in the source data
1413 * (the number of channels total, not just
1414 * the number used)
1415 *
1416 * \param[in] swizzle describes how to get the destination data
1417 * from the source data.
1418 *
1419 * \param[in] normalized for integer types, this indicates whether
1420 * the data should be considered as integers
1421 * or as normalized integers;
1422 *
1423 * \param[in] count the number of pixels to convert
1424 */
1425 void
1426 _mesa_swizzle_and_convert(void *void_dst, enum mesa_array_format_datatype dst_type, int num_dst_channels,
1427 const void *void_src, enum mesa_array_format_datatype src_type, int num_src_channels,
1428 const uint8_t swizzle[4], bool normalized, int count)
1429 {
1430 if (swizzle_convert_try_memcpy(void_dst, dst_type, num_dst_channels,
1431 void_src, src_type, num_src_channels,
1432 swizzle, normalized, count))
1433 return;
1434
1435 switch (dst_type) {
1436 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1437 convert_float(void_dst, num_dst_channels, void_src, src_type,
1438 num_src_channels, swizzle, normalized, count);
1439 break;
1440 case MESA_ARRAY_FORMAT_TYPE_HALF:
1441 convert_half_float(void_dst, num_dst_channels, void_src, src_type,
1442 num_src_channels, swizzle, normalized, count);
1443 break;
1444 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1445 convert_ubyte(void_dst, num_dst_channels, void_src, src_type,
1446 num_src_channels, swizzle, normalized, count);
1447 break;
1448 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1449 convert_byte(void_dst, num_dst_channels, void_src, src_type,
1450 num_src_channels, swizzle, normalized, count);
1451 break;
1452 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1453 convert_ushort(void_dst, num_dst_channels, void_src, src_type,
1454 num_src_channels, swizzle, normalized, count);
1455 break;
1456 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1457 convert_short(void_dst, num_dst_channels, void_src, src_type,
1458 num_src_channels, swizzle, normalized, count);
1459 break;
1460 case MESA_ARRAY_FORMAT_TYPE_UINT:
1461 convert_uint(void_dst, num_dst_channels, void_src, src_type,
1462 num_src_channels, swizzle, normalized, count);
1463 break;
1464 case MESA_ARRAY_FORMAT_TYPE_INT:
1465 convert_int(void_dst, num_dst_channels, void_src, src_type,
1466 num_src_channels, swizzle, normalized, count);
1467 break;
1468 default:
1469 assert(!"Invalid channel type");
1470 }
1471 }