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