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 
33 const 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 
37 const 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 
41 const 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 
45 const 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 
49 const 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 
53 static void
invert_swizzle(uint8_t dst[4],const uint8_t src[4])54 invert_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  */
81 static void
compute_rebased_rgba_component_mapping(uint8_t * src2rgba,uint8_t * rebase_swizzle,uint8_t * rebased_src2rgba)82 compute_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  */
111 static void
compute_src2dst_component_mapping(uint8_t * src2rgba,uint8_t * rgba2dst,uint8_t * rebase_swizzle,uint8_t * src2dst)112 compute_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  */
153 bool
_mesa_compute_rgba2base2rgba_component_mapping(GLenum baseFormat,uint8_t * map)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  */
198 static void
convert_ubyte_rgba_to_bgra(size_t width,size_t height,const uint8_t * src,size_t src_stride,uint8_t * dst,size_t dst_stride)199 convert_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  */
277 void
_mesa_format_convert(void * void_dst,uint32_t dst_format,size_t dst_stride,void * void_src,uint32_t src_format,size_t src_stride,size_t width,size_t height,uint8_t * rebase_swizzle)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 
664 static const uint8_t map_identity[7] = { 0, 1, 2, 3, 4, 5, 6 };
665 #if UTIL_ARCH_BIG_ENDIAN
666 static const uint8_t map_3210[7] = { 3, 2, 1, 0, 4, 5, 6 };
667 static 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  */
686 bool
_mesa_format_to_array(mesa_format format,GLenum * type,int * num_components,uint8_t swizzle[4],bool * normalized)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  */
797 static bool
swizzle_convert_try_memcpy(void * dst,enum mesa_array_format_datatype dst_type,int num_dst_channels,const void * src,enum mesa_array_format_datatype src_type,int num_src_channels,const uint8_t swizzle[4],bool normalized,int count)798 swizzle_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 
966 static void
convert_float(void * void_dst,int num_dst_channels,const void * void_src,GLenum src_type,int num_src_channels,const uint8_t swizzle[4],bool normalized,int count)967 convert_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 
1028 static void
convert_half_float(void * void_dst,int num_dst_channels,const void * void_src,GLenum src_type,int num_src_channels,const uint8_t swizzle[4],bool normalized,int count)1029 convert_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 
1089 static void
convert_ubyte(void * void_dst,int num_dst_channels,const void * void_src,GLenum src_type,int num_src_channels,const uint8_t swizzle[4],bool normalized,int count)1090 convert_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 
1155 static void
convert_byte(void * void_dst,int num_dst_channels,const void * void_src,GLenum src_type,int num_src_channels,const uint8_t swizzle[4],bool normalized,int count)1156 convert_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 
1221 static void
convert_ushort(void * void_dst,int num_dst_channels,const void * void_src,GLenum src_type,int num_src_channels,const uint8_t swizzle[4],bool normalized,int count)1222 convert_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 
1287 static void
convert_short(void * void_dst,int num_dst_channels,const void * void_src,GLenum src_type,int num_src_channels,const uint8_t swizzle[4],bool normalized,int count)1288 convert_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 
1352 static void
convert_uint(void * void_dst,int num_dst_channels,const void * void_src,GLenum src_type,int num_src_channels,const uint8_t swizzle[4],bool normalized,int count)1353 convert_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 
1418 static void
convert_int(void * void_dst,int num_dst_channels,const void * void_src,GLenum src_type,int num_src_channels,const uint8_t swizzle[4],bool normalized,int count)1419 convert_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  */
1532 void
_mesa_swizzle_and_convert(void * void_dst,enum mesa_array_format_datatype dst_type,int num_dst_channels,const void * void_src,enum mesa_array_format_datatype src_type,int num_src_channels,const uint8_t swizzle[4],bool normalized,int count)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