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