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