u_format.h revision 866f9b18c68ede63c00917ec9c3dae3524ca8826
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 "util/u_debug.h"
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40
41/**
42 * Describe how to pack/unpack pixels into/from the prescribed format.
43 *
44 * XXX: This could be renamed to something like util_format_pack, or broke down
45 * in flags inside util_format_block that said exactly what we want.
46 */
47enum util_format_layout {
48   /**
49    * Formats with util_format_block::width == util_format_block::height == 1
50    * that can be described as an ordinary data structure.
51    */
52   UTIL_FORMAT_LAYOUT_PLAIN = 0,
53
54   /**
55    * Formats with sub-sampled channels.
56    *
57    * This is for formats like YV12 where there is less than one sample per
58    * pixel.
59    */
60   UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3,
61
62   /**
63    * S3 Texture Compression formats.
64    */
65   UTIL_FORMAT_LAYOUT_S3TC = 4,
66
67   /**
68    * Red-Green Texture Compression formats.
69    */
70   UTIL_FORMAT_LAYOUT_RGTC = 5,
71
72   /**
73    * Everything else that doesn't fit in any of the above layouts.
74    */
75   UTIL_FORMAT_LAYOUT_OTHER = 6
76};
77
78
79struct util_format_block
80{
81   /** Block width in pixels */
82   unsigned width;
83
84   /** Block height in pixels */
85   unsigned height;
86
87   /** Block size in bits */
88   unsigned bits;
89};
90
91
92enum util_format_type {
93   UTIL_FORMAT_TYPE_VOID = 0,
94   UTIL_FORMAT_TYPE_UNSIGNED = 1,
95   UTIL_FORMAT_TYPE_SIGNED = 2,
96   UTIL_FORMAT_TYPE_FIXED = 3,
97   UTIL_FORMAT_TYPE_FLOAT = 4
98};
99
100
101enum util_format_swizzle {
102   UTIL_FORMAT_SWIZZLE_X = 0,
103   UTIL_FORMAT_SWIZZLE_Y = 1,
104   UTIL_FORMAT_SWIZZLE_Z = 2,
105   UTIL_FORMAT_SWIZZLE_W = 3,
106   UTIL_FORMAT_SWIZZLE_0 = 4,
107   UTIL_FORMAT_SWIZZLE_1 = 5,
108   UTIL_FORMAT_SWIZZLE_NONE = 6,
109   UTIL_FORMAT_SWIZZLE_MAX = 7  /**< Number of enums counter (must be last) */
110};
111
112
113enum util_format_colorspace {
114   UTIL_FORMAT_COLORSPACE_RGB = 0,
115   UTIL_FORMAT_COLORSPACE_SRGB = 1,
116   UTIL_FORMAT_COLORSPACE_YUV = 2,
117   UTIL_FORMAT_COLORSPACE_ZS = 3
118};
119
120
121struct util_format_channel_description
122{
123   unsigned type:5;        /**< UTIL_FORMAT_TYPE_x */
124   unsigned normalized:1;
125   unsigned pure_integer:1;
126   unsigned size:9;        /**< bits per channel */
127};
128
129
130struct util_format_description
131{
132   enum pipe_format format;
133
134   const char *name;
135
136   /**
137    * Short name, striped of the prefix, lower case.
138    */
139   const char *short_name;
140
141   /**
142    * Pixel block dimensions.
143    */
144   struct util_format_block block;
145
146   enum util_format_layout layout;
147
148   /**
149    * The number of channels.
150    */
151   unsigned nr_channels:3;
152
153   /**
154    * Whether all channels have the same number of (whole) bytes.
155    */
156   unsigned is_array:1;
157
158   /**
159    * Whether the pixel format can be described as a bitfield structure.
160    *
161    * In particular:
162    * - pixel depth must be 8, 16, or 32 bits;
163    * - all channels must be unsigned, signed, or void
164    */
165   unsigned is_bitmask:1;
166
167   /**
168    * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
169    */
170   unsigned is_mixed:1;
171
172   /**
173    * Input channel description.
174    *
175    * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.
176    */
177   struct util_format_channel_description channel[4];
178
179   /**
180    * Output channel swizzle.
181    *
182    * The order is either:
183    * - RGBA
184    * - YUV(A)
185    * - ZS
186    * depending on the colorspace.
187    */
188   unsigned char swizzle[4];
189
190   /**
191    * Colorspace transformation.
192    */
193   enum util_format_colorspace colorspace;
194
195   /**
196    * Unpack pixel blocks to R8G8B8A8_UNORM.
197    * Note: strides are in bytes.
198    *
199    * Only defined for non-depth-stencil formats.
200    */
201   void
202   (*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
203                         const uint8_t *src, unsigned src_stride,
204                         unsigned width, unsigned height);
205
206   /**
207    * Pack pixel blocks from R8G8B8A8_UNORM.
208    * Note: strides are in bytes.
209    *
210    * Only defined for non-depth-stencil formats.
211    */
212   void
213   (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
214                       const uint8_t *src, unsigned src_stride,
215                       unsigned width, unsigned height);
216
217   /**
218    * Fetch a single pixel (i, j) from a block.
219    *
220    * XXX: Only defined for a very few select formats.
221    */
222   void
223   (*fetch_rgba_8unorm)(uint8_t *dst,
224                        const uint8_t *src,
225                        unsigned i, unsigned j);
226
227   /**
228    * Unpack pixel blocks to R32G32B32A32_FLOAT.
229    * Note: strides are in bytes.
230    *
231    * Only defined for non-depth-stencil formats.
232    */
233   void
234   (*unpack_rgba_float)(float *dst, unsigned dst_stride,
235                        const uint8_t *src, unsigned src_stride,
236                        unsigned width, unsigned height);
237
238   /**
239    * Pack pixel blocks from R32G32B32A32_FLOAT.
240    * Note: strides are in bytes.
241    *
242    * Only defined for non-depth-stencil formats.
243    */
244   void
245   (*pack_rgba_float)(uint8_t *dst, unsigned dst_stride,
246                      const float *src, unsigned src_stride,
247                      unsigned width, unsigned height);
248
249   /**
250    * Fetch a single pixel (i, j) from a block.
251    *
252    * Only defined for non-depth-stencil formats.
253    */
254   void
255   (*fetch_rgba_float)(float *dst,
256                       const uint8_t *src,
257                       unsigned i, unsigned j);
258
259   /**
260    * Unpack pixels to Z32_UNORM.
261    * Note: strides are in bytes.
262    *
263    * Only defined for depth formats.
264    */
265   void
266   (*unpack_z_32unorm)(uint32_t *dst, unsigned dst_stride,
267                       const uint8_t *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 *dst, unsigned dst_stride,
278                     const uint32_t *src, unsigned src_stride,
279                     unsigned width, unsigned height);
280
281   /**
282    * Unpack pixels to Z32_FLOAT.
283    * Note: strides are in bytes.
284    *
285    * Only defined for depth formats.
286    */
287   void
288   (*unpack_z_float)(float *dst, unsigned dst_stride,
289                     const uint8_t *src, unsigned src_stride,
290                     unsigned width, unsigned height);
291
292   /**
293    * Pack pixels from Z32_FLOAT.
294    * Note: strides are in bytes.
295    *
296    * Only defined for depth formats.
297    */
298   void
299   (*pack_z_float)(uint8_t *dst, unsigned dst_stride,
300                   const float *src, unsigned src_stride,
301                   unsigned width, unsigned height);
302
303   /**
304    * Unpack pixels to S8_UINT.
305    * Note: strides are in bytes.
306    *
307    * Only defined for stencil formats.
308    */
309   void
310   (*unpack_s_8uint)(uint8_t *dst, unsigned dst_stride,
311                     const uint8_t *src, unsigned src_stride,
312                     unsigned width, unsigned height);
313
314   /**
315    * Pack pixels from S8_UINT.
316    * Note: strides are in bytes.
317    *
318    * Only defined for stencil formats.
319    */
320   void
321   (*pack_s_8uint)(uint8_t *dst, unsigned dst_stride,
322                   const uint8_t *src, unsigned src_stride,
323                   unsigned width, unsigned height);
324
325  /**
326    * Unpack pixel blocks to R32G32B32A32_UINT.
327    * Note: strides are in bytes.
328    *
329    * Only defined for INT formats.
330    */
331   void
332   (*unpack_rgba_uint)(unsigned *dst, unsigned dst_stride,
333                       const uint8_t *src, unsigned src_stride,
334                       unsigned width, unsigned height);
335
336   void
337   (*pack_rgba_uint)(uint8_t *dst, unsigned dst_stride,
338                     const unsigned *src, unsigned src_stride,
339                     unsigned width, unsigned height);
340
341  /**
342    * Unpack pixel blocks to R32G32B32A32_SINT.
343    * Note: strides are in bytes.
344    *
345    * Only defined for INT formats.
346    */
347   void
348   (*unpack_rgba_sint)(signed *dst, unsigned dst_stride,
349                       const uint8_t *src, unsigned src_stride,
350                       unsigned width, unsigned height);
351
352   void
353   (*pack_rgba_sint)(uint8_t *dst, unsigned dst_stride,
354                     const int *src, unsigned src_stride,
355                     unsigned width, unsigned height);
356};
357
358
359extern const struct util_format_description
360util_format_description_table[];
361
362
363const struct util_format_description *
364util_format_description(enum pipe_format format);
365
366
367/*
368 * Format query functions.
369 */
370
371static INLINE const char *
372util_format_name(enum pipe_format format)
373{
374   const struct util_format_description *desc = util_format_description(format);
375
376   assert(desc);
377   if (!desc) {
378      return "PIPE_FORMAT_???";
379   }
380
381   return desc->name;
382}
383
384static INLINE const char *
385util_format_short_name(enum pipe_format format)
386{
387   const struct util_format_description *desc = util_format_description(format);
388
389   assert(desc);
390   if (!desc) {
391      return "???";
392   }
393
394   return desc->short_name;
395}
396
397/**
398 * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
399 */
400static INLINE boolean
401util_format_is_plain(enum pipe_format format)
402{
403   const struct util_format_description *desc = util_format_description(format);
404
405   if (!format) {
406      return FALSE;
407   }
408
409   return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;
410}
411
412static INLINE boolean
413util_format_is_compressed(enum pipe_format format)
414{
415   const struct util_format_description *desc = util_format_description(format);
416
417   assert(desc);
418   if (!desc) {
419      return FALSE;
420   }
421
422   switch (desc->layout) {
423   case UTIL_FORMAT_LAYOUT_S3TC:
424   case UTIL_FORMAT_LAYOUT_RGTC:
425      /* XXX add other formats in the future */
426      return TRUE;
427   default:
428      return FALSE;
429   }
430}
431
432static INLINE boolean
433util_format_is_s3tc(enum pipe_format format)
434{
435   const struct util_format_description *desc = util_format_description(format);
436
437   assert(desc);
438   if (!desc) {
439      return FALSE;
440   }
441
442   return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
443}
444
445static INLINE boolean
446util_format_is_srgb(enum pipe_format format)
447{
448   const struct util_format_description *desc = util_format_description(format);
449   return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;
450}
451
452static INLINE boolean
453util_format_has_depth(const struct util_format_description *desc)
454{
455   return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
456          desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE;
457}
458
459static INLINE boolean
460util_format_has_stencil(const struct util_format_description *desc)
461{
462   return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
463          desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE;
464}
465
466static INLINE boolean
467util_format_is_depth_or_stencil(enum pipe_format format)
468{
469   const struct util_format_description *desc = util_format_description(format);
470
471   assert(desc);
472   if (!desc) {
473      return FALSE;
474   }
475
476   return util_format_has_depth(desc) ||
477          util_format_has_stencil(desc);
478}
479
480static INLINE boolean
481util_format_is_depth_and_stencil(enum pipe_format format)
482{
483   const struct util_format_description *desc = util_format_description(format);
484
485   assert(desc);
486   if (!desc) {
487      return FALSE;
488   }
489
490   return util_format_has_depth(desc) &&
491          util_format_has_stencil(desc);
492}
493
494
495/**
496 * Give the RGBA colormask of the channels that can be represented in this
497 * format.
498 *
499 * That is, the channels whose values are preserved.
500 */
501static INLINE unsigned
502util_format_colormask(const struct util_format_description *desc)
503{
504   unsigned colormask;
505   unsigned chan;
506
507   switch (desc->colorspace) {
508   case UTIL_FORMAT_COLORSPACE_RGB:
509   case UTIL_FORMAT_COLORSPACE_SRGB:
510   case UTIL_FORMAT_COLORSPACE_YUV:
511      colormask = 0;
512      for (chan = 0; chan < 4; ++chan) {
513         if (desc->swizzle[chan] < 4) {
514            colormask |= (1 << chan);
515         }
516      }
517      return colormask;
518   case UTIL_FORMAT_COLORSPACE_ZS:
519      return 0;
520   default:
521      assert(0);
522      return 0;
523   }
524}
525
526
527boolean
528util_format_is_float(enum pipe_format format);
529
530
531boolean
532util_format_is_rgb_no_alpha(enum pipe_format format);
533
534
535boolean
536util_format_is_luminance(enum pipe_format format);
537
538
539boolean
540util_format_is_luminance_alpha(enum pipe_format format);
541
542
543boolean
544util_format_is_intensity(enum pipe_format format);
545
546boolean
547util_format_is_pure_integer(enum pipe_format format);
548
549boolean
550util_format_is_pure_sint(enum pipe_format format);
551
552boolean
553util_format_is_pure_uint(enum pipe_format format);
554
555/**
556 * Whether the src format can be blitted to destation format with a simple
557 * memcpy.
558 */
559boolean
560util_is_format_compatible(const struct util_format_description *src_desc,
561                          const struct util_format_description *dst_desc);
562
563/**
564 * Whether the format is supported by Gallium for the given bindings.
565 * This covers S3TC textures and floating-point render targets.
566 */
567boolean
568util_format_is_supported(enum pipe_format format, unsigned bind);
569
570/**
571 * Whether this format is a rgab8 variant.
572 *
573 * That is, any format that matches the
574 *
575 *   PIPE_FORMAT_?8?8?8?8_UNORM
576 */
577static INLINE boolean
578util_format_is_rgba8_variant(const struct util_format_description *desc)
579{
580   unsigned chan;
581
582   if(desc->block.width != 1 ||
583      desc->block.height != 1 ||
584      desc->block.bits != 32)
585      return FALSE;
586
587   for(chan = 0; chan < 4; ++chan) {
588      if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
589         desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
590         return FALSE;
591      if(desc->channel[chan].size != 8)
592         return FALSE;
593   }
594
595   return TRUE;
596}
597
598
599/**
600 * Return total bits needed for the pixel format per block.
601 */
602static INLINE uint
603util_format_get_blocksizebits(enum pipe_format format)
604{
605   const struct util_format_description *desc = util_format_description(format);
606
607   assert(desc);
608   if (!desc) {
609      return 0;
610   }
611
612   return desc->block.bits;
613}
614
615/**
616 * Return bytes per block (not pixel) for the given format.
617 */
618static INLINE uint
619util_format_get_blocksize(enum pipe_format format)
620{
621   uint bits = util_format_get_blocksizebits(format);
622
623   assert(bits % 8 == 0);
624
625   return bits / 8;
626}
627
628static INLINE uint
629util_format_get_blockwidth(enum pipe_format format)
630{
631   const struct util_format_description *desc = util_format_description(format);
632
633   assert(desc);
634   if (!desc) {
635      return 1;
636   }
637
638   return desc->block.width;
639}
640
641static INLINE uint
642util_format_get_blockheight(enum pipe_format format)
643{
644   const struct util_format_description *desc = util_format_description(format);
645
646   assert(desc);
647   if (!desc) {
648      return 1;
649   }
650
651   return desc->block.height;
652}
653
654static INLINE unsigned
655util_format_get_nblocksx(enum pipe_format format,
656                         unsigned x)
657{
658   unsigned blockwidth = util_format_get_blockwidth(format);
659   return (x + blockwidth - 1) / blockwidth;
660}
661
662static INLINE unsigned
663util_format_get_nblocksy(enum pipe_format format,
664                         unsigned y)
665{
666   unsigned blockheight = util_format_get_blockheight(format);
667   return (y + blockheight - 1) / blockheight;
668}
669
670static INLINE unsigned
671util_format_get_nblocks(enum pipe_format format,
672                        unsigned width,
673                        unsigned height)
674{
675   return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);
676}
677
678static INLINE size_t
679util_format_get_stride(enum pipe_format format,
680                       unsigned width)
681{
682   return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
683}
684
685static INLINE size_t
686util_format_get_2d_size(enum pipe_format format,
687                        size_t stride,
688                        unsigned height)
689{
690   return util_format_get_nblocksy(format, height) * stride;
691}
692
693static INLINE uint
694util_format_get_component_bits(enum pipe_format format,
695                               enum util_format_colorspace colorspace,
696                               uint component)
697{
698   const struct util_format_description *desc = util_format_description(format);
699   enum util_format_colorspace desc_colorspace;
700
701   assert(format);
702   if (!format) {
703      return 0;
704   }
705
706   assert(component < 4);
707
708   /* Treat RGB and SRGB as equivalent. */
709   if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
710      colorspace = UTIL_FORMAT_COLORSPACE_RGB;
711   }
712   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
713      desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
714   } else {
715      desc_colorspace = desc->colorspace;
716   }
717
718   if (desc_colorspace != colorspace) {
719      return 0;
720   }
721
722   switch (desc->swizzle[component]) {
723   case UTIL_FORMAT_SWIZZLE_X:
724      return desc->channel[0].size;
725   case UTIL_FORMAT_SWIZZLE_Y:
726      return desc->channel[1].size;
727   case UTIL_FORMAT_SWIZZLE_Z:
728      return desc->channel[2].size;
729   case UTIL_FORMAT_SWIZZLE_W:
730      return desc->channel[3].size;
731   default:
732      return 0;
733   }
734}
735
736static INLINE boolean
737util_format_has_alpha(enum pipe_format format)
738{
739   const struct util_format_description *desc = util_format_description(format);
740
741   assert(format);
742   if (!format) {
743      return FALSE;
744   }
745
746   switch (desc->colorspace) {
747   case UTIL_FORMAT_COLORSPACE_RGB:
748   case UTIL_FORMAT_COLORSPACE_SRGB:
749      return desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1;
750   case UTIL_FORMAT_COLORSPACE_YUV:
751      return FALSE;
752   case UTIL_FORMAT_COLORSPACE_ZS:
753      return FALSE;
754   default:
755      assert(0);
756      return FALSE;
757   }
758}
759
760/**
761 * Given a linear RGB colorspace format, return the corresponding SRGB
762 * format, or PIPE_FORMAT_NONE if none.
763 */
764static INLINE enum pipe_format
765util_format_srgb(enum pipe_format format)
766{
767   switch (format) {
768   case PIPE_FORMAT_L8_UNORM:
769      return PIPE_FORMAT_L8_SRGB;
770   case PIPE_FORMAT_L8A8_UNORM:
771      return PIPE_FORMAT_L8A8_SRGB;
772   case PIPE_FORMAT_R8G8B8_UNORM:
773      return PIPE_FORMAT_R8G8B8_SRGB;
774   case PIPE_FORMAT_A8B8G8R8_UNORM:
775      return PIPE_FORMAT_A8B8G8R8_SRGB;
776   case PIPE_FORMAT_X8B8G8R8_UNORM:
777      return PIPE_FORMAT_X8B8G8R8_SRGB;
778   case PIPE_FORMAT_B8G8R8A8_UNORM:
779      return PIPE_FORMAT_B8G8R8A8_SRGB;
780   case PIPE_FORMAT_B8G8R8X8_UNORM:
781      return PIPE_FORMAT_B8G8R8X8_SRGB;
782   case PIPE_FORMAT_A8R8G8B8_UNORM:
783      return PIPE_FORMAT_A8R8G8B8_SRGB;
784   case PIPE_FORMAT_X8R8G8B8_UNORM:
785      return PIPE_FORMAT_X8R8G8B8_SRGB;
786   case PIPE_FORMAT_DXT1_RGB:
787      return PIPE_FORMAT_DXT1_SRGB;
788   case PIPE_FORMAT_DXT1_RGBA:
789      return PIPE_FORMAT_DXT1_SRGBA;
790   case PIPE_FORMAT_DXT3_RGBA:
791      return PIPE_FORMAT_DXT3_SRGBA;
792   case PIPE_FORMAT_DXT5_RGBA:
793      return PIPE_FORMAT_DXT5_SRGBA;
794   default:
795      return PIPE_FORMAT_NONE;
796   }
797}
798
799/**
800 * Given an sRGB format, return the corresponding linear colorspace format.
801 * For non sRGB formats, return the format unchanged.
802 */
803static INLINE enum pipe_format
804util_format_linear(enum pipe_format format)
805{
806   switch (format) {
807   case PIPE_FORMAT_L8_SRGB:
808      return PIPE_FORMAT_L8_UNORM;
809   case PIPE_FORMAT_L8A8_SRGB:
810      return PIPE_FORMAT_L8A8_UNORM;
811   case PIPE_FORMAT_R8G8B8_SRGB:
812      return PIPE_FORMAT_R8G8B8_UNORM;
813   case PIPE_FORMAT_A8B8G8R8_SRGB:
814      return PIPE_FORMAT_A8B8G8R8_UNORM;
815   case PIPE_FORMAT_X8B8G8R8_SRGB:
816      return PIPE_FORMAT_X8B8G8R8_UNORM;
817   case PIPE_FORMAT_B8G8R8A8_SRGB:
818      return PIPE_FORMAT_B8G8R8A8_UNORM;
819   case PIPE_FORMAT_B8G8R8X8_SRGB:
820      return PIPE_FORMAT_B8G8R8X8_UNORM;
821   case PIPE_FORMAT_A8R8G8B8_SRGB:
822      return PIPE_FORMAT_A8R8G8B8_UNORM;
823   case PIPE_FORMAT_X8R8G8B8_SRGB:
824      return PIPE_FORMAT_X8R8G8B8_UNORM;
825   case PIPE_FORMAT_DXT1_SRGB:
826      return PIPE_FORMAT_DXT1_RGB;
827   case PIPE_FORMAT_DXT1_SRGBA:
828      return PIPE_FORMAT_DXT1_RGBA;
829   case PIPE_FORMAT_DXT3_SRGBA:
830      return PIPE_FORMAT_DXT3_RGBA;
831   case PIPE_FORMAT_DXT5_SRGBA:
832      return PIPE_FORMAT_DXT5_RGBA;
833   default:
834      return format;
835   }
836}
837
838/**
839 * Return the number of components stored.
840 * Formats with block size != 1x1 will always have 1 component (the block).
841 */
842static INLINE unsigned
843util_format_get_nr_components(enum pipe_format format)
844{
845   const struct util_format_description *desc = util_format_description(format);
846   return desc->nr_channels;
847}
848
849/**
850 * Return the index of the first non-void channel
851 * -1 if no non-void channels
852 */
853static INLINE int
854util_format_get_first_non_void_channel(enum pipe_format format)
855{
856   const struct util_format_description *desc = util_format_description(format);
857   int i;
858
859   for (i = 0; i < 4; i++)
860      if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
861         break;
862
863   if (i == 4)
864       return -1;
865
866   return i;
867}
868
869/*
870 * Format access functions.
871 */
872
873void
874util_format_read_4f(enum pipe_format format,
875                    float *dst, unsigned dst_stride,
876                    const void *src, unsigned src_stride,
877                    unsigned x, unsigned y, unsigned w, unsigned h);
878
879void
880util_format_write_4f(enum pipe_format format,
881                     const float *src, unsigned src_stride,
882                     void *dst, unsigned dst_stride,
883                     unsigned x, unsigned y, unsigned w, unsigned h);
884
885void
886util_format_read_4ub(enum pipe_format format,
887                     uint8_t *dst, unsigned dst_stride,
888                     const void *src, unsigned src_stride,
889                     unsigned x, unsigned y, unsigned w, unsigned h);
890
891void
892util_format_write_4ub(enum pipe_format format,
893                      const uint8_t *src, unsigned src_stride,
894                      void *dst, unsigned dst_stride,
895                      unsigned x, unsigned y, unsigned w, unsigned h);
896
897void
898util_format_read_4ui(enum pipe_format format,
899                     unsigned *dst, unsigned dst_stride,
900                     const void *src, unsigned src_stride,
901                     unsigned x, unsigned y, unsigned w, unsigned h);
902
903void
904util_format_write_4ui(enum pipe_format format,
905                      const unsigned int *src, unsigned src_stride,
906                      void *dst, unsigned dst_stride,
907                      unsigned x, unsigned y, unsigned w, unsigned h);
908
909void
910util_format_read_4i(enum pipe_format format,
911                    int *dst, unsigned dst_stride,
912                    const void *src, unsigned src_stride,
913                    unsigned x, unsigned y, unsigned w, unsigned h);
914
915void
916util_format_write_4i(enum pipe_format format,
917                     const int *src, unsigned src_stride,
918                     void *dst, unsigned dst_stride,
919                     unsigned x, unsigned y, unsigned w, unsigned h);
920
921/*
922 * Generic format conversion;
923 */
924
925boolean
926util_format_fits_8unorm(const struct util_format_description *format_desc);
927
928void
929util_format_translate(enum pipe_format dst_format,
930                      void *dst, unsigned dst_stride,
931                      unsigned dst_x, unsigned dst_y,
932                      enum pipe_format src_format,
933                      const void *src, unsigned src_stride,
934                      unsigned src_x, unsigned src_y,
935                      unsigned width, unsigned height);
936
937/*
938 * Swizzle operations.
939 */
940
941/* Compose two sets of swizzles.
942 * If V is a 4D vector and the function parameters represent functions that
943 * swizzle vector components, this holds:
944 *     swz2(swz1(V)) = dst(V)
945 */
946void util_format_compose_swizzles(const unsigned char swz1[4],
947                                  const unsigned char swz2[4],
948                                  unsigned char dst[4]);
949
950void util_format_swizzle_4f(float *dst, const float *src,
951                            const unsigned char swz[4]);
952
953void util_format_unswizzle_4f(float *dst, const float *src,
954                              const unsigned char swz[4]);
955
956#ifdef __cplusplus
957} // extern "C" {
958#endif
959
960#endif /* ! U_FORMAT_H */
961