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
37union pipe_color_union;
38
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44
45/**
46 * Describe how to pack/unpack pixels into/from the prescribed format.
47 *
48 * XXX: This could be renamed to something like util_format_pack, or broke down
49 * in flags inside util_format_block that said exactly what we want.
50 */
51enum util_format_layout {
52   /**
53    * Formats with util_format_block::width == util_format_block::height == 1
54    * that can be described as an ordinary data structure.
55    */
56   UTIL_FORMAT_LAYOUT_PLAIN = 0,
57
58   /**
59    * Formats with sub-sampled channels.
60    *
61    * This is for formats like YVYU where there is less than one sample per
62    * pixel.
63    */
64   UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3,
65
66   /**
67    * S3 Texture Compression formats.
68    */
69   UTIL_FORMAT_LAYOUT_S3TC = 4,
70
71   /**
72    * Red-Green Texture Compression formats.
73    */
74   UTIL_FORMAT_LAYOUT_RGTC = 5,
75
76   /**
77    * Ericsson Texture Compression
78    */
79   UTIL_FORMAT_LAYOUT_ETC = 6,
80
81   /**
82    * BC6/7 Texture Compression
83    */
84   UTIL_FORMAT_LAYOUT_BPTC = 7,
85
86   /**
87    * ASTC
88    */
89   UTIL_FORMAT_LAYOUT_ASTC = 8,
90
91   /**
92    * ATC
93    */
94   UTIL_FORMAT_LAYOUT_ATC = 9,
95
96   /**
97    * Everything else that doesn't fit in any of the above layouts.
98    */
99   UTIL_FORMAT_LAYOUT_OTHER = 10
100};
101
102
103struct util_format_block
104{
105   /** Block width in pixels */
106   unsigned width;
107
108   /** Block height in pixels */
109   unsigned height;
110
111   /** Block size in bits */
112   unsigned bits;
113};
114
115
116enum util_format_type {
117   UTIL_FORMAT_TYPE_VOID = 0,
118   UTIL_FORMAT_TYPE_UNSIGNED = 1,
119   UTIL_FORMAT_TYPE_SIGNED = 2,
120   UTIL_FORMAT_TYPE_FIXED = 3,
121   UTIL_FORMAT_TYPE_FLOAT = 4
122};
123
124
125enum util_format_colorspace {
126   UTIL_FORMAT_COLORSPACE_RGB = 0,
127   UTIL_FORMAT_COLORSPACE_SRGB = 1,
128   UTIL_FORMAT_COLORSPACE_YUV = 2,
129   UTIL_FORMAT_COLORSPACE_ZS = 3
130};
131
132
133struct util_format_channel_description
134{
135   unsigned type:5;        /**< UTIL_FORMAT_TYPE_x */
136   unsigned normalized:1;
137   unsigned pure_integer:1;
138   unsigned size:9;        /**< bits per channel */
139   unsigned shift:16;      /** number of bits from lsb */
140};
141
142
143struct util_format_description
144{
145   enum pipe_format format;
146
147   const char *name;
148
149   /**
150    * Short name, striped of the prefix, lower case.
151    */
152   const char *short_name;
153
154   /**
155    * Pixel block dimensions.
156    */
157   struct util_format_block block;
158
159   enum util_format_layout layout;
160
161   /**
162    * The number of channels.
163    */
164   unsigned nr_channels:3;
165
166   /**
167    * Whether all channels have the same number of (whole) bytes and type.
168    */
169   unsigned is_array:1;
170
171   /**
172    * Whether the pixel format can be described as a bitfield structure.
173    *
174    * In particular:
175    * - pixel depth must be 8, 16, or 32 bits;
176    * - all channels must be unsigned, signed, or void
177    */
178   unsigned is_bitmask:1;
179
180   /**
181    * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
182    */
183   unsigned is_mixed:1;
184
185   /**
186    * Whether the format contains UNORM channels
187    */
188   unsigned is_unorm:1;
189
190   /**
191    * Whether the format contains SNORM channels
192    */
193   unsigned is_snorm:1;
194
195   /**
196    * Input channel description, in the order XYZW.
197    *
198    * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.
199    *
200    * If each channel is accessed as an individual N-byte value, X is always
201    * at the lowest address in memory, Y is always next, and so on.  For all
202    * currently-defined formats, the N-byte value has native endianness.
203    *
204    * If instead a group of channels is accessed as a single N-byte value,
205    * the order of the channels within that value depends on endianness.
206    * For big-endian targets, X is the most significant subvalue,
207    * otherwise it is the least significant one.
208    *
209    * For example, if X is 8 bits and Y is 24 bits, the memory order is:
210    *
211    *                 0  1  2  3
212    *  little-endian: X  Yl Ym Yu    (l = lower, m = middle, u = upper)
213    *  big-endian:    X  Yu Ym Yl
214    *
215    * If X is 5 bits, Y is 5 bits, Z is 5 bits and W is 1 bit, the layout is:
216    *
217    *                        0        1
218    *                 msb  lsb msb  lsb
219    *  little-endian: YYYXXXXX WZZZZZYY
220    *  big-endian:    XXXXXYYY YYZZZZZW
221    */
222   struct util_format_channel_description channel[4];
223
224   /**
225    * Output channel swizzle.
226    *
227    * The order is either:
228    * - RGBA
229    * - YUV(A)
230    * - ZS
231    * depending on the colorspace.
232    */
233   unsigned char swizzle[4];
234
235   /**
236    * Colorspace transformation.
237    */
238   enum util_format_colorspace colorspace;
239
240   /**
241    * Unpack pixel blocks to R8G8B8A8_UNORM.
242    * Note: strides are in bytes.
243    *
244    * Only defined for non-depth-stencil formats.
245    */
246   void
247   (*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
248                         const uint8_t *src, unsigned src_stride,
249                         unsigned width, unsigned height);
250
251   /**
252    * Pack pixel blocks from R8G8B8A8_UNORM.
253    * Note: strides are in bytes.
254    *
255    * Only defined for non-depth-stencil formats.
256    */
257   void
258   (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
259                       const uint8_t *src, unsigned src_stride,
260                       unsigned width, unsigned height);
261
262   /**
263    * Fetch a single pixel (i, j) from a block.
264    *
265    * XXX: Only defined for a very few select formats.
266    */
267   void
268   (*fetch_rgba_8unorm)(uint8_t *dst,
269                        const uint8_t *src,
270                        unsigned i, unsigned j);
271
272   /**
273    * Unpack pixel blocks to R32G32B32A32_FLOAT.
274    * Note: strides are in bytes.
275    *
276    * Only defined for non-depth-stencil formats.
277    */
278   void
279   (*unpack_rgba_float)(float *dst, unsigned dst_stride,
280                        const uint8_t *src, unsigned src_stride,
281                        unsigned width, unsigned height);
282
283   /**
284    * Pack pixel blocks from R32G32B32A32_FLOAT.
285    * Note: strides are in bytes.
286    *
287    * Only defined for non-depth-stencil formats.
288    */
289   void
290   (*pack_rgba_float)(uint8_t *dst, unsigned dst_stride,
291                      const float *src, unsigned src_stride,
292                      unsigned width, unsigned height);
293
294   /**
295    * Fetch a single pixel (i, j) from a block.
296    *
297    * Only defined for non-depth-stencil and non-integer formats.
298    */
299   void
300   (*fetch_rgba_float)(float *dst,
301                       const uint8_t *src,
302                       unsigned i, unsigned j);
303
304   /**
305    * Unpack pixels to Z32_UNORM.
306    * Note: strides are in bytes.
307    *
308    * Only defined for depth formats.
309    */
310   void
311   (*unpack_z_32unorm)(uint32_t *dst, unsigned dst_stride,
312                       const uint8_t *src, unsigned src_stride,
313                       unsigned width, unsigned height);
314
315   /**
316    * Pack pixels from Z32_FLOAT.
317    * Note: strides are in bytes.
318    *
319    * Only defined for depth formats.
320    */
321   void
322   (*pack_z_32unorm)(uint8_t *dst, unsigned dst_stride,
323                     const uint32_t *src, unsigned src_stride,
324                     unsigned width, unsigned height);
325
326   /**
327    * Unpack pixels to Z32_FLOAT.
328    * Note: strides are in bytes.
329    *
330    * Only defined for depth formats.
331    */
332   void
333   (*unpack_z_float)(float *dst, unsigned dst_stride,
334                     const uint8_t *src, unsigned src_stride,
335                     unsigned width, unsigned height);
336
337   /**
338    * Pack pixels from Z32_FLOAT.
339    * Note: strides are in bytes.
340    *
341    * Only defined for depth formats.
342    */
343   void
344   (*pack_z_float)(uint8_t *dst, unsigned dst_stride,
345                   const float *src, unsigned src_stride,
346                   unsigned width, unsigned height);
347
348   /**
349    * Unpack pixels to S8_UINT.
350    * Note: strides are in bytes.
351    *
352    * Only defined for stencil formats.
353    */
354   void
355   (*unpack_s_8uint)(uint8_t *dst, unsigned dst_stride,
356                     const uint8_t *src, unsigned src_stride,
357                     unsigned width, unsigned height);
358
359   /**
360    * Pack pixels from S8_UINT.
361    * Note: strides are in bytes.
362    *
363    * Only defined for stencil formats.
364    */
365   void
366   (*pack_s_8uint)(uint8_t *dst, unsigned dst_stride,
367                   const uint8_t *src, unsigned src_stride,
368                   unsigned width, unsigned height);
369
370  /**
371    * Unpack pixel blocks to R32G32B32A32_UINT.
372    * Note: strides are in bytes.
373    *
374    * Only defined for INT formats.
375    */
376   void
377   (*unpack_rgba_uint)(uint32_t *dst, unsigned dst_stride,
378                       const uint8_t *src, unsigned src_stride,
379                       unsigned width, unsigned height);
380
381   void
382   (*pack_rgba_uint)(uint8_t *dst, unsigned dst_stride,
383                     const uint32_t *src, unsigned src_stride,
384                     unsigned width, unsigned height);
385
386  /**
387    * Unpack pixel blocks to R32G32B32A32_SINT.
388    * Note: strides are in bytes.
389    *
390    * Only defined for INT formats.
391    */
392   void
393   (*unpack_rgba_sint)(int32_t *dst, unsigned dst_stride,
394                       const uint8_t *src, unsigned src_stride,
395                       unsigned width, unsigned height);
396
397   void
398   (*pack_rgba_sint)(uint8_t *dst, unsigned dst_stride,
399                     const int32_t *src, unsigned src_stride,
400                     unsigned width, unsigned height);
401
402   /**
403    * Fetch a single pixel (i, j) from a block.
404    *
405    * Only defined for unsigned (pure) integer formats.
406    */
407   void
408   (*fetch_rgba_uint)(uint32_t *dst,
409                      const uint8_t *src,
410                      unsigned i, unsigned j);
411
412   /**
413    * Fetch a single pixel (i, j) from a block.
414    *
415    * Only defined for signed (pure) integer formats.
416    */
417   void
418   (*fetch_rgba_sint)(int32_t *dst,
419                      const uint8_t *src,
420                      unsigned i, unsigned j);
421};
422
423
424extern const struct util_format_description
425util_format_description_table[];
426
427
428const struct util_format_description *
429util_format_description(enum pipe_format format);
430
431
432/*
433 * Format query functions.
434 */
435
436static inline const char *
437util_format_name(enum pipe_format format)
438{
439   const struct util_format_description *desc = util_format_description(format);
440
441   assert(desc);
442   if (!desc) {
443      return "PIPE_FORMAT_???";
444   }
445
446   return desc->name;
447}
448
449static inline const char *
450util_format_short_name(enum pipe_format format)
451{
452   const struct util_format_description *desc = util_format_description(format);
453
454   assert(desc);
455   if (!desc) {
456      return "???";
457   }
458
459   return desc->short_name;
460}
461
462/**
463 * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
464 */
465static inline boolean
466util_format_is_plain(enum pipe_format format)
467{
468   const struct util_format_description *desc = util_format_description(format);
469
470   if (!format) {
471      return FALSE;
472   }
473
474   return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;
475}
476
477static inline boolean
478util_format_is_compressed(enum pipe_format format)
479{
480   const struct util_format_description *desc = util_format_description(format);
481
482   assert(desc);
483   if (!desc) {
484      return FALSE;
485   }
486
487   switch (desc->layout) {
488   case UTIL_FORMAT_LAYOUT_S3TC:
489   case UTIL_FORMAT_LAYOUT_RGTC:
490   case UTIL_FORMAT_LAYOUT_ETC:
491   case UTIL_FORMAT_LAYOUT_BPTC:
492   case UTIL_FORMAT_LAYOUT_ASTC:
493   case UTIL_FORMAT_LAYOUT_ATC:
494      /* XXX add other formats in the future */
495      return TRUE;
496   default:
497      return FALSE;
498   }
499}
500
501static inline boolean
502util_format_is_s3tc(enum pipe_format format)
503{
504   const struct util_format_description *desc = util_format_description(format);
505
506   assert(desc);
507   if (!desc) {
508      return FALSE;
509   }
510
511   return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
512}
513
514static inline boolean
515util_format_is_etc(enum pipe_format format)
516{
517   const struct util_format_description *desc = util_format_description(format);
518
519   assert(desc);
520   if (!desc) {
521      return FALSE;
522   }
523
524   return desc->layout == UTIL_FORMAT_LAYOUT_ETC ? TRUE : FALSE;
525}
526
527static inline boolean
528util_format_is_srgb(enum pipe_format format)
529{
530   const struct util_format_description *desc = util_format_description(format);
531   return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;
532}
533
534static inline boolean
535util_format_has_depth(const struct util_format_description *desc)
536{
537   return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
538          desc->swizzle[0] != PIPE_SWIZZLE_NONE;
539}
540
541static inline boolean
542util_format_has_stencil(const struct util_format_description *desc)
543{
544   return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
545          desc->swizzle[1] != PIPE_SWIZZLE_NONE;
546}
547
548static inline boolean
549util_format_is_depth_or_stencil(enum pipe_format format)
550{
551   const struct util_format_description *desc = util_format_description(format);
552
553   assert(desc);
554   if (!desc) {
555      return FALSE;
556   }
557
558   return util_format_has_depth(desc) ||
559          util_format_has_stencil(desc);
560}
561
562static inline boolean
563util_format_is_depth_and_stencil(enum pipe_format format)
564{
565   const struct util_format_description *desc = util_format_description(format);
566
567   assert(desc);
568   if (!desc) {
569      return FALSE;
570   }
571
572   return util_format_has_depth(desc) &&
573          util_format_has_stencil(desc);
574}
575
576/**
577 * For depth-stencil formats, return the equivalent depth-only format.
578 */
579static inline enum pipe_format
580util_format_get_depth_only(enum pipe_format format)
581{
582   switch (format) {
583   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
584      return PIPE_FORMAT_Z24X8_UNORM;
585
586   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
587      return PIPE_FORMAT_X8Z24_UNORM;
588
589   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
590      return PIPE_FORMAT_Z32_FLOAT;
591
592   default:
593      return format;
594   }
595}
596
597static inline boolean
598util_format_is_yuv(enum pipe_format format)
599{
600   const struct util_format_description *desc = util_format_description(format);
601
602   assert(desc);
603   if (!desc) {
604      return FALSE;
605   }
606
607   return desc->colorspace == UTIL_FORMAT_COLORSPACE_YUV;
608}
609
610/**
611 * Calculates the depth format type based upon the incoming format description.
612 */
613static inline unsigned
614util_get_depth_format_type(const struct util_format_description *desc)
615{
616   unsigned depth_channel = desc->swizzle[0];
617   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
618       depth_channel != PIPE_SWIZZLE_NONE) {
619      return desc->channel[depth_channel].type;
620   } else {
621      return UTIL_FORMAT_TYPE_VOID;
622   }
623}
624
625
626/**
627 * Calculates the MRD for the depth format. MRD is used in depth bias
628 * for UNORM and unbound depth buffers. When the depth buffer is floating
629 * point, the depth bias calculation does not use the MRD. However, the
630 * default MRD will be 1.0 / ((1 << 24) - 1).
631 */
632double
633util_get_depth_format_mrd(const struct util_format_description *desc);
634
635
636/**
637 * Return whether this is an RGBA, Z, S, or combined ZS format.
638 * Useful for initializing pipe_blit_info::mask.
639 */
640static inline unsigned
641util_format_get_mask(enum pipe_format format)
642{
643   const struct util_format_description *desc =
644      util_format_description(format);
645
646   if (!desc)
647      return 0;
648
649   if (util_format_has_depth(desc)) {
650      if (util_format_has_stencil(desc)) {
651         return PIPE_MASK_ZS;
652      } else {
653         return PIPE_MASK_Z;
654      }
655   } else {
656      if (util_format_has_stencil(desc)) {
657         return PIPE_MASK_S;
658      } else {
659         return PIPE_MASK_RGBA;
660      }
661   }
662}
663
664/**
665 * Give the RGBA colormask of the channels that can be represented in this
666 * format.
667 *
668 * That is, the channels whose values are preserved.
669 */
670static inline unsigned
671util_format_colormask(const struct util_format_description *desc)
672{
673   unsigned colormask;
674   unsigned chan;
675
676   switch (desc->colorspace) {
677   case UTIL_FORMAT_COLORSPACE_RGB:
678   case UTIL_FORMAT_COLORSPACE_SRGB:
679   case UTIL_FORMAT_COLORSPACE_YUV:
680      colormask = 0;
681      for (chan = 0; chan < 4; ++chan) {
682         if (desc->swizzle[chan] < 4) {
683            colormask |= (1 << chan);
684         }
685      }
686      return colormask;
687   case UTIL_FORMAT_COLORSPACE_ZS:
688      return 0;
689   default:
690      assert(0);
691      return 0;
692   }
693}
694
695
696/**
697 * Checks if color mask covers every channel for the specified format
698 *
699 * @param desc       a format description to check colormask with
700 * @param colormask  a bit mask for channels, matches format of PIPE_MASK_RGBA
701 */
702static inline boolean
703util_format_colormask_full(const struct util_format_description *desc, unsigned colormask)
704{
705   return (~colormask & util_format_colormask(desc)) == 0;
706}
707
708
709boolean
710util_format_is_float(enum pipe_format format);
711
712
713boolean
714util_format_has_alpha(enum pipe_format format);
715
716
717boolean
718util_format_is_luminance(enum pipe_format format);
719
720boolean
721util_format_is_alpha(enum pipe_format format);
722
723boolean
724util_format_is_luminance_alpha(enum pipe_format format);
725
726
727boolean
728util_format_is_intensity(enum pipe_format format);
729
730boolean
731util_format_is_subsampled_422(enum pipe_format format);
732
733boolean
734util_format_is_pure_integer(enum pipe_format format);
735
736boolean
737util_format_is_pure_sint(enum pipe_format format);
738
739boolean
740util_format_is_pure_uint(enum pipe_format format);
741
742boolean
743util_format_is_snorm(enum pipe_format format);
744
745boolean
746util_format_is_unorm(enum pipe_format format);
747
748boolean
749util_format_is_snorm8(enum pipe_format format);
750
751/**
752 * Check if the src format can be blitted to the destination format with
753 * a simple memcpy.  For example, blitting from RGBA to RGBx is OK, but not
754 * the reverse.
755 */
756boolean
757util_is_format_compatible(const struct util_format_description *src_desc,
758                          const struct util_format_description *dst_desc);
759
760/**
761 * Whether this format is a rgab8 variant.
762 *
763 * That is, any format that matches the
764 *
765 *   PIPE_FORMAT_?8?8?8?8_UNORM
766 */
767static inline boolean
768util_format_is_rgba8_variant(const struct util_format_description *desc)
769{
770   unsigned chan;
771
772   if(desc->block.width != 1 ||
773      desc->block.height != 1 ||
774      desc->block.bits != 32)
775      return FALSE;
776
777   for(chan = 0; chan < 4; ++chan) {
778      if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
779         desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
780         return FALSE;
781      if(desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED &&
782         !desc->channel[chan].normalized)
783         return FALSE;
784      if(desc->channel[chan].size != 8)
785         return FALSE;
786   }
787
788   return TRUE;
789}
790
791
792/**
793 * Return total bits needed for the pixel format per block.
794 */
795static inline uint
796util_format_get_blocksizebits(enum pipe_format format)
797{
798   const struct util_format_description *desc = util_format_description(format);
799
800   assert(desc);
801   if (!desc) {
802      return 0;
803   }
804
805   return desc->block.bits;
806}
807
808/**
809 * Return bytes per block (not pixel) for the given format.
810 */
811static inline uint
812util_format_get_blocksize(enum pipe_format format)
813{
814   uint bits = util_format_get_blocksizebits(format);
815   uint bytes = bits / 8;
816
817   assert(bits % 8 == 0);
818   assert(bytes > 0);
819   if (bytes == 0) {
820      bytes = 1;
821   }
822
823   return bytes;
824}
825
826static inline uint
827util_format_get_blockwidth(enum pipe_format format)
828{
829   const struct util_format_description *desc = util_format_description(format);
830
831   assert(desc);
832   if (!desc) {
833      return 1;
834   }
835
836   return desc->block.width;
837}
838
839static inline uint
840util_format_get_blockheight(enum pipe_format format)
841{
842   const struct util_format_description *desc = util_format_description(format);
843
844   assert(desc);
845   if (!desc) {
846      return 1;
847   }
848
849   return desc->block.height;
850}
851
852static inline unsigned
853util_format_get_nblocksx(enum pipe_format format,
854                         unsigned x)
855{
856   unsigned blockwidth = util_format_get_blockwidth(format);
857   return (x + blockwidth - 1) / blockwidth;
858}
859
860static inline unsigned
861util_format_get_nblocksy(enum pipe_format format,
862                         unsigned y)
863{
864   unsigned blockheight = util_format_get_blockheight(format);
865   return (y + blockheight - 1) / blockheight;
866}
867
868static inline unsigned
869util_format_get_nblocks(enum pipe_format format,
870                        unsigned width,
871                        unsigned height)
872{
873   return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);
874}
875
876static inline size_t
877util_format_get_stride(enum pipe_format format,
878                       unsigned width)
879{
880   return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
881}
882
883static inline size_t
884util_format_get_2d_size(enum pipe_format format,
885                        size_t stride,
886                        unsigned height)
887{
888   return util_format_get_nblocksy(format, height) * stride;
889}
890
891static inline uint
892util_format_get_component_bits(enum pipe_format format,
893                               enum util_format_colorspace colorspace,
894                               uint component)
895{
896   const struct util_format_description *desc = util_format_description(format);
897   enum util_format_colorspace desc_colorspace;
898
899   assert(format);
900   if (!format) {
901      return 0;
902   }
903
904   assert(component < 4);
905
906   /* Treat RGB and SRGB as equivalent. */
907   if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
908      colorspace = UTIL_FORMAT_COLORSPACE_RGB;
909   }
910   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
911      desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
912   } else {
913      desc_colorspace = desc->colorspace;
914   }
915
916   if (desc_colorspace != colorspace) {
917      return 0;
918   }
919
920   switch (desc->swizzle[component]) {
921   case PIPE_SWIZZLE_X:
922      return desc->channel[0].size;
923   case PIPE_SWIZZLE_Y:
924      return desc->channel[1].size;
925   case PIPE_SWIZZLE_Z:
926      return desc->channel[2].size;
927   case PIPE_SWIZZLE_W:
928      return desc->channel[3].size;
929   default:
930      return 0;
931   }
932}
933
934/**
935 * Given a linear RGB colorspace format, return the corresponding SRGB
936 * format, or PIPE_FORMAT_NONE if none.
937 */
938static inline enum pipe_format
939util_format_srgb(enum pipe_format format)
940{
941   if (util_format_is_srgb(format))
942      return format;
943
944   switch (format) {
945   case PIPE_FORMAT_L8_UNORM:
946      return PIPE_FORMAT_L8_SRGB;
947   case PIPE_FORMAT_R8_UNORM:
948      return PIPE_FORMAT_R8_SRGB;
949   case PIPE_FORMAT_L8A8_UNORM:
950      return PIPE_FORMAT_L8A8_SRGB;
951   case PIPE_FORMAT_R8G8B8_UNORM:
952      return PIPE_FORMAT_R8G8B8_SRGB;
953   case PIPE_FORMAT_A8B8G8R8_UNORM:
954      return PIPE_FORMAT_A8B8G8R8_SRGB;
955   case PIPE_FORMAT_X8B8G8R8_UNORM:
956      return PIPE_FORMAT_X8B8G8R8_SRGB;
957   case PIPE_FORMAT_B8G8R8A8_UNORM:
958      return PIPE_FORMAT_B8G8R8A8_SRGB;
959   case PIPE_FORMAT_B8G8R8X8_UNORM:
960      return PIPE_FORMAT_B8G8R8X8_SRGB;
961   case PIPE_FORMAT_A8R8G8B8_UNORM:
962      return PIPE_FORMAT_A8R8G8B8_SRGB;
963   case PIPE_FORMAT_X8R8G8B8_UNORM:
964      return PIPE_FORMAT_X8R8G8B8_SRGB;
965   case PIPE_FORMAT_R8G8B8A8_UNORM:
966      return PIPE_FORMAT_R8G8B8A8_SRGB;
967   case PIPE_FORMAT_R8G8B8X8_UNORM:
968      return PIPE_FORMAT_R8G8B8X8_SRGB;
969   case PIPE_FORMAT_DXT1_RGB:
970      return PIPE_FORMAT_DXT1_SRGB;
971   case PIPE_FORMAT_DXT1_RGBA:
972      return PIPE_FORMAT_DXT1_SRGBA;
973   case PIPE_FORMAT_DXT3_RGBA:
974      return PIPE_FORMAT_DXT3_SRGBA;
975   case PIPE_FORMAT_DXT5_RGBA:
976      return PIPE_FORMAT_DXT5_SRGBA;
977   case PIPE_FORMAT_B5G6R5_UNORM:
978      return PIPE_FORMAT_B5G6R5_SRGB;
979   case PIPE_FORMAT_BPTC_RGBA_UNORM:
980      return PIPE_FORMAT_BPTC_SRGBA;
981   case PIPE_FORMAT_ASTC_4x4:
982      return PIPE_FORMAT_ASTC_4x4_SRGB;
983   case PIPE_FORMAT_ASTC_5x4:
984      return PIPE_FORMAT_ASTC_5x4_SRGB;
985   case PIPE_FORMAT_ASTC_5x5:
986      return PIPE_FORMAT_ASTC_5x5_SRGB;
987   case PIPE_FORMAT_ASTC_6x5:
988      return PIPE_FORMAT_ASTC_6x5_SRGB;
989   case PIPE_FORMAT_ASTC_6x6:
990      return PIPE_FORMAT_ASTC_6x6_SRGB;
991   case PIPE_FORMAT_ASTC_8x5:
992      return PIPE_FORMAT_ASTC_8x5_SRGB;
993   case PIPE_FORMAT_ASTC_8x6:
994      return PIPE_FORMAT_ASTC_8x6_SRGB;
995   case PIPE_FORMAT_ASTC_8x8:
996      return PIPE_FORMAT_ASTC_8x8_SRGB;
997   case PIPE_FORMAT_ASTC_10x5:
998      return PIPE_FORMAT_ASTC_10x5_SRGB;
999   case PIPE_FORMAT_ASTC_10x6:
1000      return PIPE_FORMAT_ASTC_10x6_SRGB;
1001   case PIPE_FORMAT_ASTC_10x8:
1002      return PIPE_FORMAT_ASTC_10x8_SRGB;
1003   case PIPE_FORMAT_ASTC_10x10:
1004      return PIPE_FORMAT_ASTC_10x10_SRGB;
1005   case PIPE_FORMAT_ASTC_12x10:
1006      return PIPE_FORMAT_ASTC_12x10_SRGB;
1007   case PIPE_FORMAT_ASTC_12x12:
1008      return PIPE_FORMAT_ASTC_12x12_SRGB;
1009
1010   default:
1011      return PIPE_FORMAT_NONE;
1012   }
1013}
1014
1015/**
1016 * Given an sRGB format, return the corresponding linear colorspace format.
1017 * For non sRGB formats, return the format unchanged.
1018 */
1019static inline enum pipe_format
1020util_format_linear(enum pipe_format format)
1021{
1022   switch (format) {
1023   case PIPE_FORMAT_L8_SRGB:
1024      return PIPE_FORMAT_L8_UNORM;
1025   case PIPE_FORMAT_R8_SRGB:
1026      return PIPE_FORMAT_R8_UNORM;
1027   case PIPE_FORMAT_L8A8_SRGB:
1028      return PIPE_FORMAT_L8A8_UNORM;
1029   case PIPE_FORMAT_R8G8B8_SRGB:
1030      return PIPE_FORMAT_R8G8B8_UNORM;
1031   case PIPE_FORMAT_A8B8G8R8_SRGB:
1032      return PIPE_FORMAT_A8B8G8R8_UNORM;
1033   case PIPE_FORMAT_X8B8G8R8_SRGB:
1034      return PIPE_FORMAT_X8B8G8R8_UNORM;
1035   case PIPE_FORMAT_B8G8R8A8_SRGB:
1036      return PIPE_FORMAT_B8G8R8A8_UNORM;
1037   case PIPE_FORMAT_B8G8R8X8_SRGB:
1038      return PIPE_FORMAT_B8G8R8X8_UNORM;
1039   case PIPE_FORMAT_A8R8G8B8_SRGB:
1040      return PIPE_FORMAT_A8R8G8B8_UNORM;
1041   case PIPE_FORMAT_X8R8G8B8_SRGB:
1042      return PIPE_FORMAT_X8R8G8B8_UNORM;
1043   case PIPE_FORMAT_R8G8B8A8_SRGB:
1044      return PIPE_FORMAT_R8G8B8A8_UNORM;
1045   case PIPE_FORMAT_R8G8B8X8_SRGB:
1046      return PIPE_FORMAT_R8G8B8X8_UNORM;
1047   case PIPE_FORMAT_DXT1_SRGB:
1048      return PIPE_FORMAT_DXT1_RGB;
1049   case PIPE_FORMAT_DXT1_SRGBA:
1050      return PIPE_FORMAT_DXT1_RGBA;
1051   case PIPE_FORMAT_DXT3_SRGBA:
1052      return PIPE_FORMAT_DXT3_RGBA;
1053   case PIPE_FORMAT_DXT5_SRGBA:
1054      return PIPE_FORMAT_DXT5_RGBA;
1055   case PIPE_FORMAT_B5G6R5_SRGB:
1056      return PIPE_FORMAT_B5G6R5_UNORM;
1057   case PIPE_FORMAT_BPTC_SRGBA:
1058      return PIPE_FORMAT_BPTC_RGBA_UNORM;
1059   case PIPE_FORMAT_ASTC_4x4_SRGB:
1060      return PIPE_FORMAT_ASTC_4x4;
1061   case PIPE_FORMAT_ASTC_5x4_SRGB:
1062      return PIPE_FORMAT_ASTC_5x4;
1063   case PIPE_FORMAT_ASTC_5x5_SRGB:
1064      return PIPE_FORMAT_ASTC_5x5;
1065   case PIPE_FORMAT_ASTC_6x5_SRGB:
1066      return PIPE_FORMAT_ASTC_6x5;
1067   case PIPE_FORMAT_ASTC_6x6_SRGB:
1068      return PIPE_FORMAT_ASTC_6x6;
1069   case PIPE_FORMAT_ASTC_8x5_SRGB:
1070      return PIPE_FORMAT_ASTC_8x5;
1071   case PIPE_FORMAT_ASTC_8x6_SRGB:
1072      return PIPE_FORMAT_ASTC_8x6;
1073   case PIPE_FORMAT_ASTC_8x8_SRGB:
1074      return PIPE_FORMAT_ASTC_8x8;
1075   case PIPE_FORMAT_ASTC_10x5_SRGB:
1076      return PIPE_FORMAT_ASTC_10x5;
1077   case PIPE_FORMAT_ASTC_10x6_SRGB:
1078      return PIPE_FORMAT_ASTC_10x6;
1079   case PIPE_FORMAT_ASTC_10x8_SRGB:
1080      return PIPE_FORMAT_ASTC_10x8;
1081   case PIPE_FORMAT_ASTC_10x10_SRGB:
1082      return PIPE_FORMAT_ASTC_10x10;
1083   case PIPE_FORMAT_ASTC_12x10_SRGB:
1084      return PIPE_FORMAT_ASTC_12x10;
1085   case PIPE_FORMAT_ASTC_12x12_SRGB:
1086      return PIPE_FORMAT_ASTC_12x12;
1087   default:
1088      return format;
1089   }
1090}
1091
1092/**
1093 * Given a depth-stencil format, return the corresponding stencil-only format.
1094 * For stencil-only formats, return the format unchanged.
1095 */
1096static inline enum pipe_format
1097util_format_stencil_only(enum pipe_format format)
1098{
1099   switch (format) {
1100   /* mask out the depth component */
1101   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
1102      return PIPE_FORMAT_X24S8_UINT;
1103   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
1104      return PIPE_FORMAT_S8X24_UINT;
1105   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
1106      return PIPE_FORMAT_X32_S8X24_UINT;
1107
1108   /* stencil only formats */
1109   case PIPE_FORMAT_X24S8_UINT:
1110   case PIPE_FORMAT_S8X24_UINT:
1111   case PIPE_FORMAT_X32_S8X24_UINT:
1112   case PIPE_FORMAT_S8_UINT:
1113      return format;
1114
1115   default:
1116      assert(0);
1117      return PIPE_FORMAT_NONE;
1118   }
1119}
1120
1121/**
1122 * Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*.
1123 * This is identity for non-intensity formats.
1124 */
1125static inline enum pipe_format
1126util_format_intensity_to_red(enum pipe_format format)
1127{
1128   switch (format) {
1129   case PIPE_FORMAT_I8_UNORM:
1130      return PIPE_FORMAT_R8_UNORM;
1131   case PIPE_FORMAT_I8_SNORM:
1132      return PIPE_FORMAT_R8_SNORM;
1133   case PIPE_FORMAT_I16_UNORM:
1134      return PIPE_FORMAT_R16_UNORM;
1135   case PIPE_FORMAT_I16_SNORM:
1136      return PIPE_FORMAT_R16_SNORM;
1137   case PIPE_FORMAT_I16_FLOAT:
1138      return PIPE_FORMAT_R16_FLOAT;
1139   case PIPE_FORMAT_I32_FLOAT:
1140      return PIPE_FORMAT_R32_FLOAT;
1141   case PIPE_FORMAT_I8_UINT:
1142      return PIPE_FORMAT_R8_UINT;
1143   case PIPE_FORMAT_I8_SINT:
1144      return PIPE_FORMAT_R8_SINT;
1145   case PIPE_FORMAT_I16_UINT:
1146      return PIPE_FORMAT_R16_UINT;
1147   case PIPE_FORMAT_I16_SINT:
1148      return PIPE_FORMAT_R16_SINT;
1149   case PIPE_FORMAT_I32_UINT:
1150      return PIPE_FORMAT_R32_UINT;
1151   case PIPE_FORMAT_I32_SINT:
1152      return PIPE_FORMAT_R32_SINT;
1153   default:
1154      assert(!util_format_is_intensity(format));
1155      return format;
1156   }
1157}
1158
1159/**
1160 * Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*.
1161 * This is identity for non-luminance formats.
1162 */
1163static inline enum pipe_format
1164util_format_luminance_to_red(enum pipe_format format)
1165{
1166   switch (format) {
1167   case PIPE_FORMAT_L8_UNORM:
1168      return PIPE_FORMAT_R8_UNORM;
1169   case PIPE_FORMAT_L8_SNORM:
1170      return PIPE_FORMAT_R8_SNORM;
1171   case PIPE_FORMAT_L16_UNORM:
1172      return PIPE_FORMAT_R16_UNORM;
1173   case PIPE_FORMAT_L16_SNORM:
1174      return PIPE_FORMAT_R16_SNORM;
1175   case PIPE_FORMAT_L16_FLOAT:
1176      return PIPE_FORMAT_R16_FLOAT;
1177   case PIPE_FORMAT_L32_FLOAT:
1178      return PIPE_FORMAT_R32_FLOAT;
1179   case PIPE_FORMAT_L8_UINT:
1180      return PIPE_FORMAT_R8_UINT;
1181   case PIPE_FORMAT_L8_SINT:
1182      return PIPE_FORMAT_R8_SINT;
1183   case PIPE_FORMAT_L16_UINT:
1184      return PIPE_FORMAT_R16_UINT;
1185   case PIPE_FORMAT_L16_SINT:
1186      return PIPE_FORMAT_R16_SINT;
1187   case PIPE_FORMAT_L32_UINT:
1188      return PIPE_FORMAT_R32_UINT;
1189   case PIPE_FORMAT_L32_SINT:
1190      return PIPE_FORMAT_R32_SINT;
1191
1192   case PIPE_FORMAT_LATC1_UNORM:
1193      return PIPE_FORMAT_RGTC1_UNORM;
1194   case PIPE_FORMAT_LATC1_SNORM:
1195      return PIPE_FORMAT_RGTC1_SNORM;
1196
1197   case PIPE_FORMAT_L4A4_UNORM:
1198      return PIPE_FORMAT_R4A4_UNORM;
1199
1200   case PIPE_FORMAT_L8A8_UNORM:
1201      return PIPE_FORMAT_R8A8_UNORM;
1202   case PIPE_FORMAT_L8A8_SNORM:
1203      return PIPE_FORMAT_R8A8_SNORM;
1204   case PIPE_FORMAT_L16A16_UNORM:
1205      return PIPE_FORMAT_R16A16_UNORM;
1206   case PIPE_FORMAT_L16A16_SNORM:
1207      return PIPE_FORMAT_R16A16_SNORM;
1208   case PIPE_FORMAT_L16A16_FLOAT:
1209      return PIPE_FORMAT_R16A16_FLOAT;
1210   case PIPE_FORMAT_L32A32_FLOAT:
1211      return PIPE_FORMAT_R32A32_FLOAT;
1212   case PIPE_FORMAT_L8A8_UINT:
1213      return PIPE_FORMAT_R8A8_UINT;
1214   case PIPE_FORMAT_L8A8_SINT:
1215      return PIPE_FORMAT_R8A8_SINT;
1216   case PIPE_FORMAT_L16A16_UINT:
1217      return PIPE_FORMAT_R16A16_UINT;
1218   case PIPE_FORMAT_L16A16_SINT:
1219      return PIPE_FORMAT_R16A16_SINT;
1220   case PIPE_FORMAT_L32A32_UINT:
1221      return PIPE_FORMAT_R32A32_UINT;
1222   case PIPE_FORMAT_L32A32_SINT:
1223      return PIPE_FORMAT_R32A32_SINT;
1224
1225   /* We don't have compressed red-alpha variants for these. */
1226   case PIPE_FORMAT_LATC2_UNORM:
1227   case PIPE_FORMAT_LATC2_SNORM:
1228      return PIPE_FORMAT_NONE;
1229
1230   default:
1231      assert(!util_format_is_luminance(format) &&
1232	     !util_format_is_luminance_alpha(format));
1233      return format;
1234   }
1235}
1236
1237/**
1238 * Return the number of components stored.
1239 * Formats with block size != 1x1 will always have 1 component (the block).
1240 */
1241static inline unsigned
1242util_format_get_nr_components(enum pipe_format format)
1243{
1244   const struct util_format_description *desc = util_format_description(format);
1245   return desc->nr_channels;
1246}
1247
1248/**
1249 * Return the index of the first non-void channel
1250 * -1 if no non-void channels
1251 */
1252static inline int
1253util_format_get_first_non_void_channel(enum pipe_format format)
1254{
1255   const struct util_format_description *desc = util_format_description(format);
1256   int i;
1257
1258   for (i = 0; i < 4; i++)
1259      if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
1260         break;
1261
1262   if (i == 4)
1263       return -1;
1264
1265   return i;
1266}
1267
1268/*
1269 * Format access functions.
1270 */
1271
1272void
1273util_format_read_4f(enum pipe_format format,
1274                    float *dst, unsigned dst_stride,
1275                    const void *src, unsigned src_stride,
1276                    unsigned x, unsigned y, unsigned w, unsigned h);
1277
1278void
1279util_format_write_4f(enum pipe_format format,
1280                     const float *src, unsigned src_stride,
1281                     void *dst, unsigned dst_stride,
1282                     unsigned x, unsigned y, unsigned w, unsigned h);
1283
1284void
1285util_format_read_4ub(enum pipe_format format,
1286                     uint8_t *dst, unsigned dst_stride,
1287                     const void *src, unsigned src_stride,
1288                     unsigned x, unsigned y, unsigned w, unsigned h);
1289
1290void
1291util_format_write_4ub(enum pipe_format format,
1292                      const uint8_t *src, unsigned src_stride,
1293                      void *dst, unsigned dst_stride,
1294                      unsigned x, unsigned y, unsigned w, unsigned h);
1295
1296void
1297util_format_read_4ui(enum pipe_format format,
1298                     unsigned *dst, unsigned dst_stride,
1299                     const void *src, unsigned src_stride,
1300                     unsigned x, unsigned y, unsigned w, unsigned h);
1301
1302void
1303util_format_write_4ui(enum pipe_format format,
1304                      const unsigned int *src, unsigned src_stride,
1305                      void *dst, unsigned dst_stride,
1306                      unsigned x, unsigned y, unsigned w, unsigned h);
1307
1308void
1309util_format_read_4i(enum pipe_format format,
1310                    int *dst, unsigned dst_stride,
1311                    const void *src, unsigned src_stride,
1312                    unsigned x, unsigned y, unsigned w, unsigned h);
1313
1314void
1315util_format_write_4i(enum pipe_format format,
1316                     const int *src, unsigned src_stride,
1317                     void *dst, unsigned dst_stride,
1318                     unsigned x, unsigned y, unsigned w, unsigned h);
1319
1320/*
1321 * Generic format conversion;
1322 */
1323
1324boolean
1325util_format_fits_8unorm(const struct util_format_description *format_desc);
1326
1327boolean
1328util_format_translate(enum pipe_format dst_format,
1329                      void *dst, unsigned dst_stride,
1330                      unsigned dst_x, unsigned dst_y,
1331                      enum pipe_format src_format,
1332                      const void *src, unsigned src_stride,
1333                      unsigned src_x, unsigned src_y,
1334                      unsigned width, unsigned height);
1335
1336boolean
1337util_format_translate_3d(enum pipe_format dst_format,
1338                         void *dst, unsigned dst_stride,
1339                         unsigned dst_slice_stride,
1340                         unsigned dst_x, unsigned dst_y,
1341                         unsigned dst_z,
1342                         enum pipe_format src_format,
1343                         const void *src, unsigned src_stride,
1344                         unsigned src_slice_stride,
1345                         unsigned src_x, unsigned src_y,
1346                         unsigned src_z, unsigned width,
1347                         unsigned height, unsigned depth);
1348
1349/*
1350 * Swizzle operations.
1351 */
1352
1353/* Compose two sets of swizzles.
1354 * If V is a 4D vector and the function parameters represent functions that
1355 * swizzle vector components, this holds:
1356 *     swz2(swz1(V)) = dst(V)
1357 */
1358void util_format_compose_swizzles(const unsigned char swz1[4],
1359                                  const unsigned char swz2[4],
1360                                  unsigned char dst[4]);
1361
1362/* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x)
1363 * to \param src and store the result in \param dst.
1364 * \param is_integer determines the value written for PIPE_SWIZZLE_1.
1365 */
1366void util_format_apply_color_swizzle(union pipe_color_union *dst,
1367                                     const union pipe_color_union *src,
1368                                     const unsigned char swz[4],
1369                                     const boolean is_integer);
1370
1371void pipe_swizzle_4f(float *dst, const float *src,
1372                            const unsigned char swz[4]);
1373
1374void util_format_unswizzle_4f(float *dst, const float *src,
1375                              const unsigned char swz[4]);
1376
1377enum pipe_format
1378util_format_snorm8_to_sint8(enum pipe_format format);
1379
1380#ifdef __cplusplus
1381} // extern "C" {
1382#endif
1383
1384#endif /* ! U_FORMAT_H */
1385