1f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu/**************************************************************************
2f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
3f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Copyright 2009-2010 Vmware, Inc.
4f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * All Rights Reserved.
5f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
6f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Permission is hereby granted, free of charge, to any person obtaining a
7f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * copy of this software and associated documentation files (the
8f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * "Software"), to deal in the Software without restriction, including
9f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * without limitation the rights to use, copy, modify, merge, publish,
10f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * distribute, sub license, and/or sell copies of the Software, and to
11f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * permit persons to whom the Software is furnished to do so, subject to
12f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * the following conditions:
13f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
14f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * The above copyright notice and this permission notice (including the
15f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * next paragraph) shall be included in all copies or substantial portions
16f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * of the Software.
17f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
18f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
26f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu **************************************************************************/
27f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu
28f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu
29f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu#ifndef U_FORMAT_H
30f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu#define U_FORMAT_H
31daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
32daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
33daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul#include "pipe/p_format.h"
34daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul#include "util/u_debug.h"
35e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul
36daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul#ifdef __cplusplus
3794cb321b5d246185abf71d89968d472a626f1a23Chia-I Wuextern "C" {
38daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul#endif
39daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
40e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul
41e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul/**
42e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul * Describe how to pack/unpack pixels into/from the prescribed format.
43e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul *
44daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul * XXX: This could be renamed to something like util_format_pack, or broke down
45a4a38dcf61f141297a083ccac217200947d57b0dChia-I Wu * in flags inside util_format_block that said exactly what we want.
462f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu */
47daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paulenum util_format_layout {
48daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   /**
492f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu    * Formats with util_format_block::width == util_format_block::height == 1
502f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu    * that can be described as an ordinary data structure.
512f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu    */
52daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   UTIL_FORMAT_LAYOUT_PLAIN = 0,
53daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
542f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu   /**
552f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu    * Formats with sub-sampled channels.
5617330479b39409a63a06ec9e6b0f8e28b585db12Chia-I Wu    *
572f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu    * This is for formats like YVYU where there is less than one sample per
582f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu    * pixel.
59daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    */
60daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3,
614aed0944f4b8b8d14d210cf6bc87ccddfa9a77ecChia-I Wu
624aed0944f4b8b8d14d210cf6bc87ccddfa9a77ecChia-I Wu   /**
632f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu    * S3 Texture Compression formats.
642f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu    */
652f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu   UTIL_FORMAT_LAYOUT_S3TC = 4,
662f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu
672f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu   /**
682f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu    * Red-Green Texture Compression formats.
6957da499d7ba074128e8c97b8076805e403a2b9c4Chia-I Wu    */
702f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu   UTIL_FORMAT_LAYOUT_RGTC = 5,
714aed0944f4b8b8d14d210cf6bc87ccddfa9a77ecChia-I Wu
72daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   /**
73daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    * Ericsson Texture Compression
742f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu    */
756c21c8862bc6edc9cddf3b6eb6f276961099a7a8Chia-I Wu   UTIL_FORMAT_LAYOUT_ETC = 6,
762f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu
77daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   /**
78655f4654675e601a9482e40d8e50156c965b8934Chia-I Wu    * Everything else that doesn't fit in any of the above layouts.
793e6139d158a054a0dfe8def28bf60201cdb9f385Chia-I Wu    */
80e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul   UTIL_FORMAT_LAYOUT_OTHER = 7
81e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul};
82daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
83b2006a40eb22899d38cd31691640555228e36975Brian Paul
842f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wustruct util_format_block
852f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu{
862f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu   /** Block width in pixels */
872f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu   unsigned width;
882f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu
892f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu   /** Block height in pixels */
902f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu   unsigned height;
912f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu
922f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu   /** Block size in bits */
932f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu   unsigned bits;
942f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu};
952f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu
96b2006a40eb22899d38cd31691640555228e36975Brian Paul
97b2006a40eb22899d38cd31691640555228e36975Brian Paulenum util_format_type {
98b2006a40eb22899d38cd31691640555228e36975Brian Paul   UTIL_FORMAT_TYPE_VOID = 0,
992f2cf461c57974abd89e4917945cc8ae6a67a72eChia-I Wu   UTIL_FORMAT_TYPE_UNSIGNED = 1,
100b2006a40eb22899d38cd31691640555228e36975Brian Paul   UTIL_FORMAT_TYPE_SIGNED = 2,
101daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   UTIL_FORMAT_TYPE_FIXED = 3,
102a1c4a8a3c855d52fbfef10023b9a8f116e163a97Chia-I Wu   UTIL_FORMAT_TYPE_FLOAT = 4
103a1c4a8a3c855d52fbfef10023b9a8f116e163a97Chia-I Wu};
104a1c4a8a3c855d52fbfef10023b9a8f116e163a97Chia-I Wu
1054eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu
1064eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wuenum util_format_swizzle {
1074eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu   UTIL_FORMAT_SWIZZLE_X = 0,
1084eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu   UTIL_FORMAT_SWIZZLE_Y = 1,
1094eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu   UTIL_FORMAT_SWIZZLE_Z = 2,
1104eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu   UTIL_FORMAT_SWIZZLE_W = 3,
1114eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu   UTIL_FORMAT_SWIZZLE_0 = 4,
1124eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu   UTIL_FORMAT_SWIZZLE_1 = 5,
11352c554a79d3ed3104a9f7d112faa9129073b5a25Kristian Høgsberg   UTIL_FORMAT_SWIZZLE_NONE = 6,
11452c554a79d3ed3104a9f7d112faa9129073b5a25Kristian Høgsberg   UTIL_FORMAT_SWIZZLE_MAX = 7  /**< Number of enums counter (must be last) */
11552c554a79d3ed3104a9f7d112faa9129073b5a25Kristian Høgsberg};
116daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
117b7a8893a2413adfddf4dc836676a19463fb6ffd7Kristian Høgsberg
118b7a8893a2413adfddf4dc836676a19463fb6ffd7Kristian Høgsbergenum util_format_colorspace {
119b7a8893a2413adfddf4dc836676a19463fb6ffd7Kristian Høgsberg   UTIL_FORMAT_COLORSPACE_RGB = 0,
120b7a8893a2413adfddf4dc836676a19463fb6ffd7Kristian Høgsberg   UTIL_FORMAT_COLORSPACE_SRGB = 1,
121b7a8893a2413adfddf4dc836676a19463fb6ffd7Kristian Høgsberg   UTIL_FORMAT_COLORSPACE_YUV = 2,
1226b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   UTIL_FORMAT_COLORSPACE_ZS = 3
1236b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke};
1246b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
1256b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
126e6a33570b73aa56c87818d7f67a122d4427b7841Kristian Høgsbergstruct util_format_channel_description
1276b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke{
1286b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   unsigned type:5;        /**< UTIL_FORMAT_TYPE_x */
1297d46b45c5bd7d1ab3e32a2722ca65061ca80dc34Fredrik Höglund   unsigned normalized:1;
1307d46b45c5bd7d1ab3e32a2722ca65061ca80dc34Fredrik Höglund   unsigned pure_integer:1;
131daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   unsigned size:9;        /**< bits per channel */
132daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul};
133daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
134daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
135daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paulstruct util_format_description
136daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul{
137daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   enum pipe_format format;
138daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
139daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   const char *name;
140daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
141daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   /**
142daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    * Short name, striped of the prefix, lower case.
143daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    */
144daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   const char *short_name;
145daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
146daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   /**
147daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    * Pixel block dimensions.
148daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    */
149daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   struct util_format_block block;
150daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
151daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   enum util_format_layout layout;
152daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
153daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   /**
154daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    * The number of channels.
155daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    */
156daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   unsigned nr_channels:3;
157daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
158daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   /**
159daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    * Whether all channels have the same number of (whole) bytes.
160daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    */
1616c21c8862bc6edc9cddf3b6eb6f276961099a7a8Chia-I Wu   unsigned is_array:1;
162daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
163e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul   /**
164daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    * Whether the pixel format can be described as a bitfield structure.
165a1c4a8a3c855d52fbfef10023b9a8f116e163a97Chia-I Wu    *
166daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    * In particular:
167daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    * - pixel depth must be 8, 16, or 32 bits;
168daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    * - all channels must be unsigned, signed, or void
169daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    */
170daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   unsigned is_bitmask:1;
171daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
17248822796339cb4a55714dc3f1abbe379562ec538Brian Paul   /**
173daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
174daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul    */
175daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   unsigned is_mixed:1;
176daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul
177daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   /**
178a1c4a8a3c855d52fbfef10023b9a8f116e163a97Chia-I Wu    * Input channel description.
179b2006a40eb22899d38cd31691640555228e36975Brian Paul    *
180b2006a40eb22899d38cd31691640555228e36975Brian Paul    * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats.
181a1c4a8a3c855d52fbfef10023b9a8f116e163a97Chia-I Wu    */
182a1c4a8a3c855d52fbfef10023b9a8f116e163a97Chia-I Wu   struct util_format_channel_description channel[4];
183a1c4a8a3c855d52fbfef10023b9a8f116e163a97Chia-I Wu
18452c554a79d3ed3104a9f7d112faa9129073b5a25Kristian Høgsberg   /**
1854eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu    * Output channel swizzle.
1864eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu    *
1874eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu    * The order is either:
1884eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu    * - RGBA
1894eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu    * - YUV(A)
1904eebea74a81ec5fbacf2347ea88cac137ddd4d69Chia-I Wu    * - ZS
19152c554a79d3ed3104a9f7d112faa9129073b5a25Kristian Høgsberg    * depending on the colorspace.
19252c554a79d3ed3104a9f7d112faa9129073b5a25Kristian Høgsberg    */
19352c554a79d3ed3104a9f7d112faa9129073b5a25Kristian Høgsberg   unsigned char swizzle[4];
194b7a8893a2413adfddf4dc836676a19463fb6ffd7Kristian Høgsberg
195b7a8893a2413adfddf4dc836676a19463fb6ffd7Kristian Høgsberg   /**
196b7a8893a2413adfddf4dc836676a19463fb6ffd7Kristian Høgsberg    * Colorspace transformation.
197b7a8893a2413adfddf4dc836676a19463fb6ffd7Kristian Høgsberg    */
198b7a8893a2413adfddf4dc836676a19463fb6ffd7Kristian Høgsberg   enum util_format_colorspace colorspace;
1996b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke
2006b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke   /**
2016b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke    * Unpack pixel blocks to R8G8B8A8_UNORM.
2026b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke    * Note: strides are in bytes.
203e6a33570b73aa56c87818d7f67a122d4427b7841Kristian Høgsberg    *
2046b369c4c7cd8a52f99bbff2a57fb316b33a87495Benjamin Franzke    * Only defined for non-depth-stencil formats.
2057d46b45c5bd7d1ab3e32a2722ca65061ca80dc34Fredrik Höglund    */
2067d46b45c5bd7d1ab3e32a2722ca65061ca80dc34Fredrik Höglund   void
207daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul   (*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
208daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul                         const uint8_t *src, unsigned src_stride,
209daf585d0f00df1d4d2e8dc5b465dad60a4bf0122Brian Paul                         unsigned width, unsigned height);
210
211   /**
212    * Pack pixel blocks from R8G8B8A8_UNORM.
213    * Note: strides are in bytes.
214    *
215    * Only defined for non-depth-stencil formats.
216    */
217   void
218   (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
219                       const uint8_t *src, unsigned src_stride,
220                       unsigned width, unsigned height);
221
222   /**
223    * Fetch a single pixel (i, j) from a block.
224    *
225    * XXX: Only defined for a very few select formats.
226    */
227   void
228   (*fetch_rgba_8unorm)(uint8_t *dst,
229                        const uint8_t *src,
230                        unsigned i, unsigned j);
231
232   /**
233    * Unpack pixel blocks to R32G32B32A32_FLOAT.
234    * Note: strides are in bytes.
235    *
236    * Only defined for non-depth-stencil formats.
237    */
238   void
239   (*unpack_rgba_float)(float *dst, unsigned dst_stride,
240                        const uint8_t *src, unsigned src_stride,
241                        unsigned width, unsigned height);
242
243   /**
244    * Pack pixel blocks from R32G32B32A32_FLOAT.
245    * Note: strides are in bytes.
246    *
247    * Only defined for non-depth-stencil formats.
248    */
249   void
250   (*pack_rgba_float)(uint8_t *dst, unsigned dst_stride,
251                      const float *src, unsigned src_stride,
252                      unsigned width, unsigned height);
253
254   /**
255    * Fetch a single pixel (i, j) from a block.
256    *
257    * Only defined for non-depth-stencil and non-integer formats.
258    */
259   void
260   (*fetch_rgba_float)(float *dst,
261                       const uint8_t *src,
262                       unsigned i, unsigned j);
263
264   /**
265    * Unpack pixels to Z32_UNORM.
266    * Note: strides are in bytes.
267    *
268    * Only defined for depth formats.
269    */
270   void
271   (*unpack_z_32unorm)(uint32_t *dst, unsigned dst_stride,
272                       const uint8_t *src, unsigned src_stride,
273                       unsigned width, unsigned height);
274
275   /**
276    * Pack pixels from Z32_FLOAT.
277    * Note: strides are in bytes.
278    *
279    * Only defined for depth formats.
280    */
281   void
282   (*pack_z_32unorm)(uint8_t *dst, unsigned dst_stride,
283                     const uint32_t *src, unsigned src_stride,
284                     unsigned width, unsigned height);
285
286   /**
287    * Unpack pixels to Z32_FLOAT.
288    * Note: strides are in bytes.
289    *
290    * Only defined for depth formats.
291    */
292   void
293   (*unpack_z_float)(float *dst, unsigned dst_stride,
294                     const uint8_t *src, unsigned src_stride,
295                     unsigned width, unsigned height);
296
297   /**
298    * Pack pixels from Z32_FLOAT.
299    * Note: strides are in bytes.
300    *
301    * Only defined for depth formats.
302    */
303   void
304   (*pack_z_float)(uint8_t *dst, unsigned dst_stride,
305                   const float *src, unsigned src_stride,
306                   unsigned width, unsigned height);
307
308   /**
309    * Unpack pixels to S8_UINT.
310    * Note: strides are in bytes.
311    *
312    * Only defined for stencil formats.
313    */
314   void
315   (*unpack_s_8uint)(uint8_t *dst, unsigned dst_stride,
316                     const uint8_t *src, unsigned src_stride,
317                     unsigned width, unsigned height);
318
319   /**
320    * Pack pixels from S8_UINT.
321    * Note: strides are in bytes.
322    *
323    * Only defined for stencil formats.
324    */
325   void
326   (*pack_s_8uint)(uint8_t *dst, unsigned dst_stride,
327                   const uint8_t *src, unsigned src_stride,
328                   unsigned width, unsigned height);
329
330  /**
331    * Unpack pixel blocks to R32G32B32A32_UINT.
332    * Note: strides are in bytes.
333    *
334    * Only defined for INT formats.
335    */
336   void
337   (*unpack_rgba_uint)(unsigned *dst, unsigned dst_stride,
338                       const uint8_t *src, unsigned src_stride,
339                       unsigned width, unsigned height);
340
341   void
342   (*pack_rgba_uint)(uint8_t *dst, unsigned dst_stride,
343                     const unsigned *src, unsigned src_stride,
344                     unsigned width, unsigned height);
345
346  /**
347    * Unpack pixel blocks to R32G32B32A32_SINT.
348    * Note: strides are in bytes.
349    *
350    * Only defined for INT formats.
351    */
352   void
353   (*unpack_rgba_sint)(signed *dst, unsigned dst_stride,
354                       const uint8_t *src, unsigned src_stride,
355                       unsigned width, unsigned height);
356
357   void
358   (*pack_rgba_sint)(uint8_t *dst, unsigned dst_stride,
359                     const int *src, unsigned src_stride,
360                     unsigned width, unsigned height);
361
362   /**
363    * Fetch a single pixel (i, j) from a block.
364    *
365    * Only defined for unsigned (pure) integer formats.
366    */
367   void
368   (*fetch_rgba_uint)(uint32_t *dst,
369                      const uint8_t *src,
370                      unsigned i, unsigned j);
371
372   /**
373    * Fetch a single pixel (i, j) from a block.
374    *
375    * Only defined for signed (pure) integer formats.
376    */
377   void
378   (*fetch_rgba_sint)(int32_t *dst,
379                      const uint8_t *src,
380                      unsigned i, unsigned j);
381};
382
383
384extern const struct util_format_description
385util_format_description_table[];
386
387
388const struct util_format_description *
389util_format_description(enum pipe_format format);
390
391
392/*
393 * Format query functions.
394 */
395
396static INLINE const char *
397util_format_name(enum pipe_format format)
398{
399   const struct util_format_description *desc = util_format_description(format);
400
401   assert(desc);
402   if (!desc) {
403      return "PIPE_FORMAT_???";
404   }
405
406   return desc->name;
407}
408
409static INLINE const char *
410util_format_short_name(enum pipe_format format)
411{
412   const struct util_format_description *desc = util_format_description(format);
413
414   assert(desc);
415   if (!desc) {
416      return "???";
417   }
418
419   return desc->short_name;
420}
421
422/**
423 * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
424 */
425static INLINE boolean
426util_format_is_plain(enum pipe_format format)
427{
428   const struct util_format_description *desc = util_format_description(format);
429
430   if (!format) {
431      return FALSE;
432   }
433
434   return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;
435}
436
437static INLINE boolean
438util_format_is_compressed(enum pipe_format format)
439{
440   const struct util_format_description *desc = util_format_description(format);
441
442   assert(desc);
443   if (!desc) {
444      return FALSE;
445   }
446
447   switch (desc->layout) {
448   case UTIL_FORMAT_LAYOUT_S3TC:
449   case UTIL_FORMAT_LAYOUT_RGTC:
450      /* XXX add other formats in the future */
451      return TRUE;
452   default:
453      return FALSE;
454   }
455}
456
457static INLINE boolean
458util_format_is_s3tc(enum pipe_format format)
459{
460   const struct util_format_description *desc = util_format_description(format);
461
462   assert(desc);
463   if (!desc) {
464      return FALSE;
465   }
466
467   return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
468}
469
470static INLINE boolean
471util_format_is_srgb(enum pipe_format format)
472{
473   const struct util_format_description *desc = util_format_description(format);
474   return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;
475}
476
477static INLINE boolean
478util_format_has_depth(const struct util_format_description *desc)
479{
480   return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
481          desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE;
482}
483
484static INLINE boolean
485util_format_has_stencil(const struct util_format_description *desc)
486{
487   return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
488          desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE;
489}
490
491static INLINE boolean
492util_format_is_depth_or_stencil(enum pipe_format format)
493{
494   const struct util_format_description *desc = util_format_description(format);
495
496   assert(desc);
497   if (!desc) {
498      return FALSE;
499   }
500
501   return util_format_has_depth(desc) ||
502          util_format_has_stencil(desc);
503}
504
505static INLINE boolean
506util_format_is_depth_and_stencil(enum pipe_format format)
507{
508   const struct util_format_description *desc = util_format_description(format);
509
510   assert(desc);
511   if (!desc) {
512      return FALSE;
513   }
514
515   return util_format_has_depth(desc) &&
516          util_format_has_stencil(desc);
517}
518
519
520/**
521 * Give the RGBA colormask of the channels that can be represented in this
522 * format.
523 *
524 * That is, the channels whose values are preserved.
525 */
526static INLINE unsigned
527util_format_colormask(const struct util_format_description *desc)
528{
529   unsigned colormask;
530   unsigned chan;
531
532   switch (desc->colorspace) {
533   case UTIL_FORMAT_COLORSPACE_RGB:
534   case UTIL_FORMAT_COLORSPACE_SRGB:
535   case UTIL_FORMAT_COLORSPACE_YUV:
536      colormask = 0;
537      for (chan = 0; chan < 4; ++chan) {
538         if (desc->swizzle[chan] < 4) {
539            colormask |= (1 << chan);
540         }
541      }
542      return colormask;
543   case UTIL_FORMAT_COLORSPACE_ZS:
544      return 0;
545   default:
546      assert(0);
547      return 0;
548   }
549}
550
551
552/**
553 * Checks if color mask covers every channel for the specified format
554 *
555 * @param desc       a format description to check colormask with
556 * @param colormask  a bit mask for channels, matches format of PIPE_MASK_RGBA
557 */
558static INLINE boolean
559util_format_colormask_full(const struct util_format_description *desc, unsigned colormask)
560{
561   return (~colormask & util_format_colormask(desc)) == 0;
562}
563
564
565boolean
566util_format_is_float(enum pipe_format format);
567
568
569boolean
570util_format_is_rgb_no_alpha(enum pipe_format format);
571
572
573boolean
574util_format_is_luminance(enum pipe_format format);
575
576
577boolean
578util_format_is_luminance_alpha(enum pipe_format format);
579
580
581boolean
582util_format_is_intensity(enum pipe_format format);
583
584boolean
585util_format_is_pure_integer(enum pipe_format format);
586
587boolean
588util_format_is_pure_sint(enum pipe_format format);
589
590boolean
591util_format_is_pure_uint(enum pipe_format format);
592
593/**
594 * Whether the format is a simple array format where all channels
595 * are of the same type and can be loaded from memory as a vector
596 */
597boolean
598util_format_is_array(const struct util_format_description *desc);
599
600/**
601 * Check if the src format can be blitted to the destination format with
602 * a simple memcpy.  For example, blitting from RGBA to RGBx is OK, but not
603 * the reverse.
604 */
605boolean
606util_is_format_compatible(const struct util_format_description *src_desc,
607                          const struct util_format_description *dst_desc);
608
609/**
610 * Whether the format is supported by Gallium for the given bindings.
611 * This covers S3TC textures and floating-point render targets.
612 */
613boolean
614util_format_is_supported(enum pipe_format format, unsigned bind);
615
616/**
617 * Whether this format is a rgab8 variant.
618 *
619 * That is, any format that matches the
620 *
621 *   PIPE_FORMAT_?8?8?8?8_UNORM
622 */
623static INLINE boolean
624util_format_is_rgba8_variant(const struct util_format_description *desc)
625{
626   unsigned chan;
627
628   if(desc->block.width != 1 ||
629      desc->block.height != 1 ||
630      desc->block.bits != 32)
631      return FALSE;
632
633   for(chan = 0; chan < 4; ++chan) {
634      if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
635         desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
636         return FALSE;
637      if(desc->channel[chan].size != 8)
638         return FALSE;
639   }
640
641   return TRUE;
642}
643
644
645/**
646 * Return total bits needed for the pixel format per block.
647 */
648static INLINE uint
649util_format_get_blocksizebits(enum pipe_format format)
650{
651   const struct util_format_description *desc = util_format_description(format);
652
653   assert(desc);
654   if (!desc) {
655      return 0;
656   }
657
658   return desc->block.bits;
659}
660
661/**
662 * Return bytes per block (not pixel) for the given format.
663 */
664static INLINE uint
665util_format_get_blocksize(enum pipe_format format)
666{
667   uint bits = util_format_get_blocksizebits(format);
668
669   assert(bits % 8 == 0);
670
671   return bits / 8;
672}
673
674static INLINE uint
675util_format_get_blockwidth(enum pipe_format format)
676{
677   const struct util_format_description *desc = util_format_description(format);
678
679   assert(desc);
680   if (!desc) {
681      return 1;
682   }
683
684   return desc->block.width;
685}
686
687static INLINE uint
688util_format_get_blockheight(enum pipe_format format)
689{
690   const struct util_format_description *desc = util_format_description(format);
691
692   assert(desc);
693   if (!desc) {
694      return 1;
695   }
696
697   return desc->block.height;
698}
699
700static INLINE unsigned
701util_format_get_nblocksx(enum pipe_format format,
702                         unsigned x)
703{
704   unsigned blockwidth = util_format_get_blockwidth(format);
705   return (x + blockwidth - 1) / blockwidth;
706}
707
708static INLINE unsigned
709util_format_get_nblocksy(enum pipe_format format,
710                         unsigned y)
711{
712   unsigned blockheight = util_format_get_blockheight(format);
713   return (y + blockheight - 1) / blockheight;
714}
715
716static INLINE unsigned
717util_format_get_nblocks(enum pipe_format format,
718                        unsigned width,
719                        unsigned height)
720{
721   return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height);
722}
723
724static INLINE size_t
725util_format_get_stride(enum pipe_format format,
726                       unsigned width)
727{
728   return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format);
729}
730
731static INLINE size_t
732util_format_get_2d_size(enum pipe_format format,
733                        size_t stride,
734                        unsigned height)
735{
736   return util_format_get_nblocksy(format, height) * stride;
737}
738
739static INLINE uint
740util_format_get_component_bits(enum pipe_format format,
741                               enum util_format_colorspace colorspace,
742                               uint component)
743{
744   const struct util_format_description *desc = util_format_description(format);
745   enum util_format_colorspace desc_colorspace;
746
747   assert(format);
748   if (!format) {
749      return 0;
750   }
751
752   assert(component < 4);
753
754   /* Treat RGB and SRGB as equivalent. */
755   if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
756      colorspace = UTIL_FORMAT_COLORSPACE_RGB;
757   }
758   if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
759      desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB;
760   } else {
761      desc_colorspace = desc->colorspace;
762   }
763
764   if (desc_colorspace != colorspace) {
765      return 0;
766   }
767
768   switch (desc->swizzle[component]) {
769   case UTIL_FORMAT_SWIZZLE_X:
770      return desc->channel[0].size;
771   case UTIL_FORMAT_SWIZZLE_Y:
772      return desc->channel[1].size;
773   case UTIL_FORMAT_SWIZZLE_Z:
774      return desc->channel[2].size;
775   case UTIL_FORMAT_SWIZZLE_W:
776      return desc->channel[3].size;
777   default:
778      return 0;
779   }
780}
781
782static INLINE boolean
783util_format_has_alpha(enum pipe_format format)
784{
785   const struct util_format_description *desc = util_format_description(format);
786
787   assert(format);
788   if (!format) {
789      return FALSE;
790   }
791
792   switch (desc->colorspace) {
793   case UTIL_FORMAT_COLORSPACE_RGB:
794   case UTIL_FORMAT_COLORSPACE_SRGB:
795      return desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1;
796   case UTIL_FORMAT_COLORSPACE_YUV:
797      return FALSE;
798   case UTIL_FORMAT_COLORSPACE_ZS:
799      return FALSE;
800   default:
801      assert(0);
802      return FALSE;
803   }
804}
805
806/**
807 * Given a linear RGB colorspace format, return the corresponding SRGB
808 * format, or PIPE_FORMAT_NONE if none.
809 */
810static INLINE enum pipe_format
811util_format_srgb(enum pipe_format format)
812{
813   switch (format) {
814   case PIPE_FORMAT_L8_UNORM:
815      return PIPE_FORMAT_L8_SRGB;
816   case PIPE_FORMAT_L8A8_UNORM:
817      return PIPE_FORMAT_L8A8_SRGB;
818   case PIPE_FORMAT_R8G8B8_UNORM:
819      return PIPE_FORMAT_R8G8B8_SRGB;
820   case PIPE_FORMAT_A8B8G8R8_UNORM:
821      return PIPE_FORMAT_A8B8G8R8_SRGB;
822   case PIPE_FORMAT_X8B8G8R8_UNORM:
823      return PIPE_FORMAT_X8B8G8R8_SRGB;
824   case PIPE_FORMAT_B8G8R8A8_UNORM:
825      return PIPE_FORMAT_B8G8R8A8_SRGB;
826   case PIPE_FORMAT_B8G8R8X8_UNORM:
827      return PIPE_FORMAT_B8G8R8X8_SRGB;
828   case PIPE_FORMAT_A8R8G8B8_UNORM:
829      return PIPE_FORMAT_A8R8G8B8_SRGB;
830   case PIPE_FORMAT_X8R8G8B8_UNORM:
831      return PIPE_FORMAT_X8R8G8B8_SRGB;
832   case PIPE_FORMAT_DXT1_RGB:
833      return PIPE_FORMAT_DXT1_SRGB;
834   case PIPE_FORMAT_DXT1_RGBA:
835      return PIPE_FORMAT_DXT1_SRGBA;
836   case PIPE_FORMAT_DXT3_RGBA:
837      return PIPE_FORMAT_DXT3_SRGBA;
838   case PIPE_FORMAT_DXT5_RGBA:
839      return PIPE_FORMAT_DXT5_SRGBA;
840   default:
841      return PIPE_FORMAT_NONE;
842   }
843}
844
845/**
846 * Given an sRGB format, return the corresponding linear colorspace format.
847 * For non sRGB formats, return the format unchanged.
848 */
849static INLINE enum pipe_format
850util_format_linear(enum pipe_format format)
851{
852   switch (format) {
853   case PIPE_FORMAT_L8_SRGB:
854      return PIPE_FORMAT_L8_UNORM;
855   case PIPE_FORMAT_L8A8_SRGB:
856      return PIPE_FORMAT_L8A8_UNORM;
857   case PIPE_FORMAT_R8G8B8_SRGB:
858      return PIPE_FORMAT_R8G8B8_UNORM;
859   case PIPE_FORMAT_A8B8G8R8_SRGB:
860      return PIPE_FORMAT_A8B8G8R8_UNORM;
861   case PIPE_FORMAT_X8B8G8R8_SRGB:
862      return PIPE_FORMAT_X8B8G8R8_UNORM;
863   case PIPE_FORMAT_B8G8R8A8_SRGB:
864      return PIPE_FORMAT_B8G8R8A8_UNORM;
865   case PIPE_FORMAT_B8G8R8X8_SRGB:
866      return PIPE_FORMAT_B8G8R8X8_UNORM;
867   case PIPE_FORMAT_A8R8G8B8_SRGB:
868      return PIPE_FORMAT_A8R8G8B8_UNORM;
869   case PIPE_FORMAT_X8R8G8B8_SRGB:
870      return PIPE_FORMAT_X8R8G8B8_UNORM;
871   case PIPE_FORMAT_DXT1_SRGB:
872      return PIPE_FORMAT_DXT1_RGB;
873   case PIPE_FORMAT_DXT1_SRGBA:
874      return PIPE_FORMAT_DXT1_RGBA;
875   case PIPE_FORMAT_DXT3_SRGBA:
876      return PIPE_FORMAT_DXT3_RGBA;
877   case PIPE_FORMAT_DXT5_SRGBA:
878      return PIPE_FORMAT_DXT5_RGBA;
879   default:
880      return format;
881   }
882}
883
884/**
885 * Given a depth-stencil format, return the corresponding stencil-only format.
886 * For stencil-only formats, return the format unchanged.
887 */
888static INLINE enum pipe_format
889util_format_stencil_only(enum pipe_format format)
890{
891   switch (format) {
892   /* mask out the depth component */
893   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
894      return PIPE_FORMAT_X24S8_UINT;
895   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
896      return PIPE_FORMAT_S8X24_UINT;
897   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
898      return PIPE_FORMAT_X32_S8X24_UINT;
899
900   /* stencil only formats */
901   case PIPE_FORMAT_X24S8_UINT:
902   case PIPE_FORMAT_S8X24_UINT:
903   case PIPE_FORMAT_X32_S8X24_UINT:
904   case PIPE_FORMAT_S8_UINT:
905      return format;
906
907   default:
908      assert(0);
909      return PIPE_FORMAT_NONE;
910   }
911}
912
913/**
914 * Return the number of components stored.
915 * Formats with block size != 1x1 will always have 1 component (the block).
916 */
917static INLINE unsigned
918util_format_get_nr_components(enum pipe_format format)
919{
920   const struct util_format_description *desc = util_format_description(format);
921   return desc->nr_channels;
922}
923
924/**
925 * Return the index of the first non-void channel
926 * -1 if no non-void channels
927 */
928static INLINE int
929util_format_get_first_non_void_channel(enum pipe_format format)
930{
931   const struct util_format_description *desc = util_format_description(format);
932   int i;
933
934   for (i = 0; i < 4; i++)
935      if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
936         break;
937
938   if (i == 4)
939       return -1;
940
941   return i;
942}
943
944/*
945 * Format access functions.
946 */
947
948void
949util_format_read_4f(enum pipe_format format,
950                    float *dst, unsigned dst_stride,
951                    const void *src, unsigned src_stride,
952                    unsigned x, unsigned y, unsigned w, unsigned h);
953
954void
955util_format_write_4f(enum pipe_format format,
956                     const float *src, unsigned src_stride,
957                     void *dst, unsigned dst_stride,
958                     unsigned x, unsigned y, unsigned w, unsigned h);
959
960void
961util_format_read_4ub(enum pipe_format format,
962                     uint8_t *dst, unsigned dst_stride,
963                     const void *src, unsigned src_stride,
964                     unsigned x, unsigned y, unsigned w, unsigned h);
965
966void
967util_format_write_4ub(enum pipe_format format,
968                      const uint8_t *src, unsigned src_stride,
969                      void *dst, unsigned dst_stride,
970                      unsigned x, unsigned y, unsigned w, unsigned h);
971
972void
973util_format_read_4ui(enum pipe_format format,
974                     unsigned *dst, unsigned dst_stride,
975                     const void *src, unsigned src_stride,
976                     unsigned x, unsigned y, unsigned w, unsigned h);
977
978void
979util_format_write_4ui(enum pipe_format format,
980                      const unsigned int *src, unsigned src_stride,
981                      void *dst, unsigned dst_stride,
982                      unsigned x, unsigned y, unsigned w, unsigned h);
983
984void
985util_format_read_4i(enum pipe_format format,
986                    int *dst, unsigned dst_stride,
987                    const void *src, unsigned src_stride,
988                    unsigned x, unsigned y, unsigned w, unsigned h);
989
990void
991util_format_write_4i(enum pipe_format format,
992                     const int *src, unsigned src_stride,
993                     void *dst, unsigned dst_stride,
994                     unsigned x, unsigned y, unsigned w, unsigned h);
995
996/*
997 * Generic format conversion;
998 */
999
1000boolean
1001util_format_fits_8unorm(const struct util_format_description *format_desc);
1002
1003void
1004util_format_translate(enum pipe_format dst_format,
1005                      void *dst, unsigned dst_stride,
1006                      unsigned dst_x, unsigned dst_y,
1007                      enum pipe_format src_format,
1008                      const void *src, unsigned src_stride,
1009                      unsigned src_x, unsigned src_y,
1010                      unsigned width, unsigned height);
1011
1012/*
1013 * Swizzle operations.
1014 */
1015
1016/* Compose two sets of swizzles.
1017 * If V is a 4D vector and the function parameters represent functions that
1018 * swizzle vector components, this holds:
1019 *     swz2(swz1(V)) = dst(V)
1020 */
1021void util_format_compose_swizzles(const unsigned char swz1[4],
1022                                  const unsigned char swz2[4],
1023                                  unsigned char dst[4]);
1024
1025void util_format_swizzle_4f(float *dst, const float *src,
1026                            const unsigned char swz[4]);
1027
1028void util_format_unswizzle_4f(float *dst, const float *src,
1029                              const unsigned char swz[4]);
1030
1031#ifdef __cplusplus
1032} // extern "C" {
1033#endif
1034
1035#endif /* ! U_FORMAT_H */
1036