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