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