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