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