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