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