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 supported by Vulkan. 11 //! 12 //! A format is mostly used to describe the texel data of an image. However, formats also show up in 13 //! a few other places, most notably to describe the format of vertex buffers. 14 //! 15 //! # Format support 16 //! 17 //! Not all formats are supported by every device. Those that devices do support may only be 18 //! supported for certain use cases. It is an error to use a format where it is not supported, but 19 //! you can query a device beforehand for its support by calling `format_properties` on the physical 20 //! device. You can use this to select a usable format from one or more suitable alternatives. 21 //! Some formats are required to be always supported for a particular usage. These are listed in the 22 //! [tables in the Vulkan specification](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap43.html#features-required-format-support). 23 //! 24 //! # Special format types 25 //! 26 //! ## Depth/stencil formats 27 //! 28 //! Depth/stencil formats can be identified by the `D` and `S` components in their names. They are 29 //! used primarily as the format for framebuffer attachments, for the purposes of depth and stencil 30 //! testing. 31 //! 32 //! Some formats have only a depth or stencil component, while others combine both. The two 33 //! components are represented as separate *aspects*, which means that they can be accessed 34 //! individually as separate images. These pseudo-images have the same resolution, but different 35 //! bit depth and numeric representation. 36 //! 37 //! Depth/stencil formats deviate from the others in a few more ways. Their data representation is 38 //! considered opaque, meaning that they do not have a fixed layout in memory nor a fixed size per 39 //! texel. They also have special limitations in several operations such as copying; a depth/stencil 40 //! format is not compatible with any other format, only with itself. 41 //! 42 //! ## Block-compressed formats 43 //! 44 //! A block-compressed format uses compression to encode a larger block of texels into a smaller 45 //! number of bytes. Individual texels are no longer represented in memory, only the block as a 46 //! whole. An image must consist of a whole number of blocks, so the dimensions of an image must be 47 //! a whole multiple of the block dimensions. Vulkan supports several different compression schemes, 48 //! represented in Vulkano by the `CompressionType` enum. 49 //! 50 //! Overall, block-compressed formats do not behave significantly differently from regular formats. 51 //! They are mostly restricted in terms of compatibility. Because of the compression, the notion of 52 //! bits per component does not apply, so the `components` method will only return whether a 53 //! component is present or not. 54 //! 55 //! ## YCbCr formats 56 //! 57 //! YCbCr, also known as YUV, is an alternative image representation with three components: 58 //! Y for luminance or *luma* (overall brightness) and two color or *chroma* components Cb and Cr 59 //! encoding the blueness and redness respectively. YCbCr formats are primarily used in video 60 //! applications. In Vulkan, the formats used to encode YCbCr data use the green channel to 61 //! represent the luma component, while the blue and red components hold the chroma. 62 //! 63 //! To use most YCbCr formats in an [image view](crate::image::view), a 64 //! [sampler YCbCr conversion](crate::sampler::ycbcr) object must be created, and attached to both 65 //! the image view and the sampler. To query whether a format requires the conversion, you can call 66 //! `ycbcr_chroma_sampling` on a format. As a rule, any format with `444`, `422`, `420`, 67 //! `3PACK` or `4PACK` in the name requires it. 68 //! 69 //! Many YCbCr formats make use of **chroma subsampling**. This is a technique whereby the two 70 //! chroma components are encoded using a lower resolution than the luma component. The human eye is 71 //! less sensitive to color detail than to detail in brightness, so this allows more detail to be 72 //! encoded in less data. Chroma subsampling is indicated with one of three numbered suffixes in a 73 //! format name: 74 //! - `444` indicates a YCbCr format without chroma subsampling. All components have the same 75 //! resolution. 76 //! - `422` indicates horizontal chroma subsampling. The horizontal resolution of the chroma 77 //! components is halved, so a single value is shared within a 2x1 block of texels. 78 //! - `420` indicates horizontal and vertical chroma subsampling. Both dimensions of the chroma 79 //! components are halved, so a single value is shared within a 2x2 block of texels. 80 //! 81 //! Most YCbCr formats, including all of the `444` and `420` formats, are **multi-planar**. Instead 82 //! of storing the components of a single texel together in memory, the components are separated 83 //! into *planes*, which act like independent images. In 3-plane formats, the planes hold the Y, 84 //! Cb and Cr components respectively, while in 2-plane formats, Cb and Cr are combined into a 85 //! two-component plane. Where chroma subsampling is applied, plane 0 has the full resolution, while 86 //! planes 1 and 2 have reduced resolution. Effectively, they are standalone images with half the 87 //! resolution of the original. 88 //! 89 //! The texels of multi-planar images cannot be accessed individually, for example to copy or blit, 90 //! since the components of each texel are split across the planes. Instead, you must access each 91 //! plane as an individual *aspect* of the image. A single-plane aspect of a multi-planar image 92 //! behaves as a regular image, and even has its own format, which can be queried with the `plane` 93 //! method on a format. 94 95 use crate::{ 96 device::physical::PhysicalDevice, image::ImageAspects, macros::vulkan_bitflags, 97 shader::spirv::ImageFormat, DeviceSize, 98 }; 99 100 // Generated by build.rs 101 include!(concat!(env!("OUT_DIR"), "/formats.rs")); 102 103 impl Format { 104 /// Retrieves the properties of a format when used by a certain device. 105 #[deprecated( 106 since = "0.28.0", 107 note = "Use PhysicalDevice::format_properties instead" 108 )] 109 #[inline] properties(self, physical_device: PhysicalDevice) -> FormatProperties110 pub fn properties(self, physical_device: PhysicalDevice) -> FormatProperties { 111 physical_device.format_properties(self).unwrap() 112 } 113 114 /// Returns whether the format can be used with a storage image, without specifying 115 /// the format in the shader, if the 116 /// [`shader_storage_image_read_without_format`](crate::device::Features::shader_storage_image_read_without_format) 117 /// and/or 118 /// [`shader_storage_image_write_without_format`](crate::device::Features::shader_storage_image_write_without_format) 119 /// features are enabled on the device. 120 #[inline] shader_storage_image_without_format(self) -> bool121 pub fn shader_storage_image_without_format(self) -> bool { 122 matches!( 123 self, 124 Format::R8G8B8A8_UNORM 125 | Format::R8G8B8A8_SNORM 126 | Format::R8G8B8A8_UINT 127 | Format::R8G8B8A8_SINT 128 | Format::R32_UINT 129 | Format::R32_SINT 130 | Format::R32_SFLOAT 131 | Format::R32G32_UINT 132 | Format::R32G32_SINT 133 | Format::R32G32_SFLOAT 134 | Format::R32G32B32A32_UINT 135 | Format::R32G32B32A32_SINT 136 | Format::R32G32B32A32_SFLOAT 137 | Format::R16G16B16A16_UINT 138 | Format::R16G16B16A16_SINT 139 | Format::R16G16B16A16_SFLOAT 140 | Format::R16G16_SFLOAT 141 | Format::B10G11R11_UFLOAT_PACK32 142 | Format::R16_SFLOAT 143 | Format::R16G16B16A16_UNORM 144 | Format::A2B10G10R10_UNORM_PACK32 145 | Format::R16G16_UNORM 146 | Format::R8G8_UNORM 147 | Format::R16_UNORM 148 | Format::R8_UNORM 149 | Format::R16G16B16A16_SNORM 150 | Format::R16G16_SNORM 151 | Format::R8G8_SNORM 152 | Format::R16_SNORM 153 | Format::R8_SNORM 154 | Format::R16G16_SINT 155 | Format::R8G8_SINT 156 | Format::R16_SINT 157 | Format::R8_SINT 158 | Format::A2B10G10R10_UINT_PACK32 159 | Format::R16G16_UINT 160 | Format::R8G8_UINT 161 | Format::R16_UINT 162 | Format::R8_UINT 163 ) 164 } 165 } 166 167 impl From<Format> for ash::vk::Format { 168 #[inline] from(val: Format) -> Self169 fn from(val: Format) -> Self { 170 ash::vk::Format::from_raw(val as i32) 171 } 172 } 173 174 // https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap46.html#spirvenv-image-formats 175 impl From<ImageFormat> for Option<Format> { 176 #[inline] from(val: ImageFormat) -> Self177 fn from(val: ImageFormat) -> Self { 178 match val { 179 ImageFormat::Unknown => None, 180 ImageFormat::Rgba32f => Some(Format::R32G32B32A32_SFLOAT), 181 ImageFormat::Rgba16f => Some(Format::R16G16B16A16_SFLOAT), 182 ImageFormat::R32f => Some(Format::R32_SFLOAT), 183 ImageFormat::Rgba8 => Some(Format::R8G8B8A8_UNORM), 184 ImageFormat::Rgba8Snorm => Some(Format::R8G8B8A8_SNORM), 185 ImageFormat::Rg32f => Some(Format::R32G32_SFLOAT), 186 ImageFormat::Rg16f => Some(Format::R16G16_SFLOAT), 187 ImageFormat::R11fG11fB10f => Some(Format::B10G11R11_UFLOAT_PACK32), 188 ImageFormat::R16f => Some(Format::R16_SFLOAT), 189 ImageFormat::Rgba16 => Some(Format::R16G16B16A16_UNORM), 190 ImageFormat::Rgb10A2 => Some(Format::A2B10G10R10_UNORM_PACK32), 191 ImageFormat::Rg16 => Some(Format::R16G16_UNORM), 192 ImageFormat::Rg8 => Some(Format::R8G8_UNORM), 193 ImageFormat::R16 => Some(Format::R16_UNORM), 194 ImageFormat::R8 => Some(Format::R8_UNORM), 195 ImageFormat::Rgba16Snorm => Some(Format::R16G16B16A16_SNORM), 196 ImageFormat::Rg16Snorm => Some(Format::R16G16_SNORM), 197 ImageFormat::Rg8Snorm => Some(Format::R8G8_SNORM), 198 ImageFormat::R16Snorm => Some(Format::R16_SNORM), 199 ImageFormat::R8Snorm => Some(Format::R8_SNORM), 200 ImageFormat::Rgba32i => Some(Format::R32G32B32A32_SINT), 201 ImageFormat::Rgba16i => Some(Format::R16G16B16A16_SINT), 202 ImageFormat::Rgba8i => Some(Format::R8G8B8A8_SINT), 203 ImageFormat::R32i => Some(Format::R32_SINT), 204 ImageFormat::Rg32i => Some(Format::R32G32_SINT), 205 ImageFormat::Rg16i => Some(Format::R16G16_SINT), 206 ImageFormat::Rg8i => Some(Format::R8G8_SINT), 207 ImageFormat::R16i => Some(Format::R16_SINT), 208 ImageFormat::R8i => Some(Format::R8_SINT), 209 ImageFormat::Rgba32ui => Some(Format::R32G32B32A32_UINT), 210 ImageFormat::Rgba16ui => Some(Format::R16G16B16A16_UINT), 211 ImageFormat::Rgba8ui => Some(Format::R8G8B8A8_UINT), 212 ImageFormat::R32ui => Some(Format::R32_UINT), 213 ImageFormat::Rgb10a2ui => Some(Format::A2B10G10R10_UINT_PACK32), 214 ImageFormat::Rg32ui => Some(Format::R32G32_UINT), 215 ImageFormat::Rg16ui => Some(Format::R16G16_UINT), 216 ImageFormat::Rg8ui => Some(Format::R8G8_UINT), 217 ImageFormat::R16ui => Some(Format::R16_UINT), 218 ImageFormat::R8ui => Some(Format::R8_UINT), 219 ImageFormat::R64ui => Some(Format::R64_UINT), 220 ImageFormat::R64i => Some(Format::R64_SINT), 221 } 222 } 223 } 224 225 /// The block compression scheme used in a format. 226 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 227 #[allow(non_camel_case_types)] 228 pub enum CompressionType { 229 /// Adaptive Scalable Texture Compression, low dynamic range. 230 ASTC_LDR, 231 /// Adaptive Scalable Texture Compression, high dynamic range. 232 ASTC_HDR, 233 /// S3TC Block Compression. 234 BC, 235 /// Ericsson Texture Compression 2. 236 ETC2, 237 /// ETC2 Alpha Compression. 238 EAC, 239 /// PowerVR Texture Compression. 240 PVRTC, 241 } 242 243 /// For YCbCr formats, the type of chroma sampling used. 244 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 245 pub enum ChromaSampling { 246 /// The chroma components are represented at the same resolution as the luma component. 247 Mode444, 248 /// The chroma components have half the horizontal resolution as the luma component. 249 Mode422, 250 /// The chroma components have half the horizontal and vertical resolution as the luma 251 /// component. 252 Mode420, 253 } 254 255 impl ChromaSampling { 256 #[inline] subsampled_extent(self, mut extent: [u32; 3]) -> [u32; 3]257 pub fn subsampled_extent(self, mut extent: [u32; 3]) -> [u32; 3] { 258 match self { 259 ChromaSampling::Mode444 => (), 260 ChromaSampling::Mode422 => { 261 debug_assert!(extent[0] % 2 == 0); 262 extent[0] /= 2; 263 } 264 ChromaSampling::Mode420 => { 265 debug_assert!(extent[0] % 2 == 0 && extent[1] % 2 == 0); 266 extent[0] /= 2; 267 extent[1] /= 2; 268 } 269 } 270 271 extent 272 } 273 } 274 275 /// The numeric type that represents data of a format in memory. 276 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 277 pub enum NumericType { 278 /// Signed floating-point number. 279 SFLOAT, 280 /// Unsigned floating-point number. 281 UFLOAT, 282 /// Signed integer. 283 SINT, 284 /// Unsigned integer. 285 UINT, 286 /// Signed integer that represents a normalized floating-point value in the range \[-1,1]. 287 SNORM, 288 /// Unsigned integer that represents a normalized floating-point value in the range \[0,1]. 289 UNORM, 290 /// Signed integer that is converted to a floating-point value directly. 291 SSCALED, 292 /// Unsigned integer that is converted to a floating-point value directly. 293 USCALED, 294 /// Unsigned integer where R, G, B components represent a normalized floating-point value in the 295 /// sRGB color space, while the A component is a simple normalized value as in `UNORM`. 296 SRGB, 297 } 298 299 /// An opaque type that represents a format compatibility class. 300 /// 301 /// Two formats are compatible if their compatibility classes compare equal. 302 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 303 #[repr(transparent)] 304 pub struct FormatCompatibility(pub(crate) &'static FormatCompatibilityInner); 305 306 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 307 #[allow(non_camel_case_types)] 308 pub(crate) enum FormatCompatibilityInner { 309 Class_8bit, 310 Class_16bit, 311 Class_24bit, 312 Class_32bit, 313 Class_48bit, 314 Class_64bit, 315 Class_96bit, 316 Class_128bit, 317 Class_192bit, 318 Class_256bit, 319 Class_D16, 320 Class_D24, 321 Class_D32, 322 Class_S8, 323 Class_D16S8, 324 Class_D24S8, 325 Class_D32S8, 326 Class_64bit_R10G10B10A10, 327 Class_64bit_R12G12B12A12, 328 Class_BC1_RGB, 329 Class_BC1_RGBA, 330 Class_BC2, 331 Class_BC3, 332 Class_BC4, 333 Class_BC5, 334 Class_BC6H, 335 Class_BC7, 336 Class_ETC2_RGB, 337 Class_ETC2_RGBA, 338 Class_ETC2_EAC_RGBA, 339 Class_EAC_R, 340 Class_EAC_RG, 341 Class_ASTC_4x4, 342 Class_ASTC_5x4, 343 Class_ASTC_5x5, 344 Class_ASTC_6x5, 345 Class_ASTC_6x6, 346 Class_ASTC_8x5, 347 Class_ASTC_8x6, 348 Class_ASTC_8x8, 349 Class_ASTC_10x5, 350 Class_ASTC_10x6, 351 Class_ASTC_10x8, 352 Class_ASTC_10x10, 353 Class_ASTC_12x10, 354 Class_ASTC_12x12, 355 Class_PVRTC1_2BPP, 356 Class_PVRTC1_4BPP, 357 Class_PVRTC2_2BPP, 358 Class_PVRTC2_4BPP, 359 Class_32bit_G8B8G8R8, 360 Class_32bit_B8G8R8G8, 361 Class_64bit_G10B10G10R10, 362 Class_64bit_B10G10R10G10, 363 Class_64bit_G12B12G12R12, 364 Class_64bit_B12G12R12G12, 365 Class_64bit_G16B16G16R16, 366 Class_64bit_B16G16R16G16, 367 Class_8bit_3plane_420, 368 Class_8bit_2plane_420, 369 Class_10bit_3plane_420, 370 Class_10bit_2plane_420, 371 Class_12bit_3plane_420, 372 Class_12bit_2plane_420, 373 Class_16bit_3plane_420, 374 Class_16bit_2plane_420, 375 Class_8bit_3plane_422, 376 Class_8bit_2plane_422, 377 Class_10bit_3plane_422, 378 Class_10bit_2plane_422, 379 Class_12bit_3plane_422, 380 Class_12bit_2plane_422, 381 Class_16bit_3plane_422, 382 Class_16bit_2plane_422, 383 Class_8bit_3plane_444, 384 Class_10bit_3plane_444, 385 Class_12bit_3plane_444, 386 Class_16bit_3plane_444, 387 Class_8bit_2plane_444, 388 Class_10bit_2plane_444, 389 Class_12bit_2plane_444, 390 Class_16bit_2plane_444, 391 } 392 393 /// Describes a uniform value that will be used to fill an image. 394 #[derive(Clone, Copy, Debug, PartialEq)] 395 pub enum ClearValue { 396 /// Value for floating-point attachments, including `UNORM`, `SNORM`, `SFLOAT`. 397 Float([f32; 4]), 398 399 /// Value for integer attachments, including `SINT`. 400 Int([i32; 4]), 401 402 /// Value for unsigned integer attachments, including `UINT`. 403 Uint([u32; 4]), 404 405 /// Value for depth attachments. 406 Depth(f32), 407 408 /// Value for stencil attachments. 409 Stencil(u32), 410 411 /// Value for depth and stencil attachments. 412 DepthStencil((f32, u32)), 413 } 414 415 impl From<ClearValue> for ash::vk::ClearValue { 416 #[inline] from(val: ClearValue) -> Self417 fn from(val: ClearValue) -> Self { 418 match val { 419 ClearValue::Float(val) => Self { 420 color: ash::vk::ClearColorValue { float32: val }, 421 }, 422 ClearValue::Int(val) => Self { 423 color: ash::vk::ClearColorValue { int32: val }, 424 }, 425 ClearValue::Uint(val) => Self { 426 color: ash::vk::ClearColorValue { uint32: val }, 427 }, 428 ClearValue::Depth(depth) => Self { 429 depth_stencil: ash::vk::ClearDepthStencilValue { depth, stencil: 0 }, 430 }, 431 ClearValue::Stencil(stencil) => Self { 432 depth_stencil: ash::vk::ClearDepthStencilValue { 433 depth: 0.0, 434 stencil, 435 }, 436 }, 437 ClearValue::DepthStencil((depth, stencil)) => Self { 438 depth_stencil: ash::vk::ClearDepthStencilValue { depth, stencil }, 439 }, 440 } 441 } 442 } 443 444 impl From<ClearColorValue> for ClearValue { 445 #[inline] from(val: ClearColorValue) -> Self446 fn from(val: ClearColorValue) -> Self { 447 match val { 448 ClearColorValue::Float(val) => Self::Float(val), 449 ClearColorValue::Int(val) => Self::Int(val), 450 ClearColorValue::Uint(val) => Self::Uint(val), 451 } 452 } 453 } 454 455 impl From<[f32; 1]> for ClearValue { 456 #[inline] from(val: [f32; 1]) -> Self457 fn from(val: [f32; 1]) -> Self { 458 Self::Float([val[0], 0.0, 0.0, 1.0]) 459 } 460 } 461 462 impl From<[f32; 2]> for ClearValue { 463 #[inline] from(val: [f32; 2]) -> Self464 fn from(val: [f32; 2]) -> Self { 465 Self::Float([val[0], val[1], 0.0, 1.0]) 466 } 467 } 468 469 impl From<[f32; 3]> for ClearValue { 470 #[inline] from(val: [f32; 3]) -> Self471 fn from(val: [f32; 3]) -> Self { 472 Self::Float([val[0], val[1], val[2], 1.0]) 473 } 474 } 475 476 impl From<[f32; 4]> for ClearValue { 477 #[inline] from(val: [f32; 4]) -> Self478 fn from(val: [f32; 4]) -> Self { 479 Self::Float(val) 480 } 481 } 482 483 impl From<[u32; 1]> for ClearValue { 484 #[inline] from(val: [u32; 1]) -> Self485 fn from(val: [u32; 1]) -> Self { 486 Self::Uint([val[0], 0, 0, 0]) // TODO: is alpha value 0 correct? 487 } 488 } 489 490 impl From<[u32; 2]> for ClearValue { 491 #[inline] from(val: [u32; 2]) -> Self492 fn from(val: [u32; 2]) -> Self { 493 Self::Uint([val[0], val[1], 0, 0]) // TODO: is alpha value 0 correct? 494 } 495 } 496 497 impl From<[u32; 3]> for ClearValue { 498 #[inline] from(val: [u32; 3]) -> Self499 fn from(val: [u32; 3]) -> Self { 500 Self::Uint([val[0], val[1], val[2], 0]) // TODO: is alpha value 0 correct? 501 } 502 } 503 504 impl From<[u32; 4]> for ClearValue { 505 #[inline] from(val: [u32; 4]) -> Self506 fn from(val: [u32; 4]) -> Self { 507 Self::Uint(val) 508 } 509 } 510 511 impl From<[i32; 1]> for ClearValue { 512 #[inline] from(val: [i32; 1]) -> Self513 fn from(val: [i32; 1]) -> Self { 514 Self::Int([val[0], 0, 0, 0]) // TODO: is alpha value 0 correct? 515 } 516 } 517 518 impl From<[i32; 2]> for ClearValue { 519 #[inline] from(val: [i32; 2]) -> Self520 fn from(val: [i32; 2]) -> Self { 521 Self::Int([val[0], val[1], 0, 0]) // TODO: is alpha value 0 correct? 522 } 523 } 524 525 impl From<[i32; 3]> for ClearValue { 526 #[inline] from(val: [i32; 3]) -> Self527 fn from(val: [i32; 3]) -> Self { 528 Self::Int([val[0], val[1], val[2], 0]) // TODO: is alpha value 0 correct? 529 } 530 } 531 532 impl From<[i32; 4]> for ClearValue { 533 #[inline] from(val: [i32; 4]) -> Self534 fn from(val: [i32; 4]) -> Self { 535 Self::Int(val) 536 } 537 } 538 539 impl From<f32> for ClearValue { 540 #[inline] from(val: f32) -> Self541 fn from(val: f32) -> Self { 542 Self::Depth(val) 543 } 544 } 545 546 impl From<u32> for ClearValue { 547 #[inline] from(val: u32) -> Self548 fn from(val: u32) -> Self { 549 Self::Stencil(val) 550 } 551 } 552 553 impl From<(f32, u32)> for ClearValue { 554 #[inline] from(val: (f32, u32)) -> Self555 fn from(val: (f32, u32)) -> Self { 556 Self::DepthStencil(val) 557 } 558 } 559 560 /// A value that will be used to clear a color image. 561 #[derive(Clone, Copy, Debug, PartialEq)] 562 pub enum ClearColorValue { 563 /// Value for formats with a numeric type that is not `SINT` or `UINT`. 564 Float([f32; 4]), 565 /// Value for formats with a numeric type of `SINT`. 566 Int([i32; 4]), 567 /// Value for formats with a numeric type of `UINT`. 568 Uint([u32; 4]), 569 } 570 571 impl From<ClearColorValue> for ash::vk::ClearColorValue { 572 #[inline] from(val: ClearColorValue) -> Self573 fn from(val: ClearColorValue) -> Self { 574 match val { 575 ClearColorValue::Float(float32) => Self { float32 }, 576 ClearColorValue::Int(int32) => Self { int32 }, 577 ClearColorValue::Uint(uint32) => Self { uint32 }, 578 } 579 } 580 } 581 582 impl From<[f32; 1]> for ClearColorValue { 583 #[inline] from(val: [f32; 1]) -> Self584 fn from(val: [f32; 1]) -> Self { 585 Self::Float([val[0], 0.0, 0.0, 1.0]) 586 } 587 } 588 589 impl From<[f32; 2]> for ClearColorValue { 590 #[inline] from(val: [f32; 2]) -> Self591 fn from(val: [f32; 2]) -> Self { 592 Self::Float([val[0], val[1], 0.0, 1.0]) 593 } 594 } 595 596 impl From<[f32; 3]> for ClearColorValue { 597 #[inline] from(val: [f32; 3]) -> Self598 fn from(val: [f32; 3]) -> Self { 599 Self::Float([val[0], val[1], val[2], 1.0]) 600 } 601 } 602 603 impl From<[f32; 4]> for ClearColorValue { 604 #[inline] from(val: [f32; 4]) -> Self605 fn from(val: [f32; 4]) -> Self { 606 Self::Float(val) 607 } 608 } 609 610 impl From<[i32; 1]> for ClearColorValue { 611 #[inline] from(val: [i32; 1]) -> Self612 fn from(val: [i32; 1]) -> Self { 613 Self::Int([val[0], 0, 0, 1]) 614 } 615 } 616 617 impl From<[i32; 2]> for ClearColorValue { 618 #[inline] from(val: [i32; 2]) -> Self619 fn from(val: [i32; 2]) -> Self { 620 Self::Int([val[0], val[1], 0, 1]) 621 } 622 } 623 624 impl From<[i32; 3]> for ClearColorValue { 625 #[inline] from(val: [i32; 3]) -> Self626 fn from(val: [i32; 3]) -> Self { 627 Self::Int([val[0], val[1], val[2], 1]) 628 } 629 } 630 631 impl From<[i32; 4]> for ClearColorValue { 632 #[inline] from(val: [i32; 4]) -> Self633 fn from(val: [i32; 4]) -> Self { 634 Self::Int(val) 635 } 636 } 637 638 impl From<[u32; 1]> for ClearColorValue { 639 #[inline] from(val: [u32; 1]) -> Self640 fn from(val: [u32; 1]) -> Self { 641 Self::Uint([val[0], 0, 0, 1]) 642 } 643 } 644 645 impl From<[u32; 2]> for ClearColorValue { 646 #[inline] from(val: [u32; 2]) -> Self647 fn from(val: [u32; 2]) -> Self { 648 Self::Uint([val[0], val[1], 0, 1]) 649 } 650 } 651 652 impl From<[u32; 3]> for ClearColorValue { 653 #[inline] from(val: [u32; 3]) -> Self654 fn from(val: [u32; 3]) -> Self { 655 Self::Uint([val[0], val[1], val[2], 1]) 656 } 657 } 658 659 impl From<[u32; 4]> for ClearColorValue { 660 #[inline] from(val: [u32; 4]) -> Self661 fn from(val: [u32; 4]) -> Self { 662 Self::Uint(val) 663 } 664 } 665 666 /// A value that will be used to clear a depth/stencil image. 667 #[derive(Clone, Copy, Debug, Default, PartialEq)] 668 pub struct ClearDepthStencilValue { 669 /// Value for the depth component. 670 pub depth: f32, 671 /// Value for the stencil component. 672 pub stencil: u32, 673 } 674 675 impl From<ClearDepthStencilValue> for ash::vk::ClearDepthStencilValue { 676 #[inline] from(val: ClearDepthStencilValue) -> Self677 fn from(val: ClearDepthStencilValue) -> Self { 678 Self { 679 depth: val.depth, 680 stencil: val.stencil, 681 } 682 } 683 } 684 685 impl From<f32> for ClearDepthStencilValue { 686 #[inline] from(depth: f32) -> Self687 fn from(depth: f32) -> Self { 688 Self { depth, stencil: 0 } 689 } 690 } 691 692 impl From<u32> for ClearDepthStencilValue { 693 #[inline] from(stencil: u32) -> Self694 fn from(stencil: u32) -> Self { 695 Self { 696 depth: 0.0, 697 stencil, 698 } 699 } 700 } 701 702 impl From<(f32, u32)> for ClearDepthStencilValue { 703 #[inline] from((depth, stencil): (f32, u32)) -> Self704 fn from((depth, stencil): (f32, u32)) -> Self { 705 Self { depth, stencil } 706 } 707 } 708 709 /// The properties of a format that are supported by a physical device. 710 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] 711 pub struct FormatProperties { 712 /// Features available for images with linear tiling. 713 pub linear_tiling_features: FormatFeatures, 714 715 /// Features available for images with optimal tiling. 716 pub optimal_tiling_features: FormatFeatures, 717 718 /// Features available for buffers. 719 pub buffer_features: FormatFeatures, 720 721 pub _ne: crate::NonExhaustive, 722 } 723 724 impl Default for FormatProperties { 725 #[inline] default() -> Self726 fn default() -> Self { 727 Self { 728 linear_tiling_features: Default::default(), 729 optimal_tiling_features: Default::default(), 730 buffer_features: Default::default(), 731 _ne: crate::NonExhaustive(()), 732 } 733 } 734 } 735 736 impl FormatProperties { 737 /// Returns the potential format features, following the definition of 738 /// <https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap43.html#potential-format-features>. 739 #[inline] potential_format_features(&self) -> FormatFeatures740 pub fn potential_format_features(&self) -> FormatFeatures { 741 self.linear_tiling_features | self.optimal_tiling_features 742 } 743 } 744 745 vulkan_bitflags! { 746 #[non_exhaustive] 747 748 /// The features supported by a device for an image or buffer with a particular format. 749 FormatFeatures = FormatFeatureFlags2(u64); 750 751 /* Image usage */ 752 753 /// Can be used with a sampled image descriptor. 754 SAMPLED_IMAGE = SAMPLED_IMAGE, 755 756 /// Can be used with a storage image descriptor. 757 STORAGE_IMAGE = STORAGE_IMAGE, 758 759 /// Can be used with a storage image descriptor with atomic operations in a shader. 760 STORAGE_IMAGE_ATOMIC = STORAGE_IMAGE_ATOMIC, 761 762 /// Can be used with a storage image descriptor for reading, without specifying a format on the 763 /// image view. 764 STORAGE_READ_WITHOUT_FORMAT = STORAGE_READ_WITHOUT_FORMAT { 765 api_version: V1_3, 766 device_extensions: [khr_format_feature_flags2], 767 }, 768 769 /// Can be used with a storage image descriptor for writing, without specifying a format on the 770 /// image view. 771 STORAGE_WRITE_WITHOUT_FORMAT = STORAGE_WRITE_WITHOUT_FORMAT { 772 api_version: V1_3, 773 device_extensions: [khr_format_feature_flags2], 774 }, 775 776 /// Can be used with a color attachment in a framebuffer, or with an input attachment 777 /// descriptor. 778 COLOR_ATTACHMENT = COLOR_ATTACHMENT, 779 780 /// Can be used with a color attachment in a framebuffer with blending, or with an input 781 /// attachment descriptor. 782 COLOR_ATTACHMENT_BLEND = COLOR_ATTACHMENT_BLEND, 783 784 /// Can be used with a depth/stencil attachment in a framebuffer, or with an input attachment 785 /// descriptor. 786 DEPTH_STENCIL_ATTACHMENT = DEPTH_STENCIL_ATTACHMENT, 787 788 /// Can be used with a fragment density map attachment in a framebuffer. 789 FRAGMENT_DENSITY_MAP = FRAGMENT_DENSITY_MAP_EXT { 790 device_extensions: [ext_fragment_density_map], 791 }, 792 793 /// Can be used with a fragment shading rate attachment in a framebuffer. 794 FRAGMENT_SHADING_RATE_ATTACHMENT = FRAGMENT_SHADING_RATE_ATTACHMENT_KHR { 795 device_extensions: [khr_fragment_shading_rate], 796 }, 797 798 /// Can be used with the source image in a transfer (copy) operation. 799 TRANSFER_SRC = TRANSFER_SRC { 800 api_version: V1_1, 801 device_extensions: [khr_maintenance1], 802 }, 803 804 /// Can be used with the destination image in a transfer (copy) operation. 805 TRANSFER_DST = TRANSFER_DST { 806 api_version: V1_1, 807 device_extensions: [khr_maintenance1], 808 }, 809 810 /// Can be used with the source image in a blit operation. 811 BLIT_SRC = BLIT_SRC, 812 813 /// Can be used with the destination image in a blit operation. 814 BLIT_DST = BLIT_DST, 815 816 /* Sampling */ 817 818 /// Can be used with samplers or as a blit source, using the 819 /// [`Linear`](crate::sampler::Filter::Linear) filter. 820 SAMPLED_IMAGE_FILTER_LINEAR = SAMPLED_IMAGE_FILTER_LINEAR, 821 822 /// Can be used with samplers or as a blit source, using the 823 /// [`Cubic`](crate::sampler::Filter::Cubic) filter. 824 SAMPLED_IMAGE_FILTER_CUBIC = SAMPLED_IMAGE_FILTER_CUBIC_EXT { 825 device_extensions: [ext_filter_cubic, img_filter_cubic], 826 }, 827 828 /// Can be used with samplers using a reduction mode of 829 /// [`Min`](crate::sampler::SamplerReductionMode::Min) or 830 /// [`Max`](crate::sampler::SamplerReductionMode::Max). 831 SAMPLED_IMAGE_FILTER_MINMAX = SAMPLED_IMAGE_FILTER_MINMAX { 832 api_version: V1_2, 833 device_extensions: [ext_sampler_filter_minmax], 834 }, 835 836 /// Can be used with sampler YCbCr conversions using a chroma offset of 837 /// [`Midpoint`](crate::sampler::ycbcr::ChromaLocation::Midpoint). 838 MIDPOINT_CHROMA_SAMPLES = MIDPOINT_CHROMA_SAMPLES { 839 api_version: V1_1, 840 device_extensions: [khr_sampler_ycbcr_conversion], 841 }, 842 843 /// Can be used with sampler YCbCr conversions using a chroma offset of 844 /// [`CositedEven`](crate::sampler::ycbcr::ChromaLocation::CositedEven). 845 COSITED_CHROMA_SAMPLES = COSITED_CHROMA_SAMPLES { 846 api_version: V1_1, 847 device_extensions: [khr_sampler_ycbcr_conversion], 848 }, 849 850 /// Can be used with sampler YCbCr conversions using the 851 /// [`Linear`](crate::sampler::Filter::Linear) chroma filter. 852 SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER = SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER { 853 api_version: V1_1, 854 device_extensions: [khr_sampler_ycbcr_conversion], 855 }, 856 857 /// Can be used with sampler YCbCr conversions whose chroma filter differs from the filters of 858 /// the base sampler. 859 SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER = SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER { 860 api_version: V1_1, 861 device_extensions: [khr_sampler_ycbcr_conversion], 862 }, 863 864 /// When used with a sampler YCbCr conversion, the implementation will always perform 865 /// explicit chroma reconstruction. 866 SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT = SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT { 867 api_version: V1_1, 868 device_extensions: [khr_sampler_ycbcr_conversion], 869 }, 870 871 /// Can be used with sampler YCbCr conversions with forced explicit reconstruction. 872 SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE = SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE { 873 api_version: V1_1, 874 device_extensions: [khr_sampler_ycbcr_conversion], 875 }, 876 877 /// Can be used with samplers using depth comparison. 878 SAMPLED_IMAGE_DEPTH_COMPARISON = SAMPLED_IMAGE_DEPTH_COMPARISON { 879 api_version: V1_3, 880 device_extensions: [khr_format_feature_flags2], 881 }, 882 883 /* Video */ 884 885 /// Can be used with the output image of a video decode operation. 886 VIDEO_DECODE_OUTPUT = VIDEO_DECODE_OUTPUT_KHR { 887 device_extensions: [khr_video_decode_queue], 888 }, 889 890 /// Can be used with the DPB image of a video decode operation. 891 VIDEO_DECODE_DPB = VIDEO_DECODE_DPB_KHR { 892 device_extensions: [khr_video_decode_queue], 893 }, 894 895 /// Can be used with the input image of a video encode operation. 896 VIDEO_ENCODE_INPUT = VIDEO_ENCODE_INPUT_KHR { 897 device_extensions: [khr_video_encode_queue], 898 }, 899 900 /// Can be used with the DPB image of a video encode operation. 901 VIDEO_ENCODE_DPB = VIDEO_ENCODE_DPB_KHR { 902 device_extensions: [khr_video_encode_queue], 903 }, 904 905 /* Misc image features */ 906 907 /// For multi-planar formats, can be used with images created with the [`DISJOINT`] flag. 908 /// 909 /// [`DISJOINT`]: crate::image::ImageCreateFlags::DISJOINT 910 DISJOINT = DISJOINT { 911 api_version: V1_1, 912 device_extensions: [khr_sampler_ycbcr_conversion], 913 }, 914 915 // TODO: document 916 LINEAR_COLOR_ATTACHMENT = LINEAR_COLOR_ATTACHMENT_NV { 917 device_extensions: [nv_linear_color_attachment], 918 }, 919 920 // TODO: document 921 WEIGHT_IMAGE = WEIGHT_IMAGE_QCOM { 922 device_extensions: [qcom_image_processing], 923 }, 924 925 // TODO: document 926 WEIGHT_SAMPLED_IMAGE = WEIGHT_SAMPLED_IMAGE_QCOM { 927 device_extensions: [qcom_image_processing], 928 }, 929 930 // TODO: document 931 BLOCK_MATCHING = BLOCK_MATCHING_QCOM { 932 device_extensions: [qcom_image_processing], 933 }, 934 935 // TODO: document 936 BOX_FILTER_SAMPLED = BOX_FILTER_SAMPLED_QCOM { 937 device_extensions: [qcom_image_processing], 938 }, 939 940 // TODO: document 941 OPTICAL_FLOW_IMAGE = OPTICAL_FLOW_IMAGE_NV { 942 device_extensions: [nv_optical_flow], 943 }, 944 945 // TODO: document 946 OPTICAL_FLOW_VECTOR = OPTICAL_FLOW_VECTOR_NV { 947 device_extensions: [nv_optical_flow], 948 }, 949 950 // TODO: document 951 OPTICAL_FLOW_COST = OPTICAL_FLOW_COST_NV { 952 device_extensions: [nv_optical_flow], 953 }, 954 955 /* Buffer usage */ 956 957 /// Can be used with a uniform texel buffer descriptor. 958 UNIFORM_TEXEL_BUFFER = UNIFORM_TEXEL_BUFFER, 959 960 /// Can be used with a storage texel buffer descriptor. 961 STORAGE_TEXEL_BUFFER = STORAGE_TEXEL_BUFFER, 962 963 /// Can be used with a storage texel buffer descriptor with atomic operations in a shader. 964 STORAGE_TEXEL_BUFFER_ATOMIC = STORAGE_TEXEL_BUFFER_ATOMIC, 965 966 /// Can be used as the format of a vertex attribute in the vertex input state of a graphics 967 /// pipeline. 968 VERTEX_BUFFER = VERTEX_BUFFER, 969 970 /// Can be used with the vertex buffer of an acceleration structure. 971 ACCELERATION_STRUCTURE_VERTEX_BUFFER = ACCELERATION_STRUCTURE_VERTEX_BUFFER_KHR { 972 device_extensions: [khr_acceleration_structure], 973 }, 974 } 975 976 impl From<ash::vk::FormatFeatureFlags> for FormatFeatures { 977 #[inline] from(val: ash::vk::FormatFeatureFlags) -> Self978 fn from(val: ash::vk::FormatFeatureFlags) -> Self { 979 Self::from(ash::vk::FormatFeatureFlags2::from_raw(val.as_raw() as u64)) 980 } 981 } 982