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