xref: /third_party/mesa3d/src/util/format/u_format.h (revision bf215546)
1/**************************************************************************
2 *
3 * Copyright 2009-2010 VMware, Inc.
4 * 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
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29#ifndef U_FORMAT_H
30#define U_FORMAT_H
31
32
33#include "pipe/p_format.h"
34#include "pipe/p_defines.h"
35#include "util/u_debug.h"
36
37#include "c99_compat.h"
38
39union pipe_color_union;
40struct pipe_screen;
41
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47
48/**
49 * Describe how to pack/unpack pixels into/from the prescribed format.
50 *
51 * XXX: This could be renamed to something like util_format_pack, or broke down
52 * in flags inside util_format_block that said exactly what we want.
53 */
54enum util_format_layout {
55   /**
56    * Formats with util_format_block::width == util_format_block::height == 1
57    * that can be described as an ordinary data structure.
58    */
59   UTIL_FORMAT_LAYOUT_PLAIN,
60
61   /**
62    * Formats with sub-sampled channels.
63    *
64    * This is for formats like YVYU where there is less than one sample per
65    * pixel.
66    */
67   UTIL_FORMAT_LAYOUT_SUBSAMPLED,
68
69   /**
70    * S3 Texture Compression formats.
71    */
72   UTIL_FORMAT_LAYOUT_S3TC,
73
74   /**
75    * Red-Green Texture Compression formats.
76    */
77   UTIL_FORMAT_LAYOUT_RGTC,
78
79   /**
80    * Ericsson Texture Compression
81    */
82   UTIL_FORMAT_LAYOUT_ETC,
83
84   /**
85    * BC6/7 Texture Compression
86    */
87   UTIL_FORMAT_LAYOUT_BPTC,
88
89   UTIL_FORMAT_LAYOUT_ASTC,
90
91   UTIL_FORMAT_LAYOUT_ATC,
92
93   /** Formats with 2 or more planes. */
94   UTIL_FORMAT_LAYOUT_PLANAR2,
95   UTIL_FORMAT_LAYOUT_PLANAR3,
96
97   UTIL_FORMAT_LAYOUT_FXT1 = 10,
98
99   /**
100    * Everything else that doesn't fit in any of the above layouts.
101    */
102   UTIL_FORMAT_LAYOUT_OTHER,
103};
104
105
106struct util_format_block
107{
108   /** Block width in pixels */
109   unsigned width;
110
111   /** Block height in pixels */
112   unsigned height;
113
114   /** Block depth in pixels */
115   unsigned depth;
116
117   /** Block size in bits */
118   unsigned bits;
119};
120
121
122enum util_format_type {
123   UTIL_FORMAT_TYPE_VOID = 0,
124   UTIL_FORMAT_TYPE_UNSIGNED = 1,
125   UTIL_FORMAT_TYPE_SIGNED = 2,
126   UTIL_FORMAT_TYPE_FIXED = 3,
127   UTIL_FORMAT_TYPE_FLOAT = 4
128};
129
130
131enum util_format_colorspace {
132   UTIL_FORMAT_COLORSPACE_RGB = 0,
133   UTIL_FORMAT_COLORSPACE_SRGB = 1,
134   UTIL_FORMAT_COLORSPACE_YUV = 2,
135   UTIL_FORMAT_COLORSPACE_ZS = 3
136};
137
138
139struct util_format_channel_description
140{
141   unsigned type:5;        /**< UTIL_FORMAT_TYPE_x */
142   unsigned normalized:1;
143   unsigned pure_integer:1;
144   unsigned size:9;        /**< bits per channel */
145   unsigned shift:16;      /** number of bits from lsb */
146};
147
148
149struct util_format_description
150{
151   enum pipe_format format;
152
153   const char *name;
154
155   /**
156    * Short name, striped of the prefix, lower case.
157    */
158   const char *short_name;
159
160   /**
161    * Pixel block dimensions.
162    */
163   struct util_format_block block;
164
165   enum util_format_layout layout;
166
167   /**
168    * The number of channels.
169    */
170   unsigned nr_channels:3;
171
172   /**
173    * Whether all channels have the same number of (whole) bytes and type.
174    */
175   unsigned is_array:1;
176
177   /**
178    * Whether the pixel format can be described as a bitfield structure.
179    *
180    * In particular:
181    * - pixel depth must be 8, 16, or 32 bits;
182    * - all channels must be unsigned, signed, or void
183    */
184   unsigned is_bitmask:1;
185
186   /**
187    * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
188    */
189   unsigned is_mixed:1;
190
191   /**
192    * Whether the format contains UNORM channels
193    */
194   unsigned is_unorm:1;
195
196   /**
197    * Whether the format contains SNORM channels
198    */
199   unsigned is_snorm:1;
200
201   /**
202    * Input channel description, in the order XYZW.
203    *
204    * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.
205    *
206    * If each channel is accessed as an individual N-byte value, X is always
207    * at the lowest address in memory, Y is always next, and so on.  For all
208    * currently-defined formats, the N-byte value has native endianness.
209    *
210    * If instead a group of channels is accessed as a single N-byte value,
211    * the order of the channels within that value depends on endianness.
212    * For big-endian targets, X is the most significant subvalue,
213    * otherwise it is the least significant one.
214    *
215    * For example, if X is 8 bits and Y is 24 bits, the memory order is:
216    *
217    *                 0  1  2  3
218    *  little-endian: X  Yl Ym Yu    (l = lower, m = middle, u = upper)
219    *  big-endian:    X  Yu Ym Yl
220    *
221    * If X is 5 bits, Y is 5 bits, Z is 5 bits and W is 1 bit, the layout is:
222    *
223    *                        0        1
224    *                 msb  lsb msb  lsb
225    *  little-endian: YYYXXXXX WZZZZZYY
226    *  big-endian:    XXXXXYYY YYZZZZZW
227    */
228   struct util_format_channel_description channel[4];
229
230   /**
231    * Output channel swizzle.
232    *
233    * The order is either:
234    * - RGBA
235    * - YUV(A)
236    * - ZS
237    * depending on the colorspace.
238    */
239   unsigned char swizzle[4];
240
241   /**
242    * Colorspace transformation.
243    */
244   enum util_format_colorspace colorspace;
245};
246
247struct util_format_pack_description {
248   /**
249    * Pack pixel blocks from R8G8B8A8_UNORM.
250    * Note: strides are in bytes.
251    *
252    * Only defined for non-depth-stencil formats.
253    */
254   void
255   (*pack_rgba_8unorm)(uint8_t *restrict dst, unsigned dst_stride,
256                       const uint8_t *restrict src, unsigned src_stride,
257                       unsigned width, unsigned height);
258
259   /**
260    * Pack pixel blocks from R32G32B32A32_FLOAT.
261    * Note: strides are in bytes.
262    *
263    * Only defined for non-depth-stencil formats.
264    */
265   void
266   (*pack_rgba_float)(uint8_t *restrict dst, unsigned dst_stride,
267                      const float *restrict src, unsigned src_stride,
268                      unsigned width, unsigned height);
269
270   /**
271    * Pack pixels from Z32_FLOAT.
272    * Note: strides are in bytes.
273    *
274    * Only defined for depth formats.
275    */
276   void
277   (*pack_z_32unorm)(uint8_t *restrict dst, unsigned dst_stride,
278                     const uint32_t *restrict src, unsigned src_stride,
279                     unsigned width, unsigned height);
280
281   /**
282    * Pack pixels from Z32_FLOAT.
283    * Note: strides are in bytes.
284    *
285    * Only defined for depth formats.
286    */
287   void
288   (*pack_z_float)(uint8_t *restrict dst, unsigned dst_stride,
289                   const float *restrict src, unsigned src_stride,
290                   unsigned width, unsigned height);
291
292   /**
293    * Pack pixels from S8_UINT.
294    * Note: strides are in bytes.
295    *
296    * Only defined for stencil formats.
297    */
298   void
299   (*pack_s_8uint)(uint8_t *restrict dst, unsigned dst_stride,
300                   const uint8_t *restrict src, unsigned src_stride,
301                   unsigned width, unsigned height);
302
303   void
304   (*pack_rgba_uint)(uint8_t *restrict dst, unsigned dst_stride,
305                     const uint32_t *restrict src, unsigned src_stride,
306                     unsigned width, unsigned height);
307
308   void
309   (*pack_rgba_sint)(uint8_t *restrict dst, unsigned dst_stride,
310                     const int32_t *restrict src, unsigned src_stride,
311                     unsigned width, unsigned height);
312};
313
314
315struct util_format_unpack_description {
316   /**
317    * Unpack pixel blocks to R8G8B8A8_UNORM.
318    * Note: strides are in bytes.
319    *
320    * Only defined for non-block non-depth-stencil formats.
321    */
322   void
323   (*unpack_rgba_8unorm)(uint8_t *restrict dst, const uint8_t *restrict src,
324                         unsigned width);
325
326   /**
327    * Unpack pixel blocks to R8G8B8A8_UNORM.
328    * Note: strides are in bytes.
329    *
330    * Only defined for block non-depth-stencil formats.
331    */
332   void
333   (*unpack_rgba_8unorm_rect)(uint8_t *restrict dst, unsigned dst_stride,
334                         const uint8_t *restrict src, unsigned src_stride,
335                         unsigned width, unsigned height);
336
337   /**
338    * Fetch a single pixel (i, j) from a block.
339    *
340    * XXX: Only defined for a very few select formats.
341    */
342   void
343   (*fetch_rgba_8unorm)(uint8_t *restrict dst,
344                        const uint8_t *restrict src,
345                        unsigned i, unsigned j);
346
347   /**
348    * Unpack pixel blocks to R32G32B32A32_UINT/_INT_FLOAT based on whether the
349    * type is pure uint, int, or other.
350    *
351    * Note: strides are in bytes.
352    *
353    * Only defined for non-block non-depth-stencil formats.
354    */
355   void
356   (*unpack_rgba)(void *restrict dst, const uint8_t *restrict src,
357                  unsigned width);
358
359   /**
360    * Unpack pixel blocks to R32G32B32A32_UINT/_INT_FLOAT based on whether the
361    * type is pure uint, int, or other.
362    *
363    * Note: strides are in bytes.
364    *
365    * Only defined for block non-depth-stencil formats.
366    */
367   void
368   (*unpack_rgba_rect)(void *restrict dst, unsigned dst_stride,
369                  const uint8_t *restrict src, unsigned src_stride,
370                  unsigned width, unsigned height);
371
372   /**
373    * Unpack pixels to Z32_UNORM.
374    * Note: strides are in bytes.
375    *
376    * Only defined for depth formats.
377    */
378   void
379   (*unpack_z_32unorm)(uint32_t *restrict dst, unsigned dst_stride,
380                       const uint8_t *restrict src, unsigned src_stride,
381                       unsigned width, unsigned height);
382
383   /**
384    * Unpack pixels to Z32_FLOAT.
385    * Note: strides are in bytes.
386    *
387    * Only defined for depth formats.
388    */
389   void
390   (*unpack_z_float)(float *restrict dst, unsigned dst_stride,
391                     const uint8_t *restrict src, unsigned src_stride,
392                     unsigned width, unsigned height);
393
394   /**
395    * Unpack pixels to S8_UINT.
396    * Note: strides are in bytes.
397    *
398    * Only defined for stencil formats.
399    */
400   void
401   (*unpack_s_8uint)(uint8_t *restrict dst, unsigned dst_stride,
402                     const uint8_t *restrict src, unsigned src_stride,
403                     unsigned width, unsigned height);
404};
405
406typedef void (*util_format_fetch_rgba_func_ptr)(void *restrict dst, const uint8_t *restrict src,
407                                                unsigned i, unsigned j);
408
409/* Silence warnings triggered by sharing function/struct names */
410#ifdef __GNUC__
411#pragma GCC diagnostic push
412#pragma GCC diagnostic ignored "-Wshadow"
413#endif
414const struct util_format_description *
415util_format_description(enum pipe_format format) ATTRIBUTE_CONST;
416
417const struct util_format_pack_description *
418util_format_pack_description(enum pipe_format format) ATTRIBUTE_CONST;
419
420/* Lookup with CPU detection for choosing optimized paths. */
421const struct util_format_unpack_description *
422util_format_unpack_description(enum pipe_format format) ATTRIBUTE_CONST;
423
424/* Codegenned table of CPU-agnostic unpack code. */
425const struct util_format_unpack_description *
426util_format_unpack_description_generic(enum pipe_format format) ATTRIBUTE_CONST;
427
428const struct util_format_unpack_description *
429util_format_unpack_description_neon(enum pipe_format format) ATTRIBUTE_CONST;
430
431#ifdef __GNUC__
432#pragma GCC diagnostic pop
433#endif
434
435/**
436 * Returns a function to fetch a single pixel (i, j) from a block.
437 *
438 * Only defined for non-depth-stencil and non-integer formats.
439 */
440util_format_fetch_rgba_func_ptr
441util_format_fetch_rgba_func(enum pipe_format format) ATTRIBUTE_CONST;
442
443/*
444 * Format query functions.
445 */
446
447static inline const char *
448util_format_name(enum pipe_format format)
449{
450   const struct util_format_description *desc = util_format_description(format);
451
452   assert(desc);
453   if (!desc) {
454      return "PIPE_FORMAT_???";
455   }
456
457   return desc->name;
458}
459
460static inline const char *
461util_format_short_name(enum pipe_format format)
462{
463   const struct util_format_description *desc = util_format_description(format);
464
465   assert(desc);
466   if (!desc) {
467      return "???";
468   }
469
470   return desc->short_name;
471}
472
473/**
474 * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
475 */
476static inline boolean
477util_format_is_plain(enum pipe_format format)
478{
479   const struct util_format_description *desc = util_format_description(format);
480
481   if (!format) {
482      return FALSE;
483   }
484
485   return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;
486}
487
488static inline boolean
489util_format_is_compressed(enum pipe_format format)
490{
491   const struct util_format_description *desc = util_format_description(format);
492
493   assert(desc);
494   if (!desc) {
495      return FALSE;
496   }
497
498   switch (desc->layout) {
499   case UTIL_FORMAT_LAYOUT_S3TC:
500   case UTIL_FORMAT_LAYOUT_RGTC:
501   case UTIL_FORMAT_LAYOUT_ETC:
502   case UTIL_FORMAT_LAYOUT_BPTC:
503   case UTIL_FORMAT_LAYOUT_ASTC:
504   case UTIL_FORMAT_LAYOUT_ATC:
505   case UTIL_FORMAT_LAYOUT_FXT1:
506      /* XXX add other formats in the future */
507      return TRUE;
508   default:
509      return FALSE;
510   }
511}
512
513static inline boolean
514util_format_is_s3tc(enum pipe_format format)
515{
516   const struct util_format_description *desc = util_format_description(format);
517
518   assert(desc);
519   if (!desc) {
520      return FALSE;
521   }
522
523   return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
524}
525
526static inline boolean
527util_format_is_etc(enum pipe_format format)
528{
529   const struct util_format_description *desc = util_format_description(format);
530
531   assert(desc);
532   if (!desc) {
533      return FALSE;
534   }
535
536   return desc->layout == UTIL_FORMAT_LAYOUT_ETC ? TRUE : FALSE;
537}
538
539static inline boolean
540util_format_is_srgb(enum pipe_format format)
541{
542   const struct util_format_description *desc = util_format_description(format);
543   return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;
544}
545
546static inline boolean
547util_format_has_depth(const struct util_format_description *desc)
548{
549   return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
550          desc->swizzle[0] != PIPE_SWIZZLE_NONE;
551}
552
553static inline boolean
554util_format_has_stencil(const struct util_format_description *desc)
555{
556   return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
557          desc->swizzle[1] != PIPE_SWIZZLE_NONE;
558}
559
560static inline boolean
561util_format_is_depth_or_stencil(enum pipe_format format)
562{
563   const struct util_format_description *desc = util_format_description(format);
564
565   assert(desc);
566   if (!desc) {
567      return FALSE;
568   }
569
570   return util_format_has_depth(desc) ||
571          util_format_has_stencil(desc);
572}
573
574static inline boolean
575util_format_is_depth_and_stencil(enum pipe_format format)
576{
577   const struct util_format_description *desc = util_format_description(format);
578
579   assert(desc);
580   if (!desc) {
581      return FALSE;
582   }
583
584   return util_format_has_depth(desc) &&
585          util_format_has_stencil(desc);
586}
587
588/**
589 * For depth-stencil formats, return the equivalent depth-only format.
590 */
591static inline enum pipe_format
592util_format_get_depth_only(enum pipe_format format)
593{
594   switch (format) {
595   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
596      return PIPE_FORMAT_Z24X8_UNORM;
597
598   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
599      return PIPE_FORMAT_X8Z24_UNORM;
600
601   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
602      return PIPE_FORMAT_Z32_FLOAT;
603
604   default:
605      return format;
606   }
607}
608
609static inline boolean
610util_format_is_yuv(enum pipe_format format)
611{
612   const struct util_format_description *desc = util_format_description(format);
613
614   assert(desc);
615   if (!desc) {
616      return FALSE;
617   }
618
619   return desc->colorspace == UTIL_FORMAT_COLORSPACE_YUV;
620}
621
622/**
623 * Calculates the depth format type based upon the incoming format description.
624 */
625static inline unsigned
626util_get_depth_format_type(const struct util_format_description *desc)
627{
628   unsigned depth_channel = desc->swizzle[0];
629   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
630       depth_channel != PIPE_SWIZZLE_NONE) {
631      return desc->channel[depth_channel].type;
632   } else {
633      return UTIL_FORMAT_TYPE_VOID;
634   }
635}
636
637
638/**
639 * Calculates the MRD for the depth format. MRD is used in depth bias
640 * for UNORM and unbound depth buffers. When the depth buffer is floating
641 * point, the depth bias calculation does not use the MRD. However, the
642 * default MRD will be 1.0 / ((1 << 24) - 1).
643 */
644double
645util_get_depth_format_mrd(const struct util_format_description *desc);
646
647
648/**
649 * Return whether this is an RGBA, Z, S, or combined ZS format.
650 * Useful for initializing pipe_blit_info::mask.
651 */
652static inline unsigned
653util_format_get_mask(enum pipe_format format)
654{
655   const struct util_format_description *desc =
656      util_format_description(format);
657
658   if (!desc)
659      return 0;
660
661   if (util_format_has_depth(desc)) {
662      if (util_format_has_stencil(desc)) {
663         return PIPE_MASK_ZS;
664      } else {
665         return PIPE_MASK_Z;
666      }
667   } else {
668      if (util_format_has_stencil(desc)) {
669         return PIPE_MASK_S;
670      } else {
671         return PIPE_MASK_RGBA;
672      }
673   }
674}
675
676/**
677 * Give the RGBA colormask of the channels that can be represented in this
678 * format.
679 *
680 * That is, the channels whose values are preserved.
681 */
682static inline unsigned
683util_format_colormask(const struct util_format_description *desc)
684{
685   unsigned colormask;
686   unsigned chan;
687
688   switch (desc->colorspace) {
689   case UTIL_FORMAT_COLORSPACE_RGB:
690   case UTIL_FORMAT_COLORSPACE_SRGB:
691   case UTIL_FORMAT_COLORSPACE_YUV:
692      colormask = 0;
693      for (chan = 0; chan < 4; ++chan) {
694         if (desc->swizzle[chan] < 4) {
695            colormask |= (1 << chan);
696         }
697      }
698      return colormask;
699   case UTIL_FORMAT_COLORSPACE_ZS:
700      return 0;
701   default:
702      assert(0);
703      return 0;
704   }
705}
706
707
708/**
709 * Checks if color mask covers every channel for the specified format
710 *
711 * @param desc       a format description to check colormask with
712 * @param colormask  a bit mask for channels, matches format of PIPE_MASK_RGBA
713 */
714static inline boolean
715util_format_colormask_full(const struct util_format_description *desc, unsigned colormask)
716{
717   return (~colormask & util_format_colormask(desc)) == 0;
718}
719
720
721boolean
722util_format_is_float(enum pipe_format format) ATTRIBUTE_CONST;
723
724
725boolean
726util_format_has_alpha(enum pipe_format format) ATTRIBUTE_CONST;
727
728boolean
729util_format_has_alpha1(enum pipe_format format) ATTRIBUTE_CONST;
730
731boolean
732util_format_is_luminance(enum pipe_format format) ATTRIBUTE_CONST;
733
734boolean
735util_format_is_alpha(enum pipe_format format) ATTRIBUTE_CONST;
736
737boolean
738util_format_is_luminance_alpha(enum pipe_format format) ATTRIBUTE_CONST;
739
740
741boolean
742util_format_is_intensity(enum pipe_format format) ATTRIBUTE_CONST;
743
744boolean
745util_format_is_subsampled_422(enum pipe_format format) ATTRIBUTE_CONST;
746
747boolean
748util_format_is_pure_integer(enum pipe_format format) ATTRIBUTE_CONST;
749
750boolean
751util_format_is_pure_sint(enum pipe_format format) ATTRIBUTE_CONST;
752
753boolean
754util_format_is_pure_uint(enum pipe_format format) ATTRIBUTE_CONST;
755
756boolean
757util_format_is_snorm(enum pipe_format format) ATTRIBUTE_CONST;
758
759boolean
760util_format_is_unorm(enum pipe_format format) ATTRIBUTE_CONST;
761
762boolean
763util_format_is_snorm8(enum pipe_format format) ATTRIBUTE_CONST;
764
765boolean
766util_format_is_scaled(enum pipe_format format) ATTRIBUTE_CONST;
767/**
768 * Check if the src format can be blitted to the destination format with
769 * a simple memcpy.  For example, blitting from RGBA to RGBx is OK, but not
770 * the reverse.
771 */
772boolean
773util_is_format_compatible(const struct util_format_description *src_desc,
774                          const struct util_format_description *dst_desc) ATTRIBUTE_CONST;
775
776/**
777 * Whether this format is a rgab8 variant.
778 *
779 * That is, any format that matches the
780 *
781 *   PIPE_FORMAT_?8?8?8?8_UNORM
782 */
783static inline boolean
784util_format_is_rgba8_variant(const struct util_format_description *desc)
785{
786   unsigned chan;
787
788   if(desc->block.width != 1 ||
789      desc->block.height != 1 ||
790      desc->block.bits != 32)
791      return FALSE;
792
793   for(chan = 0; chan < 4; ++chan) {
794      if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
795         desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
796         return FALSE;
797      if(desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED &&
798         !desc->channel[chan].normalized)
799         return FALSE;
800      if(desc->channel[chan].size != 8)
801         return FALSE;
802   }
803
804   return TRUE;
805}
806
807
808static inline bool
809util_format_is_rgbx_or_bgrx(enum pipe_format format)
810{
811   const struct util_format_description *desc = util_format_description(format);
812   return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
813          desc->nr_channels == 4 &&
814          (desc->swizzle[0] == PIPE_SWIZZLE_X || desc->swizzle[0] == PIPE_SWIZZLE_Z) &&
815          desc->swizzle[1] == PIPE_SWIZZLE_Y &&
816          (desc->swizzle[2] == PIPE_SWIZZLE_Z || desc->swizzle[2] == PIPE_SWIZZLE_X) &&
817          desc->swizzle[3] == PIPE_SWIZZLE_1;
818}
819
820/**
821 * Return total bits needed for the pixel format per block.
822 */
823static inline uint
824util_format_get_blocksizebits(enum pipe_format format)
825{
826   const struct util_format_description *desc = util_format_description(format);
827
828   assert(desc);
829   if (!desc) {
830      return 0;
831   }
832
833   return desc->block.bits;
834}
835
836/**
837 * Return bytes per block (not pixel) for the given format.
838 */
839static inline uint
840util_format_get_blocksize(enum pipe_format format)
841{
842   uint bits = util_format_get_blocksizebits(format);
843   uint bytes = bits / 8;
844
845   assert(bits % 8 == 0);
846   /* Some formats have bits set to 0, let's default to 1.*/
847   if (bytes == 0) {
848      bytes = 1;
849   }
850
851   return bytes;
852}
853
854static inline uint
855util_format_get_blockwidth(enum pipe_format format)
856{
857   const struct util_format_description *desc = util_format_description(format);
858
859   assert(desc);
860   if (!desc) {
861      return 1;
862   }
863
864   return desc->block.width;
865}
866
867static inline uint
868util_format_get_blockheight(enum pipe_format format)
869{
870   const struct util_format_description *desc = util_format_description(format);
871
872   assert(desc);
873   if (!desc) {
874      return 1;
875   }
876
877   return desc->block.height;
878}
879
880static inline uint
881util_format_get_blockdepth(enum pipe_format format)
882{
883   const struct util_format_description *desc = util_format_description(format);
884
885   assert(desc);
886   if (!desc) {
887      return 1;
888   }
889
890   return desc->block.depth;
891}
892
893static inline unsigned
894util_format_get_nblocksx(enum pipe_format format,
895                         unsigned x)
896{
897   unsigned blockwidth = util_format_get_blockwidth(format);
898   return (x + blockwidth - 1) / blockwidth;
899}
900
901static inline unsigned
902util_format_get_nblocksy(enum pipe_format format,
903                         unsigned y)
904{
905   unsigned blockheight = util_format_get_blockheight(format);
906   return (y + blockheight - 1) / blockheight;
907}
908
909static inline unsigned
910util_format_get_nblocksz(enum pipe_format format,
911                         unsigned z)
912{
913   unsigned blockdepth = util_format_get_blockdepth(format);
914   return (z + blockdepth - 1) / blockdepth;
915}
916
917static inline unsigned
918util_format_get_nblocks(enum pipe_format format,
919                        unsigned width,
920                        unsigned height)
921{
922   assert(util_format_get_blockdepth(format) == 1);
923   return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);
924}
925
926static inline size_t
927util_format_get_stride(enum pipe_format format,
928                       unsigned width)
929{
930   return (size_t)util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
931}
932
933static inline size_t
934util_format_get_2d_size(enum pipe_format format,
935                        size_t stride,
936                        unsigned height)
937{
938   return util_format_get_nblocksy(format, height) * stride;
939}
940
941static inline uint
942util_format_get_component_bits(enum pipe_format format,
943                               enum util_format_colorspace colorspace,
944                               uint component)
945{
946   const struct util_format_description *desc = util_format_description(format);
947   enum util_format_colorspace desc_colorspace;
948
949   assert(format);
950   if (!format) {
951      return 0;
952   }
953
954   assert(component < 4);
955
956   /* Treat RGB and SRGB as equivalent. */
957   if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
958      colorspace = UTIL_FORMAT_COLORSPACE_RGB;
959   }
960   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
961      desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
962   } else {
963      desc_colorspace = desc->colorspace;
964   }
965
966   if (desc_colorspace != colorspace) {
967      return 0;
968   }
969
970   switch (desc->swizzle[component]) {
971   case PIPE_SWIZZLE_X:
972      return desc->channel[0].size;
973   case PIPE_SWIZZLE_Y:
974      return desc->channel[1].size;
975   case PIPE_SWIZZLE_Z:
976      return desc->channel[2].size;
977   case PIPE_SWIZZLE_W:
978      return desc->channel[3].size;
979   default:
980      return 0;
981   }
982}
983
984/**
985 * Given a linear RGB colorspace format, return the corresponding SRGB
986 * format, or PIPE_FORMAT_NONE if none.
987 */
988static inline enum pipe_format
989util_format_srgb(enum pipe_format format)
990{
991   if (util_format_is_srgb(format))
992      return format;
993
994   switch (format) {
995   case PIPE_FORMAT_L8_UNORM:
996      return PIPE_FORMAT_L8_SRGB;
997   case PIPE_FORMAT_R8_UNORM:
998      return PIPE_FORMAT_R8_SRGB;
999   case PIPE_FORMAT_L8A8_UNORM:
1000      return PIPE_FORMAT_L8A8_SRGB;
1001   case PIPE_FORMAT_R8G8_UNORM:
1002      return PIPE_FORMAT_R8G8_SRGB;
1003   case PIPE_FORMAT_R8G8B8_UNORM:
1004      return PIPE_FORMAT_R8G8B8_SRGB;
1005   case PIPE_FORMAT_B8G8R8_UNORM:
1006      return PIPE_FORMAT_B8G8R8_SRGB;
1007   case PIPE_FORMAT_A8B8G8R8_UNORM:
1008      return PIPE_FORMAT_A8B8G8R8_SRGB;
1009   case PIPE_FORMAT_X8B8G8R8_UNORM:
1010      return PIPE_FORMAT_X8B8G8R8_SRGB;
1011   case PIPE_FORMAT_B8G8R8A8_UNORM:
1012      return PIPE_FORMAT_B8G8R8A8_SRGB;
1013   case PIPE_FORMAT_B8G8R8X8_UNORM:
1014      return PIPE_FORMAT_B8G8R8X8_SRGB;
1015   case PIPE_FORMAT_A8R8G8B8_UNORM:
1016      return PIPE_FORMAT_A8R8G8B8_SRGB;
1017   case PIPE_FORMAT_X8R8G8B8_UNORM:
1018      return PIPE_FORMAT_X8R8G8B8_SRGB;
1019   case PIPE_FORMAT_R8G8B8A8_UNORM:
1020      return PIPE_FORMAT_R8G8B8A8_SRGB;
1021   case PIPE_FORMAT_R8G8B8X8_UNORM:
1022      return PIPE_FORMAT_R8G8B8X8_SRGB;
1023   case PIPE_FORMAT_DXT1_RGB:
1024      return PIPE_FORMAT_DXT1_SRGB;
1025   case PIPE_FORMAT_DXT1_RGBA:
1026      return PIPE_FORMAT_DXT1_SRGBA;
1027   case PIPE_FORMAT_DXT3_RGBA:
1028      return PIPE_FORMAT_DXT3_SRGBA;
1029   case PIPE_FORMAT_DXT5_RGBA:
1030      return PIPE_FORMAT_DXT5_SRGBA;
1031   case PIPE_FORMAT_R5G6B5_UNORM:
1032      return PIPE_FORMAT_R5G6B5_SRGB;
1033   case PIPE_FORMAT_B5G6R5_UNORM:
1034      return PIPE_FORMAT_B5G6R5_SRGB;
1035   case PIPE_FORMAT_BPTC_RGBA_UNORM:
1036      return PIPE_FORMAT_BPTC_SRGBA;
1037   case PIPE_FORMAT_ETC2_RGB8:
1038      return PIPE_FORMAT_ETC2_SRGB8;
1039   case PIPE_FORMAT_ETC2_RGB8A1:
1040      return PIPE_FORMAT_ETC2_SRGB8A1;
1041   case PIPE_FORMAT_ETC2_RGBA8:
1042      return PIPE_FORMAT_ETC2_SRGBA8;
1043   case PIPE_FORMAT_ASTC_4x4:
1044      return PIPE_FORMAT_ASTC_4x4_SRGB;
1045   case PIPE_FORMAT_ASTC_5x4:
1046      return PIPE_FORMAT_ASTC_5x4_SRGB;
1047   case PIPE_FORMAT_ASTC_5x5:
1048      return PIPE_FORMAT_ASTC_5x5_SRGB;
1049   case PIPE_FORMAT_ASTC_6x5:
1050      return PIPE_FORMAT_ASTC_6x5_SRGB;
1051   case PIPE_FORMAT_ASTC_6x6:
1052      return PIPE_FORMAT_ASTC_6x6_SRGB;
1053   case PIPE_FORMAT_ASTC_8x5:
1054      return PIPE_FORMAT_ASTC_8x5_SRGB;
1055   case PIPE_FORMAT_ASTC_8x6:
1056      return PIPE_FORMAT_ASTC_8x6_SRGB;
1057   case PIPE_FORMAT_ASTC_8x8:
1058      return PIPE_FORMAT_ASTC_8x8_SRGB;
1059   case PIPE_FORMAT_ASTC_10x5:
1060      return PIPE_FORMAT_ASTC_10x5_SRGB;
1061   case PIPE_FORMAT_ASTC_10x6:
1062      return PIPE_FORMAT_ASTC_10x6_SRGB;
1063   case PIPE_FORMAT_ASTC_10x8:
1064      return PIPE_FORMAT_ASTC_10x8_SRGB;
1065   case PIPE_FORMAT_ASTC_10x10:
1066      return PIPE_FORMAT_ASTC_10x10_SRGB;
1067   case PIPE_FORMAT_ASTC_12x10:
1068      return PIPE_FORMAT_ASTC_12x10_SRGB;
1069   case PIPE_FORMAT_ASTC_12x12:
1070      return PIPE_FORMAT_ASTC_12x12_SRGB;
1071   case PIPE_FORMAT_ASTC_3x3x3:
1072      return PIPE_FORMAT_ASTC_3x3x3_SRGB;
1073   case PIPE_FORMAT_ASTC_4x3x3:
1074      return PIPE_FORMAT_ASTC_4x3x3_SRGB;
1075   case PIPE_FORMAT_ASTC_4x4x3:
1076      return PIPE_FORMAT_ASTC_4x4x3_SRGB;
1077   case PIPE_FORMAT_ASTC_4x4x4:
1078      return PIPE_FORMAT_ASTC_4x4x4_SRGB;
1079   case PIPE_FORMAT_ASTC_5x4x4:
1080      return PIPE_FORMAT_ASTC_5x4x4_SRGB;
1081   case PIPE_FORMAT_ASTC_5x5x4:
1082      return PIPE_FORMAT_ASTC_5x5x4_SRGB;
1083   case PIPE_FORMAT_ASTC_5x5x5:
1084      return PIPE_FORMAT_ASTC_5x5x5_SRGB;
1085   case PIPE_FORMAT_ASTC_6x5x5:
1086      return PIPE_FORMAT_ASTC_6x5x5_SRGB;
1087   case PIPE_FORMAT_ASTC_6x6x5:
1088      return PIPE_FORMAT_ASTC_6x6x5_SRGB;
1089   case PIPE_FORMAT_ASTC_6x6x6:
1090      return PIPE_FORMAT_ASTC_6x6x6_SRGB;
1091
1092   default:
1093      return PIPE_FORMAT_NONE;
1094   }
1095}
1096
1097/**
1098 * Given an sRGB format, return the corresponding linear colorspace format.
1099 * For non sRGB formats, return the format unchanged.
1100 */
1101static inline enum pipe_format
1102util_format_linear(enum pipe_format format)
1103{
1104   switch (format) {
1105   case PIPE_FORMAT_L8_SRGB:
1106      return PIPE_FORMAT_L8_UNORM;
1107   case PIPE_FORMAT_R8_SRGB:
1108      return PIPE_FORMAT_R8_UNORM;
1109   case PIPE_FORMAT_L8A8_SRGB:
1110      return PIPE_FORMAT_L8A8_UNORM;
1111   case PIPE_FORMAT_R8G8_SRGB:
1112      return PIPE_FORMAT_R8G8_UNORM;
1113   case PIPE_FORMAT_R8G8B8_SRGB:
1114      return PIPE_FORMAT_R8G8B8_UNORM;
1115   case PIPE_FORMAT_B8G8R8_SRGB:
1116      return PIPE_FORMAT_B8G8R8_UNORM;
1117   case PIPE_FORMAT_A8B8G8R8_SRGB:
1118      return PIPE_FORMAT_A8B8G8R8_UNORM;
1119   case PIPE_FORMAT_X8B8G8R8_SRGB:
1120      return PIPE_FORMAT_X8B8G8R8_UNORM;
1121   case PIPE_FORMAT_B8G8R8A8_SRGB:
1122      return PIPE_FORMAT_B8G8R8A8_UNORM;
1123   case PIPE_FORMAT_B8G8R8X8_SRGB:
1124      return PIPE_FORMAT_B8G8R8X8_UNORM;
1125   case PIPE_FORMAT_A8R8G8B8_SRGB:
1126      return PIPE_FORMAT_A8R8G8B8_UNORM;
1127   case PIPE_FORMAT_X8R8G8B8_SRGB:
1128      return PIPE_FORMAT_X8R8G8B8_UNORM;
1129   case PIPE_FORMAT_R8G8B8A8_SRGB:
1130      return PIPE_FORMAT_R8G8B8A8_UNORM;
1131   case PIPE_FORMAT_R8G8B8X8_SRGB:
1132      return PIPE_FORMAT_R8G8B8X8_UNORM;
1133   case PIPE_FORMAT_DXT1_SRGB:
1134      return PIPE_FORMAT_DXT1_RGB;
1135   case PIPE_FORMAT_DXT1_SRGBA:
1136      return PIPE_FORMAT_DXT1_RGBA;
1137   case PIPE_FORMAT_DXT3_SRGBA:
1138      return PIPE_FORMAT_DXT3_RGBA;
1139   case PIPE_FORMAT_DXT5_SRGBA:
1140      return PIPE_FORMAT_DXT5_RGBA;
1141   case PIPE_FORMAT_R5G6B5_SRGB:
1142      return PIPE_FORMAT_R5G6B5_UNORM;
1143   case PIPE_FORMAT_B5G6R5_SRGB:
1144      return PIPE_FORMAT_B5G6R5_UNORM;
1145   case PIPE_FORMAT_BPTC_SRGBA:
1146      return PIPE_FORMAT_BPTC_RGBA_UNORM;
1147   case PIPE_FORMAT_ETC2_SRGB8:
1148      return PIPE_FORMAT_ETC2_RGB8;
1149   case PIPE_FORMAT_ETC2_SRGB8A1:
1150      return PIPE_FORMAT_ETC2_RGB8A1;
1151   case PIPE_FORMAT_ETC2_SRGBA8:
1152      return PIPE_FORMAT_ETC2_RGBA8;
1153   case PIPE_FORMAT_ASTC_4x4_SRGB:
1154      return PIPE_FORMAT_ASTC_4x4;
1155   case PIPE_FORMAT_ASTC_5x4_SRGB:
1156      return PIPE_FORMAT_ASTC_5x4;
1157   case PIPE_FORMAT_ASTC_5x5_SRGB:
1158      return PIPE_FORMAT_ASTC_5x5;
1159   case PIPE_FORMAT_ASTC_6x5_SRGB:
1160      return PIPE_FORMAT_ASTC_6x5;
1161   case PIPE_FORMAT_ASTC_6x6_SRGB:
1162      return PIPE_FORMAT_ASTC_6x6;
1163   case PIPE_FORMAT_ASTC_8x5_SRGB:
1164      return PIPE_FORMAT_ASTC_8x5;
1165   case PIPE_FORMAT_ASTC_8x6_SRGB:
1166      return PIPE_FORMAT_ASTC_8x6;
1167   case PIPE_FORMAT_ASTC_8x8_SRGB:
1168      return PIPE_FORMAT_ASTC_8x8;
1169   case PIPE_FORMAT_ASTC_10x5_SRGB:
1170      return PIPE_FORMAT_ASTC_10x5;
1171   case PIPE_FORMAT_ASTC_10x6_SRGB:
1172      return PIPE_FORMAT_ASTC_10x6;
1173   case PIPE_FORMAT_ASTC_10x8_SRGB:
1174      return PIPE_FORMAT_ASTC_10x8;
1175   case PIPE_FORMAT_ASTC_10x10_SRGB:
1176      return PIPE_FORMAT_ASTC_10x10;
1177   case PIPE_FORMAT_ASTC_12x10_SRGB:
1178      return PIPE_FORMAT_ASTC_12x10;
1179   case PIPE_FORMAT_ASTC_12x12_SRGB:
1180      return PIPE_FORMAT_ASTC_12x12;
1181   case PIPE_FORMAT_ASTC_3x3x3_SRGB:
1182      return PIPE_FORMAT_ASTC_3x3x3;
1183   case PIPE_FORMAT_ASTC_4x3x3_SRGB:
1184      return PIPE_FORMAT_ASTC_4x3x3;
1185   case PIPE_FORMAT_ASTC_4x4x3_SRGB:
1186      return PIPE_FORMAT_ASTC_4x4x3;
1187   case PIPE_FORMAT_ASTC_4x4x4_SRGB:
1188      return PIPE_FORMAT_ASTC_4x4x4;
1189   case PIPE_FORMAT_ASTC_5x4x4_SRGB:
1190      return PIPE_FORMAT_ASTC_5x4x4;
1191   case PIPE_FORMAT_ASTC_5x5x4_SRGB:
1192      return PIPE_FORMAT_ASTC_5x5x4;
1193   case PIPE_FORMAT_ASTC_5x5x5_SRGB:
1194      return PIPE_FORMAT_ASTC_5x5x5;
1195   case PIPE_FORMAT_ASTC_6x5x5_SRGB:
1196      return PIPE_FORMAT_ASTC_6x5x5;
1197   case PIPE_FORMAT_ASTC_6x6x5_SRGB:
1198      return PIPE_FORMAT_ASTC_6x6x5;
1199   case PIPE_FORMAT_ASTC_6x6x6_SRGB:
1200      return PIPE_FORMAT_ASTC_6x6x6;
1201   default:
1202      assert(!util_format_is_srgb(format));
1203      return format;
1204   }
1205}
1206
1207/**
1208 * Given a depth-stencil format, return the corresponding stencil-only format.
1209 * For stencil-only formats, return the format unchanged.
1210 */
1211static inline enum pipe_format
1212util_format_stencil_only(enum pipe_format format)
1213{
1214   switch (format) {
1215   /* mask out the depth component */
1216   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
1217      return PIPE_FORMAT_X24S8_UINT;
1218   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
1219      return PIPE_FORMAT_S8X24_UINT;
1220   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
1221      return PIPE_FORMAT_X32_S8X24_UINT;
1222
1223   /* stencil only formats */
1224   case PIPE_FORMAT_X24S8_UINT:
1225   case PIPE_FORMAT_S8X24_UINT:
1226   case PIPE_FORMAT_X32_S8X24_UINT:
1227   case PIPE_FORMAT_S8_UINT:
1228      return format;
1229
1230   default:
1231      assert(0);
1232      return PIPE_FORMAT_NONE;
1233   }
1234}
1235
1236/**
1237 * Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*.
1238 * This is identity for non-intensity formats.
1239 */
1240static inline enum pipe_format
1241util_format_intensity_to_red(enum pipe_format format)
1242{
1243   switch (format) {
1244   case PIPE_FORMAT_I8_UNORM:
1245      return PIPE_FORMAT_R8_UNORM;
1246   case PIPE_FORMAT_I8_SNORM:
1247      return PIPE_FORMAT_R8_SNORM;
1248   case PIPE_FORMAT_I16_UNORM:
1249      return PIPE_FORMAT_R16_UNORM;
1250   case PIPE_FORMAT_I16_SNORM:
1251      return PIPE_FORMAT_R16_SNORM;
1252   case PIPE_FORMAT_I16_FLOAT:
1253      return PIPE_FORMAT_R16_FLOAT;
1254   case PIPE_FORMAT_I32_FLOAT:
1255      return PIPE_FORMAT_R32_FLOAT;
1256   case PIPE_FORMAT_I8_UINT:
1257      return PIPE_FORMAT_R8_UINT;
1258   case PIPE_FORMAT_I8_SINT:
1259      return PIPE_FORMAT_R8_SINT;
1260   case PIPE_FORMAT_I16_UINT:
1261      return PIPE_FORMAT_R16_UINT;
1262   case PIPE_FORMAT_I16_SINT:
1263      return PIPE_FORMAT_R16_SINT;
1264   case PIPE_FORMAT_I32_UINT:
1265      return PIPE_FORMAT_R32_UINT;
1266   case PIPE_FORMAT_I32_SINT:
1267      return PIPE_FORMAT_R32_SINT;
1268   default:
1269      assert(!util_format_is_intensity(format));
1270      return format;
1271   }
1272}
1273
1274/**
1275 * Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*.
1276 * This is identity for non-luminance formats.
1277 */
1278static inline enum pipe_format
1279util_format_luminance_to_red(enum pipe_format format)
1280{
1281   switch (format) {
1282   case PIPE_FORMAT_L8_UNORM:
1283      return PIPE_FORMAT_R8_UNORM;
1284   case PIPE_FORMAT_L8_SNORM:
1285      return PIPE_FORMAT_R8_SNORM;
1286   case PIPE_FORMAT_L16_UNORM:
1287      return PIPE_FORMAT_R16_UNORM;
1288   case PIPE_FORMAT_L16_SNORM:
1289      return PIPE_FORMAT_R16_SNORM;
1290   case PIPE_FORMAT_L16_FLOAT:
1291      return PIPE_FORMAT_R16_FLOAT;
1292   case PIPE_FORMAT_L32_FLOAT:
1293      return PIPE_FORMAT_R32_FLOAT;
1294   case PIPE_FORMAT_L8_UINT:
1295      return PIPE_FORMAT_R8_UINT;
1296   case PIPE_FORMAT_L8_SINT:
1297      return PIPE_FORMAT_R8_SINT;
1298   case PIPE_FORMAT_L16_UINT:
1299      return PIPE_FORMAT_R16_UINT;
1300   case PIPE_FORMAT_L16_SINT:
1301      return PIPE_FORMAT_R16_SINT;
1302   case PIPE_FORMAT_L32_UINT:
1303      return PIPE_FORMAT_R32_UINT;
1304   case PIPE_FORMAT_L32_SINT:
1305      return PIPE_FORMAT_R32_SINT;
1306
1307   case PIPE_FORMAT_LATC1_UNORM:
1308      return PIPE_FORMAT_RGTC1_UNORM;
1309   case PIPE_FORMAT_LATC1_SNORM:
1310      return PIPE_FORMAT_RGTC1_SNORM;
1311
1312   case PIPE_FORMAT_L4A4_UNORM:
1313      return PIPE_FORMAT_R4A4_UNORM;
1314
1315   case PIPE_FORMAT_L8A8_UNORM:
1316      return PIPE_FORMAT_R8A8_UNORM;
1317   case PIPE_FORMAT_L8A8_SNORM:
1318      return PIPE_FORMAT_R8A8_SNORM;
1319   case PIPE_FORMAT_L16A16_UNORM:
1320      return PIPE_FORMAT_R16A16_UNORM;
1321   case PIPE_FORMAT_L16A16_SNORM:
1322      return PIPE_FORMAT_R16A16_SNORM;
1323   case PIPE_FORMAT_L16A16_FLOAT:
1324      return PIPE_FORMAT_R16A16_FLOAT;
1325   case PIPE_FORMAT_L32A32_FLOAT:
1326      return PIPE_FORMAT_R32A32_FLOAT;
1327   case PIPE_FORMAT_L8A8_UINT:
1328      return PIPE_FORMAT_R8A8_UINT;
1329   case PIPE_FORMAT_L8A8_SINT:
1330      return PIPE_FORMAT_R8A8_SINT;
1331   case PIPE_FORMAT_L16A16_UINT:
1332      return PIPE_FORMAT_R16A16_UINT;
1333   case PIPE_FORMAT_L16A16_SINT:
1334      return PIPE_FORMAT_R16A16_SINT;
1335   case PIPE_FORMAT_L32A32_UINT:
1336      return PIPE_FORMAT_R32A32_UINT;
1337   case PIPE_FORMAT_L32A32_SINT:
1338      return PIPE_FORMAT_R32A32_SINT;
1339
1340   /* We don't have compressed red-alpha variants for these. */
1341   case PIPE_FORMAT_LATC2_UNORM:
1342   case PIPE_FORMAT_LATC2_SNORM:
1343      return PIPE_FORMAT_NONE;
1344
1345   default:
1346      assert(!util_format_is_luminance(format) &&
1347	     !util_format_is_luminance_alpha(format));
1348      return format;
1349   }
1350}
1351
1352static inline unsigned
1353util_format_get_num_planes(enum pipe_format format)
1354{
1355   switch (util_format_description(format)->layout) {
1356   case UTIL_FORMAT_LAYOUT_PLANAR3:
1357      return 3;
1358   case UTIL_FORMAT_LAYOUT_PLANAR2:
1359      return 2;
1360   default:
1361      return 1;
1362   }
1363}
1364
1365static inline enum pipe_format
1366util_format_get_plane_format(enum pipe_format format, unsigned plane)
1367{
1368   switch (format) {
1369   case PIPE_FORMAT_YV12:
1370   case PIPE_FORMAT_YV16:
1371   case PIPE_FORMAT_IYUV:
1372   case PIPE_FORMAT_Y8_U8_V8_422_UNORM:
1373   case PIPE_FORMAT_Y8_U8_V8_444_UNORM:
1374      return PIPE_FORMAT_R8_UNORM;
1375   case PIPE_FORMAT_NV12:
1376   case PIPE_FORMAT_Y8_U8V8_422_UNORM:
1377      return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_RG88_UNORM;
1378   case PIPE_FORMAT_NV21:
1379      return !plane ? PIPE_FORMAT_R8_UNORM : PIPE_FORMAT_GR88_UNORM;
1380   case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
1381   case PIPE_FORMAT_Y16_U16_V16_422_UNORM:
1382   case PIPE_FORMAT_Y16_U16_V16_444_UNORM:
1383      return PIPE_FORMAT_R16_UNORM;
1384   case PIPE_FORMAT_P010:
1385   case PIPE_FORMAT_P012:
1386   case PIPE_FORMAT_P016:
1387   case PIPE_FORMAT_Y16_U16V16_422_UNORM:
1388      return !plane ? PIPE_FORMAT_R16_UNORM : PIPE_FORMAT_R16G16_UNORM;
1389   default:
1390      return format;
1391   }
1392}
1393
1394static inline unsigned
1395util_format_get_plane_width(enum pipe_format format, unsigned plane,
1396                            unsigned width)
1397{
1398   switch (format) {
1399   case PIPE_FORMAT_YV12:
1400   case PIPE_FORMAT_YV16:
1401   case PIPE_FORMAT_IYUV:
1402   case PIPE_FORMAT_NV12:
1403   case PIPE_FORMAT_NV21:
1404   case PIPE_FORMAT_P010:
1405   case PIPE_FORMAT_P012:
1406   case PIPE_FORMAT_P016:
1407   case PIPE_FORMAT_Y8_U8_V8_422_UNORM:
1408   case PIPE_FORMAT_Y8_U8V8_422_UNORM:
1409   case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
1410   case PIPE_FORMAT_Y16_U16_V16_422_UNORM:
1411   case PIPE_FORMAT_Y16_U16V16_422_UNORM:
1412      return !plane ? width : (width + 1) / 2;
1413   default:
1414      return width;
1415   }
1416}
1417
1418static inline unsigned
1419util_format_get_plane_height(enum pipe_format format, unsigned plane,
1420                             unsigned height)
1421{
1422   switch (format) {
1423   case PIPE_FORMAT_YV12:
1424   case PIPE_FORMAT_IYUV:
1425   case PIPE_FORMAT_NV12:
1426   case PIPE_FORMAT_NV21:
1427   case PIPE_FORMAT_P010:
1428   case PIPE_FORMAT_P012:
1429   case PIPE_FORMAT_P016:
1430   case PIPE_FORMAT_Y16_U16_V16_420_UNORM:
1431      return !plane ? height : (height + 1) / 2;
1432   case PIPE_FORMAT_YV16:
1433   default:
1434      return height;
1435   }
1436}
1437
1438/**
1439 * Return the number of components stored.
1440 * Formats with block size != 1x1 will always have 1 component (the block).
1441 */
1442static inline unsigned
1443util_format_get_nr_components(enum pipe_format format)
1444{
1445   const struct util_format_description *desc = util_format_description(format);
1446   return desc->nr_channels;
1447}
1448
1449/**
1450 * Return the index of the first non-void channel
1451 * -1 if no non-void channels
1452 */
1453static inline int
1454util_format_get_first_non_void_channel(enum pipe_format format)
1455{
1456   const struct util_format_description *desc = util_format_description(format);
1457   int i;
1458
1459   for (i = 0; i < 4; i++)
1460      if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
1461         break;
1462
1463   if (i == 4)
1464       return -1;
1465
1466   return i;
1467}
1468
1469/**
1470 * Whether this format is any 8-bit UNORM variant. Looser than
1471 * util_is_rgba8_variant (also includes alpha textures, for instance).
1472 */
1473
1474static inline bool
1475util_format_is_unorm8(const struct util_format_description *desc)
1476{
1477   int c = util_format_get_first_non_void_channel(desc->format);
1478
1479   if (c == -1)
1480      return false;
1481
1482   return desc->is_unorm && desc->is_array && desc->channel[c].size == 8;
1483}
1484
1485static inline void
1486util_format_unpack_z_float(enum pipe_format format, float *dst,
1487                           const void *src, unsigned w)
1488{
1489   const struct util_format_unpack_description *desc =
1490      util_format_unpack_description(format);
1491
1492   desc->unpack_z_float(dst, 0, (const uint8_t *)src, 0, w, 1);
1493}
1494
1495static inline void
1496util_format_unpack_z_32unorm(enum pipe_format format, uint32_t *dst,
1497                             const void *src, unsigned w)
1498{
1499   const struct util_format_unpack_description *desc =
1500      util_format_unpack_description(format);
1501
1502   desc->unpack_z_32unorm(dst, 0, (const uint8_t *)src, 0, w, 1);
1503}
1504
1505static inline void
1506util_format_unpack_s_8uint(enum pipe_format format, uint8_t *dst,
1507                           const void *src, unsigned w)
1508{
1509   const struct util_format_unpack_description *desc =
1510      util_format_unpack_description(format);
1511
1512   desc->unpack_s_8uint(dst, 0, (const uint8_t *)src, 0, w, 1);
1513}
1514
1515/**
1516 * Unpacks a row of color data to 32-bit RGBA, either integers for pure
1517 * integer formats (sign-extended for signed data), or 32-bit floats.
1518 */
1519static inline void
1520util_format_unpack_rgba(enum pipe_format format, void *dst,
1521                        const void *src, unsigned w)
1522{
1523   const struct util_format_unpack_description *desc =
1524      util_format_unpack_description(format);
1525
1526   desc->unpack_rgba(dst, (const uint8_t *)src, w);
1527}
1528
1529static inline void
1530util_format_pack_z_float(enum pipe_format format, void *dst,
1531                         const float *src, unsigned w)
1532{
1533   const struct util_format_pack_description *desc =
1534      util_format_pack_description(format);
1535
1536   desc->pack_z_float((uint8_t *)dst, 0, src, 0, w, 1);
1537}
1538
1539static inline void
1540util_format_pack_z_32unorm(enum pipe_format format, void *dst,
1541                           const uint32_t *src, unsigned w)
1542{
1543   const struct util_format_pack_description *desc =
1544      util_format_pack_description(format);
1545
1546   desc->pack_z_32unorm((uint8_t *)dst, 0, src, 0, w, 1);
1547}
1548
1549static inline void
1550util_format_pack_s_8uint(enum pipe_format format, void *dst,
1551                         const uint8_t *src, unsigned w)
1552{
1553   const struct util_format_pack_description *desc =
1554      util_format_pack_description(format);
1555
1556   desc->pack_s_8uint((uint8_t *)dst, 0, src, 0, w, 1);
1557}
1558
1559/**
1560 * Packs a row of color data from 32-bit RGBA, either integers for pure
1561 * integer formats, or 32-bit floats.  Values are clamped to the packed
1562 * representation's range.
1563 */
1564static inline void
1565util_format_pack_rgba(enum pipe_format format, void *dst,
1566                        const void *src, unsigned w)
1567{
1568   const struct util_format_pack_description *desc =
1569      util_format_pack_description(format);
1570
1571   if (util_format_is_pure_uint(format))
1572      desc->pack_rgba_uint((uint8_t *)dst, 0, (const uint32_t *)src, 0, w, 1);
1573   else if (util_format_is_pure_sint(format))
1574      desc->pack_rgba_sint((uint8_t *)dst, 0, (const int32_t *)src, 0, w, 1);
1575   else
1576      desc->pack_rgba_float((uint8_t *)dst, 0, (const float *)src, 0, w, 1);
1577}
1578
1579/*
1580 * Format access functions for subrectangles
1581 */
1582
1583void
1584util_format_read_4(enum pipe_format format,
1585                   void *dst, unsigned dst_stride,
1586                   const void *src, unsigned src_stride,
1587                   unsigned x, unsigned y, unsigned w, unsigned h);
1588
1589void
1590util_format_write_4(enum pipe_format format,
1591                    const void *src, unsigned src_stride,
1592                    void *dst, unsigned dst_stride,
1593                    unsigned x, unsigned y, unsigned w, unsigned h);
1594
1595void
1596util_format_read_4ub(enum pipe_format format,
1597                     uint8_t *dst, unsigned dst_stride,
1598                     const void *src, unsigned src_stride,
1599                     unsigned x, unsigned y, unsigned w, unsigned h);
1600
1601void
1602util_format_write_4ub(enum pipe_format format,
1603                      const uint8_t *src, unsigned src_stride,
1604                      void *dst, unsigned dst_stride,
1605                      unsigned x, unsigned y, unsigned w, unsigned h);
1606
1607void
1608util_format_unpack_rgba_rect(enum pipe_format format,
1609                             void *dst, unsigned dst_stride,
1610                             const void *src, unsigned src_stride,
1611                             unsigned w, unsigned h);
1612
1613void
1614util_format_unpack_rgba_8unorm_rect(enum pipe_format format,
1615                                    void *dst, unsigned dst_stride,
1616                                    const void *src, unsigned src_stride,
1617                                    unsigned w, unsigned h);
1618
1619/*
1620 * Generic format conversion;
1621 */
1622
1623boolean
1624util_format_fits_8unorm(const struct util_format_description *format_desc) ATTRIBUTE_CONST;
1625
1626boolean
1627util_format_translate(enum pipe_format dst_format,
1628                      void *dst, unsigned dst_stride,
1629                      unsigned dst_x, unsigned dst_y,
1630                      enum pipe_format src_format,
1631                      const void *src, unsigned src_stride,
1632                      unsigned src_x, unsigned src_y,
1633                      unsigned width, unsigned height);
1634
1635boolean
1636util_format_translate_3d(enum pipe_format dst_format,
1637                         void *dst, unsigned dst_stride,
1638                         unsigned dst_slice_stride,
1639                         unsigned dst_x, unsigned dst_y,
1640                         unsigned dst_z,
1641                         enum pipe_format src_format,
1642                         const void *src, unsigned src_stride,
1643                         unsigned src_slice_stride,
1644                         unsigned src_x, unsigned src_y,
1645                         unsigned src_z, unsigned width,
1646                         unsigned height, unsigned depth);
1647
1648/*
1649 * Swizzle operations.
1650 */
1651
1652/* Compose two sets of swizzles.
1653 * If V is a 4D vector and the function parameters represent functions that
1654 * swizzle vector components, this holds:
1655 *     swz2(swz1(V)) = dst(V)
1656 */
1657void util_format_compose_swizzles(const unsigned char swz1[4],
1658                                  const unsigned char swz2[4],
1659                                  unsigned char dst[4]);
1660
1661/* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x)
1662 * to \param src and store the result in \param dst.
1663 * \param is_integer determines the value written for PIPE_SWIZZLE_1.
1664 */
1665void util_format_apply_color_swizzle(union pipe_color_union *dst,
1666                                     const union pipe_color_union *src,
1667                                     const unsigned char swz[4],
1668                                     const boolean is_integer);
1669
1670void pipe_swizzle_4f(float *dst, const float *src,
1671                            const unsigned char swz[4]);
1672
1673void util_format_unswizzle_4f(float *dst, const float *src,
1674                              const unsigned char swz[4]);
1675
1676enum pipe_format
1677util_format_snorm_to_sint(enum pipe_format format) ATTRIBUTE_CONST;
1678
1679extern void
1680util_copy_rect(ubyte * dst, enum pipe_format format,
1681               unsigned dst_stride, unsigned dst_x, unsigned dst_y,
1682               unsigned width, unsigned height, const ubyte * src,
1683               int src_stride, unsigned src_x, unsigned src_y);
1684
1685/**
1686 * If the format is RGB, return BGR. If the format is BGR, return RGB.
1687 * This may fail by returning PIPE_FORMAT_NONE.
1688 */
1689enum pipe_format
1690util_format_rgb_to_bgr(enum pipe_format format);
1691
1692/* Returns the pipe format with SNORM formats cast to UNORM, otherwise the original pipe format. */
1693enum pipe_format
1694util_format_snorm_to_unorm(enum pipe_format format);
1695
1696enum pipe_format
1697util_format_rgbx_to_rgba(enum pipe_format format);
1698
1699#ifdef __cplusplus
1700} // extern "C" {
1701#endif
1702
1703#endif /* ! U_FORMAT_H */
1704