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