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