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