1 // Copyright (c) 2016 The vulkano developers 2 // Licensed under the Apache License, Version 2.0 3 // <LICENSE-APACHE or 4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT 5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, 6 // at your option. All files in the project carrying such 7 // notice may not be copied, modified, or distributed except 8 // according to those terms. 9 10 //! All the formats of images supported by Vulkan. 11 //! 12 //! # Formats 13 //! 14 //! List of suffixes: 15 //! 16 //! - `Unorm` means that the values are unsigned integers that are converted into floating points. 17 //! The maximum possible representable value becomes `1.0`, and the minimum representable value 18 //! becomes `0.0`. For example the value `255` in a `R8Unorm` will be interpreted as `1.0`. 19 //! 20 //! - `Snorm` is the same as `Unorm`, but the integers are signed and the range is from `-1.0` to 21 //! `1.0` instead. 22 //! 23 //! - `Uscaled` means that the values are unsigned integers that are converted into floating points. 24 //! No change in the value is done. For example the value `255` in a `R8Uscaled` will be 25 //! interpreted as `255.0`. 26 //! 27 //! - `Sscaled` is the same as `Uscaled` expect that the integers are signed. 28 //! 29 //! - `Uint` means that the values are unsigned integers. No conversion is performed. 30 //! 31 //! - `Sint` means that the values are signed integers. No conversion is performed. 32 //! 33 //! - `Ufloat` means that the values are unsigned floating points. No conversion is performed. This 34 //! format is very unusual. 35 //! 36 //! - `Sfloat` means that the values are regular floating points. No conversion is performed. 37 //! 38 //! - `Srgb` is the same as `Unorm`, except that the value is interpreted as being in the sRGB 39 //! color space. This means that its value will be converted to fit in the RGB color space when 40 //! it is read. The fourth channel (usually used for alpha), if present, is not concerned by the 41 //! conversion. 42 //! 43 //! # Choosing a format 44 //! 45 //! The following formats are guaranteed to be supported for everything that is related to 46 //! texturing (ie. blitting source and sampling them linearly). You should choose one of these 47 //! formats if you have an image that you are going to sample from: 48 //! 49 //! - B4G4R4A4UnormPack16 50 //! - R5G6B5UnormPack16 51 //! - A1R5G5B5UnormPack16 52 //! - R8Unorm 53 //! - R8Snorm 54 //! - R8G8Unorm 55 //! - R8G8Snorm 56 //! - R8G8B8A8Unorm 57 //! - R8G8B8A8Snorm 58 //! - R8G8B8A8Srgb 59 //! - B8G8R8A8Unorm 60 //! - B8G8R8A8Srgb 61 //! - A8B8G8R8UnormPack32 62 //! - A8B8G8R8SnormPack32 63 //! - A8B8G8R8SrgbPack32 64 //! - A2B10G10R10UnormPack32 65 //! - R16Sfloat 66 //! - R16G16Sfloat 67 //! - R16G16B16A16Sfloat 68 //! - B10G11R11UfloatPack32 69 //! - E5B9G9R9UfloatPack32 70 //! 71 //! The following formats are guaranteed to be supported for everything that is related to 72 //! intermediate render targets (ie. blitting destination, color attachment and sampling linearly): 73 //! 74 //! - R5G6B5UnormPack16 75 //! - A1R5G5B5UnormPack16 76 //! - R8Unorm 77 //! - R8G8Unorm 78 //! - R8G8B8A8Unorm 79 //! - R8G8B8A8Srgb 80 //! - B8G8R8A8Unorm 81 //! - B8G8R8A8Srgb 82 //! - A8B8G8R8UnormPack32 83 //! - A8B8G8R8SrgbPack32 84 //! - A2B10G10R10UnormPack32 85 //! - R16Sfloat 86 //! - R16G16Sfloat 87 //! - R16G16B16A16Sfloat 88 //! 89 //! For depth images, only `D16Unorm` is guaranteed to be supported. For depth-stencil images, 90 //! it is guaranteed that either `D24Unorm_S8Uint` or `D32Sfloat_S8Uint` are supported. 91 //! 92 //! // TODO: storage formats 93 //! 94 95 use crate::device::physical::PhysicalDevice; 96 use crate::image::ImageAspects; 97 use crate::DeviceSize; 98 use crate::VulkanObject; 99 use half::f16; 100 use std::convert::TryFrom; 101 use std::mem::MaybeUninit; 102 use std::vec::IntoIter as VecIntoIter; 103 use std::{error, fmt, mem}; 104 105 macro_rules! formats { 106 ($($name:ident => { vk: $vk:ident, bdim: $bdim:expr, size: $sz:expr, ty: $f_ty:ident$(, planes: $planes:expr)?},)+) => ( 107 /// An enumeration of all the possible formats. 108 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] 109 #[repr(i32)] 110 #[allow(missing_docs)] 111 #[allow(non_camel_case_types)] 112 pub enum Format { 113 $($name = ash::vk::Format::$vk.as_raw(),)+ 114 } 115 116 impl Format { 117 /*pub fn is_supported_for_vertex_attributes(&self) -> bool { 118 119 } 120 121 .. other functions .. 122 */ 123 124 /// Returns the size in bytes of an element of this format. For block based formats 125 /// this will be the size of a single block. Returns `None` if the 126 /// size is irrelevant. 127 #[inline] 128 pub const fn size(&self) -> Option<DeviceSize> { 129 match *self { 130 $( 131 Format::$name => $sz, 132 )+ 133 } 134 } 135 136 /// Returns (width, height) of the dimensions for block based formats. For 137 /// non block formats will return (1,1) 138 #[inline] 139 pub const fn block_dimensions(&self) -> (u32, u32) { 140 match *self { 141 $( 142 Format::$name => $bdim, 143 )+ 144 } 145 } 146 147 /// Returns the data type of the format. 148 #[inline] 149 pub const fn ty(&self) -> FormatTy { 150 match *self { 151 $( 152 Format::$name => FormatTy::$f_ty, 153 )+ 154 } 155 } 156 157 /// Returns the number of planes that images of this format have. 158 /// 159 /// Returns 0 if the format is not multi-planar. 160 #[inline] 161 pub const fn planes(&self) -> u8 { 162 match *self { 163 $( 164 $(Format::$name => $planes,)? 165 )+ 166 _ => 0, 167 } 168 } 169 } 170 171 impl TryFrom<ash::vk::Format> for Format { 172 type Error = (); 173 174 #[inline] 175 fn try_from(val: ash::vk::Format) -> Result<Format, ()> { 176 match val { 177 $( 178 ash::vk::Format::$vk => Ok(Format::$name), 179 )+ 180 _ => Err(()), 181 } 182 } 183 } 184 185 impl From<Format> for ash::vk::Format { 186 #[inline] 187 fn from(val: Format) -> Self { 188 ash::vk::Format::from_raw(val as i32) 189 } 190 } 191 ); 192 } 193 194 formats! { 195 R4G4UnormPack8 => {vk: R4G4_UNORM_PACK8, bdim: (1, 1), size: Some(1), ty: Float}, 196 R4G4B4A4UnormPack16 => {vk: R4G4B4A4_UNORM_PACK16, bdim: (1, 1), size: Some(2), ty: Float}, 197 B4G4R4A4UnormPack16 => {vk: B4G4R4A4_UNORM_PACK16, bdim: (1, 1), size: Some(2), ty: Float}, 198 R5G6B5UnormPack16 => {vk: R5G6B5_UNORM_PACK16, bdim: (1, 1), size: Some(2), ty: Float}, 199 B5G6R5UnormPack16 => {vk: B5G6R5_UNORM_PACK16, bdim: (1, 1), size: Some(2), ty: Float}, 200 R5G5B5A1UnormPack16 => {vk: R5G5B5A1_UNORM_PACK16, bdim: (1, 1), size: Some(2), ty: Float}, 201 B5G5R5A1UnormPack16 => {vk: B5G5R5A1_UNORM_PACK16, bdim: (1, 1), size: Some(2), ty: Float}, 202 A1R5G5B5UnormPack16 => {vk: A1R5G5B5_UNORM_PACK16, bdim: (1, 1), size: Some(2), ty: Float}, 203 R8Unorm => {vk: R8_UNORM, bdim: (1, 1), size: Some(1), ty: Float}, 204 R8Snorm => {vk: R8_SNORM, bdim: (1, 1), size: Some(1), ty: Float}, 205 R8Uscaled => {vk: R8_USCALED, bdim: (1, 1), size: Some(1), ty: Float}, 206 R8Sscaled => {vk: R8_SSCALED, bdim: (1, 1), size: Some(1), ty: Float}, 207 R8Uint => {vk: R8_UINT, bdim: (1, 1), size: Some(1), ty: Uint}, 208 R8Sint => {vk: R8_SINT, bdim: (1, 1), size: Some(1), ty: Sint}, 209 R8Srgb => {vk: R8_SRGB, bdim: (1, 1), size: Some(1), ty: Float}, 210 R8G8Unorm => {vk: R8G8_UNORM, bdim: (1, 1), size: Some(2), ty: Float}, 211 R8G8Snorm => {vk: R8G8_SNORM, bdim: (1, 1), size: Some(2), ty: Float}, 212 R8G8Uscaled => {vk: R8G8_USCALED, bdim: (1, 1), size: Some(2), ty: Float}, 213 R8G8Sscaled => {vk: R8G8_SSCALED, bdim: (1, 1), size: Some(2), ty: Float}, 214 R8G8Uint => {vk: R8G8_UINT, bdim: (1, 1), size: Some(2), ty: Uint}, 215 R8G8Sint => {vk: R8G8_SINT, bdim: (1, 1), size: Some(2), ty: Sint}, 216 R8G8Srgb => {vk: R8G8_SRGB, bdim: (1, 1), size: Some(2), ty: Float}, 217 R8G8B8Unorm => {vk: R8G8B8_UNORM, bdim: (1, 1), size: Some(3), ty: Float}, 218 R8G8B8Snorm => {vk: R8G8B8_SNORM, bdim: (1, 1), size: Some(3), ty: Float}, 219 R8G8B8Uscaled => {vk: R8G8B8_USCALED, bdim: (1, 1), size: Some(3), ty: Float}, 220 R8G8B8Sscaled => {vk: R8G8B8_SSCALED, bdim: (1, 1), size: Some(3), ty: Float}, 221 R8G8B8Uint => {vk: R8G8B8_UINT, bdim: (1, 1), size: Some(3), ty: Uint}, 222 R8G8B8Sint => {vk: R8G8B8_SINT, bdim: (1, 1), size: Some(3), ty: Sint}, 223 R8G8B8Srgb => {vk: R8G8B8_SRGB, bdim: (1, 1), size: Some(3), ty: Float}, 224 B8G8R8Unorm => {vk: B8G8R8_UNORM, bdim: (1, 1), size: Some(3), ty: Float}, 225 B8G8R8Snorm => {vk: B8G8R8_SNORM, bdim: (1, 1), size: Some(3), ty: Float}, 226 B8G8R8Uscaled => {vk: B8G8R8_USCALED, bdim: (1, 1), size: Some(3), ty: Float}, 227 B8G8R8Sscaled => {vk: B8G8R8_SSCALED, bdim: (1, 1), size: Some(3), ty: Float}, 228 B8G8R8Uint => {vk: B8G8R8_UINT, bdim: (1, 1), size: Some(3), ty: Uint}, 229 B8G8R8Sint => {vk: B8G8R8_SINT, bdim: (1, 1), size: Some(3), ty: Sint}, 230 B8G8R8Srgb => {vk: B8G8R8_SRGB, bdim: (1, 1), size: Some(3), ty: Float}, 231 R8G8B8A8Unorm => {vk: R8G8B8A8_UNORM, bdim: (1, 1), size: Some(4), ty: Float}, 232 R8G8B8A8Snorm => {vk: R8G8B8A8_SNORM, bdim: (1, 1), size: Some(4), ty: Float}, 233 R8G8B8A8Uscaled => {vk: R8G8B8A8_USCALED, bdim: (1, 1), size: Some(4), ty: Float}, 234 R8G8B8A8Sscaled => {vk: R8G8B8A8_SSCALED, bdim: (1, 1), size: Some(4), ty: Float}, 235 R8G8B8A8Uint => {vk: R8G8B8A8_UINT, bdim: (1, 1), size: Some(4), ty: Uint}, 236 R8G8B8A8Sint => {vk: R8G8B8A8_SINT, bdim: (1, 1), size: Some(4), ty: Sint}, 237 R8G8B8A8Srgb => {vk: R8G8B8A8_SRGB, bdim: (1, 1), size: Some(4), ty: Float}, 238 B8G8R8A8Unorm => {vk: B8G8R8A8_UNORM, bdim: (1, 1), size: Some(4), ty: Float}, 239 B8G8R8A8Snorm => {vk: B8G8R8A8_SNORM, bdim: (1, 1), size: Some(4), ty: Float}, 240 B8G8R8A8Uscaled => {vk: B8G8R8A8_USCALED, bdim: (1, 1), size: Some(4), ty: Float}, 241 B8G8R8A8Sscaled => {vk: B8G8R8A8_SSCALED, bdim: (1, 1), size: Some(4), ty: Float}, 242 B8G8R8A8Uint => {vk: B8G8R8A8_UINT, bdim: (1, 1), size: Some(4), ty: Uint}, 243 B8G8R8A8Sint => {vk: B8G8R8A8_SINT, bdim: (1, 1), size: Some(4), ty: Sint}, 244 B8G8R8A8Srgb => {vk: B8G8R8A8_SRGB, bdim: (1, 1), size: Some(4), ty: Float}, 245 A8B8G8R8UnormPack32 => {vk: A8B8G8R8_UNORM_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 246 A8B8G8R8SnormPack32 => {vk: A8B8G8R8_SNORM_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 247 A8B8G8R8UscaledPack32 => {vk: A8B8G8R8_USCALED_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 248 A8B8G8R8SscaledPack32 => {vk: A8B8G8R8_SSCALED_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 249 A8B8G8R8UintPack32 => {vk: A8B8G8R8_UINT_PACK32, bdim: (1, 1), size: Some(4), ty: Uint}, 250 A8B8G8R8SintPack32 => {vk: A8B8G8R8_SINT_PACK32, bdim: (1, 1), size: Some(4), ty: Sint}, 251 A8B8G8R8SrgbPack32 => {vk: A8B8G8R8_SRGB_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 252 A2R10G10B10UnormPack32 => {vk: A2R10G10B10_UNORM_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 253 A2R10G10B10SnormPack32 => {vk: A2R10G10B10_SNORM_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 254 A2R10G10B10UscaledPack32 => {vk: A2R10G10B10_USCALED_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 255 A2R10G10B10SscaledPack32 => {vk: A2R10G10B10_SSCALED_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 256 A2R10G10B10UintPack32 => {vk: A2R10G10B10_UINT_PACK32, bdim: (1, 1), size: Some(4), ty: Uint}, 257 A2R10G10B10SintPack32 => {vk: A2R10G10B10_SINT_PACK32, bdim: (1, 1), size: Some(4), ty: Sint}, 258 A2B10G10R10UnormPack32 => {vk: A2B10G10R10_UNORM_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 259 A2B10G10R10SnormPack32 => {vk: A2B10G10R10_SNORM_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 260 A2B10G10R10UscaledPack32 => {vk: A2B10G10R10_USCALED_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 261 A2B10G10R10SscaledPack32 => {vk: A2B10G10R10_SSCALED_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 262 A2B10G10R10UintPack32 => {vk: A2B10G10R10_UINT_PACK32, bdim: (1, 1), size: Some(4), ty: Uint}, 263 A2B10G10R10SintPack32 => {vk: A2B10G10R10_SINT_PACK32, bdim: (1, 1), size: Some(4), ty: Sint}, 264 R16Unorm => {vk: R16_UNORM, bdim: (1, 1), size: Some(2), ty: Float}, 265 R16Snorm => {vk: R16_SNORM, bdim: (1, 1), size: Some(2), ty: Float}, 266 R16Uscaled => {vk: R16_USCALED, bdim: (1, 1), size: Some(2), ty: Float}, 267 R16Sscaled => {vk: R16_SSCALED, bdim: (1, 1), size: Some(2), ty: Float}, 268 R16Uint => {vk: R16_UINT, bdim: (1, 1), size: Some(2), ty: Uint}, 269 R16Sint => {vk: R16_SINT, bdim: (1, 1), size: Some(2), ty: Sint}, 270 R16Sfloat => {vk: R16_SFLOAT, bdim: (1, 1), size: Some(2), ty: Float}, 271 R16G16Unorm => {vk: R16G16_UNORM, bdim: (1, 1), size: Some(4), ty: Float}, 272 R16G16Snorm => {vk: R16G16_SNORM, bdim: (1, 1), size: Some(4), ty: Float}, 273 R16G16Uscaled => {vk: R16G16_USCALED, bdim: (1, 1), size: Some(4), ty: Float}, 274 R16G16Sscaled => {vk: R16G16_SSCALED, bdim: (1, 1), size: Some(4), ty: Float}, 275 R16G16Uint => {vk: R16G16_UINT, bdim: (1, 1), size: Some(4), ty: Uint}, 276 R16G16Sint => {vk: R16G16_SINT, bdim: (1, 1), size: Some(4), ty: Sint}, 277 R16G16Sfloat => {vk: R16G16_SFLOAT, bdim: (1, 1), size: Some(4), ty: Float}, 278 R16G16B16Unorm => {vk: R16G16B16_UNORM, bdim: (1, 1), size: Some(6), ty: Float}, 279 R16G16B16Snorm => {vk: R16G16B16_SNORM, bdim: (1, 1), size: Some(6), ty: Float}, 280 R16G16B16Uscaled => {vk: R16G16B16_USCALED, bdim: (1, 1), size: Some(6), ty: Float}, 281 R16G16B16Sscaled => {vk: R16G16B16_SSCALED, bdim: (1, 1), size: Some(6), ty: Float}, 282 R16G16B16Uint => {vk: R16G16B16_UINT, bdim: (1, 1), size: Some(6), ty: Uint}, 283 R16G16B16Sint => {vk: R16G16B16_SINT, bdim: (1, 1), size: Some(6), ty: Sint}, 284 R16G16B16Sfloat => {vk: R16G16B16_SFLOAT, bdim: (1, 1), size: Some(6), ty: Float}, 285 R16G16B16A16Unorm => {vk: R16G16B16A16_UNORM, bdim: (1, 1), size: Some(8), ty: Float}, 286 R16G16B16A16Snorm => {vk: R16G16B16A16_SNORM, bdim: (1, 1), size: Some(8), ty: Float}, 287 R16G16B16A16Uscaled => {vk: R16G16B16A16_USCALED, bdim: (1, 1), size: Some(8), ty: Float}, 288 R16G16B16A16Sscaled => {vk: R16G16B16A16_SSCALED, bdim: (1, 1), size: Some(8), ty: Float}, 289 R16G16B16A16Uint => {vk: R16G16B16A16_UINT, bdim: (1, 1), size: Some(8), ty: Uint}, 290 R16G16B16A16Sint => {vk: R16G16B16A16_SINT, bdim: (1, 1), size: Some(8), ty: Sint}, 291 R16G16B16A16Sfloat => {vk: R16G16B16A16_SFLOAT, bdim: (1, 1), size: Some(8), ty: Float}, 292 R32Uint => {vk: R32_UINT, bdim: (1, 1), size: Some(4), ty: Uint}, 293 R32Sint => {vk: R32_SINT, bdim: (1, 1), size: Some(4), ty: Sint}, 294 R32Sfloat => {vk: R32_SFLOAT, bdim: (1, 1), size: Some(4), ty: Float}, 295 R32G32Uint => {vk: R32G32_UINT, bdim: (1, 1), size: Some(8), ty: Uint}, 296 R32G32Sint => {vk: R32G32_SINT, bdim: (1, 1), size: Some(8), ty: Sint}, 297 R32G32Sfloat => {vk: R32G32_SFLOAT, bdim: (1, 1), size: Some(8), ty: Float}, 298 R32G32B32Uint => {vk: R32G32B32_UINT, bdim: (1, 1), size: Some(12), ty: Uint}, 299 R32G32B32Sint => {vk: R32G32B32_SINT, bdim: (1, 1), size: Some(12), ty: Sint}, 300 R32G32B32Sfloat => {vk: R32G32B32_SFLOAT, bdim: (1, 1), size: Some(12), ty: Float}, 301 R32G32B32A32Uint => {vk: R32G32B32A32_UINT, bdim: (1, 1), size: Some(16), ty: Uint}, 302 R32G32B32A32Sint => {vk: R32G32B32A32_SINT, bdim: (1, 1), size: Some(16), ty: Sint}, 303 R32G32B32A32Sfloat => {vk: R32G32B32A32_SFLOAT, bdim: (1, 1), size: Some(16), ty: Float}, 304 R64Uint => {vk: R64_UINT, bdim: (1, 1), size: Some(8), ty: Uint}, 305 R64Sint => {vk: R64_SINT, bdim: (1, 1), size: Some(8), ty: Sint}, 306 R64Sfloat => {vk: R64_SFLOAT, bdim: (1, 1), size: Some(8), ty: Float}, 307 R64G64Uint => {vk: R64G64_UINT, bdim: (1, 1), size: Some(16), ty: Uint}, 308 R64G64Sint => {vk: R64G64_SINT, bdim: (1, 1), size: Some(16), ty: Sint}, 309 R64G64Sfloat => {vk: R64G64_SFLOAT, bdim: (1, 1), size: Some(16), ty: Float}, 310 R64G64B64Uint => {vk: R64G64B64_UINT, bdim: (1, 1), size: Some(24), ty: Uint}, 311 R64G64B64Sint => {vk: R64G64B64_SINT, bdim: (1, 1), size: Some(24), ty: Sint}, 312 R64G64B64Sfloat => {vk: R64G64B64_SFLOAT, bdim: (1, 1), size: Some(24), ty: Float}, 313 R64G64B64A64Uint => {vk: R64G64B64A64_UINT, bdim: (1, 1), size: Some(32), ty: Uint}, 314 R64G64B64A64Sint => {vk: R64G64B64A64_SINT, bdim: (1, 1), size: Some(32), ty: Sint}, 315 R64G64B64A64Sfloat => {vk: R64G64B64A64_SFLOAT, bdim: (1, 1), size: Some(32), ty: Float}, 316 B10G11R11UfloatPack32 => {vk: B10G11R11_UFLOAT_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 317 E5B9G9R9UfloatPack32 => {vk: E5B9G9R9_UFLOAT_PACK32, bdim: (1, 1), size: Some(4), ty: Float}, 318 D16Unorm => {vk: D16_UNORM, bdim: (1, 1), size: Some(2), ty: Depth}, 319 X8_D24UnormPack32 => {vk: X8_D24_UNORM_PACK32, bdim: (1, 1), size: Some(4), ty: Depth}, 320 D32Sfloat => {vk: D32_SFLOAT, bdim: (1, 1), size: Some(4), ty: Depth}, 321 S8Uint => {vk: S8_UINT, bdim: (1, 1), size: Some(1), ty: Stencil}, 322 D16Unorm_S8Uint => {vk: D16_UNORM_S8_UINT, bdim: (1, 1), size: None, ty: DepthStencil}, 323 D24Unorm_S8Uint => {vk: D24_UNORM_S8_UINT, bdim: (1, 1), size: None, ty: DepthStencil}, 324 D32Sfloat_S8Uint => {vk: D32_SFLOAT_S8_UINT, bdim: (1, 1), size: None, ty: DepthStencil}, 325 BC1_RGBUnormBlock => {vk: BC1_RGB_UNORM_BLOCK, bdim: (4, 4), size: Some(8), ty: Compressed}, 326 BC1_RGBSrgbBlock => {vk: BC1_RGB_SRGB_BLOCK, bdim: (4, 4), size: Some(8), ty: Compressed}, 327 BC1_RGBAUnormBlock => {vk: BC1_RGBA_UNORM_BLOCK, bdim: (4, 4), size: Some(8), ty: Compressed}, 328 BC1_RGBASrgbBlock => {vk: BC1_RGBA_SRGB_BLOCK, bdim: (4, 4), size: Some(8), ty: Compressed}, 329 BC2UnormBlock => {vk: BC2_UNORM_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 330 BC2SrgbBlock => {vk: BC2_SRGB_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 331 BC3UnormBlock => {vk: BC3_UNORM_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 332 BC3SrgbBlock => {vk: BC3_SRGB_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 333 BC4UnormBlock => {vk: BC4_UNORM_BLOCK, bdim: (4, 4), size: Some(8), ty: Compressed}, 334 BC4SnormBlock => {vk: BC4_SNORM_BLOCK, bdim: (4, 4), size: Some(8), ty: Compressed}, 335 BC5UnormBlock => {vk: BC5_UNORM_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 336 BC5SnormBlock => {vk: BC5_SNORM_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 337 BC6HUfloatBlock => {vk: BC6H_UFLOAT_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 338 BC6HSfloatBlock => {vk: BC6H_SFLOAT_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 339 BC7UnormBlock => {vk: BC7_UNORM_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 340 BC7SrgbBlock => {vk: BC7_SRGB_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 341 ETC2_R8G8B8UnormBlock => {vk: ETC2_R8G8B8_UNORM_BLOCK, bdim: (4, 4), size: Some(8), ty: Compressed}, 342 ETC2_R8G8B8SrgbBlock => {vk: ETC2_R8G8B8_SRGB_BLOCK, bdim: (4, 4), size: Some(8), ty: Compressed}, 343 ETC2_R8G8B8A1UnormBlock => {vk: ETC2_R8G8B8A1_UNORM_BLOCK, bdim: (4, 4), size: Some(8), ty: Compressed}, 344 ETC2_R8G8B8A1SrgbBlock => {vk: ETC2_R8G8B8A1_SRGB_BLOCK, bdim: (4, 4), size: Some(8), ty: Compressed}, 345 ETC2_R8G8B8A8UnormBlock => {vk: ETC2_R8G8B8A8_UNORM_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 346 ETC2_R8G8B8A8SrgbBlock => {vk: ETC2_R8G8B8A8_SRGB_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 347 EAC_R11UnormBlock => {vk: EAC_R11_UNORM_BLOCK, bdim: (4, 4), size: Some(8), ty: Compressed}, 348 EAC_R11SnormBlock => {vk: EAC_R11_SNORM_BLOCK, bdim: (4, 4), size: Some(8), ty: Compressed}, 349 EAC_R11G11UnormBlock => {vk: EAC_R11G11_UNORM_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 350 EAC_R11G11SnormBlock => {vk: EAC_R11G11_SNORM_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 351 ASTC_4x4UnormBlock => {vk: ASTC_4X4_UNORM_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 352 ASTC_4x4SrgbBlock => {vk: ASTC_4X4_SRGB_BLOCK, bdim: (4, 4), size: Some(16), ty: Compressed}, 353 ASTC_5x4UnormBlock => {vk: ASTC_5X4_UNORM_BLOCK, bdim: (5, 4), size: Some(16), ty: Compressed}, 354 ASTC_5x4SrgbBlock => {vk: ASTC_5X4_SRGB_BLOCK, bdim: (5, 4), size: Some(16), ty: Compressed}, 355 ASTC_5x5UnormBlock => {vk: ASTC_5X5_UNORM_BLOCK, bdim: (5, 5), size: Some(16), ty: Compressed}, 356 ASTC_5x5SrgbBlock => {vk: ASTC_5X5_SRGB_BLOCK, bdim: (5, 5), size: Some(16), ty: Compressed}, 357 ASTC_6x5UnormBlock => {vk: ASTC_6X5_UNORM_BLOCK, bdim: (6, 5), size: Some(16), ty: Compressed}, 358 ASTC_6x5SrgbBlock => {vk: ASTC_6X5_SRGB_BLOCK, bdim: (6, 5), size: Some(16), ty: Compressed}, 359 ASTC_6x6UnormBlock => {vk: ASTC_6X6_UNORM_BLOCK, bdim: (6, 6), size: Some(16), ty: Compressed}, 360 ASTC_6x6SrgbBlock => {vk: ASTC_6X6_SRGB_BLOCK, bdim: (6, 6), size: Some(16), ty: Compressed}, 361 ASTC_8x5UnormBlock => {vk: ASTC_8X5_UNORM_BLOCK, bdim: (8, 5), size: Some(16), ty: Compressed}, 362 ASTC_8x5SrgbBlock => {vk: ASTC_8X5_SRGB_BLOCK, bdim: (8, 5), size: Some(16), ty: Compressed}, 363 ASTC_8x6UnormBlock => {vk: ASTC_8X6_UNORM_BLOCK, bdim: (8, 6), size: Some(16), ty: Compressed}, 364 ASTC_8x6SrgbBlock => {vk: ASTC_8X6_SRGB_BLOCK, bdim: (8, 6), size: Some(16), ty: Compressed}, 365 ASTC_8x8UnormBlock => {vk: ASTC_8X8_UNORM_BLOCK, bdim: (8, 8), size: Some(16), ty: Compressed}, 366 ASTC_8x8SrgbBlock => {vk: ASTC_8X8_SRGB_BLOCK, bdim: (8, 8), size: Some(16), ty: Compressed}, 367 ASTC_10x5UnormBlock => {vk: ASTC_10X5_UNORM_BLOCK, bdim: (10, 5), size: Some(16), ty: Compressed}, 368 ASTC_10x5SrgbBlock => {vk: ASTC_10X5_SRGB_BLOCK, bdim: (10, 5), size: Some(16), ty: Compressed}, 369 ASTC_10x6UnormBlock => {vk: ASTC_10X6_UNORM_BLOCK, bdim: (10, 6), size: Some(16), ty: Compressed}, 370 ASTC_10x6SrgbBlock => {vk: ASTC_10X6_SRGB_BLOCK, bdim: (10, 6), size: Some(16), ty: Compressed}, 371 ASTC_10x8UnormBlock => {vk: ASTC_10X8_UNORM_BLOCK, bdim: (10, 8), size: Some(16), ty: Compressed}, 372 ASTC_10x8SrgbBlock => {vk: ASTC_10X8_SRGB_BLOCK, bdim: (10, 8), size: Some(16), ty: Compressed}, 373 ASTC_10x10UnormBlock => {vk: ASTC_10X10_UNORM_BLOCK, bdim: (10, 10), size: Some(16), ty: Compressed}, 374 ASTC_10x10SrgbBlock => {vk: ASTC_10X10_SRGB_BLOCK, bdim: (10, 10), size: Some(16), ty: Compressed}, 375 ASTC_12x10UnormBlock => {vk: ASTC_12X10_UNORM_BLOCK, bdim: (12, 10), size: Some(16), ty: Compressed}, 376 ASTC_12x10SrgbBlock => {vk: ASTC_12X10_SRGB_BLOCK, bdim: (12, 10), size: Some(16), ty: Compressed}, 377 ASTC_12x12UnormBlock => {vk: ASTC_12X12_UNORM_BLOCK, bdim: (12, 12), size: Some(16), ty: Compressed}, 378 ASTC_12x12SrgbBlock => {vk: ASTC_12X12_SRGB_BLOCK, bdim: (12, 12), size: Some(16), ty: Compressed}, 379 G8B8R8_3PLANE420Unorm => {vk: G8_B8_R8_3PLANE_420_UNORM, bdim: (1, 1), size: None, ty: Ycbcr, planes: 3}, 380 G8B8R8_2PLANE420Unorm => {vk: G8_B8R8_2PLANE_420_UNORM, bdim: (1, 1), size: None, ty: Ycbcr, planes: 2}, 381 } 382 383 impl Format { 384 /// Returns the aspects that images of this format have. 385 #[inline] aspects(&self) -> ImageAspects386 pub const fn aspects(&self) -> ImageAspects { 387 let ty = self.ty(); 388 let planes = self.planes(); 389 ImageAspects { 390 color: matches!( 391 ty, 392 FormatTy::Float | FormatTy::Uint | FormatTy::Sint | FormatTy::Compressed 393 ), 394 depth: matches!(ty, FormatTy::Depth | FormatTy::DepthStencil), 395 stencil: matches!(ty, FormatTy::Stencil | FormatTy::DepthStencil), 396 plane0: planes >= 1, 397 plane1: planes >= 2, 398 plane2: planes >= 3, 399 ..ImageAspects::none() 400 } 401 } 402 403 /// Retrieves the properties of a format when used by a certain device. 404 #[inline] properties(&self, physical_device: PhysicalDevice) -> FormatProperties405 pub fn properties(&self, physical_device: PhysicalDevice) -> FormatProperties { 406 let vk_properties = unsafe { 407 let fns_i = physical_device.instance().fns(); 408 let mut output = MaybeUninit::uninit(); 409 fns_i.v1_0.get_physical_device_format_properties( 410 physical_device.internal_object(), 411 (*self).into(), 412 output.as_mut_ptr(), 413 ); 414 output.assume_init() 415 }; 416 417 FormatProperties { 418 linear_tiling_features: vk_properties.linear_tiling_features.into(), 419 optimal_tiling_features: vk_properties.optimal_tiling_features.into(), 420 buffer_features: vk_properties.buffer_features.into(), 421 } 422 } 423 424 #[inline] decode_clear_value(&self, value: ClearValue) -> ClearValue425 pub fn decode_clear_value(&self, value: ClearValue) -> ClearValue { 426 match (self.ty(), value) { 427 (FormatTy::Float, f @ ClearValue::Float(_)) => f, 428 (FormatTy::Compressed, f @ ClearValue::Float(_)) => f, 429 (FormatTy::Sint, f @ ClearValue::Int(_)) => f, 430 (FormatTy::Uint, f @ ClearValue::Uint(_)) => f, 431 (FormatTy::Depth, f @ ClearValue::Depth(_)) => f, 432 (FormatTy::Stencil, f @ ClearValue::Stencil(_)) => f, 433 (FormatTy::DepthStencil, f @ ClearValue::DepthStencil(_)) => f, 434 _ => panic!("Wrong clear value"), 435 } 436 } 437 } 438 439 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 440 pub enum FormatTy { 441 Float, 442 Uint, 443 Sint, 444 Depth, 445 Stencil, 446 DepthStencil, 447 Compressed, 448 Ycbcr, 449 } 450 451 /// Trait for Rust types that can represent a pixel in an image. 452 pub unsafe trait Pixel { 453 /// Returns an error if `Self` cannot be used as a source of pixels for `format`. ensure_accepts(format: Format) -> Result<(), IncompatiblePixelsType>454 fn ensure_accepts(format: Format) -> Result<(), IncompatiblePixelsType>; 455 456 /// The number of `Self`s which make up a single pixel. 457 /// 458 /// # Panics 459 /// 460 /// May panic if `ensure_accepts` would not return `Ok(())`. rate(format: Format) -> u32461 fn rate(format: Format) -> u32; 462 } 463 464 #[derive(Debug, Copy, Clone, PartialEq, Eq)] 465 pub struct IncompatiblePixelsType; 466 467 impl error::Error for IncompatiblePixelsType {} 468 469 impl fmt::Display for IncompatiblePixelsType { 470 #[inline] fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>471 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { 472 write!( 473 fmt, 474 "{}", 475 "supplied pixels' type is incompatible with this format" 476 ) 477 } 478 } 479 480 macro_rules! impl_pixel { 481 {$($ty:ty;)+} => { 482 $(impl_pixel!(inner $ty);)* 483 $(impl_pixel!(inner [$ty; 1]);)* 484 $(impl_pixel!(inner [$ty; 2]);)* 485 $(impl_pixel!(inner [$ty; 3]);)* 486 $(impl_pixel!(inner [$ty; 4]);)* 487 $(impl_pixel!(inner ($ty,));)* 488 $(impl_pixel!(inner ($ty, $ty));)* 489 $(impl_pixel!(inner ($ty, $ty, $ty));)* 490 $(impl_pixel!(inner ($ty, $ty, $ty, $ty));)* 491 }; 492 (inner $ty:ty) => { 493 unsafe impl Pixel for $ty { 494 fn ensure_accepts(format: Format) -> Result<(), IncompatiblePixelsType> { 495 // TODO: Be more strict: accept only if the format has a matching AcceptsPixels impl. 496 if format.size().map_or(false, |x| x % mem::size_of::<$ty>() as DeviceSize == 0) { 497 Ok(()) 498 } else { 499 Err(IncompatiblePixelsType) 500 } 501 } 502 503 fn rate(format: Format) -> u32 { 504 (format.size().expect("this format cannot accept pixels") / mem::size_of::<$ty>() as DeviceSize) as u32 505 } 506 } 507 } 508 } 509 510 impl_pixel! { 511 u8; i8; u16; i16; u32; i32; u64; i64; f16; f32; f64; 512 } 513 514 /// Describes a uniform value that will be used to fill an image. 515 // TODO: should have the same layout as `vk::ClearValue` for performance 516 #[derive(Debug, Copy, Clone, PartialEq)] 517 pub enum ClearValue { 518 /// Entry for attachments that aren't cleared. 519 None, 520 /// Value for floating-point attachments, including `Unorm`, `Snorm`, `Sfloat`. 521 Float([f32; 4]), 522 /// Value for integer attachments, including `Int`. 523 Int([i32; 4]), 524 /// Value for unsigned integer attachments, including `Uint`. 525 Uint([u32; 4]), 526 /// Value for depth attachments. 527 Depth(f32), 528 /// Value for stencil attachments. 529 Stencil(u32), 530 /// Value for depth and stencil attachments. 531 DepthStencil((f32, u32)), 532 } 533 534 // TODO: remove all these From implementations once they are no longer needed 535 536 impl From<[f32; 1]> for ClearValue { 537 #[inline] from(val: [f32; 1]) -> ClearValue538 fn from(val: [f32; 1]) -> ClearValue { 539 ClearValue::Float([val[0], 0.0, 0.0, 1.0]) 540 } 541 } 542 543 impl From<[f32; 2]> for ClearValue { 544 #[inline] from(val: [f32; 2]) -> ClearValue545 fn from(val: [f32; 2]) -> ClearValue { 546 ClearValue::Float([val[0], val[1], 0.0, 1.0]) 547 } 548 } 549 550 impl From<[f32; 3]> for ClearValue { 551 #[inline] from(val: [f32; 3]) -> ClearValue552 fn from(val: [f32; 3]) -> ClearValue { 553 ClearValue::Float([val[0], val[1], val[2], 1.0]) 554 } 555 } 556 557 impl From<[f32; 4]> for ClearValue { 558 #[inline] from(val: [f32; 4]) -> ClearValue559 fn from(val: [f32; 4]) -> ClearValue { 560 ClearValue::Float(val) 561 } 562 } 563 564 impl From<[u32; 1]> for ClearValue { 565 #[inline] from(val: [u32; 1]) -> ClearValue566 fn from(val: [u32; 1]) -> ClearValue { 567 ClearValue::Uint([val[0], 0, 0, 0]) // TODO: is alpha value 0 correct? 568 } 569 } 570 571 impl From<[u32; 2]> for ClearValue { 572 #[inline] from(val: [u32; 2]) -> ClearValue573 fn from(val: [u32; 2]) -> ClearValue { 574 ClearValue::Uint([val[0], val[1], 0, 0]) // TODO: is alpha value 0 correct? 575 } 576 } 577 578 impl From<[u32; 3]> for ClearValue { 579 #[inline] from(val: [u32; 3]) -> ClearValue580 fn from(val: [u32; 3]) -> ClearValue { 581 ClearValue::Uint([val[0], val[1], val[2], 0]) // TODO: is alpha value 0 correct? 582 } 583 } 584 585 impl From<[u32; 4]> for ClearValue { 586 #[inline] from(val: [u32; 4]) -> ClearValue587 fn from(val: [u32; 4]) -> ClearValue { 588 ClearValue::Uint(val) 589 } 590 } 591 592 impl From<[i32; 1]> for ClearValue { 593 #[inline] from(val: [i32; 1]) -> ClearValue594 fn from(val: [i32; 1]) -> ClearValue { 595 ClearValue::Int([val[0], 0, 0, 0]) // TODO: is alpha value 0 correct? 596 } 597 } 598 599 impl From<[i32; 2]> for ClearValue { 600 #[inline] from(val: [i32; 2]) -> ClearValue601 fn from(val: [i32; 2]) -> ClearValue { 602 ClearValue::Int([val[0], val[1], 0, 0]) // TODO: is alpha value 0 correct? 603 } 604 } 605 606 impl From<[i32; 3]> for ClearValue { 607 #[inline] from(val: [i32; 3]) -> ClearValue608 fn from(val: [i32; 3]) -> ClearValue { 609 ClearValue::Int([val[0], val[1], val[2], 0]) // TODO: is alpha value 0 correct? 610 } 611 } 612 613 impl From<[i32; 4]> for ClearValue { 614 #[inline] from(val: [i32; 4]) -> ClearValue615 fn from(val: [i32; 4]) -> ClearValue { 616 ClearValue::Int(val) 617 } 618 } 619 620 impl From<f32> for ClearValue { 621 #[inline] from(val: f32) -> ClearValue622 fn from(val: f32) -> ClearValue { 623 ClearValue::Depth(val) 624 } 625 } 626 627 impl From<u32> for ClearValue { 628 #[inline] from(val: u32) -> ClearValue629 fn from(val: u32) -> ClearValue { 630 ClearValue::Stencil(val) 631 } 632 } 633 634 impl From<(f32, u32)> for ClearValue { 635 #[inline] from(val: (f32, u32)) -> ClearValue636 fn from(val: (f32, u32)) -> ClearValue { 637 ClearValue::DepthStencil(val) 638 } 639 } 640 641 // TODO: remove once no longer needed 642 pub unsafe trait ClearValuesTuple { 643 type Iter: Iterator<Item = ClearValue>; iter(self) -> Self::Iter644 fn iter(self) -> Self::Iter; 645 } 646 647 macro_rules! impl_clear_values_tuple { 648 ($first:ident $($others:ident)+) => ( 649 #[allow(non_snake_case)] 650 unsafe impl<$first $(, $others)*> ClearValuesTuple for ($first, $($others,)+) 651 where $first: Into<ClearValue> $(, $others: Into<ClearValue>)* 652 { 653 type Iter = VecIntoIter<ClearValue>; 654 #[inline] 655 fn iter(self) -> VecIntoIter<ClearValue> { 656 let ($first, $($others,)+) = self; 657 vec![ 658 $first.into() $(, $others.into())+ 659 ].into_iter() 660 } 661 } 662 663 impl_clear_values_tuple!($($others)*); 664 ); 665 666 ($first:ident) => ( 667 unsafe impl<$first> ClearValuesTuple for ($first,) 668 where $first: Into<ClearValue> 669 { 670 type Iter = VecIntoIter<ClearValue>; 671 #[inline] 672 fn iter(self) -> VecIntoIter<ClearValue> { 673 vec![self.0.into()].into_iter() 674 } 675 } 676 ); 677 } 678 679 impl_clear_values_tuple!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z); 680 681 /// The properties of an image format that are supported by a physical device. 682 #[derive(Debug, Clone, PartialEq, Eq, Hash, Default)] 683 pub struct FormatProperties { 684 /// Features available for images with linear tiling. 685 pub linear_tiling_features: FormatFeatures, 686 687 /// Features available for images with optimal tiling. 688 pub optimal_tiling_features: FormatFeatures, 689 690 /// Features available for buffers. 691 pub buffer_features: FormatFeatures, 692 } 693 694 /// The features supported by images with a particular format. 695 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] 696 #[allow(missing_docs)] 697 pub struct FormatFeatures { 698 pub sampled_image: bool, 699 pub storage_image: bool, 700 pub storage_image_atomic: bool, 701 pub uniform_texel_buffer: bool, 702 pub storage_texel_buffer: bool, 703 pub storage_texel_buffer_atomic: bool, 704 pub vertex_buffer: bool, 705 pub color_attachment: bool, 706 pub color_attachment_blend: bool, 707 pub depth_stencil_attachment: bool, 708 pub blit_src: bool, 709 pub blit_dst: bool, 710 pub sampled_image_filter_linear: bool, 711 pub transfer_src: bool, 712 pub transfer_dst: bool, 713 pub midpoint_chroma_samples: bool, 714 pub sampled_image_ycbcr_conversion_linear_filter: bool, 715 pub sampled_image_ycbcr_conversion_separate_reconstruction_filter: bool, 716 pub sampled_image_ycbcr_conversion_chroma_reconstruction_explicit: bool, 717 pub sampled_image_ycbcr_conversion_chroma_reconstruction_explicit_forceable: bool, 718 pub disjoint: bool, 719 pub cosited_chroma_samples: bool, 720 pub sampled_image_filter_minmax: bool, 721 pub img_sampled_image_filter_cubic: bool, 722 pub khr_acceleration_structure_vertex_buffer: bool, 723 pub ext_fragment_density_map: bool, 724 } 725 726 impl From<ash::vk::FormatFeatureFlags> for FormatFeatures { 727 #[inline] 728 #[rustfmt::skip] from(val: ash::vk::FormatFeatureFlags) -> FormatFeatures729 fn from(val: ash::vk::FormatFeatureFlags) -> FormatFeatures { 730 FormatFeatures { 731 sampled_image: !(val & ash::vk::FormatFeatureFlags::SAMPLED_IMAGE).is_empty(), 732 storage_image: !(val & ash::vk::FormatFeatureFlags::STORAGE_IMAGE).is_empty(), 733 storage_image_atomic: !(val & ash::vk::FormatFeatureFlags::STORAGE_IMAGE_ATOMIC).is_empty(), 734 uniform_texel_buffer: !(val & ash::vk::FormatFeatureFlags::UNIFORM_TEXEL_BUFFER).is_empty(), 735 storage_texel_buffer: !(val & ash::vk::FormatFeatureFlags::STORAGE_TEXEL_BUFFER).is_empty(), 736 storage_texel_buffer_atomic: !(val & ash::vk::FormatFeatureFlags::STORAGE_TEXEL_BUFFER_ATOMIC).is_empty(), 737 vertex_buffer: !(val & ash::vk::FormatFeatureFlags::VERTEX_BUFFER).is_empty(), 738 color_attachment: !(val & ash::vk::FormatFeatureFlags::COLOR_ATTACHMENT).is_empty(), 739 color_attachment_blend: !(val & ash::vk::FormatFeatureFlags::COLOR_ATTACHMENT_BLEND).is_empty(), 740 depth_stencil_attachment: !(val & ash::vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT).is_empty(), 741 blit_src: !(val & ash::vk::FormatFeatureFlags::BLIT_SRC).is_empty(), 742 blit_dst: !(val & ash::vk::FormatFeatureFlags::BLIT_DST).is_empty(), 743 sampled_image_filter_linear: !(val & ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_FILTER_LINEAR).is_empty(), 744 transfer_src: !(val & ash::vk::FormatFeatureFlags::TRANSFER_SRC).is_empty(), 745 transfer_dst: !(val & ash::vk::FormatFeatureFlags::TRANSFER_DST).is_empty(), 746 midpoint_chroma_samples: !(val & ash::vk::FormatFeatureFlags::MIDPOINT_CHROMA_SAMPLES).is_empty(), 747 sampled_image_ycbcr_conversion_linear_filter: !(val & ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER).is_empty(), 748 sampled_image_ycbcr_conversion_separate_reconstruction_filter: !(val & ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER).is_empty(), 749 sampled_image_ycbcr_conversion_chroma_reconstruction_explicit: !(val & ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT).is_empty(), 750 sampled_image_ycbcr_conversion_chroma_reconstruction_explicit_forceable: !(val & ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE).is_empty(), 751 disjoint: !(val & ash::vk::FormatFeatureFlags::DISJOINT).is_empty(), 752 cosited_chroma_samples: !(val & ash::vk::FormatFeatureFlags::COSITED_CHROMA_SAMPLES).is_empty(), 753 sampled_image_filter_minmax: !(val & ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_FILTER_MINMAX).is_empty(), 754 img_sampled_image_filter_cubic: !(val & ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_FILTER_CUBIC_IMG).is_empty(), 755 khr_acceleration_structure_vertex_buffer: !(val & ash::vk::FormatFeatureFlags::ACCELERATION_STRUCTURE_VERTEX_BUFFER_KHR).is_empty(), 756 ext_fragment_density_map: !(val & ash::vk::FormatFeatureFlags::FRAGMENT_DENSITY_MAP_EXT).is_empty(), 757 } 758 } 759 } 760