gfx_hal/
format.rs

1//! Universal format specification.
2//! Applicable to textures, views, and vertex buffers.
3//!
4//! For a more detailed description of all the specific format specifiers,
5//! please see [the official Vulkan documentation](https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkFormat.html)
6//!
7//! `gfx-rs` splits a `Format` into two sub-components, a `SurfaceType` and
8//! a `ChannelType`.  The `SurfaceType` specifies how the large the channels are,
9//! for instance `R32_G32_B32_A32`.  The `ChannelType` specifies how the
10//! components are interpreted, for instance `Sfloat` or `Sint`.
11
12pub use external_memory::DrmModifier;
13
14bitflags!(
15    /// Bitflags which describe what properties of an image
16    /// a format specifies or does not specify.  For example,
17    /// the `Rgba8Unorm` format only specifies a `COLOR` aspect,
18    /// while `D32SfloatS8Uint` specifies both a depth and stencil
19    /// aspect but no color.
20    #[derive(Default)]
21    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
22    pub struct Aspects: u8 {
23        /// Color aspect.
24        const COLOR = 0x1;
25        /// Depth aspect.
26        const DEPTH = 0x2;
27        /// Stencil aspect.
28        const STENCIL = 0x4;
29    }
30);
31
32/// Description of a format.
33#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
34pub struct FormatDesc {
35    /// Total number of bits.
36    ///
37    /// * Depth/Stencil formats are opaque formats, where the total number of bits is unknown.
38    ///   A dummy value is used for these formats instead (sum of depth and stencil bits).
39    ///   For copy operations, the number of bits of the corresponding aspect should be used.
40    /// * The total number can be larger than the sum of individual format bits
41    ///   (`color`, `alpha`, `depth` and `stencil`) for packed formats.
42    /// * For compressed formats, this denotes the number of bits per block.
43    pub bits: u16,
44    /// Dimensions (width, height) of the texel blocks.
45    pub dim: (u8, u8),
46    /// The format representation depends on the endianness of the platform.
47    ///
48    /// * On little-endian systems, the actual oreder of components is reverse of what
49    ///   a surface type specifies.
50    pub packed: bool,
51    /// Format aspects
52    pub aspects: Aspects,
53}
54
55impl FormatDesc {
56    /// Check if the format is compressed.
57    pub fn is_compressed(&self) -> bool {
58        self.dim != (1, 1)
59    }
60}
61
62/// Description of the bits distribution of a format.
63#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
64pub struct FormatBits {
65    /// Number of color bits (summed for R/G/B).
66    ///
67    /// For compressed formats, this value is 0.
68    pub color: u8,
69    /// Number of alpha bits.
70    ///
71    /// For compressed formats, this value is 0.
72    pub alpha: u8,
73    /// Number of depth bits
74    pub depth: u8,
75    /// Number of stencil bits
76    pub stencil: u8,
77}
78
79/// Format bits configuration with no bits assigned.
80pub const BITS_ZERO: FormatBits = FormatBits {
81    color: 0,
82    alpha: 0,
83    depth: 0,
84    stencil: 0,
85};
86
87/// Source channel in a swizzle configuration. Some may redirect onto
88/// different physical channels, some may be hardcoded to 0 or 1.
89#[repr(u8)]
90#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
91#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
92pub enum Component {
93    //TODO: add `Identity = 0`?
94    /// Hardcoded zero
95    Zero = 1,
96    /// Hardcoded one
97    One = 2,
98    /// Red channel
99    R = 3,
100    /// Green channel
101    G = 4,
102    /// Blue channel
103    B = 5,
104    /// Alpha channel.
105    A = 6,
106}
107
108/// Channel swizzle configuration for the resource views.
109/// This specifies a "swizzle" operation which remaps the various
110/// channels of a format into a different order.  For example,
111/// `Swizzle(Component::B, Component::G, Component::R, Component::A)`
112/// will swap `RGBA` formats into `BGRA` formats and back.
113///
114/// Note: It's not currently mirrored at compile-time,
115/// thus providing less safety and convenience.
116#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
117#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
118pub struct Swizzle(pub Component, pub Component, pub Component, pub Component);
119
120impl Swizzle {
121    /// A trivially non-swizzling configuration; performs no changes.
122    pub const NO: Swizzle = Swizzle(Component::R, Component::G, Component::B, Component::A);
123}
124
125impl Default for Swizzle {
126    fn default() -> Self {
127        Self::NO
128    }
129}
130
131/// Drm format properties
132#[derive(Debug, Clone, PartialEq, Eq, Hash)]
133#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
134pub struct DrmFormatProperties {
135    /// Drm format modifier.
136    pub drm_modifier: DrmModifier,
137    /// Number of memory planes each image crated with `drm_modifier` has.
138    pub plane_count: u32,
139    /// Valid image usage with the `drm_modifier`.
140    pub valid_usages: ImageFeature,
141}
142impl Default for DrmFormatProperties {
143    fn default() -> Self {
144        Self {
145            drm_modifier: DrmModifier::Invalid,
146            plane_count: 0,
147            valid_usages: ImageFeature::default(),
148        }
149    }
150}
151
152/// Format properties of the physical device.
153#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
154#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
155pub struct Properties {
156    /// A bitmask of the features supported when an image with linear tiling is requested.
157    /// Linear tiling has a known layout in-memory so data can be copied to and from host
158    /// memory.
159    pub linear_tiling: ImageFeature,
160    /// A bitmask of the features supported when an image with optimal tiling is requested.
161    /// Optimal tiling is arranged however the GPU wants; its exact layout is undefined.
162    pub optimal_tiling: ImageFeature,
163    /// The features supported by buffers.
164    pub buffer_features: BufferFeature,
165    /// Drm format properties
166    pub drm_format_properties: Vec<DrmFormatProperties>,
167}
168
169//Note: these are detached from Vulkan!
170bitflags!(
171    /// Image feature flags.
172    #[derive(Default)]
173    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
174    pub struct ImageFeature: u32 {
175        /// Image view can be sampled.
176        const SAMPLED = 0x1;
177        /// Image can be sampled with a linear sampler or as blit source with linear sampling.
178        const SAMPLED_LINEAR = 0x2;
179        /// Image can be sampled with a min/max reduction sampler.
180        const SAMPLED_MINMAX = 0x4;
181
182        /// Image view can be used as storage image with exclusive read & write access.
183        const STORAGE = 0x10;
184        /// Image view can be used as storage image with simultaneous read/write access.
185        const STORAGE_READ_WRITE = 0x20;
186        /// Image view can be used as storage image with atomics.
187        const STORAGE_ATOMIC = 0x40;
188
189        /// Image view can be used as color and input attachment.
190        const COLOR_ATTACHMENT = 0x100;
191        /// Image view can be used as color (with blending) and input attachment.
192        const COLOR_ATTACHMENT_BLEND = 0x200;
193        /// Image view can be used as depth-stencil and input attachment.
194        const DEPTH_STENCIL_ATTACHMENT = 0x400;
195
196        /// Image can be used as source for blit commands.
197        const BLIT_SRC = 0x1000;
198        /// Image can be used as destination for blit commands.
199        const BLIT_DST = 0x2000;
200        /// Image can be copied from.
201        const TRANSFER_SRC = 0x4000;
202        /// Image can be copied to.
203        const TRANSFER_DST = 0x8000;
204    }
205);
206
207bitflags!(
208    /// Buffer feature flags.
209    #[derive(Default)]
210    #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
211    pub struct BufferFeature: u32 {
212        /// Buffer view can be used as uniform texel buffer.
213        const UNIFORM_TEXEL = 0x8;
214        /// Buffer view can be used as storage texel buffer.
215        const STORAGE_TEXEL = 0x10;
216        /// Buffer view can be used as storage texel buffer (with atomics).
217        const STORAGE_TEXEL_ATOMIC = 0x20;
218        /// Image view can be used as vertex buffer.
219        const VERTEX = 0x40;
220    }
221);
222
223/// Type of a surface channel. This is how we interpret the
224/// storage allocated with `SurfaceType`.
225#[repr(u8)]
226#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
227#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
228pub enum ChannelType {
229    /// Unsigned normalized.
230    Unorm,
231    /// Signed normalized.
232    Snorm,
233    /// Unsigned integer.
234    Uint,
235    /// Signed integer.
236    Sint,
237    /// Unsigned floating-point.
238    Ufloat,
239    /// Signed floating-point.
240    Sfloat,
241    /// Unsigned scaled integer.
242    Uscaled,
243    /// Signed scaled integer.
244    Sscaled,
245    /// Unsigned normalized, SRGB non-linear encoded.
246    Srgb,
247}
248
249macro_rules! surface_types {
250    { $($name:ident { $total:expr, $($aspect:ident)|*, $dim:expr $( ,$component:ident : $bits:expr )*} ,)* } => {
251        /// Type of the allocated texture surface. It is supposed to only
252        /// carry information about the number of bits per each channel.
253        /// The actual types are up to the views to decide and interpret.
254        /// The actual components are up to the swizzle to define.
255        #[repr(u8)]
256        #[allow(missing_docs, non_camel_case_types)]
257        #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
258        #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
259        pub enum SurfaceType {
260            $( $name, )*
261        }
262
263        impl SurfaceType {
264            /// Return the bits for this format.
265            pub fn describe_bits(&self) -> FormatBits {
266                match *self {
267                    $( SurfaceType::$name => FormatBits {
268                        $( $component: $bits, )*
269                        .. BITS_ZERO
270                    }, )*
271                }
272            }
273
274            /// Return the format descriptor.
275            pub fn desc(&self) -> FormatDesc {
276                match *self {
277                    $( SurfaceType::$name => FormatDesc {
278                        bits: $total.min(!$total),
279                        dim: $dim,
280                        packed: $total > 0x1000,
281                        aspects: $(Aspects::$aspect)|*,
282                    }, )*
283                }
284            }
285        }
286    }
287}
288
289// ident { num_bits, aspects, dim, (color, alpha, ..) }
290// if the number of bits is given with exclamation (e.g. `!16`), the format is considered packed
291surface_types! {
292    R4_G4               {  !8, COLOR, (1, 1), color: 8 },
293    R4_G4_B4_A4         { !16, COLOR, (1, 1), color: 12, alpha: 4 },
294    B4_G4_R4_A4         { !16, COLOR, (1, 1), color: 12, alpha: 4 },
295    R5_G6_B5            { !16, COLOR, (1, 1), color: 16 },
296    B5_G6_R5            { !16, COLOR, (1, 1), color: 16 },
297    R5_G5_B5_A1         { !16, COLOR, (1, 1), color: 15, alpha: 1 },
298    B5_G5_R5_A1         { !16, COLOR, (1, 1), color: 15, alpha: 1 },
299    A1_R5_G5_B5         { !16, COLOR, (1, 1), color: 15, alpha: 1 },
300    R8                  {   8, COLOR, (1, 1), color: 8 },
301    R8_G8               {  16, COLOR, (1, 1), color: 16 },
302    R8_G8_B8            {  24, COLOR, (1, 1), color: 24 },
303    B8_G8_R8            {  24, COLOR, (1, 1), color: 24 },
304    R8_G8_B8_A8         {  32, COLOR, (1, 1), color: 24, alpha: 8 },
305    B8_G8_R8_A8         {  32, COLOR, (1, 1), color: 24, alpha: 8 },
306    A8_B8_G8_R8         { !32, COLOR, (1, 1), color: 24, alpha: 8 },
307    A2_R10_G10_B10      { !32, COLOR, (1, 1), color: 30, alpha: 2 },
308    A2_B10_G10_R10      { !32, COLOR, (1, 1), color: 30, alpha: 2 },
309    R16                 {  16, COLOR, (1, 1), color: 16 },
310    R16_G16             {  32, COLOR, (1, 1), color: 32 },
311    R16_G16_B16         {  48, COLOR, (1, 1), color: 48 },
312    R16_G16_B16_A16     {  64, COLOR, (1, 1), color: 48, alpha: 16 },
313    R32                 {  32, COLOR, (1, 1), color: 32 },
314    R32_G32             {  64, COLOR, (1, 1), color: 64 },
315    R32_G32_B32         {  96, COLOR, (1, 1), color: 96 },
316    R32_G32_B32_A32     { 128, COLOR, (1, 1), color: 96, alpha: 32 },
317    R64                 {  64, COLOR, (1, 1), color: 64 },
318    R64_G64             { 128, COLOR, (1, 1), color: 128 },
319    R64_G64_B64         { 192, COLOR, (1, 1), color: 192 },
320    R64_G64_B64_A64     { 256, COLOR, (1, 1), color: 192, alpha: 64 },
321    B10_G11_R11         { !32, COLOR, (1, 1), color: 32 },
322    E5_B9_G9_R9         { !32, COLOR, (1, 1), color: 27 },
323    D16                 {  16, DEPTH, (1, 1), depth: 16 },
324    X8D24               { !32, DEPTH, (1, 1), depth: 24 },
325    D32                 {  32, DEPTH, (1, 1), depth: 32 },
326    S8                  {   8, STENCIL, (1, 1), stencil: 8 },
327    D16_S8              {  24, DEPTH | STENCIL, (1, 1), depth: 16, stencil: 8 },
328    D24_S8              {  32, DEPTH | STENCIL, (1, 1), depth: 24, stencil: 8 },
329    D32_S8              {  40, DEPTH | STENCIL, (1, 1), depth: 32, stencil: 8 },
330    BC1_RGB             {  64, COLOR, (4, 4) },
331    BC1_RGBA            {  64, COLOR, (4, 4) },
332    BC2                 { 128, COLOR, (4, 4) },
333    BC3                 { 128, COLOR, (4, 4) },
334    BC4                 {  64, COLOR, (4, 4) },
335    BC5                 { 128, COLOR, (4, 4) },
336    BC6                 { 128, COLOR, (4, 4) },
337    BC7                 { 128, COLOR, (4, 4) },
338    ETC2_R8_G8_B8       {  64, COLOR, (4, 4) },
339    ETC2_R8_G8_B8_A1    {  64, COLOR, (4, 4) },
340    ETC2_R8_G8_B8_A8    { 128, COLOR, (4, 4) },
341    EAC_R11             {  64, COLOR, (4, 4) },
342    EAC_R11_G11         { 128, COLOR, (4, 4) },
343    ASTC_4x4            { 128, COLOR, (4, 4) },
344    ASTC_5x4            { 128, COLOR, (5, 4) },
345    ASTC_5x5            { 128, COLOR, (5, 5) },
346    ASTC_6x5            { 128, COLOR, (6, 5) },
347    ASTC_6x6            { 128, COLOR, (6, 6) },
348    ASTC_8x5            { 128, COLOR, (8, 5) },
349    ASTC_8x6            { 128, COLOR, (8, 6) },
350    ASTC_8x8            { 128, COLOR, (8, 8) },
351    ASTC_10x5           { 128, COLOR, (10, 5) },
352    ASTC_10x6           { 128, COLOR, (10, 6) },
353    ASTC_10x8           { 128, COLOR, (10, 8) },
354    ASTC_10x10          { 128, COLOR, (10, 10) },
355    ASTC_12x10          { 128, COLOR, (12, 10) },
356    ASTC_12x12          { 128, COLOR, (12, 12) },
357}
358
359/// Generic run-time base format.
360#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
361#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
362pub struct BaseFormat(pub SurfaceType, pub ChannelType);
363
364/// Conversion trait into `Format`;
365pub trait AsFormat {
366    /// Associated format.
367    const SELF: Format;
368}
369
370macro_rules! formats {
371    {
372        $name:ident = ($surface:ident, $channel:ident),
373        $($name_tail:ident = ($surface_tail:ident, $channel_tail:ident),)*
374    } => {
375        /// A format descriptor that describes the channels present in a
376        /// texture or view, how they are laid out, what size they are,
377        /// and how the elements of the channels are interpreted (integer,
378        /// float, etc.)
379        #[allow(missing_docs)]
380        #[repr(u32)]
381        #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
382        #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
383        pub enum Format {
384            $name = 1,
385            $( $name_tail, )*
386
387            // This serves as safety net for conversion from Vulkan -> HAL,
388            // in case Vulkan adds new formats:
389            //  1. We can check if a format is out of range
390            //  2. We 'ensure' that backend implementations do non-exhaustive matching
391            #[doc(hidden)]
392            __NumFormats,
393        }
394
395        /// Number of formats.
396        pub const NUM_FORMATS: usize = Format::__NumFormats as _;
397
398        /// Conversion table from `Format` to `BaseFormat`, excluding `Undefined`.
399        pub const BASE_FORMATS: [BaseFormat; NUM_FORMATS-1] = [
400              BaseFormat(SurfaceType::$surface, ChannelType::$channel),
401            $(BaseFormat(SurfaceType::$surface_tail, ChannelType::$channel_tail), )*
402        ];
403
404            /// A struct equivalent to the matching `Format` enum member, which allows
405            /// an API to be strongly typed on particular formats.
406            #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
407            #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
408            pub struct $name;
409
410            impl AsFormat for $name {
411                const SELF: Format = Format::$name;
412            }
413
414        $(
415            /// A struct equivalent to the matching `Format` enum member, which allows
416            /// an API to be strongly typed on particular formats.
417            #[allow(missing_docs)]
418            #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
419            #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
420            pub struct $name_tail;
421
422            impl AsFormat for $name_tail {
423                const SELF: Format = Format::$name_tail;
424            }
425
426        )*
427    }
428}
429
430// Format order has to match the order exposed by the Vulkan API.
431formats! {
432    Rg4Unorm = (R4_G4, Unorm),
433    Rgba4Unorm = (R4_G4_B4_A4, Unorm),
434    Bgra4Unorm = (B4_G4_R4_A4, Unorm),
435    R5g6b5Unorm = (R5_G6_B5, Unorm),
436    B5g6r5Unorm = (B5_G6_R5, Unorm),
437    R5g5b5a1Unorm = (R5_G5_B5_A1, Unorm),
438    B5g5r5a1Unorm = (B5_G5_R5_A1, Unorm),
439    A1r5g5b5Unorm = (A1_R5_G5_B5, Unorm),
440    R8Unorm = (R8, Unorm),
441    R8Snorm = (R8, Snorm),
442    R8Uscaled = (R8, Uscaled),
443    R8Sscaled = (R8, Sscaled),
444    R8Uint = (R8, Uint),
445    R8Sint = (R8, Sint),
446    R8Srgb = (R8, Srgb),
447    Rg8Unorm = (R8_G8, Unorm),
448    Rg8Snorm = (R8_G8, Snorm),
449    Rg8Uscaled = (R8_G8, Uscaled),
450    Rg8Sscaled = (R8_G8, Sscaled),
451    Rg8Uint = (R8_G8, Uint),
452    Rg8Sint = (R8_G8, Sint),
453    Rg8Srgb = (R8_G8, Srgb),
454    Rgb8Unorm = (R8_G8_B8, Unorm),
455    Rgb8Snorm = (R8_G8_B8, Snorm),
456    Rgb8Uscaled = (R8_G8_B8, Uscaled),
457    Rgb8Sscaled = (R8_G8_B8, Sscaled),
458    Rgb8Uint = (R8_G8_B8, Uint),
459    Rgb8Sint = (R8_G8_B8, Sint),
460    Rgb8Srgb = (R8_G8_B8, Srgb),
461    Bgr8Unorm = (B8_G8_R8, Unorm),
462    Bgr8Snorm = (B8_G8_R8, Snorm),
463    Bgr8Uscaled = (B8_G8_R8, Uscaled),
464    Bgr8Sscaled = (B8_G8_R8, Sscaled),
465    Bgr8Uint = (B8_G8_R8, Uint),
466    Bgr8Sint = (B8_G8_R8, Sint),
467    Bgr8Srgb = (B8_G8_R8, Srgb),
468    Rgba8Unorm = (R8_G8_B8_A8, Unorm),
469    Rgba8Snorm = (R8_G8_B8_A8, Snorm),
470    Rgba8Uscaled = (R8_G8_B8_A8, Uscaled),
471    Rgba8Sscaled = (R8_G8_B8_A8, Sscaled),
472    Rgba8Uint = (R8_G8_B8_A8, Uint),
473    Rgba8Sint = (R8_G8_B8_A8, Sint),
474    Rgba8Srgb = (R8_G8_B8_A8, Srgb),
475    Bgra8Unorm = (B8_G8_R8_A8, Unorm),
476    Bgra8Snorm = (B8_G8_R8_A8, Snorm),
477    Bgra8Uscaled = (B8_G8_R8_A8, Uscaled),
478    Bgra8Sscaled = (B8_G8_R8_A8, Sscaled),
479    Bgra8Uint = (B8_G8_R8_A8, Uint),
480    Bgra8Sint = (B8_G8_R8_A8, Sint),
481    Bgra8Srgb = (B8_G8_R8_A8, Srgb),
482    Abgr8Unorm = (A8_B8_G8_R8, Unorm),
483    Abgr8Snorm = (A8_B8_G8_R8, Snorm),
484    Abgr8Uscaled = (A8_B8_G8_R8, Uscaled),
485    Abgr8Sscaled = (A8_B8_G8_R8, Sscaled),
486    Abgr8Uint = (A8_B8_G8_R8, Uint),
487    Abgr8Sint = (A8_B8_G8_R8, Sint),
488    Abgr8Srgb = (A8_B8_G8_R8, Srgb),
489    A2r10g10b10Unorm = (A2_R10_G10_B10, Unorm),
490    A2r10g10b10Snorm = (A2_R10_G10_B10, Snorm),
491    A2r10g10b10Uscaled = (A2_R10_G10_B10, Uscaled),
492    A2r10g10b10Sscaled = (A2_R10_G10_B10, Sscaled),
493    A2r10g10b10Uint = (A2_R10_G10_B10, Uint),
494    A2r10g10b10Sint = (A2_R10_G10_B10, Sint),
495    A2b10g10r10Unorm = (A2_B10_G10_R10, Unorm),
496    A2b10g10r10Snorm = (A2_B10_G10_R10, Snorm),
497    A2b10g10r10Uscaled = (A2_B10_G10_R10, Uscaled),
498    A2b10g10r10Sscaled = (A2_B10_G10_R10, Sscaled),
499    A2b10g10r10Uint = (A2_B10_G10_R10, Uint),
500    A2b10g10r10Sint = (A2_B10_G10_R10, Sint),
501    R16Unorm = (R16, Unorm),
502    R16Snorm = (R16, Snorm),
503    R16Uscaled = (R16, Uscaled),
504    R16Sscaled = (R16, Sscaled),
505    R16Uint = (R16, Uint),
506    R16Sint = (R16, Sint),
507    R16Sfloat = (R16, Sfloat),
508    Rg16Unorm = (R16_G16, Unorm),
509    Rg16Snorm = (R16_G16, Snorm),
510    Rg16Uscaled = (R16_G16, Uscaled),
511    Rg16Sscaled = (R16_G16, Sscaled),
512    Rg16Uint = (R16_G16, Uint),
513    Rg16Sint = (R16_G16, Sint),
514    Rg16Sfloat = (R16_G16, Sfloat),
515    Rgb16Unorm = (R16_G16_B16, Unorm),
516    Rgb16Snorm = (R16_G16_B16, Snorm),
517    Rgb16Uscaled = (R16_G16_B16, Uscaled),
518    Rgb16Sscaled = (R16_G16_B16, Sscaled),
519    Rgb16Uint = (R16_G16_B16, Uint),
520    Rgb16Sint = (R16_G16_B16, Sint),
521    Rgb16Sfloat = (R16_G16_B16, Sfloat),
522    Rgba16Unorm = (R16_G16_B16_A16, Unorm),
523    Rgba16Snorm = (R16_G16_B16_A16, Snorm),
524    Rgba16Uscaled = (R16_G16_B16_A16, Uscaled),
525    Rgba16Sscaled = (R16_G16_B16_A16, Sscaled),
526    Rgba16Uint = (R16_G16_B16_A16, Uint),
527    Rgba16Sint = (R16_G16_B16_A16, Sint),
528    Rgba16Sfloat = (R16_G16_B16_A16, Sfloat),
529    R32Uint = (R32, Uint),
530    R32Sint = (R32, Sint),
531    R32Sfloat = (R32, Sfloat),
532    Rg32Uint = (R32_G32, Uint),
533    Rg32Sint = (R32_G32, Sint),
534    Rg32Sfloat = (R32_G32, Sfloat),
535    Rgb32Uint = (R32_G32_B32, Uint),
536    Rgb32Sint = (R32_G32_B32, Sint),
537    Rgb32Sfloat = (R32_G32_B32, Sfloat),
538    Rgba32Uint = (R32_G32_B32_A32, Uint),
539    Rgba32Sint = (R32_G32_B32_A32, Sint),
540    Rgba32Sfloat = (R32_G32_B32_A32, Sfloat),
541    R64Uint = (R64, Uint),
542    R64Sint = (R64, Sint),
543    R64Sfloat = (R64, Sfloat),
544    Rg64Uint = (R64_G64, Uint),
545    Rg64Sint = (R64_G64, Sint),
546    Rg64Sfloat = (R64_G64, Sfloat),
547    Rgb64Uint = (R64_G64_B64, Uint),
548    Rgb64Sint = (R64_G64_B64, Sint),
549    Rgb64Sfloat = (R64_G64_B64, Sfloat),
550    Rgba64Uint = (R64_G64_B64_A64, Uint),
551    Rgba64Sint = (R64_G64_B64_A64, Sint),
552    Rgba64Sfloat = (R64_G64_B64_A64, Sfloat),
553    B10g11r11Ufloat = (B10_G11_R11, Ufloat),
554    E5b9g9r9Ufloat = (E5_B9_G9_R9, Ufloat),
555    D16Unorm = (D16, Unorm),
556    X8D24Unorm = (X8D24, Unorm),
557    D32Sfloat = (D32, Sfloat),
558    S8Uint = (S8, Uint),
559    D16UnormS8Uint = (D16_S8, Unorm),
560    D24UnormS8Uint = (D24_S8, Unorm),
561    D32SfloatS8Uint = (D32_S8, Sfloat),
562    Bc1RgbUnorm = (BC1_RGB, Unorm),
563    Bc1RgbSrgb = (BC1_RGB, Srgb),
564    Bc1RgbaUnorm = (BC1_RGBA, Unorm),
565    Bc1RgbaSrgb = (BC1_RGBA, Srgb),
566    Bc2Unorm = (BC2, Unorm),
567    Bc2Srgb = (BC2, Srgb),
568    Bc3Unorm = (BC3, Unorm),
569    Bc3Srgb = (BC3, Srgb),
570    Bc4Unorm = (BC4, Unorm),
571    Bc4Snorm = (BC4, Snorm),
572    Bc5Unorm = (BC5, Unorm),
573    Bc5Snorm = (BC5, Snorm),
574    Bc6hUfloat = (BC6, Ufloat),
575    Bc6hSfloat = (BC6, Sfloat),
576    Bc7Unorm = (BC7, Unorm),
577    Bc7Srgb = (BC7, Srgb),
578    Etc2R8g8b8Unorm = (ETC2_R8_G8_B8, Unorm),
579    Etc2R8g8b8Srgb = (ETC2_R8_G8_B8, Srgb),
580    Etc2R8g8b8a1Unorm = (ETC2_R8_G8_B8_A1, Unorm),
581    Etc2R8g8b8a1Srgb = (ETC2_R8_G8_B8_A1, Srgb),
582    Etc2R8g8b8a8Unorm = (ETC2_R8_G8_B8_A8, Unorm),
583    Etc2R8g8b8a8Srgb = (ETC2_R8_G8_B8_A8, Srgb),
584    EacR11Unorm = (EAC_R11, Unorm),
585    EacR11Snorm = (EAC_R11, Snorm),
586    EacR11g11Unorm = (EAC_R11_G11, Unorm),
587    EacR11g11Snorm = (EAC_R11_G11, Snorm),
588    Astc4x4Unorm = (ASTC_4x4, Unorm),
589    Astc4x4Srgb = (ASTC_4x4, Srgb),
590    Astc5x4Unorm = (ASTC_5x4, Unorm),
591    Astc5x4Srgb = (ASTC_5x4, Srgb),
592    Astc5x5Unorm = (ASTC_5x5, Unorm),
593    Astc5x5Srgb = (ASTC_5x5, Srgb),
594    Astc6x5Unorm = (ASTC_6x5, Unorm),
595    Astc6x5Srgb = (ASTC_6x5, Srgb),
596    Astc6x6Unorm = (ASTC_6x6, Unorm),
597    Astc6x6Srgb = (ASTC_6x6, Srgb),
598    Astc8x5Unorm = (ASTC_8x5, Unorm),
599    Astc8x5Srgb = (ASTC_8x5, Srgb),
600    Astc8x6Unorm = (ASTC_8x6, Unorm),
601    Astc8x6Srgb = (ASTC_8x6, Srgb),
602    Astc8x8Unorm = (ASTC_8x8, Unorm),
603    Astc8x8Srgb = (ASTC_8x8, Srgb),
604    Astc10x5Unorm = (ASTC_10x5, Unorm),
605    Astc10x5Srgb = (ASTC_10x5, Srgb),
606    Astc10x6Unorm = (ASTC_10x6, Unorm),
607    Astc10x6Srgb = (ASTC_10x6, Srgb),
608    Astc10x8Unorm = (ASTC_10x8, Unorm),
609    Astc10x8Srgb = (ASTC_10x8, Srgb),
610    Astc10x10Unorm = (ASTC_10x10, Unorm),
611    Astc10x10Srgb = (ASTC_10x10, Srgb),
612    Astc12x10Unorm = (ASTC_12x10, Unorm),
613    Astc12x10Srgb = (ASTC_12x10, Srgb),
614    Astc12x12Unorm = (ASTC_12x12, Unorm),
615    Astc12x12Srgb = (ASTC_12x12, Srgb),
616}
617
618impl Format {
619    /// Get base format.
620    ///
621    /// Returns `None` if format is `Undefined`.
622    pub fn base_format(self) -> BaseFormat {
623        assert!(self as usize != 0 && NUM_FORMATS > self as usize);
624        BASE_FORMATS[self as usize - 1]
625    }
626
627    /// A shortcut to obtain surface format description.
628    pub fn surface_desc(&self) -> FormatDesc {
629        self.base_format().0.desc()
630    }
631
632    /// Returns if the format has a color aspect.
633    pub fn is_color(self) -> bool {
634        self.surface_desc().aspects.contains(Aspects::COLOR)
635    }
636
637    /// Returns if the format has a depth aspect.
638    pub fn is_depth(self) -> bool {
639        self.surface_desc().aspects.contains(Aspects::DEPTH)
640    }
641
642    /// Returns if the format has a stencil aspect.
643    pub fn is_stencil(self) -> bool {
644        self.surface_desc().aspects.contains(Aspects::STENCIL)
645    }
646}
647
648// Common vertex attribute formats
649impl AsFormat for f32 {
650    const SELF: Format = Format::R32Sfloat;
651}
652impl AsFormat for [f32; 2] {
653    const SELF: Format = Format::Rg32Sfloat;
654}
655impl AsFormat for [f32; 3] {
656    const SELF: Format = Format::Rgb32Sfloat;
657}
658impl AsFormat for [f32; 4] {
659    const SELF: Format = Format::Rgba32Sfloat;
660}