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