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