format_utils.c revision 427dc834
1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2014  Intel Corporation  All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25#include "format_utils.h"
26#include "glformats.h"
27
28static const uint8_t map_identity[7] = { 0, 1, 2, 3, 4, 5, 6 };
29static const uint8_t map_3210[7] = { 3, 2, 1, 0, 4, 5, 6 };
30static const uint8_t map_1032[7] = { 1, 0, 3, 2, 4, 5, 6 };
31
32/**
33 * Describes a format as an array format, if possible
34 *
35 * A helper function for figuring out if a (possibly packed) format is
36 * actually an array format and, if so, what the array parameters are.
37 *
38 * \param[in]  format         the mesa format
39 * \param[out] type           the GL type of the array (GL_BYTE, etc.)
40 * \param[out] num_components the number of components in the array
41 * \param[out] swizzle        a swizzle describing how to get from the
42 *                            given format to RGBA
43 * \param[out] normalized     for integer formats, this represents whether
44 *                            the format is a normalized integer or a
45 *                            regular integer
46 * \return  true if this format is an array format, false otherwise
47 */
48bool
49_mesa_format_to_array(mesa_format format, GLenum *type, int *num_components,
50                      uint8_t swizzle[4], bool *normalized)
51{
52   int i;
53   GLuint format_components;
54   uint8_t packed_swizzle[4];
55   const uint8_t *endian;
56
57   if (_mesa_is_format_compressed(format))
58      return false;
59
60   *normalized = !_mesa_is_format_integer(format);
61
62   _mesa_format_to_type_and_comps(format, type, &format_components);
63
64   switch (_mesa_get_format_layout(format)) {
65   case MESA_FORMAT_LAYOUT_ARRAY:
66      *num_components = format_components;
67      _mesa_get_format_swizzle(format, swizzle);
68      return true;
69   case MESA_FORMAT_LAYOUT_PACKED:
70      switch (*type) {
71      case GL_UNSIGNED_BYTE:
72      case GL_BYTE:
73         if (_mesa_get_format_max_bits(format) != 8)
74            return false;
75         *num_components = _mesa_get_format_bytes(format);
76         switch (*num_components) {
77         case 1:
78            endian = map_identity;
79            break;
80         case 2:
81            endian = _mesa_little_endian() ? map_identity : map_1032;
82            break;
83         case 4:
84            endian = _mesa_little_endian() ? map_identity : map_3210;
85            break;
86         default:
87            endian = map_identity;
88            assert(!"Invalid number of components");
89         }
90         break;
91      case GL_UNSIGNED_SHORT:
92      case GL_SHORT:
93      case GL_HALF_FLOAT:
94         if (_mesa_get_format_max_bits(format) != 16)
95            return false;
96         *num_components = _mesa_get_format_bytes(format) / 2;
97         switch (*num_components) {
98         case 1:
99            endian = map_identity;
100            break;
101         case 2:
102            endian = _mesa_little_endian() ? map_identity : map_1032;
103            break;
104         default:
105            endian = map_identity;
106            assert(!"Invalid number of components");
107         }
108         break;
109      case GL_UNSIGNED_INT:
110      case GL_INT:
111      case GL_FLOAT:
112         /* This isn't packed.  At least not really. */
113         assert(format_components == 1);
114         if (_mesa_get_format_max_bits(format) != 32)
115            return false;
116         *num_components = format_components;
117         endian = map_identity;
118         break;
119      default:
120         return false;
121      }
122
123      _mesa_get_format_swizzle(format, packed_swizzle);
124
125      for (i = 0; i < 4; ++i)
126         swizzle[i] = endian[packed_swizzle[i]];
127
128      return true;
129   case MESA_FORMAT_LAYOUT_OTHER:
130   default:
131      return false;
132   }
133}
134
135/* A bunch of format conversion macros and helper functions used below */
136
137/* Only guaranteed to work for BITS <= 32 */
138#define MAX_UINT(BITS) ((BITS) == 32 ? UINT32_MAX : ((1u << (BITS)) - 1))
139#define MAX_INT(BITS) ((int)MAX_UINT((BITS) - 1))
140
141/* Extends an integer of size SRC_BITS to one of size DST_BITS linearly */
142#define EXTEND_NORMALIZED_INT(X, SRC_BITS, DST_BITS) \
143      (((X) * (int)(MAX_UINT(DST_BITS) / MAX_UINT(SRC_BITS))) + \
144       ((DST_BITS % SRC_BITS) ? ((X) >> (SRC_BITS - DST_BITS % SRC_BITS)) : 0))
145
146static inline float
147unorm_to_float(unsigned x, unsigned src_bits)
148{
149   return x * (1.0f / (float)MAX_UINT(src_bits));
150}
151
152static inline float
153snorm_to_float(int x, unsigned src_bits)
154{
155   if (x == -MAX_INT(src_bits))
156      return -1.0f;
157   else
158      return x * (1.0f / (float)MAX_INT(src_bits));
159}
160
161static inline uint16_t
162unorm_to_half(unsigned x, unsigned src_bits)
163{
164   return _mesa_float_to_half(unorm_to_float(x, src_bits));
165}
166
167static inline uint16_t
168snorm_to_half(int x, unsigned src_bits)
169{
170   return _mesa_float_to_half(snorm_to_float(x, src_bits));
171}
172
173static inline unsigned
174float_to_unorm(float x, unsigned dst_bits)
175{
176   if (x < 0.0f)
177      return 0;
178   else if (x > 1.0f)
179      return MAX_UINT(dst_bits);
180   else
181      return F_TO_I(x * MAX_UINT(dst_bits));
182}
183
184static inline unsigned
185half_to_unorm(uint16_t x, unsigned dst_bits)
186{
187   return float_to_unorm(_mesa_half_to_float(x), dst_bits);
188}
189
190static inline unsigned
191unorm_to_unorm(unsigned x, unsigned src_bits, unsigned dst_bits)
192{
193   if (src_bits < dst_bits)
194      return EXTEND_NORMALIZED_INT(x, src_bits, dst_bits);
195   else
196      return x >> (src_bits - dst_bits);
197}
198
199static inline unsigned
200snorm_to_unorm(int x, unsigned src_bits, unsigned dst_bits)
201{
202   if (x < 0)
203      return 0;
204   else
205      return unorm_to_unorm(x, src_bits - 1, dst_bits);
206}
207
208static inline int
209float_to_snorm(float x, unsigned dst_bits)
210{
211   if (x < -1.0f)
212      return -MAX_INT(dst_bits);
213   else if (x > 1.0f)
214      return MAX_INT(dst_bits);
215   else
216      return F_TO_I(x * MAX_INT(dst_bits));
217}
218
219static inline int
220half_to_snorm(uint16_t x, unsigned dst_bits)
221{
222   return float_to_snorm(_mesa_half_to_float(x), dst_bits);
223}
224
225static inline int
226unorm_to_snorm(unsigned x, unsigned src_bits, unsigned dst_bits)
227{
228   return unorm_to_unorm(x, src_bits, dst_bits - 1);
229}
230
231static inline int
232snorm_to_snorm(int x, unsigned src_bits, unsigned dst_bits)
233{
234   if (x < -MAX_INT(src_bits))
235      return -MAX_INT(dst_bits);
236   else if (src_bits < dst_bits)
237      return EXTEND_NORMALIZED_INT(x, src_bits - 1, dst_bits - 1);
238   else
239      return x >> (src_bits - dst_bits);
240}
241
242static inline unsigned
243float_to_uint(float x)
244{
245   if (x < 0.0f)
246      return 0;
247   else
248      return x;
249}
250
251static inline unsigned
252half_to_uint(uint16_t x)
253{
254   if (_mesa_half_is_negative(x))
255      return 0;
256   else
257      return _mesa_float_to_half(x);
258}
259
260/**
261 * Attempts to perform the given swizzle-and-convert operation with memcpy
262 *
263 * This function determines if the given swizzle-and-convert operation can
264 * be done with a simple memcpy and, if so, does the memcpy.  If not, it
265 * returns false and we fall back to the standard version below.
266 *
267 * The arguments are exactly the same as for _mesa_swizzle_and_convert
268 *
269 * \return  true if it successfully performed the swizzle-and-convert
270 *          operation with memcpy, false otherwise
271 */
272static bool
273swizzle_convert_try_memcpy(void *dst, GLenum dst_type, int num_dst_channels,
274                           const void *src, GLenum src_type, int num_src_channels,
275                           const uint8_t swizzle[4], bool normalized, int count)
276{
277   int i;
278
279   if (src_type != dst_type)
280      return false;
281   if (num_src_channels != num_dst_channels)
282      return false;
283
284   for (i = 0; i < num_dst_channels; ++i)
285      if (swizzle[i] != i && swizzle[i] != MESA_FORMAT_SWIZZLE_NONE)
286         return false;
287
288   memcpy(dst, src, count * num_src_channels * _mesa_sizeof_type(src_type));
289
290   return true;
291}
292
293/**
294 * Represents a single instance of the standard swizzle-and-convert loop
295 *
296 * Any swizzle-and-convert operation simply loops through the pixels and
297 * performs the transformation operation one pixel at a time.  This macro
298 * embodies one instance of the conversion loop.  This way we can do all
299 * control flow outside of the loop and allow the compiler to unroll
300 * everything inside the loop.
301 *
302 * Note: This loop is carefully crafted for performance.  Be careful when
303 * changing it and run some benchmarks to ensure no performance regressions
304 * if you do.
305 *
306 * \param   DST_TYPE    the C datatype of the destination
307 * \param   DST_CHANS   the number of destination channels
308 * \param   SRC_TYPE    the C datatype of the source
309 * \param   SRC_CHANS   the number of source channels
310 * \param   CONV        an expression for converting from the source data,
311 *                      storred in the variable "src", to the destination
312 *                      format
313 */
314#define SWIZZLE_CONVERT_LOOP(DST_TYPE, DST_CHANS, SRC_TYPE, SRC_CHANS, CONV) \
315   for (s = 0; s < count; ++s) {                                  \
316      for (j = 0; j < SRC_CHANS; ++j) {                           \
317         SRC_TYPE src = typed_src[j];                             \
318         tmp[j] = CONV;                                           \
319      }                                                           \
320                                                                  \
321      typed_dst[0] = tmp[swizzle_x];                              \
322      if (DST_CHANS > 1) {                                        \
323         typed_dst[1] = tmp[swizzle_y];                           \
324         if (DST_CHANS > 2) {                                     \
325            typed_dst[2] = tmp[swizzle_z];                        \
326            if (DST_CHANS > 3) {                                  \
327               typed_dst[3] = tmp[swizzle_w];                     \
328            }                                                     \
329         }                                                        \
330      }                                                           \
331      typed_src += SRC_CHANS;                                     \
332      typed_dst += DST_CHANS;                                     \
333   }                                                              \
334
335/**
336 * Represents a single swizzle-and-convert operation
337 *
338 * This macro represents everything done in a single swizzle-and-convert
339 * operation.  The actual work is done by the SWIZZLE_CONVERT_LOOP macro.
340 * This macro acts as a wrapper that uses a nested switch to ensure that
341 * all looping parameters get unrolled.
342 *
343 * This macro makes assumptions about variables etc. in the calling
344 * function.  Changes to _mesa_swizzle_and_convert may require changes to
345 * this macro.
346 *
347 * \param   DST_TYPE    the C datatype of the destination
348 * \param   SRC_TYPE    the C datatype of the source
349 * \param   CONV        an expression for converting from the source data,
350 *                      storred in the variable "src", to the destination
351 *                      format
352 */
353#define SWIZZLE_CONVERT(DST_TYPE, SRC_TYPE, CONV)                 \
354   do {                                                           \
355      const SRC_TYPE *typed_src = void_src;                       \
356      DST_TYPE *typed_dst = void_dst;                             \
357      DST_TYPE tmp[7];                                            \
358      tmp[4] = 0;                                                 \
359      tmp[5] = one;                                               \
360      switch (num_dst_channels) {                                 \
361      case 1:                                                     \
362         switch (num_src_channels) {                              \
363         case 1:                                                  \
364            SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 1, CONV)  \
365            break;                                                \
366         case 2:                                                  \
367            SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 2, CONV)  \
368            break;                                                \
369         case 3:                                                  \
370            SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 3, CONV)  \
371            break;                                                \
372         case 4:                                                  \
373            SWIZZLE_CONVERT_LOOP(DST_TYPE, 1, SRC_TYPE, 4, CONV)  \
374            break;                                                \
375         }                                                        \
376         break;                                                   \
377      case 2:                                                     \
378         switch (num_src_channels) {                              \
379         case 1:                                                  \
380            SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 1, CONV)  \
381            break;                                                \
382         case 2:                                                  \
383            SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 2, CONV)  \
384            break;                                                \
385         case 3:                                                  \
386            SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 3, CONV)  \
387            break;                                                \
388         case 4:                                                  \
389            SWIZZLE_CONVERT_LOOP(DST_TYPE, 2, SRC_TYPE, 4, CONV)  \
390            break;                                                \
391         }                                                        \
392         break;                                                   \
393      case 3:                                                     \
394         switch (num_src_channels) {                              \
395         case 1:                                                  \
396            SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 1, CONV)  \
397            break;                                                \
398         case 2:                                                  \
399            SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 2, CONV)  \
400            break;                                                \
401         case 3:                                                  \
402            SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 3, CONV)  \
403            break;                                                \
404         case 4:                                                  \
405            SWIZZLE_CONVERT_LOOP(DST_TYPE, 3, SRC_TYPE, 4, CONV)  \
406            break;                                                \
407         }                                                        \
408         break;                                                   \
409      case 4:                                                     \
410         switch (num_src_channels) {                              \
411         case 1:                                                  \
412            SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 1, CONV)  \
413            break;                                                \
414         case 2:                                                  \
415            SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 2, CONV)  \
416            break;                                                \
417         case 3:                                                  \
418            SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 3, CONV)  \
419            break;                                                \
420         case 4:                                                  \
421            SWIZZLE_CONVERT_LOOP(DST_TYPE, 4, SRC_TYPE, 4, CONV)  \
422            break;                                                \
423         }                                                        \
424         break;                                                   \
425      }                                                           \
426   } while (0);
427
428/**
429 * Convert between array-based color formats.
430 *
431 * Most format conversion operations required by GL can be performed by
432 * converting one channel at a time, shuffling the channels around, and
433 * optionally filling missing channels with zeros and ones.  This function
434 * does just that in a general, yet efficient, way.
435 *
436 * The swizzle parameter is an array of 4 numbers (see
437 * _mesa_get_format_swizzle) that describes where each channel in the
438 * destination should come from in the source.  If swizzle[i] < 4 then it
439 * means that dst[i] = CONVERT(src[swizzle[i]]).  If swizzle[i] is
440 * MESA_FORMAT_SWIZZLE_ZERO or MESA_FORMAT_SWIZZLE_ONE, the corresponding
441 * dst[i] will be filled with the appropreate representation of zero or one
442 * respectively.
443 *
444 * Under most circumstances, the source and destination images must be
445 * different as no care is taken not to clobber one with the other.
446 * However, if they have the same number of bits per pixel, it is safe to
447 * do an in-place conversion.
448 *
449 * \param[out] dst               pointer to where the converted data should
450 *                               be stored
451 *
452 * \param[in]  dst_type          the destination GL type of the converted
453 *                               data (GL_BYTE, etc.)
454 *
455 * \param[in]  num_dst_channels  the number of channels in the converted
456 *                               data
457 *
458 * \param[in]  src               pointer to the source data
459 *
460 * \param[in]  src_type          the GL type of the source data (GL_BYTE,
461 *                               etc.)
462 *
463 * \param[in]  num_src_channels  the number of channels in the source data
464 *                               (the number of channels total, not just
465 *                               the number used)
466 *
467 * \param[in]  swizzle           describes how to get the destination data
468 *                               from the source data.
469 *
470 * \param[in]  normalized        for integer types, this indicates whether
471 *                               the data should be considered as integers
472 *                               or as normalized integers;
473 *
474 * \param[in]  count             the number of pixels to convert
475 */
476static void
477_mesa_swizzle_and_convert_float(
478    void *void_dst, GLenum dst_type, int num_dst_channels,
479    const void *void_src, GLenum src_type, int num_src_channels,
480    const uint8_t swizzle[4], bool normalized, int count)
481{
482   int s, j;
483   register uint8_t swizzle_x, swizzle_y, swizzle_z, swizzle_w;
484
485   swizzle_x = swizzle[0];
486   swizzle_y = swizzle[1];
487   swizzle_z = swizzle[2];
488   swizzle_w = swizzle[3];
489
490   {
491      const float one = 1.0f;
492      switch (src_type) {
493      case GL_FLOAT:
494         SWIZZLE_CONVERT(float, float, src)
495         break;
496      case GL_HALF_FLOAT:
497         SWIZZLE_CONVERT(float, uint16_t, _mesa_half_to_float(src))
498         break;
499      case GL_UNSIGNED_BYTE:
500         if (normalized) {
501            SWIZZLE_CONVERT(float, uint8_t, unorm_to_float(src, 8))
502         } else {
503            SWIZZLE_CONVERT(float, uint8_t, src)
504         }
505         break;
506      case GL_BYTE:
507         if (normalized) {
508            SWIZZLE_CONVERT(float, int8_t, snorm_to_float(src, 8))
509         } else {
510            SWIZZLE_CONVERT(float, int8_t, src)
511         }
512         break;
513      case GL_UNSIGNED_SHORT:
514         if (normalized) {
515            SWIZZLE_CONVERT(float, uint16_t, unorm_to_float(src, 16))
516         } else {
517            SWIZZLE_CONVERT(float, uint16_t, src)
518         }
519         break;
520      case GL_SHORT:
521         if (normalized) {
522            SWIZZLE_CONVERT(float, int16_t, snorm_to_float(src, 16))
523         } else {
524            SWIZZLE_CONVERT(float, int16_t, src)
525         }
526         break;
527      case GL_UNSIGNED_INT:
528         if (normalized) {
529            SWIZZLE_CONVERT(float, uint32_t, unorm_to_float(src, 32))
530         } else {
531            SWIZZLE_CONVERT(float, uint32_t, src)
532         }
533         break;
534      case GL_INT:
535         if (normalized) {
536            SWIZZLE_CONVERT(float, int32_t, snorm_to_float(src, 32))
537         } else {
538            SWIZZLE_CONVERT(float, int32_t, src)
539         }
540         break;
541      default:
542         assert(!"Invalid channel type combination");
543      }
544   }
545}
546
547static void
548_mesa_swizzle_and_convert_half_float(
549    void *void_dst, GLenum dst_type, int num_dst_channels,
550    const void *void_src, GLenum src_type, int num_src_channels,
551    const uint8_t swizzle[4], bool normalized, int count)
552{
553   int s, j;
554   register uint8_t swizzle_x, swizzle_y, swizzle_z, swizzle_w;
555
556   swizzle_x = swizzle[0];
557   swizzle_y = swizzle[1];
558   swizzle_z = swizzle[2];
559   swizzle_w = swizzle[3];
560
561   {
562      const uint16_t one = _mesa_float_to_half(1.0f);
563      switch (src_type) {
564      case GL_FLOAT:
565         SWIZZLE_CONVERT(uint16_t, float, _mesa_float_to_half(src))
566         break;
567      case GL_HALF_FLOAT:
568         SWIZZLE_CONVERT(uint16_t, uint16_t, src)
569         break;
570      case GL_UNSIGNED_BYTE:
571         if (normalized) {
572            SWIZZLE_CONVERT(uint16_t, uint8_t, unorm_to_half(src, 8))
573         } else {
574            SWIZZLE_CONVERT(uint16_t, uint8_t, _mesa_float_to_half(src))
575         }
576         break;
577      case GL_BYTE:
578         if (normalized) {
579            SWIZZLE_CONVERT(uint16_t, int8_t, snorm_to_half(src, 8))
580         } else {
581            SWIZZLE_CONVERT(uint16_t, int8_t, _mesa_float_to_half(src))
582         }
583         break;
584      case GL_UNSIGNED_SHORT:
585         if (normalized) {
586            SWIZZLE_CONVERT(uint16_t, uint16_t, unorm_to_half(src, 16))
587         } else {
588            SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_float_to_half(src))
589         }
590         break;
591      case GL_SHORT:
592         if (normalized) {
593            SWIZZLE_CONVERT(uint16_t, int16_t, snorm_to_half(src, 16))
594         } else {
595            SWIZZLE_CONVERT(uint16_t, int16_t, _mesa_float_to_half(src))
596         }
597         break;
598      case GL_UNSIGNED_INT:
599         if (normalized) {
600            SWIZZLE_CONVERT(uint16_t, uint32_t, unorm_to_half(src, 32))
601         } else {
602            SWIZZLE_CONVERT(uint16_t, uint32_t, _mesa_float_to_half(src))
603         }
604         break;
605      case GL_INT:
606         if (normalized) {
607            SWIZZLE_CONVERT(uint16_t, int32_t, snorm_to_half(src, 32))
608         } else {
609            SWIZZLE_CONVERT(uint16_t, int32_t, _mesa_float_to_half(src))
610         }
611         break;
612      default:
613         assert(!"Invalid channel type combination");
614      }
615   }
616}
617
618static void
619_mesa_swizzle_and_convert_unsigned_byte(
620    void *void_dst, GLenum dst_type, int num_dst_channels,
621    const void *void_src, GLenum src_type, int num_src_channels,
622    const uint8_t swizzle[4], bool normalized, int count)
623{
624   int s, j;
625   register uint8_t swizzle_x, swizzle_y, swizzle_z, swizzle_w;
626
627   swizzle_x = swizzle[0];
628   swizzle_y = swizzle[1];
629   swizzle_z = swizzle[2];
630   swizzle_w = swizzle[3];
631
632   {
633      const uint8_t one = normalized ? UINT8_MAX : 1;
634      switch (src_type) {
635      case GL_FLOAT:
636         if (normalized) {
637            SWIZZLE_CONVERT(uint8_t, float, float_to_unorm(src, 8))
638         } else {
639            SWIZZLE_CONVERT(uint8_t, float, (src < 0) ? 0 : src)
640         }
641         break;
642      case GL_HALF_FLOAT:
643         if (normalized) {
644            SWIZZLE_CONVERT(uint8_t, uint16_t, half_to_unorm(src, 8))
645         } else {
646            SWIZZLE_CONVERT(uint8_t, uint16_t, half_to_uint(src))
647         }
648         break;
649      case GL_UNSIGNED_BYTE:
650         SWIZZLE_CONVERT(uint8_t, uint8_t, src)
651         break;
652      case GL_BYTE:
653         if (normalized) {
654            SWIZZLE_CONVERT(uint8_t, int8_t, snorm_to_unorm(src, 8, 8))
655         } else {
656            SWIZZLE_CONVERT(uint8_t, int8_t, (src < 0) ? 0 : src)
657         }
658         break;
659      case GL_UNSIGNED_SHORT:
660         if (normalized) {
661            SWIZZLE_CONVERT(uint8_t, uint16_t, unorm_to_unorm(src, 16, 8))
662         } else {
663            SWIZZLE_CONVERT(uint8_t, uint16_t, src)
664         }
665         break;
666      case GL_SHORT:
667         if (normalized) {
668            SWIZZLE_CONVERT(uint8_t, int16_t, snorm_to_unorm(src, 16, 8))
669         } else {
670            SWIZZLE_CONVERT(uint8_t, int16_t, (src < 0) ? 0 : src)
671         }
672         break;
673      case GL_UNSIGNED_INT:
674         if (normalized) {
675            SWIZZLE_CONVERT(uint8_t, uint32_t, unorm_to_unorm(src, 32, 8))
676         } else {
677            SWIZZLE_CONVERT(uint8_t, uint32_t, src)
678         }
679         break;
680      case GL_INT:
681         if (normalized) {
682            SWIZZLE_CONVERT(uint8_t, int32_t, snorm_to_unorm(src, 32, 8))
683         } else {
684            SWIZZLE_CONVERT(uint8_t, int32_t, (src < 0) ? 0 : src)
685         }
686         break;
687      default:
688         assert(!"Invalid channel type combination");
689      }
690   }
691}
692
693static void
694_mesa_swizzle_and_convert_byte(
695    void *void_dst, GLenum dst_type, int num_dst_channels,
696    const void *void_src, GLenum src_type, int num_src_channels,
697    const uint8_t swizzle[4], bool normalized, int count)
698{
699   int s, j;
700   register uint8_t swizzle_x, swizzle_y, swizzle_z, swizzle_w;
701
702   swizzle_x = swizzle[0];
703   swizzle_y = swizzle[1];
704   swizzle_z = swizzle[2];
705   swizzle_w = swizzle[3];
706
707   {
708      const int8_t one = normalized ? INT8_MAX : 1;
709      switch (src_type) {
710      case GL_FLOAT:
711         if (normalized) {
712            SWIZZLE_CONVERT(uint8_t, float, float_to_snorm(src, 8))
713         } else {
714            SWIZZLE_CONVERT(uint8_t, float, src)
715         }
716         break;
717      case GL_HALF_FLOAT:
718         if (normalized) {
719            SWIZZLE_CONVERT(uint8_t, uint16_t, half_to_snorm(src, 8))
720         } else {
721            SWIZZLE_CONVERT(uint8_t, uint16_t, _mesa_half_to_float(src))
722         }
723         break;
724      case GL_UNSIGNED_BYTE:
725         if (normalized) {
726            SWIZZLE_CONVERT(int8_t, uint8_t, unorm_to_snorm(src, 8, 8))
727         } else {
728            SWIZZLE_CONVERT(int8_t, uint8_t, src)
729         }
730         break;
731      case GL_BYTE:
732         SWIZZLE_CONVERT(int8_t, int8_t, src)
733         break;
734      case GL_UNSIGNED_SHORT:
735         if (normalized) {
736            SWIZZLE_CONVERT(int8_t, uint16_t, unorm_to_snorm(src, 16, 8))
737         } else {
738            SWIZZLE_CONVERT(int8_t, uint16_t, src)
739         }
740         break;
741      case GL_SHORT:
742         if (normalized) {
743            SWIZZLE_CONVERT(int8_t, int16_t, snorm_to_snorm(src, 16, 8))
744         } else {
745            SWIZZLE_CONVERT(int8_t, int16_t, src)
746         }
747         break;
748      case GL_UNSIGNED_INT:
749         if (normalized) {
750            SWIZZLE_CONVERT(int8_t, uint32_t, unorm_to_snorm(src, 32, 8))
751         } else {
752            SWIZZLE_CONVERT(int8_t, uint32_t, src)
753         }
754         break;
755      case GL_INT:
756         if (normalized) {
757            SWIZZLE_CONVERT(int8_t, int32_t, snorm_to_snorm(src, 32, 8))
758         } else {
759            SWIZZLE_CONVERT(int8_t, int32_t, src)
760         }
761         break;
762      default:
763         assert(!"Invalid channel type combination");
764      }
765   }
766}
767
768static void
769_mesa_swizzle_and_convert_unsigned_short(
770    void *void_dst, GLenum dst_type, int num_dst_channels,
771    const void *void_src, GLenum src_type, int num_src_channels,
772    const uint8_t swizzle[4], bool normalized, int count)
773{
774   int s, j;
775   register uint8_t swizzle_x, swizzle_y, swizzle_z, swizzle_w;
776
777   swizzle_x = swizzle[0];
778   swizzle_y = swizzle[1];
779   swizzle_z = swizzle[2];
780   swizzle_w = swizzle[3];
781
782   {
783      const uint16_t one = normalized ? UINT16_MAX : 1;
784      switch (src_type) {
785      case GL_FLOAT:
786         if (normalized) {
787            SWIZZLE_CONVERT(uint16_t, float, float_to_unorm(src, 16))
788         } else {
789            SWIZZLE_CONVERT(uint16_t, float, (src < 0) ? 0 : src)
790         }
791         break;
792      case GL_HALF_FLOAT:
793         if (normalized) {
794            SWIZZLE_CONVERT(uint16_t, uint16_t, half_to_unorm(src, 16))
795         } else {
796            SWIZZLE_CONVERT(uint16_t, uint16_t, half_to_uint(src))
797         }
798         break;
799      case GL_UNSIGNED_BYTE:
800         if (normalized) {
801            SWIZZLE_CONVERT(uint16_t, uint8_t, unorm_to_unorm(src, 8, 16))
802         } else {
803            SWIZZLE_CONVERT(uint16_t, uint8_t, src)
804         }
805         break;
806      case GL_BYTE:
807         if (normalized) {
808            SWIZZLE_CONVERT(uint16_t, int8_t, snorm_to_unorm(src, 8, 16))
809         } else {
810            SWIZZLE_CONVERT(uint16_t, int8_t, (src < 0) ? 0 : src)
811         }
812         break;
813      case GL_UNSIGNED_SHORT:
814         SWIZZLE_CONVERT(uint16_t, uint16_t, src)
815         break;
816      case GL_SHORT:
817         if (normalized) {
818            SWIZZLE_CONVERT(uint16_t, int16_t, snorm_to_unorm(src, 16, 16))
819         } else {
820            SWIZZLE_CONVERT(uint16_t, int16_t, (src < 0) ? 0 : src)
821         }
822         break;
823      case GL_UNSIGNED_INT:
824         if (normalized) {
825            SWIZZLE_CONVERT(uint16_t, uint32_t, unorm_to_unorm(src, 32, 16))
826         } else {
827            SWIZZLE_CONVERT(uint16_t, uint32_t, src)
828         }
829         break;
830      case GL_INT:
831         if (normalized) {
832            SWIZZLE_CONVERT(uint16_t, int32_t, snorm_to_unorm(src, 32, 16))
833         } else {
834            SWIZZLE_CONVERT(uint16_t, int32_t, (src < 0) ? 0 : src)
835         }
836         break;
837      default:
838         assert(!"Invalid channel type combination");
839      }
840   }
841}
842
843static void
844_mesa_swizzle_and_convert_short(
845    void *void_dst, GLenum dst_type, int num_dst_channels,
846    const void *void_src, GLenum src_type, int num_src_channels,
847    const uint8_t swizzle[4], bool normalized, int count)
848{
849   int s, j;
850   register uint8_t swizzle_x, swizzle_y, swizzle_z, swizzle_w;
851
852   swizzle_x = swizzle[0];
853   swizzle_y = swizzle[1];
854   swizzle_z = swizzle[2];
855   swizzle_w = swizzle[3];
856
857   {
858      const int16_t one = normalized ? INT16_MAX : 1;
859      switch (src_type) {
860      case GL_FLOAT:
861         if (normalized) {
862            SWIZZLE_CONVERT(uint16_t, float, float_to_snorm(src, 16))
863         } else {
864            SWIZZLE_CONVERT(uint16_t, float, src)
865         }
866         break;
867      case GL_HALF_FLOAT:
868         if (normalized) {
869            SWIZZLE_CONVERT(uint16_t, uint16_t, half_to_snorm(src, 16))
870         } else {
871            SWIZZLE_CONVERT(uint16_t, uint16_t, _mesa_half_to_float(src))
872         }
873         break;
874      case GL_UNSIGNED_BYTE:
875         if (normalized) {
876            SWIZZLE_CONVERT(int16_t, uint8_t, unorm_to_snorm(src, 8, 16))
877         } else {
878            SWIZZLE_CONVERT(int16_t, uint8_t, src)
879         }
880         break;
881      case GL_BYTE:
882         if (normalized) {
883            SWIZZLE_CONVERT(int16_t, int8_t, snorm_to_snorm(src, 8, 16))
884         } else {
885            SWIZZLE_CONVERT(int16_t, int8_t, src)
886         }
887         break;
888      case GL_UNSIGNED_SHORT:
889         if (normalized) {
890            SWIZZLE_CONVERT(int16_t, uint16_t, unorm_to_snorm(src, 16, 16))
891         } else {
892            SWIZZLE_CONVERT(int16_t, uint16_t, src)
893         }
894         break;
895      case GL_SHORT:
896         SWIZZLE_CONVERT(int16_t, int16_t, src)
897         break;
898      case GL_UNSIGNED_INT:
899         if (normalized) {
900            SWIZZLE_CONVERT(int16_t, uint32_t, unorm_to_snorm(src, 32, 16))
901         } else {
902            SWIZZLE_CONVERT(int16_t, uint32_t, src)
903         }
904         break;
905      case GL_INT:
906         if (normalized) {
907            SWIZZLE_CONVERT(int16_t, int32_t, snorm_to_snorm(src, 32, 16))
908         } else {
909            SWIZZLE_CONVERT(int16_t, int32_t, src)
910         }
911         break;
912      default:
913         assert(!"Invalid channel type combination");
914      }
915   }
916}
917
918static void
919_mesa_swizzle_and_convert_unsigned_int(
920    void *void_dst, GLenum dst_type, int num_dst_channels,
921    const void *void_src, GLenum src_type, int num_src_channels,
922    const uint8_t swizzle[4], bool normalized, int count)
923{
924   int s, j;
925   register uint8_t swizzle_x, swizzle_y, swizzle_z, swizzle_w;
926
927   swizzle_x = swizzle[0];
928   swizzle_y = swizzle[1];
929   swizzle_z = swizzle[2];
930   swizzle_w = swizzle[3];
931
932   {
933      const uint32_t one = normalized ? UINT32_MAX : 1;
934      switch (src_type) { case GL_FLOAT:
935         if (normalized) {
936            SWIZZLE_CONVERT(uint32_t, float, float_to_unorm(src, 32))
937         } else {
938            SWIZZLE_CONVERT(uint32_t, float, (src < 0) ? 0 : src)
939         }
940         break;
941      case GL_HALF_FLOAT:
942         if (normalized) {
943            SWIZZLE_CONVERT(uint32_t, uint16_t, half_to_unorm(src, 32))
944         } else {
945            SWIZZLE_CONVERT(uint32_t, uint16_t, half_to_uint(src))
946         }
947         break;
948      case GL_UNSIGNED_BYTE:
949         if (normalized) {
950            SWIZZLE_CONVERT(uint32_t, uint8_t, unorm_to_unorm(src, 8, 32))
951         } else {
952            SWIZZLE_CONVERT(uint32_t, uint8_t, src)
953         }
954         break;
955      case GL_BYTE:
956         if (normalized) {
957            SWIZZLE_CONVERT(uint32_t, int8_t, snorm_to_unorm(src, 8, 32))
958         } else {
959            SWIZZLE_CONVERT(uint32_t, int8_t, (src < 0) ? 0 : src)
960         }
961         break;
962      case GL_UNSIGNED_SHORT:
963         if (normalized) {
964            SWIZZLE_CONVERT(uint32_t, uint16_t, unorm_to_unorm(src, 16, 32))
965         } else {
966            SWIZZLE_CONVERT(uint32_t, uint16_t, src)
967         }
968         break;
969      case GL_SHORT:
970         if (normalized) {
971            SWIZZLE_CONVERT(uint32_t, int16_t, snorm_to_unorm(src, 16, 32))
972         } else {
973            SWIZZLE_CONVERT(uint32_t, int16_t, (src < 0) ? 0 : src)
974         }
975         break;
976      case GL_UNSIGNED_INT:
977         SWIZZLE_CONVERT(uint32_t, uint32_t, src)
978         break;
979      case GL_INT:
980         if (normalized) {
981            SWIZZLE_CONVERT(uint32_t, int32_t, snorm_to_unorm(src, 32, 32))
982         } else {
983            SWIZZLE_CONVERT(uint32_t, int32_t, (src < 0) ? 0 : src)
984         }
985         break;
986      default:
987         assert(!"Invalid channel type combination");
988      }
989   }
990}
991
992static void
993_mesa_swizzle_and_convert_int(
994    void *void_dst, GLenum dst_type, int num_dst_channels,
995    const void *void_src, GLenum src_type, int num_src_channels,
996    const uint8_t swizzle[4], bool normalized, int count)
997{
998   int s, j;
999   register uint8_t swizzle_x, swizzle_y, swizzle_z, swizzle_w;
1000
1001   swizzle_x = swizzle[0];
1002   swizzle_y = swizzle[1];
1003   swizzle_z = swizzle[2];
1004   swizzle_w = swizzle[3];
1005
1006   {
1007      const int32_t one = normalized ? INT32_MAX : 1;
1008      switch (src_type) {
1009      case GL_FLOAT:
1010         if (normalized) {
1011            SWIZZLE_CONVERT(uint32_t, float, float_to_snorm(src, 32))
1012         } else {
1013            SWIZZLE_CONVERT(uint32_t, float, src)
1014         }
1015         break;
1016      case GL_HALF_FLOAT:
1017         if (normalized) {
1018            SWIZZLE_CONVERT(uint32_t, uint16_t, half_to_snorm(src, 32))
1019         } else {
1020            SWIZZLE_CONVERT(uint32_t, uint16_t, _mesa_half_to_float(src))
1021         }
1022         break;
1023      case GL_UNSIGNED_BYTE:
1024         if (normalized) {
1025            SWIZZLE_CONVERT(int32_t, uint8_t, unorm_to_snorm(src, 8, 32))
1026         } else {
1027            SWIZZLE_CONVERT(int32_t, uint8_t, src)
1028         }
1029         break;
1030      case GL_BYTE:
1031         if (normalized) {
1032            SWIZZLE_CONVERT(int32_t, int8_t, snorm_to_snorm(src, 8, 32))
1033         } else {
1034            SWIZZLE_CONVERT(int32_t, int8_t, src)
1035         }
1036         break;
1037      case GL_UNSIGNED_SHORT:
1038         if (normalized) {
1039            SWIZZLE_CONVERT(int32_t, uint16_t, unorm_to_snorm(src, 16, 32))
1040         } else {
1041            SWIZZLE_CONVERT(int32_t, uint16_t, src)
1042         }
1043         break;
1044      case GL_SHORT:
1045         if (normalized) {
1046            SWIZZLE_CONVERT(int32_t, int16_t, snorm_to_snorm(src, 16, 32))
1047         } else {
1048            SWIZZLE_CONVERT(int32_t, int16_t, src)
1049         }
1050         break;
1051      case GL_UNSIGNED_INT:
1052         if (normalized) {
1053            SWIZZLE_CONVERT(int32_t, uint32_t, unorm_to_snorm(src, 32, 32))
1054         } else {
1055            SWIZZLE_CONVERT(int32_t, uint32_t, src)
1056         }
1057         break;
1058      case GL_INT:
1059         SWIZZLE_CONVERT(int32_t, int32_t, src)
1060         break;
1061      default:
1062         assert(!"Invalid channel type combination");
1063      }
1064   }
1065}
1066
1067void
1068_mesa_swizzle_and_convert(void *void_dst, GLenum dst_type, int num_dst_channels,
1069                          const void *void_src, GLenum src_type, int num_src_channels,
1070                          const uint8_t swizzle[4], bool normalized, int count)
1071{
1072
1073   if (swizzle_convert_try_memcpy(void_dst, dst_type, num_dst_channels,
1074                                  void_src, src_type, num_src_channels,
1075                                  swizzle, normalized, count))
1076      return;
1077
1078   switch (dst_type) {
1079   case GL_FLOAT:
1080      _mesa_swizzle_and_convert_float(void_dst, dst_type,
1081	  num_dst_channels, void_src, src_type, num_src_channels,
1082	  swizzle, normalized, count);
1083      break;
1084   case GL_HALF_FLOAT:
1085      _mesa_swizzle_and_convert_half_float(void_dst, dst_type,
1086	  num_dst_channels, void_src, src_type, num_src_channels,
1087	  swizzle, normalized, count);
1088      break;
1089   case GL_UNSIGNED_BYTE:
1090      _mesa_swizzle_and_convert_unsigned_byte(void_dst, dst_type,
1091	  num_dst_channels, void_src, src_type, num_src_channels,
1092	  swizzle, normalized, count);
1093      break;
1094   case GL_BYTE:
1095      _mesa_swizzle_and_convert_byte(void_dst, dst_type,
1096	  num_dst_channels, void_src, src_type, num_src_channels,
1097	  swizzle, normalized, count);
1098      break;
1099   case GL_UNSIGNED_SHORT:
1100      _mesa_swizzle_and_convert_unsigned_short(void_dst, dst_type,
1101	  num_dst_channels, void_src, src_type, num_src_channels,
1102	  swizzle, normalized, count);
1103      break;
1104   case GL_SHORT:
1105      _mesa_swizzle_and_convert_short(void_dst, dst_type,
1106	  num_dst_channels, void_src, src_type, num_src_channels,
1107	  swizzle, normalized, count);
1108      break;
1109   case GL_UNSIGNED_INT:
1110      _mesa_swizzle_and_convert_unsigned_int(void_dst, dst_type,
1111	  num_dst_channels, void_src, src_type, num_src_channels,
1112	  swizzle, normalized, count);
1113      break;
1114   case GL_INT:
1115      _mesa_swizzle_and_convert_int(void_dst, dst_type,
1116	  num_dst_channels, void_src, src_type, num_src_channels,
1117	  swizzle, normalized, count);
1118      break;
1119   default:
1120      assert(!"Invalid channel type");
1121   }
1122}
1123