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 } else if (dst_array_format == BGRA8_UBYTE &&
360 src_format == MESA_FORMAT_R8G8B8A8_UNORM) {
361 convert_ubyte_rgba_to_bgra(width, height, src, src_stride,
362 dst, dst_stride);
363 return;
364 } else if (dst_array_format == RGBA32_UINT &&
365 _mesa_is_format_unsigned(src_format)) {
366 assert(_mesa_is_format_integer_color(src_format));
367 for (row = 0; row < height; ++row) {
368 _mesa_unpack_uint_rgba_row(src_format, width,
369 src, (uint32_t (*)[4])dst);
370 src += src_stride;
371 dst += dst_stride;
372 }
373 return;
374 }
375 }
376
377 /* Handle the cases where we can directly pack */
378 if (!dst_format_is_mesa_array_format) {
379 if (src_array_format == RGBA32_FLOAT) {
380 for (row = 0; row < height; ++row) {
381 _mesa_pack_float_rgba_row(dst_format, width,
382 (const float (*)[4])src, dst);
383 src += src_stride;
384 dst += dst_stride;
385 }
386 return;
387 } else if (src_array_format == RGBA8_UBYTE) {
388 assert(!_mesa_is_format_integer_color(dst_format));
389
390 if (dst_format == MESA_FORMAT_B8G8R8A8_UNORM) {
391 convert_ubyte_rgba_to_bgra(width, height, src, src_stride,
392 dst, dst_stride);
393 }
394 else {
395 for (row = 0; row < height; ++row) {
396 _mesa_pack_ubyte_rgba_row(dst_format, width, src, dst);
397 src += src_stride;
398 dst += dst_stride;
399 }
400 }
401 return;
402 } else if (src_array_format == RGBA32_UINT &&
403 _mesa_is_format_unsigned(dst_format)) {
404 assert(_mesa_is_format_integer_color(dst_format));
405 for (row = 0; row < height; ++row) {
406 _mesa_pack_uint_rgba_row(dst_format, width,
407 (const uint32_t (*)[4])src, dst);
408 src += src_stride;
409 dst += dst_stride;
410 }
411 return;
412 }
413 }
414 }
415
416 /* Handle conversions between array formats */
417 normalized = false;
418 if (src_array_format) {
419 src_type = _mesa_array_format_get_datatype(src_array_format);
420
421 src_num_channels = _mesa_array_format_get_num_channels(src_array_format);
422
423 _mesa_array_format_get_swizzle(src_array_format, src2rgba);
424
425 normalized = _mesa_array_format_is_normalized(src_array_format);
426 }
427
428 if (dst_array_format) {
429 dst_type = _mesa_array_format_get_datatype(dst_array_format);
430
431 dst_num_channels = _mesa_array_format_get_num_channels(dst_array_format);
432
433 _mesa_array_format_get_swizzle(dst_array_format, dst2rgba);
434 invert_swizzle(rgba2dst, dst2rgba);
435
436 normalized |= _mesa_array_format_is_normalized(dst_array_format);
437 }
438
439 if (src_array_format && dst_array_format) {
440 assert(_mesa_array_format_is_normalized(src_array_format) ==
441 _mesa_array_format_is_normalized(dst_array_format));
442
443 compute_src2dst_component_mapping(src2rgba, rgba2dst, rebase_swizzle,
444 src2dst);
445
446 for (row = 0; row < height; ++row) {
447 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels,
448 src, src_type, src_num_channels,
449 src2dst, normalized, width);
450 src += src_stride;
451 dst += dst_stride;
452 }
453 return;
454 }
455
456 /* At this point, we're fresh out of fast-paths and we need to convert
457 * to float, uint32, or, if we're lucky, uint8.
458 */
459 dst_integer = false;
460 src_integer = false;
461
462 if (src_array_format) {
463 if (!_mesa_array_format_is_float(src_array_format) &&
464 !_mesa_array_format_is_normalized(src_array_format))
465 src_integer = true;
466 } else {
467 switch (_mesa_get_format_datatype(src_format)) {
468 case GL_UNSIGNED_INT:
469 case GL_INT:
470 src_integer = true;
471 break;
472 }
473 }
474
475 /* If the destination format is signed but the source is unsigned, then we
476 * don't loose any data by converting to a signed intermediate format above
477 * and beyond the precision that we loose in the conversion itself. If the
478 * destination is unsigned then, by using an unsigned intermediate format,
479 * we make the conversion function that converts from the source to the
480 * intermediate format take care of truncating at zero. The exception here
481 * is if the intermediate format is float, in which case the first
482 * conversion will leave it signed and the second conversion will truncate
483 * at zero.
484 */
485 is_signed = false;
486 if (dst_array_format) {
487 if (!_mesa_array_format_is_float(dst_array_format) &&
488 !_mesa_array_format_is_normalized(dst_array_format))
489 dst_integer = true;
490 is_signed = _mesa_array_format_is_signed(dst_array_format);
491 bits = 8 * _mesa_array_format_get_type_size(dst_array_format);
492 } else {
493 switch (_mesa_get_format_datatype(dst_format)) {
494 case GL_UNSIGNED_NORMALIZED:
495 is_signed = false;
496 break;
497 case GL_SIGNED_NORMALIZED:
498 is_signed = true;
499 break;
500 case GL_FLOAT:
501 is_signed = true;
502 break;
503 case GL_UNSIGNED_INT:
504 is_signed = false;
505 dst_integer = true;
506 break;
507 case GL_INT:
508 is_signed = true;
509 dst_integer = true;
510 break;
511 }
512 bits = _mesa_get_format_max_bits(dst_format);
513 }
514
515 assert(src_integer == dst_integer);
516
517 if (src_integer && dst_integer) {
518 tmp_uint = malloc(width * height * sizeof(*tmp_uint));
519
520 /* The [un]packing functions for unsigned datatypes treat the 32-bit
521 * integer array as signed for signed formats and as unsigned for
522 * unsigned formats. This is a bit of a problem if we ever convert from
523 * a signed to an unsigned format because the unsigned packing function
524 * doesn't know that the input is signed and will treat it as unsigned
525 * and not do the trunctation. The thing that saves us here is that all
526 * of the packed formats are unsigned, so we can just always use
527 * _mesa_swizzle_and_convert for signed formats, which is aware of the
528 * truncation problem.
529 */
530 common_type = is_signed ? MESA_ARRAY_FORMAT_TYPE_INT :
531 MESA_ARRAY_FORMAT_TYPE_UINT;
532 if (src_array_format) {
533 compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle,
534 rebased_src2rgba);
535 for (row = 0; row < height; ++row) {
536 _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4,
537 src, src_type, src_num_channels,
538 rebased_src2rgba, normalized, width);
539 src += src_stride;
540 }
541 } else {
542 for (row = 0; row < height; ++row) {
543 _mesa_unpack_uint_rgba_row(src_format, width,
544 src, tmp_uint + row * width);
545 if (rebase_swizzle)
546 _mesa_swizzle_and_convert(tmp_uint + row * width, common_type, 4,
547 tmp_uint + row * width, common_type, 4,
548 rebase_swizzle, false, width);
549 src += src_stride;
550 }
551 }
552
553 /* At this point, we have already done the truncation if the source is
554 * signed but the destination is unsigned, so no need to force the
555 * _mesa_swizzle_and_convert path.
556 */
557 if (dst_format_is_mesa_array_format) {
558 for (row = 0; row < height; ++row) {
559 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels,
560 tmp_uint + row * width, common_type, 4,
561 rgba2dst, normalized, width);
562 dst += dst_stride;
563 }
564 } else {
565 for (row = 0; row < height; ++row) {
566 _mesa_pack_uint_rgba_row(dst_format, width,
567 (const uint32_t (*)[4])tmp_uint + row * width, dst);
568 dst += dst_stride;
569 }
570 }
571
572 free(tmp_uint);
573 } else if (is_signed || bits > 8) {
574 tmp_float = malloc(width * height * sizeof(*tmp_float));
575
576 if (src_format_is_mesa_array_format) {
577 compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle,
578 rebased_src2rgba);
579 for (row = 0; row < height; ++row) {
580 _mesa_swizzle_and_convert(tmp_float + row * width,
581 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4,
582 src, src_type, src_num_channels,
583 rebased_src2rgba, normalized, width);
584 src += src_stride;
585 }
586 } else {
587 for (row = 0; row < height; ++row) {
588 _mesa_unpack_rgba_row(src_format, width,
589 src, tmp_float + row * width);
590 if (rebase_swizzle)
591 _mesa_swizzle_and_convert(tmp_float + row * width,
592 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4,
593 tmp_float + row * width,
594 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4,
595 rebase_swizzle, normalized, width);
596 src += src_stride;
597 }
598 }
599
600 if (dst_format_is_mesa_array_format) {
601 for (row = 0; row < height; ++row) {
602 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels,
603 tmp_float + row * width,
604 MESA_ARRAY_FORMAT_TYPE_FLOAT, 4,
605 rgba2dst, normalized, width);
606 dst += dst_stride;
607 }
608 } else {
609 for (row = 0; row < height; ++row) {
610 _mesa_pack_float_rgba_row(dst_format, width,
611 (const float (*)[4])tmp_float + row * width, dst);
612 dst += dst_stride;
613 }
614 }
615
616 free(tmp_float);
617 } else {
618 tmp_ubyte = malloc(width * height * sizeof(*tmp_ubyte));
619
620 if (src_format_is_mesa_array_format) {
621 compute_rebased_rgba_component_mapping(src2rgba, rebase_swizzle,
622 rebased_src2rgba);
623 for (row = 0; row < height; ++row) {
624 _mesa_swizzle_and_convert(tmp_ubyte + row * width,
625 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4,
626 src, src_type, src_num_channels,
627 rebased_src2rgba, normalized, width);
628 src += src_stride;
629 }
630 } else {
631 for (row = 0; row < height; ++row) {
632 _mesa_unpack_ubyte_rgba_row(src_format, width,
633 src, tmp_ubyte + row * width);
634 if (rebase_swizzle)
635 _mesa_swizzle_and_convert(tmp_ubyte + row * width,
636 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4,
637 tmp_ubyte + row * width,
638 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4,
639 rebase_swizzle, normalized, width);
640 src += src_stride;
641 }
642 }
643
644 if (dst_format_is_mesa_array_format) {
645 for (row = 0; row < height; ++row) {
646 _mesa_swizzle_and_convert(dst, dst_type, dst_num_channels,
647 tmp_ubyte + row * width,
648 MESA_ARRAY_FORMAT_TYPE_UBYTE, 4,
649 rgba2dst, normalized, width);
650 dst += dst_stride;
651 }
652 } else {
653 for (row = 0; row < height; ++row) {
654 _mesa_pack_ubyte_rgba_row(dst_format, width,
655 (const uint8_t *)(tmp_ubyte + row * width), dst);
656 dst += dst_stride;
657 }
658 }
659
660 free(tmp_ubyte);
661 }
662 }
663
664 static const uint8_t map_identity[7] = { 0, 1, 2, 3, 4, 5, 6 };
665 #if UTIL_ARCH_BIG_ENDIAN
666 static const uint8_t map_3210[7] = { 3, 2, 1, 0, 4, 5, 6 };
667 static const uint8_t map_1032[7] = { 1, 0, 3, 2, 4, 5, 6 };
668 #endif
669
670 /**
671 * Describes a format as an array format, if possible
672 *
673 * A helper function for figuring out if a (possibly packed) format is
674 * actually an array format and, if so, what the array parameters are.
675 *
676 * \param[in] format the mesa format
677 * \param[out] type the GL type of the array (GL_BYTE, etc.)
678 * \param[out] num_components the number of components in the array
679 * \param[out] swizzle a swizzle describing how to get from the
680 * given format to RGBA
681 * \param[out] normalized for integer formats, this represents whether
682 * the format is a normalized integer or a
683 * regular integer
684 * \return true if this format is an array format, false otherwise
685 */
686 bool
_mesa_format_to_array(mesa_format format,GLenum * type,int * num_components,uint8_t swizzle[4],bool * normalized)687 _mesa_format_to_array(mesa_format format, GLenum *type, int *num_components,
688 uint8_t swizzle[4], bool *normalized)
689 {
690 int i;
691 GLuint format_components;
692 uint8_t packed_swizzle[4];
693 const uint8_t *endian;
694
695 if (_mesa_is_format_compressed(format))
696 return false;
697
698 *normalized = !_mesa_is_format_integer(format);
699
700 _mesa_uncompressed_format_to_type_and_comps(format, type, &format_components);
701
702 switch (_mesa_get_format_layout(format)) {
703 case MESA_FORMAT_LAYOUT_ARRAY:
704 *num_components = format_components;
705 _mesa_get_format_swizzle(format, swizzle);
706 return true;
707 case MESA_FORMAT_LAYOUT_PACKED:
708 switch (*type) {
709 case GL_UNSIGNED_BYTE:
710 case GL_BYTE:
711 if (_mesa_get_format_max_bits(format) != 8)
712 return false;
713 *num_components = _mesa_get_format_bytes(format);
714 switch (*num_components) {
715 case 1:
716 endian = map_identity;
717 break;
718 case 2:
719 #if UTIL_ARCH_LITTLE_ENDIAN
720 endian = map_identity;
721 #else
722 endian = map_1032;
723 #endif
724 break;
725 case 4:
726 #if UTIL_ARCH_LITTLE_ENDIAN
727 endian = map_identity;
728 #else
729 endian = map_3210;
730 #endif
731 break;
732 default:
733 endian = map_identity;
734 assert(!"Invalid number of components");
735 }
736 break;
737 case GL_UNSIGNED_SHORT:
738 case GL_SHORT:
739 case GL_HALF_FLOAT:
740 if (_mesa_get_format_max_bits(format) != 16)
741 return false;
742 *num_components = _mesa_get_format_bytes(format) / 2;
743 switch (*num_components) {
744 case 1:
745 endian = map_identity;
746 break;
747 case 2:
748 #if UTIL_ARCH_LITTLE_ENDIAN
749 endian = map_identity;
750 #else
751 endian = map_1032;
752 #endif
753 break;
754 default:
755 endian = map_identity;
756 assert(!"Invalid number of components");
757 }
758 break;
759 case GL_UNSIGNED_INT:
760 case GL_INT:
761 case GL_FLOAT:
762 /* This isn't packed. At least not really. */
763 assert(format_components == 1);
764 if (_mesa_get_format_max_bits(format) != 32)
765 return false;
766 *num_components = format_components;
767 endian = map_identity;
768 break;
769 default:
770 return false;
771 }
772
773 _mesa_get_format_swizzle(format, packed_swizzle);
774
775 for (i = 0; i < 4; ++i)
776 swizzle[i] = endian[packed_swizzle[i]];
777
778 return true;
779 case MESA_FORMAT_LAYOUT_OTHER:
780 default:
781 return false;
782 }
783 }
784
785 /**
786 * Attempts to perform the given swizzle-and-convert operation with memcpy
787 *
788 * This function determines if the given swizzle-and-convert operation can
789 * be done with a simple memcpy and, if so, does the memcpy. If not, it
790 * returns false and we fall back to the standard version below.
791 *
792 * The arguments are exactly the same as for _mesa_swizzle_and_convert
793 *
794 * \return true if it successfully performed the swizzle-and-convert
795 * operation with memcpy, false otherwise
796 */
797 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)798 swizzle_convert_try_memcpy(void *dst,
799 enum mesa_array_format_datatype dst_type,
800 int num_dst_channels,
801 const void *src,
802 enum mesa_array_format_datatype src_type,
803 int num_src_channels,
804 const uint8_t swizzle[4], bool normalized, int count)
805 {
806 int i;
807
808 if (src_type != dst_type)
809 return false;
810 if (num_src_channels != num_dst_channels)
811 return false;
812
813 for (i = 0; i < num_dst_channels; ++i)
814 if (swizzle[i] != i && swizzle[i] != MESA_FORMAT_SWIZZLE_NONE)
815 return false;
816
817 memcpy(dst, src, count * num_src_channels *
818 _mesa_array_format_datatype_get_size(src_type));
819
820 return true;
821 }
822
823 /**
824 * Represents a single instance of the standard swizzle-and-convert loop
825 *
826 * Any swizzle-and-convert operation simply loops through the pixels and
827 * performs the transformation operation one pixel at a time. This macro
828 * embodies one instance of the conversion loop. This way we can do all
829 * control flow outside of the loop and allow the compiler to unroll
830 * everything inside the loop.
831 *
832 * Note: This loop is carefully crafted for performance. Be careful when
833 * changing it and run some benchmarks to ensure no performance regressions
834 * if you do.
835 *
836 * \param DST_TYPE the C datatype of the destination
837 * \param DST_CHANS the number of destination channels
838 * \param SRC_TYPE the C datatype of the source
839 * \param SRC_CHANS the number of source channels
840 * \param CONV an expression for converting from the source data,
841 * storred in the variable "src", to the destination
842 * format
843 */
844 #define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \
845 do { \
846 int s, j; \
847 for (s = 0; s < count; ++s) { \
848 for (j = 0; j < SRC_CHANS; ++j) { \
849 SRC_TYPE src = typed_src[j]; \
850 tmp[j] = CONV; \
851 } \
852 \
853 typed_dst[0] = tmp[swizzle_x]; \
854 if (DST_CHANS > 1) { \
855 typed_dst[1] = tmp[swizzle_y]; \
856 if (DST_CHANS > 2) { \
857 typed_dst[2] = tmp[swizzle_z]; \
858 if (DST_CHANS > 3) { \
859 typed_dst[3] = tmp[swizzle_w]; \
860 } \
861 } \
862 } \
863 typed_src += SRC_CHANS; \
864 typed_dst += DST_CHANS; \
865 } \
866 } while (0)
867
868 /**
869 * Represents a single swizzle-and-convert operation
870 *
871 * This macro represents everything done in a single swizzle-and-convert
872 * operation. The actual work is done by the SWIZZLE_CONVERT_LOOP macro.
873 * This macro acts as a wrapper that uses a nested switch to ensure that
874 * all looping parameters get unrolled.
875 *
876 * This macro makes assumptions about variables etc. in the calling
877 * function. Changes to _mesa_swizzle_and_convert may require changes to
878 * this macro.
879 *
880 * \param DST_TYPE the C datatype of the destination
881 * \param SRC_TYPE the C datatype of the source
882 * \param CONV an expression for converting from the source data,
883 * storred in the variable "src", to the destination
884 * format
885 */
886 #define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV) \
887 do { \
888 const uint8_t swizzle_x = swizzle[0]; \
889 const uint8_t swizzle_y = swizzle[1]; \
890 const uint8_t swizzle_z = swizzle[2]; \
891 const uint8_t swizzle_w = swizzle[3]; \
892 const SRC_TYPE *typed_src = void_src; \
893 DST_TYPE *typed_dst = void_dst; \
894 DST_TYPE tmp[7]; \
895 tmp[4] = 0; \
896 tmp[5] = one; \
897 switch (num_dst_channels) { \
898 case 1: \
899 switch (num_src_channels) { \
900 case 1: \
901 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV); \
902 break; \
903 case 2: \
904 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV); \
905 break; \
906 case 3: \
907 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV); \
908 break; \
909 case 4: \
910 SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV); \
911 break; \
912 } \
913 break; \
914 case 2: \
915 switch (num_src_channels) { \
916 case 1: \
917 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV); \
918 break; \
919 case 2: \
920 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV); \
921 break; \
922 case 3: \
923 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV); \
924 break; \
925 case 4: \
926 SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV); \
927 break; \
928 } \
929 break; \
930 case 3: \
931 switch (num_src_channels) { \
932 case 1: \
933 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV); \
934 break; \
935 case 2: \
936 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV); \
937 break; \
938 case 3: \
939 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV); \
940 break; \
941 case 4: \
942 SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV); \
943 break; \
944 } \
945 break; \
946 case 4: \
947 switch (num_src_channels) { \
948 case 1: \
949 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV); \
950 break; \
951 case 2: \
952 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV); \
953 break; \
954 case 3: \
955 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV); \
956 break; \
957 case 4: \
958 SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV); \
959 break; \
960 } \
961 break; \
962 } \
963 } while (0)
964
965
966 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)967 convert_float(void *void_dst, int num_dst_channels,
968 const void *void_src, GLenum src_type, int num_src_channels,
969 const uint8_t swizzle[4], bool normalized, int count)
970 {
971 const float one = 1.0f;
972
973 switch (src_type) {
974 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
975 SWIZZLE_CONVERT(float, float, src);
976 break;
977 case MESA_ARRAY_FORMAT_TYPE_HALF:
978 SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src));
979 break;
980 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
981 if (normalized) {
982 SWIZZLE_CONVERT(float, uint8_t, _mesa_unorm_to_float(src, 8));
983 } else {
984 SWIZZLE_CONVERT(float, uint8_t, src);
985 }
986 break;
987 case MESA_ARRAY_FORMAT_TYPE_BYTE:
988 if (normalized) {
989 SWIZZLE_CONVERT(float, int8_t, _mesa_snorm_to_float(src, 8));
990 } else {
991 SWIZZLE_CONVERT(float, int8_t, src);
992 }
993 break;
994 case MESA_ARRAY_FORMAT_TYPE_USHORT:
995 if (normalized) {
996 SWIZZLE_CONVERT(float, uint16_t, _mesa_unorm_to_float(src, 16));
997 } else {
998 SWIZZLE_CONVERT(float, uint16_t, src);
999 }
1000 break;
1001 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1002 if (normalized) {
1003 SWIZZLE_CONVERT(float, int16_t, _mesa_snorm_to_float(src, 16));
1004 } else {
1005 SWIZZLE_CONVERT(float, int16_t, src);
1006 }
1007 break;
1008 case MESA_ARRAY_FORMAT_TYPE_UINT:
1009 if (normalized) {
1010 SWIZZLE_CONVERT(float, uint32_t, _mesa_unorm_to_float(src, 32));
1011 } else {
1012 SWIZZLE_CONVERT(float, uint32_t, src);
1013 }
1014 break;
1015 case MESA_ARRAY_FORMAT_TYPE_INT:
1016 if (normalized) {
1017 SWIZZLE_CONVERT(float, int32_t, _mesa_snorm_to_float(src, 32));
1018 } else {
1019 SWIZZLE_CONVERT(float, int32_t, src);
1020 }
1021 break;
1022 default:
1023 assert(!"Invalid channel type combination");
1024 }
1025 }
1026
1027
1028 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)1029 convert_half_float(void *void_dst, int num_dst_channels,
1030 const void *void_src, GLenum src_type, int num_src_channels,
1031 const uint8_t swizzle[4], bool normalized, int count)
1032 {
1033 const uint16_t one = _mesa_float_to_half(1.0f);
1034
1035 switch (src_type) {
1036 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1037 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src));
1038 break;
1039 case MESA_ARRAY_FORMAT_TYPE_HALF:
1040 SWIZZLE_CONVERT(uint16_t, uint16_t, src);
1041 break;
1042 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1043 if (normalized) {
1044 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_half(src, 8));
1045 } else {
1046 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src));
1047 }
1048 break;
1049 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1050 if (normalized) {
1051 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_half(src, 8));
1052 } else {
1053 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src));
1054 }
1055 break;
1056 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1057 if (normalized) {
1058 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_unorm_to_half(src, 16));
1059 } else {
1060 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src));
1061 }
1062 break;
1063 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1064 if (normalized) {
1065 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_half(src, 16));
1066 } else {
1067 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src));
1068 }
1069 break;
1070 case MESA_ARRAY_FORMAT_TYPE_UINT:
1071 if (normalized) {
1072 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_half(src, 32));
1073 } else {
1074 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src));
1075 }
1076 break;
1077 case MESA_ARRAY_FORMAT_TYPE_INT:
1078 if (normalized) {
1079 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_half(src, 32));
1080 } else {
1081 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src));
1082 }
1083 break;
1084 default:
1085 assert(!"Invalid channel type combination");
1086 }
1087 }
1088
1089 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)1090 convert_ubyte(void *void_dst, int num_dst_channels,
1091 const void *void_src, GLenum src_type, int num_src_channels,
1092 const uint8_t swizzle[4], bool normalized, int count)
1093 {
1094 const uint8_t one = normalized ? UINT8_MAX : 1;
1095
1096 switch (src_type) {
1097 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1098 if (normalized) {
1099 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unorm(src, 8));
1100 } else {
1101 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_unsigned(src, 8));
1102 }
1103 break;
1104 case MESA_ARRAY_FORMAT_TYPE_HALF:
1105 if (normalized) {
1106 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unorm(src, 8));
1107 } else {
1108 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_unsigned(src, 8));
1109 }
1110 break;
1111 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1112 SWIZZLE_CONVERT(uint8_t, uint8_t, src);
1113 break;
1114 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1115 if (normalized) {
1116 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_snorm_to_unorm(src, 8, 8));
1117 } else {
1118 SWIZZLE_CONVERT(uint8_t, int8_t, _mesa_signed_to_unsigned(src, 8));
1119 }
1120 break;
1121 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1122 if (normalized) {
1123 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 8));
1124 } else {
1125 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_unsigned_to_unsigned(src, 8));
1126 }
1127 break;
1128 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1129 if (normalized) {
1130 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_snorm_to_unorm(src, 16, 8));
1131 } else {
1132 SWIZZLE_CONVERT(uint8_t, int16_t, _mesa_signed_to_unsigned(src, 8));
1133 }
1134 break;
1135 case MESA_ARRAY_FORMAT_TYPE_UINT:
1136 if (normalized) {
1137 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 8));
1138 } else {
1139 SWIZZLE_CONVERT(uint8_t, uint32_t, _mesa_unsigned_to_unsigned(src, 8));
1140 }
1141 break;
1142 case MESA_ARRAY_FORMAT_TYPE_INT:
1143 if (normalized) {
1144 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_snorm_to_unorm(src, 32, 8));
1145 } else {
1146 SWIZZLE_CONVERT(uint8_t, int32_t, _mesa_signed_to_unsigned(src, 8));
1147 }
1148 break;
1149 default:
1150 assert(!"Invalid channel type combination");
1151 }
1152 }
1153
1154
1155 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)1156 convert_byte(void *void_dst, int num_dst_channels,
1157 const void *void_src, GLenum src_type, int num_src_channels,
1158 const uint8_t swizzle[4], bool normalized, int count)
1159 {
1160 const int8_t one = normalized ? INT8_MAX : 1;
1161
1162 switch (src_type) {
1163 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1164 if (normalized) {
1165 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_snorm(src, 8));
1166 } else {
1167 SWIZZLE_CONVERT(uint8_t, float, _mesa_float_to_signed(src, 8));
1168 }
1169 break;
1170 case MESA_ARRAY_FORMAT_TYPE_HALF:
1171 if (normalized) {
1172 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_snorm(src, 8));
1173 } else {
1174 SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_signed(src, 8));
1175 }
1176 break;
1177 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1178 if (normalized) {
1179 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 8));
1180 } else {
1181 SWIZZLE_CONVERT(int8_t, uint8_t, _mesa_unsigned_to_signed(src, 8));
1182 }
1183 break;
1184 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1185 SWIZZLE_CONVERT(int8_t, int8_t, src);
1186 break;
1187 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1188 if (normalized) {
1189 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 8));
1190 } else {
1191 SWIZZLE_CONVERT(int8_t, uint16_t, _mesa_unsigned_to_signed(src, 8));
1192 }
1193 break;
1194 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1195 if (normalized) {
1196 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_snorm_to_snorm(src, 16, 8));
1197 } else {
1198 SWIZZLE_CONVERT(int8_t, int16_t, _mesa_signed_to_signed(src, 8));
1199 }
1200 break;
1201 case MESA_ARRAY_FORMAT_TYPE_UINT:
1202 if (normalized) {
1203 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 8));
1204 } else {
1205 SWIZZLE_CONVERT(int8_t, uint32_t, _mesa_unsigned_to_signed(src, 8));
1206 }
1207 break;
1208 case MESA_ARRAY_FORMAT_TYPE_INT:
1209 if (normalized) {
1210 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_snorm_to_snorm(src, 32, 8));
1211 } else {
1212 SWIZZLE_CONVERT(int8_t, int32_t, _mesa_signed_to_signed(src, 8));
1213 }
1214 break;
1215 default:
1216 assert(!"Invalid channel type combination");
1217 }
1218 }
1219
1220
1221 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)1222 convert_ushort(void *void_dst, int num_dst_channels,
1223 const void *void_src, GLenum src_type, int num_src_channels,
1224 const uint8_t swizzle[4], bool normalized, int count)
1225 {
1226 const uint16_t one = normalized ? UINT16_MAX : 1;
1227
1228 switch (src_type) {
1229 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1230 if (normalized) {
1231 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unorm(src, 16));
1232 } else {
1233 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_unsigned(src, 16));
1234 }
1235 break;
1236 case MESA_ARRAY_FORMAT_TYPE_HALF:
1237 if (normalized) {
1238 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unorm(src, 16));
1239 } else {
1240 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_unsigned(src, 16));
1241 }
1242 break;
1243 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1244 if (normalized) {
1245 SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 16));
1246 } else {
1247 SWIZZLE_CONVERT(uint16_t, uint8_t, src);
1248 }
1249 break;
1250 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1251 if (normalized) {
1252 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_snorm_to_unorm(src, 8, 16));
1253 } else {
1254 SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_signed_to_unsigned(src, 16));
1255 }
1256 break;
1257 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1258 SWIZZLE_CONVERT(uint16_t, uint16_t, src);
1259 break;
1260 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1261 if (normalized) {
1262 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_snorm_to_unorm(src, 16, 16));
1263 } else {
1264 SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_signed_to_unsigned(src, 16));
1265 }
1266 break;
1267 case MESA_ARRAY_FORMAT_TYPE_UINT:
1268 if (normalized) {
1269 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unorm_to_unorm(src, 32, 16));
1270 } else {
1271 SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_unsigned_to_unsigned(src, 16));
1272 }
1273 break;
1274 case MESA_ARRAY_FORMAT_TYPE_INT:
1275 if (normalized) {
1276 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_snorm_to_unorm(src, 32, 16));
1277 } else {
1278 SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_signed_to_unsigned(src, 16));
1279 }
1280 break;
1281 default:
1282 assert(!"Invalid channel type combination");
1283 }
1284 }
1285
1286
1287 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)1288 convert_short(void *void_dst, int num_dst_channels,
1289 const void *void_src, GLenum src_type, int num_src_channels,
1290 const uint8_t swizzle[4], bool normalized, int count)
1291 {
1292 const int16_t one = normalized ? INT16_MAX : 1;
1293
1294 switch (src_type) {
1295 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1296 if (normalized) {
1297 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_snorm(src, 16));
1298 } else {
1299 SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_signed(src, 16));
1300 }
1301 break;
1302 case MESA_ARRAY_FORMAT_TYPE_HALF:
1303 if (normalized) {
1304 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_snorm(src, 16));
1305 } else {
1306 SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_signed(src, 16));
1307 }
1308 break;
1309 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1310 if (normalized) {
1311 SWIZZLE_CONVERT(int16_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 16));
1312 } else {
1313 SWIZZLE_CONVERT(int16_t, uint8_t, src);
1314 }
1315 break;
1316 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1317 if (normalized) {
1318 SWIZZLE_CONVERT(int16_t, int8_t, _mesa_snorm_to_snorm(src, 8, 16));
1319 } else {
1320 SWIZZLE_CONVERT(int16_t, int8_t, src);
1321 }
1322 break;
1323 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1324 if (normalized) {
1325 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 16));
1326 } else {
1327 SWIZZLE_CONVERT(int16_t, uint16_t, _mesa_unsigned_to_signed(src, 16));
1328 }
1329 break;
1330 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1331 SWIZZLE_CONVERT(int16_t, int16_t, src);
1332 break;
1333 case MESA_ARRAY_FORMAT_TYPE_UINT:
1334 if (normalized) {
1335 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 16));
1336 } else {
1337 SWIZZLE_CONVERT(int16_t, uint32_t, _mesa_unsigned_to_signed(src, 16));
1338 }
1339 break;
1340 case MESA_ARRAY_FORMAT_TYPE_INT:
1341 if (normalized) {
1342 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_snorm_to_snorm(src, 32, 16));
1343 } else {
1344 SWIZZLE_CONVERT(int16_t, int32_t, _mesa_signed_to_signed(src, 16));
1345 }
1346 break;
1347 default:
1348 assert(!"Invalid channel type combination");
1349 }
1350 }
1351
1352 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)1353 convert_uint(void *void_dst, int num_dst_channels,
1354 const void *void_src, GLenum src_type, int num_src_channels,
1355 const uint8_t swizzle[4], bool normalized, int count)
1356 {
1357 const uint32_t one = normalized ? UINT32_MAX : 1;
1358
1359 switch (src_type) {
1360 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1361 if (normalized) {
1362 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unorm(src, 32));
1363 } else {
1364 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_unsigned(src, 32));
1365 }
1366 break;
1367 case MESA_ARRAY_FORMAT_TYPE_HALF:
1368 if (normalized) {
1369 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unorm(src, 32));
1370 } else {
1371 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_unsigned(src, 32));
1372 }
1373 break;
1374 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1375 if (normalized) {
1376 SWIZZLE_CONVERT(uint32_t, uint8_t, _mesa_unorm_to_unorm(src, 8, 32));
1377 } else {
1378 SWIZZLE_CONVERT(uint32_t, uint8_t, src);
1379 }
1380 break;
1381 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1382 if (normalized) {
1383 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_snorm_to_unorm(src, 8, 32));
1384 } else {
1385 SWIZZLE_CONVERT(uint32_t, int8_t, _mesa_signed_to_unsigned(src, 32));
1386 }
1387 break;
1388 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1389 if (normalized) {
1390 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_unorm_to_unorm(src, 16, 32));
1391 } else {
1392 SWIZZLE_CONVERT(uint32_t, uint16_t, src);
1393 }
1394 break;
1395 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1396 if (normalized) {
1397 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_snorm_to_unorm(src, 16, 32));
1398 } else {
1399 SWIZZLE_CONVERT(uint32_t, int16_t, _mesa_signed_to_unsigned(src, 32));
1400 }
1401 break;
1402 case MESA_ARRAY_FORMAT_TYPE_UINT:
1403 SWIZZLE_CONVERT(uint32_t, uint32_t, src);
1404 break;
1405 case MESA_ARRAY_FORMAT_TYPE_INT:
1406 if (normalized) {
1407 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_snorm_to_unorm(src, 32, 32));
1408 } else {
1409 SWIZZLE_CONVERT(uint32_t, int32_t, _mesa_signed_to_unsigned(src, 32));
1410 }
1411 break;
1412 default:
1413 assert(!"Invalid channel type combination");
1414 }
1415 }
1416
1417
1418 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)1419 convert_int(void *void_dst, int num_dst_channels,
1420 const void *void_src, GLenum src_type, int num_src_channels,
1421 const uint8_t swizzle[4], bool normalized, int count)
1422 {
1423 const int32_t one = normalized ? INT32_MAX : 1;
1424
1425 switch (src_type) {
1426 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1427 if (normalized) {
1428 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_snorm(src, 32));
1429 } else {
1430 SWIZZLE_CONVERT(uint32_t, float, _mesa_float_to_signed(src, 32));
1431 }
1432 break;
1433 case MESA_ARRAY_FORMAT_TYPE_HALF:
1434 if (normalized) {
1435 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_snorm(src, 32));
1436 } else {
1437 SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_signed(src, 32));
1438 }
1439 break;
1440 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1441 if (normalized) {
1442 SWIZZLE_CONVERT(int32_t, uint8_t, _mesa_unorm_to_snorm(src, 8, 32));
1443 } else {
1444 SWIZZLE_CONVERT(int32_t, uint8_t, src);
1445 }
1446 break;
1447 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1448 if (normalized) {
1449 SWIZZLE_CONVERT(int32_t, int8_t, _mesa_snorm_to_snorm(src, 8, 32));
1450 } else {
1451 SWIZZLE_CONVERT(int32_t, int8_t, src);
1452 }
1453 break;
1454 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1455 if (normalized) {
1456 SWIZZLE_CONVERT(int32_t, uint16_t, _mesa_unorm_to_snorm(src, 16, 32));
1457 } else {
1458 SWIZZLE_CONVERT(int32_t, uint16_t, src);
1459 }
1460 break;
1461 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1462 if (normalized) {
1463 SWIZZLE_CONVERT(int32_t, int16_t, _mesa_snorm_to_snorm(src, 16, 32));
1464 } else {
1465 SWIZZLE_CONVERT(int32_t, int16_t, src);
1466 }
1467 break;
1468 case MESA_ARRAY_FORMAT_TYPE_UINT:
1469 if (normalized) {
1470 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unorm_to_snorm(src, 32, 32));
1471 } else {
1472 SWIZZLE_CONVERT(int32_t, uint32_t, _mesa_unsigned_to_signed(src, 32));
1473 }
1474 break;
1475 case MESA_ARRAY_FORMAT_TYPE_INT:
1476 SWIZZLE_CONVERT(int32_t, int32_t, src);
1477 break;
1478 default:
1479 assert(!"Invalid channel type combination");
1480 }
1481 }
1482
1483
1484 /**
1485 * Convert between array-based color formats.
1486 *
1487 * Most format conversion operations required by GL can be performed by
1488 * converting one channel at a time, shuffling the channels around, and
1489 * optionally filling missing channels with zeros and ones. This function
1490 * does just that in a general, yet efficient, way.
1491 *
1492 * The swizzle parameter is an array of 4 numbers (see
1493 * _mesa_get_format_swizzle) that describes where each channel in the
1494 * destination should come from in the source. If swizzle[i] < 4 then it
1495 * means that dst[i] = CONVERT(src[swizzle[i]]). If swizzle[i] is
1496 * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding
1497 * dst[i] will be filled with the appropreate representation of zero or one
1498 * respectively.
1499 *
1500 * Under most circumstances, the source and destination images must be
1501 * different as no care is taken not to clobber one with the other.
1502 * However, if they have the same number of bits per pixel, it is safe to
1503 * do an in-place conversion.
1504 *
1505 * \param[out] dst pointer to where the converted data should
1506 * be stored
1507 *
1508 * \param[in] dst_type the destination GL type of the converted
1509 * data (GL_BYTE, etc.)
1510 *
1511 * \param[in] num_dst_channels the number of channels in the converted
1512 * data
1513 *
1514 * \param[in] src pointer to the source data
1515 *
1516 * \param[in] src_type the GL type of the source data (GL_BYTE,
1517 * etc.)
1518 *
1519 * \param[in] num_src_channels the number of channels in the source data
1520 * (the number of channels total, not just
1521 * the number used)
1522 *
1523 * \param[in] swizzle describes how to get the destination data
1524 * from the source data.
1525 *
1526 * \param[in] normalized for integer types, this indicates whether
1527 * the data should be considered as integers
1528 * or as normalized integers;
1529 *
1530 * \param[in] count the number of pixels to convert
1531 */
1532 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)1533 _mesa_swizzle_and_convert(void *void_dst, enum mesa_array_format_datatype dst_type, int num_dst_channels,
1534 const void *void_src, enum mesa_array_format_datatype src_type, int num_src_channels,
1535 const uint8_t swizzle[4], bool normalized, int count)
1536 {
1537 if (swizzle_convert_try_memcpy(void_dst, dst_type, num_dst_channels,
1538 void_src, src_type, num_src_channels,
1539 swizzle, normalized, count))
1540 return;
1541
1542 switch (dst_type) {
1543 case MESA_ARRAY_FORMAT_TYPE_FLOAT:
1544 convert_float(void_dst, num_dst_channels, void_src, src_type,
1545 num_src_channels, swizzle, normalized, count);
1546 break;
1547 case MESA_ARRAY_FORMAT_TYPE_HALF:
1548 convert_half_float(void_dst, num_dst_channels, void_src, src_type,
1549 num_src_channels, swizzle, normalized, count);
1550 break;
1551 case MESA_ARRAY_FORMAT_TYPE_UBYTE:
1552 convert_ubyte(void_dst, num_dst_channels, void_src, src_type,
1553 num_src_channels, swizzle, normalized, count);
1554 break;
1555 case MESA_ARRAY_FORMAT_TYPE_BYTE:
1556 convert_byte(void_dst, num_dst_channels, void_src, src_type,
1557 num_src_channels, swizzle, normalized, count);
1558 break;
1559 case MESA_ARRAY_FORMAT_TYPE_USHORT:
1560 convert_ushort(void_dst, num_dst_channels, void_src, src_type,
1561 num_src_channels, swizzle, normalized, count);
1562 break;
1563 case MESA_ARRAY_FORMAT_TYPE_SHORT:
1564 convert_short(void_dst, num_dst_channels, void_src, src_type,
1565 num_src_channels, swizzle, normalized, count);
1566 break;
1567 case MESA_ARRAY_FORMAT_TYPE_UINT:
1568 convert_uint(void_dst, num_dst_channels, void_src, src_type,
1569 num_src_channels, swizzle, normalized, count);
1570 break;
1571 case MESA_ARRAY_FORMAT_TYPE_INT:
1572 convert_int(void_dst, num_dst_channels, void_src, src_type,
1573 num_src_channels, swizzle, normalized, count);
1574 break;
1575 default:
1576 assert(!"Invalid channel type");
1577 }
1578 }
1579