use crate::{
device::physical::PhysicalDevice, image::ImageAspects, shader::spirv::ImageFormat, DeviceSize,
};
use std::{ops::BitOr, vec::IntoIter as VecIntoIter};
include!(concat!(env!("OUT_DIR"), "/formats.rs"));
impl Format {
#[deprecated(since = "0.28", note = "Use PhysicalDevice::format_properties instead")]
#[inline]
pub fn properties(&self, physical_device: PhysicalDevice) -> FormatProperties {
physical_device.format_properties(*self)
}
#[inline]
pub fn shader_storage_image_without_format(&self) -> bool {
matches!(
*self,
Format::R8G8B8A8_UNORM
| Format::R8G8B8A8_SNORM
| Format::R8G8B8A8_UINT
| Format::R8G8B8A8_SINT
| Format::R32_UINT
| Format::R32_SINT
| Format::R32_SFLOAT
| Format::R32G32_UINT
| Format::R32G32_SINT
| Format::R32G32_SFLOAT
| Format::R32G32B32A32_UINT
| Format::R32G32B32A32_SINT
| Format::R32G32B32A32_SFLOAT
| Format::R16G16B16A16_UINT
| Format::R16G16B16A16_SINT
| Format::R16G16B16A16_SFLOAT
| Format::R16G16_SFLOAT
| Format::B10G11R11_UFLOAT_PACK32
| Format::R16_SFLOAT
| Format::R16G16B16A16_UNORM
| Format::A2B10G10R10_UNORM_PACK32
| Format::R16G16_UNORM
| Format::R8G8_UNORM
| Format::R16_UNORM
| Format::R8_UNORM
| Format::R16G16B16A16_SNORM
| Format::R16G16_SNORM
| Format::R8G8_SNORM
| Format::R16_SNORM
| Format::R8_SNORM
| Format::R16G16_SINT
| Format::R8G8_SINT
| Format::R16_SINT
| Format::R8_SINT
| Format::A2B10G10R10_UINT_PACK32
| Format::R16G16_UINT
| Format::R8G8_UINT
| Format::R16_UINT
| Format::R8_UINT
)
}
#[inline]
pub fn decode_clear_value(&self, value: ClearValue) -> ClearValue {
let aspects = self.aspects();
if aspects.depth && aspects.stencil {
assert!(matches!(value, ClearValue::DepthStencil(_)));
} else if aspects.depth {
assert!(matches!(value, ClearValue::Depth(_)));
} else if aspects.stencil {
assert!(matches!(value, ClearValue::Stencil(_)));
} else if let Some(numeric_type) = self.type_color() {
match numeric_type {
NumericType::SFLOAT
| NumericType::UFLOAT
| NumericType::SNORM
| NumericType::UNORM
| NumericType::SSCALED
| NumericType::USCALED
| NumericType::SRGB => {
assert!(matches!(value, ClearValue::Float(_)));
}
NumericType::SINT => {
assert!(matches!(value, ClearValue::Int(_)));
}
NumericType::UINT => {
assert!(matches!(value, ClearValue::Uint(_)));
}
}
} else {
panic!("Shouldn't happen!");
}
value
}
}
impl From<Format> for ash::vk::Format {
#[inline]
fn from(val: Format) -> Self {
ash::vk::Format::from_raw(val as i32)
}
}
impl From<ImageFormat> for Option<Format> {
fn from(val: ImageFormat) -> Self {
match val {
ImageFormat::Unknown => None,
ImageFormat::Rgba32f => Some(Format::R32G32B32A32_SFLOAT),
ImageFormat::Rgba16f => Some(Format::R16G16B16A16_SFLOAT),
ImageFormat::R32f => Some(Format::R32_SFLOAT),
ImageFormat::Rgba8 => Some(Format::R8G8B8A8_UNORM),
ImageFormat::Rgba8Snorm => Some(Format::R8G8B8A8_SNORM),
ImageFormat::Rg32f => Some(Format::R32G32_SFLOAT),
ImageFormat::Rg16f => Some(Format::R16G16_SFLOAT),
ImageFormat::R11fG11fB10f => Some(Format::B10G11R11_UFLOAT_PACK32),
ImageFormat::R16f => Some(Format::R16_SFLOAT),
ImageFormat::Rgba16 => Some(Format::R16G16B16A16_UNORM),
ImageFormat::Rgb10A2 => Some(Format::A2B10G10R10_UNORM_PACK32),
ImageFormat::Rg16 => Some(Format::R16G16_UNORM),
ImageFormat::Rg8 => Some(Format::R8G8_UNORM),
ImageFormat::R16 => Some(Format::R16_UNORM),
ImageFormat::R8 => Some(Format::R8_UNORM),
ImageFormat::Rgba16Snorm => Some(Format::R16G16B16A16_SNORM),
ImageFormat::Rg16Snorm => Some(Format::R16G16_SNORM),
ImageFormat::Rg8Snorm => Some(Format::R8G8_SNORM),
ImageFormat::R16Snorm => Some(Format::R16_SNORM),
ImageFormat::R8Snorm => Some(Format::R8_SNORM),
ImageFormat::Rgba32i => Some(Format::R32G32B32A32_SINT),
ImageFormat::Rgba16i => Some(Format::R16G16B16A16_SINT),
ImageFormat::Rgba8i => Some(Format::R8G8B8A8_SINT),
ImageFormat::R32i => Some(Format::R32_SINT),
ImageFormat::Rg32i => Some(Format::R32G32_SINT),
ImageFormat::Rg16i => Some(Format::R16G16_SINT),
ImageFormat::Rg8i => Some(Format::R8G8_SINT),
ImageFormat::R16i => Some(Format::R16_SINT),
ImageFormat::R8i => Some(Format::R8_SINT),
ImageFormat::Rgba32ui => Some(Format::R32G32B32A32_UINT),
ImageFormat::Rgba16ui => Some(Format::R16G16B16A16_UINT),
ImageFormat::Rgba8ui => Some(Format::R8G8B8A8_UINT),
ImageFormat::R32ui => Some(Format::R32_UINT),
ImageFormat::Rgb10a2ui => Some(Format::A2B10G10R10_UINT_PACK32),
ImageFormat::Rg32ui => Some(Format::R32G32_UINT),
ImageFormat::Rg16ui => Some(Format::R16G16_UINT),
ImageFormat::Rg8ui => Some(Format::R8G8_UINT),
ImageFormat::R16ui => Some(Format::R16_UINT),
ImageFormat::R8ui => Some(Format::R8_UINT),
ImageFormat::R64ui => Some(Format::R64_UINT),
ImageFormat::R64i => Some(Format::R64_SINT),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[allow(non_camel_case_types)]
pub enum CompressionType {
ASTC_LDR,
ASTC_HDR,
BC,
ETC2,
EAC,
PVRTC,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ChromaSampling {
Mode444,
Mode422,
Mode420,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum NumericType {
SFLOAT,
UFLOAT,
SINT,
UINT,
SNORM,
UNORM,
SSCALED,
USCALED,
SRGB,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[repr(transparent)]
pub struct FormatCompatibility(pub(crate) &'static FormatCompatibilityInner);
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[allow(non_camel_case_types)]
pub(crate) enum FormatCompatibilityInner {
Class_8bit,
Class_16bit,
Class_24bit,
Class_32bit,
Class_48bit,
Class_64bit,
Class_96bit,
Class_128bit,
Class_192bit,
Class_256bit,
Class_D16,
Class_D24,
Class_D32,
Class_S8,
Class_D16S8,
Class_D24S8,
Class_D32S8,
Class_64bit_R10G10B10A10,
Class_64bit_R12G12B12A12,
Class_BC1_RGB,
Class_BC1_RGBA,
Class_BC2,
Class_BC3,
Class_BC4,
Class_BC5,
Class_BC6H,
Class_BC7,
Class_ETC2_RGB,
Class_ETC2_RGBA,
Class_ETC2_EAC_RGBA,
Class_EAC_R,
Class_EAC_RG,
Class_ASTC_4x4,
Class_ASTC_5x4,
Class_ASTC_5x5,
Class_ASTC_6x5,
Class_ASTC_6x6,
Class_ASTC_8x5,
Class_ASTC_8x6,
Class_ASTC_8x8,
Class_ASTC_10x5,
Class_ASTC_10x6,
Class_ASTC_10x8,
Class_ASTC_10x10,
Class_ASTC_12x10,
Class_ASTC_12x12,
Class_PVRTC1_2BPP,
Class_PVRTC1_4BPP,
Class_PVRTC2_2BPP,
Class_PVRTC2_4BPP,
Class_32bit_G8B8G8R8,
Class_32bit_B8G8R8G8,
Class_64bit_G10B10G10R10,
Class_64bit_B10G10R10G10,
Class_64bit_G12B12G12R12,
Class_64bit_B12G12R12G12,
Class_64bit_G16B16G16R16,
Class_64bit_B16G16R16G16,
Class_8bit_3plane_420,
Class_8bit_2plane_420,
Class_10bit_3plane_420,
Class_10bit_2plane_420,
Class_12bit_3plane_420,
Class_12bit_2plane_420,
Class_16bit_3plane_420,
Class_16bit_2plane_420,
Class_8bit_3plane_422,
Class_8bit_2plane_422,
Class_10bit_3plane_422,
Class_10bit_2plane_422,
Class_12bit_3plane_422,
Class_12bit_2plane_422,
Class_16bit_3plane_422,
Class_16bit_2plane_422,
Class_8bit_3plane_444,
Class_10bit_3plane_444,
Class_12bit_3plane_444,
Class_16bit_3plane_444,
Class_8bit_2plane_444,
Class_10bit_2plane_444,
Class_12bit_2plane_444,
Class_16bit_2plane_444,
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ClearValue {
None,
Float([f32; 4]),
Int([i32; 4]),
Uint([u32; 4]),
Depth(f32),
Stencil(u32),
DepthStencil((f32, u32)),
}
impl From<[f32; 1]> for ClearValue {
#[inline]
fn from(val: [f32; 1]) -> ClearValue {
ClearValue::Float([val[0], 0.0, 0.0, 1.0])
}
}
impl From<[f32; 2]> for ClearValue {
#[inline]
fn from(val: [f32; 2]) -> ClearValue {
ClearValue::Float([val[0], val[1], 0.0, 1.0])
}
}
impl From<[f32; 3]> for ClearValue {
#[inline]
fn from(val: [f32; 3]) -> ClearValue {
ClearValue::Float([val[0], val[1], val[2], 1.0])
}
}
impl From<[f32; 4]> for ClearValue {
#[inline]
fn from(val: [f32; 4]) -> ClearValue {
ClearValue::Float(val)
}
}
impl From<[u32; 1]> for ClearValue {
#[inline]
fn from(val: [u32; 1]) -> ClearValue {
ClearValue::Uint([val[0], 0, 0, 0]) }
}
impl From<[u32; 2]> for ClearValue {
#[inline]
fn from(val: [u32; 2]) -> ClearValue {
ClearValue::Uint([val[0], val[1], 0, 0]) }
}
impl From<[u32; 3]> for ClearValue {
#[inline]
fn from(val: [u32; 3]) -> ClearValue {
ClearValue::Uint([val[0], val[1], val[2], 0]) }
}
impl From<[u32; 4]> for ClearValue {
#[inline]
fn from(val: [u32; 4]) -> ClearValue {
ClearValue::Uint(val)
}
}
impl From<[i32; 1]> for ClearValue {
#[inline]
fn from(val: [i32; 1]) -> ClearValue {
ClearValue::Int([val[0], 0, 0, 0]) }
}
impl From<[i32; 2]> for ClearValue {
#[inline]
fn from(val: [i32; 2]) -> ClearValue {
ClearValue::Int([val[0], val[1], 0, 0]) }
}
impl From<[i32; 3]> for ClearValue {
#[inline]
fn from(val: [i32; 3]) -> ClearValue {
ClearValue::Int([val[0], val[1], val[2], 0]) }
}
impl From<[i32; 4]> for ClearValue {
#[inline]
fn from(val: [i32; 4]) -> ClearValue {
ClearValue::Int(val)
}
}
impl From<f32> for ClearValue {
#[inline]
fn from(val: f32) -> ClearValue {
ClearValue::Depth(val)
}
}
impl From<u32> for ClearValue {
#[inline]
fn from(val: u32) -> ClearValue {
ClearValue::Stencil(val)
}
}
impl From<(f32, u32)> for ClearValue {
#[inline]
fn from(val: (f32, u32)) -> ClearValue {
ClearValue::DepthStencil(val)
}
}
pub unsafe trait ClearValuesTuple {
type Iter: Iterator<Item = ClearValue>;
fn iter(self) -> Self::Iter;
}
macro_rules! impl_clear_values_tuple {
($first:ident $($others:ident)+) => (
#[allow(non_snake_case)]
unsafe impl<$first $(, $others)*> ClearValuesTuple for ($first, $($others,)+)
where $first: Into<ClearValue> $(, $others: Into<ClearValue>)*
{
type Iter = VecIntoIter<ClearValue>;
#[inline]
fn iter(self) -> VecIntoIter<ClearValue> {
let ($first, $($others,)+) = self;
vec![
$first.into() $(, $others.into())+
].into_iter()
}
}
impl_clear_values_tuple!($($others)*);
);
($first:ident) => (
unsafe impl<$first> ClearValuesTuple for ($first,)
where $first: Into<ClearValue>
{
type Iter = VecIntoIter<ClearValue>;
#[inline]
fn iter(self) -> VecIntoIter<ClearValue> {
vec![self.0.into()].into_iter()
}
}
);
}
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);
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct FormatProperties {
pub linear_tiling_features: FormatFeatures,
pub optimal_tiling_features: FormatFeatures,
pub buffer_features: FormatFeatures,
pub _ne: crate::NonExhaustive,
}
impl FormatProperties {
#[inline]
pub fn potential_format_features(&self) -> FormatFeatures {
&self.linear_tiling_features | &self.optimal_tiling_features
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[allow(missing_docs)]
pub struct FormatFeatures {
pub sampled_image: bool,
pub storage_image: bool,
pub storage_image_atomic: bool,
pub storage_read_without_format: bool,
pub storage_write_without_format: bool,
pub color_attachment: bool,
pub color_attachment_blend: bool,
pub depth_stencil_attachment: bool,
pub fragment_density_map: bool,
pub fragment_shading_rate_attachment: bool,
pub transfer_src: bool,
pub transfer_dst: bool,
pub blit_src: bool,
pub blit_dst: bool,
pub sampled_image_filter_linear: bool,
pub sampled_image_filter_cubic: bool,
pub sampled_image_filter_minmax: bool,
pub midpoint_chroma_samples: bool,
pub cosited_chroma_samples: bool,
pub sampled_image_ycbcr_conversion_linear_filter: bool,
pub sampled_image_ycbcr_conversion_separate_reconstruction_filter: bool,
pub sampled_image_ycbcr_conversion_chroma_reconstruction_explicit: bool,
pub sampled_image_ycbcr_conversion_chroma_reconstruction_explicit_forceable: bool,
pub sampled_image_depth_comparison: bool,
pub video_decode_output: bool,
pub video_decode_dpb: bool,
pub video_encode_input: bool,
pub video_encode_dpb: bool,
pub disjoint: bool,
pub uniform_texel_buffer: bool,
pub storage_texel_buffer: bool,
pub storage_texel_buffer_atomic: bool,
pub vertex_buffer: bool,
pub acceleration_structure_vertex_buffer: bool,
pub _ne: crate::NonExhaustive,
}
impl BitOr for &FormatFeatures {
type Output = FormatFeatures;
fn bitor(self, rhs: Self) -> Self::Output {
Self::Output {
sampled_image: self.sampled_image || rhs.sampled_image,
storage_image: self.storage_image || rhs.storage_image,
storage_image_atomic: self.storage_image_atomic || rhs.storage_image_atomic,
storage_read_without_format: self.storage_read_without_format
|| rhs.storage_read_without_format,
storage_write_without_format: self.storage_write_without_format
|| rhs.storage_write_without_format,
color_attachment: self.color_attachment || rhs.color_attachment,
color_attachment_blend: self.color_attachment_blend || rhs.color_attachment_blend,
depth_stencil_attachment: self.depth_stencil_attachment || rhs.depth_stencil_attachment,
fragment_density_map: self.fragment_density_map || rhs.fragment_density_map,
fragment_shading_rate_attachment: self.fragment_shading_rate_attachment
|| rhs.fragment_shading_rate_attachment,
transfer_src: self.transfer_src || rhs.transfer_src,
transfer_dst: self.transfer_dst || rhs.transfer_dst,
blit_src: self.blit_src || rhs.blit_src,
blit_dst: self.blit_dst || rhs.blit_dst,
sampled_image_filter_linear: self.sampled_image_filter_linear
|| rhs.sampled_image_filter_linear,
sampled_image_filter_cubic: self.sampled_image_filter_cubic
|| rhs.sampled_image_filter_cubic,
sampled_image_filter_minmax: self.sampled_image_filter_minmax
|| rhs.sampled_image_filter_minmax,
midpoint_chroma_samples: self.midpoint_chroma_samples || rhs.midpoint_chroma_samples,
cosited_chroma_samples: self.cosited_chroma_samples || rhs.cosited_chroma_samples,
sampled_image_ycbcr_conversion_linear_filter: self
.sampled_image_ycbcr_conversion_linear_filter
|| rhs.sampled_image_ycbcr_conversion_linear_filter,
sampled_image_ycbcr_conversion_separate_reconstruction_filter: self
.sampled_image_ycbcr_conversion_separate_reconstruction_filter
|| rhs.sampled_image_ycbcr_conversion_separate_reconstruction_filter,
sampled_image_ycbcr_conversion_chroma_reconstruction_explicit: self
.sampled_image_ycbcr_conversion_chroma_reconstruction_explicit
|| rhs.sampled_image_ycbcr_conversion_chroma_reconstruction_explicit,
sampled_image_ycbcr_conversion_chroma_reconstruction_explicit_forceable: self
.sampled_image_ycbcr_conversion_chroma_reconstruction_explicit_forceable
|| rhs.sampled_image_ycbcr_conversion_chroma_reconstruction_explicit_forceable,
sampled_image_depth_comparison: self.sampled_image_depth_comparison
|| rhs.sampled_image_depth_comparison,
video_decode_output: self.video_decode_output || rhs.video_decode_output,
video_decode_dpb: self.video_decode_dpb || rhs.video_decode_dpb,
video_encode_input: self.video_encode_input || rhs.video_encode_input,
video_encode_dpb: self.video_encode_dpb || rhs.video_encode_dpb,
disjoint: self.disjoint || rhs.disjoint,
uniform_texel_buffer: self.uniform_texel_buffer || rhs.uniform_texel_buffer,
storage_texel_buffer: self.storage_texel_buffer || rhs.storage_texel_buffer,
storage_texel_buffer_atomic: self.storage_texel_buffer_atomic
|| rhs.storage_texel_buffer_atomic,
vertex_buffer: self.vertex_buffer || rhs.vertex_buffer,
acceleration_structure_vertex_buffer: self.acceleration_structure_vertex_buffer
|| rhs.acceleration_structure_vertex_buffer,
_ne: crate::NonExhaustive(()),
}
}
}
impl From<ash::vk::FormatFeatureFlags> for FormatFeatures {
#[inline]
#[rustfmt::skip]
fn from(val: ash::vk::FormatFeatureFlags) -> FormatFeatures {
FormatFeatures {
sampled_image: val.intersects(ash::vk::FormatFeatureFlags::SAMPLED_IMAGE),
storage_image: val.intersects(ash::vk::FormatFeatureFlags::STORAGE_IMAGE),
storage_image_atomic: val.intersects(ash::vk::FormatFeatureFlags::STORAGE_IMAGE_ATOMIC),
storage_read_without_format: false, storage_write_without_format: false, color_attachment: val.intersects(ash::vk::FormatFeatureFlags::COLOR_ATTACHMENT),
color_attachment_blend: val.intersects(ash::vk::FormatFeatureFlags::COLOR_ATTACHMENT_BLEND),
depth_stencil_attachment: val.intersects(ash::vk::FormatFeatureFlags::DEPTH_STENCIL_ATTACHMENT),
fragment_density_map: val.intersects(ash::vk::FormatFeatureFlags::FRAGMENT_DENSITY_MAP_EXT),
fragment_shading_rate_attachment: val.intersects(ash::vk::FormatFeatureFlags::FRAGMENT_SHADING_RATE_ATTACHMENT_KHR),
transfer_src: val.intersects(ash::vk::FormatFeatureFlags::TRANSFER_SRC),
transfer_dst: val.intersects(ash::vk::FormatFeatureFlags::TRANSFER_DST),
blit_src: val.intersects(ash::vk::FormatFeatureFlags::BLIT_SRC),
blit_dst: val.intersects(ash::vk::FormatFeatureFlags::BLIT_DST),
sampled_image_filter_linear: val.intersects(ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_FILTER_LINEAR),
sampled_image_filter_cubic: val.intersects(ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_FILTER_CUBIC_EXT),
sampled_image_filter_minmax: val.intersects(ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_FILTER_MINMAX),
midpoint_chroma_samples: val.intersects(ash::vk::FormatFeatureFlags::MIDPOINT_CHROMA_SAMPLES),
cosited_chroma_samples: val.intersects(ash::vk::FormatFeatureFlags::COSITED_CHROMA_SAMPLES),
sampled_image_ycbcr_conversion_linear_filter: val.intersects(ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER),
sampled_image_ycbcr_conversion_separate_reconstruction_filter: val.intersects(ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER),
sampled_image_ycbcr_conversion_chroma_reconstruction_explicit: val.intersects(ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT),
sampled_image_ycbcr_conversion_chroma_reconstruction_explicit_forceable: val.intersects(ash::vk::FormatFeatureFlags::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE),
sampled_image_depth_comparison: false,
video_decode_output: val.intersects(ash::vk::FormatFeatureFlags::VIDEO_DECODE_OUTPUT_KHR),
video_decode_dpb: val.intersects(ash::vk::FormatFeatureFlags::VIDEO_DECODE_DPB_KHR),
video_encode_input: val.intersects(ash::vk::FormatFeatureFlags::VIDEO_ENCODE_INPUT_KHR),
video_encode_dpb: val.intersects(ash::vk::FormatFeatureFlags::VIDEO_ENCODE_DPB_KHR),
disjoint: val.intersects(ash::vk::FormatFeatureFlags::DISJOINT),
uniform_texel_buffer: val.intersects(ash::vk::FormatFeatureFlags::UNIFORM_TEXEL_BUFFER),
storage_texel_buffer: val.intersects(ash::vk::FormatFeatureFlags::STORAGE_TEXEL_BUFFER),
storage_texel_buffer_atomic: val.intersects(ash::vk::FormatFeatureFlags::STORAGE_TEXEL_BUFFER_ATOMIC),
vertex_buffer: val.intersects(ash::vk::FormatFeatureFlags::VERTEX_BUFFER),
acceleration_structure_vertex_buffer: val.intersects(ash::vk::FormatFeatureFlags::ACCELERATION_STRUCTURE_VERTEX_BUFFER_KHR),
_ne: crate::NonExhaustive(()),
}
}
}
impl From<ash::vk::FormatFeatureFlags2> for FormatFeatures {
#[inline]
#[rustfmt::skip]
fn from(val: ash::vk::FormatFeatureFlags2) -> FormatFeatures {
FormatFeatures {
sampled_image: val.intersects(ash::vk::FormatFeatureFlags2::SAMPLED_IMAGE),
storage_image: val.intersects(ash::vk::FormatFeatureFlags2::STORAGE_IMAGE),
storage_image_atomic: val.intersects(ash::vk::FormatFeatureFlags2::STORAGE_IMAGE_ATOMIC),
storage_read_without_format: val.intersects(ash::vk::FormatFeatureFlags2::STORAGE_READ_WITHOUT_FORMAT),
storage_write_without_format: val.intersects(ash::vk::FormatFeatureFlags2::STORAGE_WRITE_WITHOUT_FORMAT),
color_attachment: val.intersects(ash::vk::FormatFeatureFlags2::COLOR_ATTACHMENT),
color_attachment_blend: val.intersects(ash::vk::FormatFeatureFlags2::COLOR_ATTACHMENT_BLEND),
depth_stencil_attachment: val.intersects(ash::vk::FormatFeatureFlags2::DEPTH_STENCIL_ATTACHMENT),
fragment_density_map: val.intersects(ash::vk::FormatFeatureFlags2::FRAGMENT_DENSITY_MAP_EXT),
fragment_shading_rate_attachment: val.intersects(ash::vk::FormatFeatureFlags2::FRAGMENT_SHADING_RATE_ATTACHMENT_KHR),
transfer_src: val.intersects(ash::vk::FormatFeatureFlags2::TRANSFER_SRC),
transfer_dst: val.intersects(ash::vk::FormatFeatureFlags2::TRANSFER_DST),
blit_src: val.intersects(ash::vk::FormatFeatureFlags2::BLIT_SRC),
blit_dst: val.intersects(ash::vk::FormatFeatureFlags2::BLIT_DST),
sampled_image_filter_linear: val.intersects(ash::vk::FormatFeatureFlags2::SAMPLED_IMAGE_FILTER_LINEAR),
sampled_image_filter_cubic: val.intersects(ash::vk::FormatFeatureFlags2::SAMPLED_IMAGE_FILTER_CUBIC_EXT),
sampled_image_filter_minmax: val.intersects(ash::vk::FormatFeatureFlags2::SAMPLED_IMAGE_FILTER_MINMAX),
midpoint_chroma_samples: val.intersects(ash::vk::FormatFeatureFlags2::MIDPOINT_CHROMA_SAMPLES),
cosited_chroma_samples: val.intersects(ash::vk::FormatFeatureFlags2::COSITED_CHROMA_SAMPLES),
sampled_image_ycbcr_conversion_linear_filter: val.intersects(ash::vk::FormatFeatureFlags2::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER),
sampled_image_ycbcr_conversion_separate_reconstruction_filter: val.intersects(ash::vk::FormatFeatureFlags2::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER),
sampled_image_ycbcr_conversion_chroma_reconstruction_explicit: val.intersects(ash::vk::FormatFeatureFlags2::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT),
sampled_image_ycbcr_conversion_chroma_reconstruction_explicit_forceable: val.intersects(ash::vk::FormatFeatureFlags2::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE),
sampled_image_depth_comparison: val.intersects(ash::vk::FormatFeatureFlags2::SAMPLED_IMAGE_DEPTH_COMPARISON),
video_decode_output: val.intersects(ash::vk::FormatFeatureFlags2::VIDEO_DECODE_OUTPUT_KHR),
video_decode_dpb: val.intersects(ash::vk::FormatFeatureFlags2::VIDEO_DECODE_DPB_KHR),
video_encode_input: val.intersects(ash::vk::FormatFeatureFlags2::VIDEO_ENCODE_INPUT_KHR),
video_encode_dpb: val.intersects(ash::vk::FormatFeatureFlags2::VIDEO_ENCODE_DPB_KHR),
disjoint: val.intersects(ash::vk::FormatFeatureFlags2::DISJOINT),
uniform_texel_buffer: val.intersects(ash::vk::FormatFeatureFlags2::UNIFORM_TEXEL_BUFFER),
storage_texel_buffer: val.intersects(ash::vk::FormatFeatureFlags2::STORAGE_TEXEL_BUFFER),
storage_texel_buffer_atomic: val.intersects(ash::vk::FormatFeatureFlags2::STORAGE_TEXEL_BUFFER_ATOMIC),
vertex_buffer: val.intersects(ash::vk::FormatFeatureFlags2::VERTEX_BUFFER),
acceleration_structure_vertex_buffer: val.intersects(ash::vk::FormatFeatureFlags2::ACCELERATION_STRUCTURE_VERTEX_BUFFER_KHR),
_ne: crate::NonExhaustive(()),
}
}
}