@ -3,6 +3,7 @@
// Refer to the license.txt file included.
# include <bitset>
# include <cstdlib>
# include <optional>
# include <set>
# include <string_view>
@ -15,6 +16,15 @@ namespace Vulkan {
namespace {
namespace Alternatives {
constexpr std : : array Depth24UnormS8Uint = { vk : : Format : : eD32SfloatS8Uint ,
vk : : Format : : eD16UnormS8Uint , vk : : Format { } } ;
constexpr std : : array Depth16UnormS8Uint = { vk : : Format : : eD24UnormS8Uint ,
vk : : Format : : eD32SfloatS8Uint , vk : : Format { } } ;
} // namespace Alternatives
template < typename T >
void SetNext ( void * * & next , T & data ) {
* next = & data ;
@ -22,7 +32,7 @@ void SetNext(void**& next, T& data) {
}
template < typename T >
T GetFeatures ( vk : : PhysicalDevice physical , vk : : DispatchLoaderDynamic dldi ) {
T GetFeatures ( vk : : PhysicalDevice physical , const vk : : DispatchLoaderDynamic & dldi ) {
vk : : PhysicalDeviceFeatures2 features ;
T extension_features ;
features . pNext = & extension_features ;
@ -30,17 +40,14 @@ T GetFeatures(vk::PhysicalDevice physical, vk::DispatchLoaderDynamic dldi) {
return extension_features ;
}
} // Anonymous namespace
namespace Alternatives {
constexpr std : : array Depth24UnormS8Uint = { vk : : Format : : eD32SfloatS8Uint ,
vk : : Format : : eD16UnormS8Uint , vk : : Format { } } ;
constexpr std : : array Depth16UnormS8Uint = { vk : : Format : : eD24UnormS8Uint ,
vk : : Format : : eD32SfloatS8Uint , vk : : Format { } } ;
constexpr std : : array Astc = { vk : : Format : : eA8B8G8R8UnormPack32 , vk : : Format { } } ;
} // namespace Alternatives
template < typename T >
T GetProperties ( vk : : PhysicalDevice physical , const vk : : DispatchLoaderDynamic & dldi ) {
vk : : PhysicalDeviceProperties2 properties ;
T extension_properties ;
properties . pNext = & extension_properties ;
physical . getProperties2 ( & properties , dldi ) ;
return extension_properties ;
}
constexpr const vk : : Format * GetFormatAlternatives ( vk : : Format format ) {
switch ( format ) {
@ -66,11 +73,13 @@ vk::FormatFeatureFlags GetFormatFeatures(vk::FormatProperties properties, Format
}
}
} // Anonymous namespace
VKDevice : : VKDevice ( const vk : : DispatchLoaderDynamic & dldi , vk : : PhysicalDevice physical ,
vk : : SurfaceKHR surface )
: physical { physical } , format_properties { GetFormatProperties ( dldi , physical ) } {
: physical { physical } , properties { physical . getProperties ( dldi ) } ,
format_properties { GetFormatProperties ( dldi , physical ) } {
SetupFamilies ( dldi , surface ) ;
SetupProperties ( dldi ) ;
SetupFeatures ( dldi ) ;
}
@ -88,12 +97,22 @@ bool VKDevice::Create(const vk::DispatchLoaderDynamic& dldi, vk::Instance instan
features . depthClamp = true ;
features . samplerAnisotropy = true ;
features . largePoints = true ;
features . multiViewport = true ;
features . depthBiasClamp = true ;
features . geometryShader = true ;
features . tessellationShader = true ;
features . fragmentStoresAndAtomics = true ;
features . shaderImageGatherExtended = true ;
features . shaderStorageImageWriteWithoutFormat = true ;
features . textureCompressionASTC_LDR = is_optimal_astc_supported ;
vk : : PhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor ;
vertex_divisor . vertexAttributeInstanceRateDivisor = true ;
vertex_divisor . vertexAttributeInstanceRateZeroDivisor = true ;
SetNext ( next , vertex_divisor ) ;
vk : : PhysicalDevice16BitStorageFeaturesKHR bit16_storage ;
bit16_storage . uniformAndStorageBuffer16BitAccess = true ;
SetNext ( next , bit16_storage ) ;
vk : : PhysicalDevice8BitStorageFeaturesKHR bit8_storage ;
bit8_storage . uniformAndStorageBuffer8BitAccess = true ;
SetNext ( next , bit8_storage ) ;
vk : : PhysicalDeviceFloat16Int8FeaturesKHR float16_int8 ;
if ( is_float16_supported ) {
@ -119,6 +138,10 @@ bool VKDevice::Create(const vk::DispatchLoaderDynamic& dldi, vk::Instance instan
LOG_INFO ( Render_Vulkan , " Device doesn't support uint8 indexes " ) ;
}
if ( ! ext_depth_range_unrestricted ) {
LOG_INFO ( Render_Vulkan , " Device doesn't support depth range unrestricted " ) ;
}
vk : : DeviceCreateInfo device_ci ( { } , static_cast < u32 > ( queue_cis . size ( ) ) , queue_cis . data ( ) , 0 ,
nullptr , static_cast < u32 > ( extensions . size ( ) ) , extensions . data ( ) ,
nullptr ) ;
@ -134,16 +157,7 @@ bool VKDevice::Create(const vk::DispatchLoaderDynamic& dldi, vk::Instance instan
logical = UniqueDevice (
dummy_logical , vk : : ObjectDestroy < vk : : NoParent , vk : : DispatchLoaderDynamic > ( nullptr , dld ) ) ;
if ( khr_driver_properties ) {
vk : : PhysicalDeviceDriverPropertiesKHR driver ;
vk : : PhysicalDeviceProperties2 properties ;
properties . pNext = & driver ;
physical . getProperties2 ( & properties , dld ) ;
driver_id = driver . driverID ;
LOG_INFO ( Render_Vulkan , " Driver: {} {} " , driver . driverName , driver . driverInfo ) ;
} else {
LOG_INFO ( Render_Vulkan , " Driver: Unknown " ) ;
}
CollectTelemetryParameters ( ) ;
graphics_queue = logical - > getQueue ( graphics_family , 0 , dld ) ;
present_queue = logical - > getQueue ( present_family , 0 , dld ) ;
@ -189,6 +203,18 @@ vk::Format VKDevice::GetSupportedFormat(vk::Format wanted_format,
bool VKDevice : : IsOptimalAstcSupported ( const vk : : PhysicalDeviceFeatures & features ,
const vk : : DispatchLoaderDynamic & dldi ) const {
// Disable for now to avoid converting ASTC twice.
return false ;
static constexpr std : : array astc_formats = {
vk : : Format : : eAstc4x4SrgbBlock , vk : : Format : : eAstc8x8SrgbBlock ,
vk : : Format : : eAstc8x5SrgbBlock , vk : : Format : : eAstc5x4SrgbBlock ,
vk : : Format : : eAstc5x5UnormBlock , vk : : Format : : eAstc5x5SrgbBlock ,
vk : : Format : : eAstc10x8UnormBlock , vk : : Format : : eAstc10x8SrgbBlock ,
vk : : Format : : eAstc6x6UnormBlock , vk : : Format : : eAstc6x6SrgbBlock ,
vk : : Format : : eAstc10x10UnormBlock , vk : : Format : : eAstc10x10SrgbBlock ,
vk : : Format : : eAstc12x12UnormBlock , vk : : Format : : eAstc12x12SrgbBlock ,
vk : : Format : : eAstc8x6UnormBlock , vk : : Format : : eAstc8x6SrgbBlock ,
vk : : Format : : eAstc6x5UnormBlock , vk : : Format : : eAstc6x5SrgbBlock } ;
if ( ! features . textureCompressionASTC_LDR ) {
return false ;
}
@ -196,12 +222,6 @@ bool VKDevice::IsOptimalAstcSupported(const vk::PhysicalDeviceFeatures& features
vk : : FormatFeatureFlagBits : : eSampledImage | vk : : FormatFeatureFlagBits : : eBlitSrc |
vk : : FormatFeatureFlagBits : : eBlitDst | vk : : FormatFeatureFlagBits : : eTransferSrc |
vk : : FormatFeatureFlagBits : : eTransferDst } ;
constexpr std : : array astc_formats = {
vk : : Format : : eAstc4x4UnormBlock , vk : : Format : : eAstc4x4SrgbBlock ,
vk : : Format : : eAstc8x8SrgbBlock , vk : : Format : : eAstc8x6SrgbBlock ,
vk : : Format : : eAstc5x4SrgbBlock , vk : : Format : : eAstc5x5UnormBlock ,
vk : : Format : : eAstc5x5SrgbBlock , vk : : Format : : eAstc10x8UnormBlock ,
vk : : Format : : eAstc10x8SrgbBlock } ;
for ( const auto format : astc_formats ) {
const auto format_properties { physical . getFormatProperties ( format , dldi ) } ;
if ( ! ( format_properties . optimalTilingFeatures & format_feature_usage ) ) {
@ -224,11 +244,17 @@ bool VKDevice::IsFormatSupported(vk::Format wanted_format, vk::FormatFeatureFlag
bool VKDevice : : IsSuitable ( const vk : : DispatchLoaderDynamic & dldi , vk : : PhysicalDevice physical ,
vk : : SurfaceKHR surface ) {
LOG_INFO ( Render_Vulkan , " {} " , physical . getProperties ( dldi ) . deviceName ) ;
bool is_suitable = true ;
constexpr std : : array required_extensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME ,
VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME } ;
constexpr std : : array required_extensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME ,
VK_KHR_16BIT_STORAGE_EXTENSION_NAME ,
VK_KHR_8BIT_STORAGE_EXTENSION_NAME ,
VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME ,
VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME ,
VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME ,
VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME ,
} ;
std : : bitset < required_extensions . size ( ) > available_extensions { } ;
for ( const auto & prop : physical . enumerateDeviceExtensionProperties ( nullptr , dldi ) ) {
@ -245,7 +271,7 @@ bool VKDevice::IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDev
if ( available_extensions [ i ] ) {
continue ;
}
LOG_ INFO ( Render_Vulkan , " Missing required extension: {} " , required_extensions [ i ] ) ;
LOG_ ERROR ( Render_Vulkan , " Missing required extension: {} " , required_extensions [ i ] ) ;
is_suitable = false ;
}
}
@ -262,7 +288,7 @@ bool VKDevice::IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDev
has_present | = physical . getSurfaceSupportKHR ( i , surface , dldi ) ! = 0 ;
}
if ( ! has_graphics | | ! has_present ) {
LOG_ INFO ( Render_Vulkan , " Device lacks a graphics and present queue " ) ;
LOG_ ERROR ( Render_Vulkan , " Device lacks a graphics and present queue " ) ;
is_suitable = false ;
}
@ -272,8 +298,15 @@ bool VKDevice::IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDev
constexpr u32 required_ubo_size = 65536 ;
if ( limits . maxUniformBufferRange < required_ubo_size ) {
LOG_INFO ( Render_Vulkan , " Device UBO size {} is too small, {} is required) " ,
limits . maxUniformBufferRange , required_ubo_size ) ;
LOG_ERROR ( Render_Vulkan , " Device UBO size {} is too small, {} is required " ,
limits . maxUniformBufferRange , required_ubo_size ) ;
is_suitable = false ;
}
constexpr u32 required_num_viewports = 16 ;
if ( limits . maxViewports < required_num_viewports ) {
LOG_INFO ( Render_Vulkan , " Device number of viewports {} is too small, {} is required " ,
limits . maxViewports , required_num_viewports ) ;
is_suitable = false ;
}
@ -284,24 +317,32 @@ bool VKDevice::IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDev
std : : make_pair ( features . depthClamp , " depthClamp " ) ,
std : : make_pair ( features . samplerAnisotropy , " samplerAnisotropy " ) ,
std : : make_pair ( features . largePoints , " largePoints " ) ,
std : : make_pair ( features . multiViewport , " multiViewport " ) ,
std : : make_pair ( features . depthBiasClamp , " depthBiasClamp " ) ,
std : : make_pair ( features . geometryShader , " geometryShader " ) ,
std : : make_pair ( features . tessellationShader , " tessellationShader " ) ,
std : : make_pair ( features . fragmentStoresAndAtomics , " fragmentStoresAndAtomics " ) ,
std : : make_pair ( features . shaderImageGatherExtended , " shaderImageGatherExtended " ) ,
std : : make_pair ( features . shaderStorageImageWriteWithoutFormat ,
" shaderStorageImageWriteWithoutFormat " ) ,
} ;
for ( const auto & [ supported , name ] : feature_report ) {
if ( supported ) {
continue ;
}
LOG_INFO ( Render_Vulkan , " Missing required feature: {} " , name ) ;
LOG_ ERROR ( Render_Vulkan , " Missing required feature: {} " , name ) ;
is_suitable = false ;
}
if ( ! is_suitable ) {
LOG_ERROR ( Render_Vulkan , " {} is not suitable " , properties . deviceName ) ;
}
return is_suitable ;
}
std : : vector < const char * > VKDevice : : LoadExtensions ( const vk : : DispatchLoaderDynamic & dldi ) {
std : : vector < const char * > extensions ;
extensions . reserve ( 7 ) ;
extensions . push_back ( VK_KHR_SWAPCHAIN_EXTENSION_NAME ) ;
extensions . push_back ( VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME ) ;
const auto Test = [ & ] ( const vk : : ExtensionProperties & extension ,
std : : optional < std : : reference_wrapper < bool > > status , const char * name ,
bool push ) {
@ -316,13 +357,30 @@ std::vector<const char*> VKDevice::LoadExtensions(const vk::DispatchLoaderDynami
}
} ;
extensions . reserve ( 13 ) ;
extensions . push_back ( VK_KHR_SWAPCHAIN_EXTENSION_NAME ) ;
extensions . push_back ( VK_KHR_16BIT_STORAGE_EXTENSION_NAME ) ;
extensions . push_back ( VK_KHR_8BIT_STORAGE_EXTENSION_NAME ) ;
extensions . push_back ( VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME ) ;
extensions . push_back ( VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME ) ;
extensions . push_back ( VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME ) ;
extensions . push_back ( VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME ) ;
[[maybe_unused]] const bool nsight =
std : : getenv ( " NVTX_INJECTION64_PATH " ) | | std : : getenv ( " NSIGHT_LAUNCHED " ) ;
bool khr_shader_float16_int8 { } ;
bool ext_subgroup_size_control { } ;
for ( const auto & extension : physical . enumerateDeviceExtensionProperties ( nullptr , dldi ) ) {
Test ( extension , khr_uniform_buffer_standard_layout ,
VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME , true ) ;
Test ( extension , ext_index_type_uint8 , VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME , true ) ;
Test ( extension , khr_driver_properties , VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME , true ) ;
Test ( extension , khr_shader_float16_int8 , VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME , false ) ;
Test ( extension , ext_depth_range_unrestricted ,
VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME , true ) ;
Test ( extension , ext_index_type_uint8 , VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME , true ) ;
Test ( extension , ext_shader_viewport_index_layer ,
VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME , true ) ;
Test ( extension , ext_subgroup_size_control , VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME ,
false ) ;
}
if ( khr_shader_float16_int8 ) {
@ -331,6 +389,23 @@ std::vector<const char*> VKDevice::LoadExtensions(const vk::DispatchLoaderDynami
extensions . push_back ( VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME ) ;
}
if ( ext_subgroup_size_control ) {
const auto features =
GetFeatures < vk : : PhysicalDeviceSubgroupSizeControlFeaturesEXT > ( physical , dldi ) ;
const auto properties =
GetProperties < vk : : PhysicalDeviceSubgroupSizeControlPropertiesEXT > ( physical , dldi ) ;
is_warp_potentially_bigger = properties . maxSubgroupSize > GuestWarpSize ;
if ( features . subgroupSizeControl & & properties . minSubgroupSize < = GuestWarpSize & &
properties . maxSubgroupSize > = GuestWarpSize ) {
extensions . push_back ( VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME ) ;
guest_warp_stages = properties . requiredSubgroupSizeStages ;
}
} else {
is_warp_potentially_bigger = true ;
}
return extensions ;
}
@ -357,19 +432,23 @@ void VKDevice::SetupFamilies(const vk::DispatchLoaderDynamic& dldi, vk::SurfaceK
present_family = * present_family_ ;
}
void VKDevice : : SetupProperties ( const vk : : DispatchLoaderDynamic & dldi ) {
const auto props = physical . getProperties ( dldi ) ;
device_type = props . deviceType ;
uniform_buffer_alignment = static_cast < u64 > ( props . limits . minUniformBufferOffsetAlignment ) ;
storage_buffer_alignment = static_cast < u64 > ( props . limits . minStorageBufferOffsetAlignment ) ;
max_storage_buffer_range = static_cast < u64 > ( props . limits . maxStorageBufferRange ) ;
}
void VKDevice : : SetupFeatures ( const vk : : DispatchLoaderDynamic & dldi ) {
const auto supported_features { physical . getFeatures ( dldi ) } ;
is_optimal_astc_supported = IsOptimalAstcSupported ( supported_features , dldi ) ;
}
void VKDevice : : CollectTelemetryParameters ( ) {
const auto driver = GetProperties < vk : : PhysicalDeviceDriverPropertiesKHR > ( physical , dld ) ;
driver_id = driver . driverID ;
vendor_name = driver . driverName ;
const auto extensions = physical . enumerateDeviceExtensionProperties ( nullptr , dld ) ;
reported_extensions . reserve ( std : : size ( extensions ) ) ;
for ( const auto & extension : extensions ) {
reported_extensions . push_back ( extension . extensionName ) ;
}
}
std : : vector < vk : : DeviceQueueCreateInfo > VKDevice : : GetDeviceQueueCreateInfos ( ) const {
static const float QUEUE_PRIORITY = 1.0f ;
@ -384,50 +463,70 @@ std::vector<vk::DeviceQueueCreateInfo> VKDevice::GetDeviceQueueCreateInfos() con
std : : unordered_map < vk : : Format , vk : : FormatProperties > VKDevice : : GetFormatProperties (
const vk : : DispatchLoaderDynamic & dldi , vk : : PhysicalDevice physical ) {
constexpr std : : array formats { vk : : Format : : eA8B8G8R8UnormPack32 ,
vk : : Format : : eA8B8G8R8SnormPack32 ,
vk : : Format : : eA8B8G8R8SrgbPack32 ,
vk : : Format : : eB5G6R5UnormPack16 ,
vk : : Format : : eA2B10G10R10UnormPack32 ,
vk : : Format : : eR32G32B32A32Sfloat ,
vk : : Format : : eR16G16B16A16Uint ,
vk : : Format : : eR16G16Unorm ,
vk : : Format : : eR16G16Snorm ,
vk : : Format : : eR16G16Sfloat ,
vk : : Format : : eR16Unorm ,
vk : : Format : : eR8G8B8A8Srgb ,
vk : : Format : : eR8G8Unorm ,
vk : : Format : : eR8G8Snorm ,
vk : : Format : : eR8Unorm ,
vk : : Format : : eB10G11R11UfloatPack32 ,
vk : : Format : : eR32Sfloat ,
vk : : Format : : eR16Sfloat ,
vk : : Format : : eR16G16B16A16Sfloat ,
vk : : Format : : eB8G8R8A8Unorm ,
vk : : Format : : eD32Sfloat ,
vk : : Format : : eD16Unorm ,
vk : : Format : : eD16UnormS8Uint ,
vk : : Format : : eD24UnormS8Uint ,
vk : : Format : : eD32SfloatS8Uint ,
vk : : Format : : eBc1RgbaUnormBlock ,
vk : : Format : : eBc2UnormBlock ,
vk : : Format : : eBc3UnormBlock ,
vk : : Format : : eBc4UnormBlock ,
vk : : Format : : eBc5UnormBlock ,
vk : : Format : : eBc5SnormBlock ,
vk : : Format : : eBc7UnormBlock ,
vk : : Format : : eBc1RgbaSrgbBlock ,
vk : : Format : : eBc3SrgbBlock ,
vk : : Format : : eBc7SrgbBlock ,
vk : : Format : : eAstc4x4UnormBlock ,
vk : : Format : : eAstc4x4SrgbBlock ,
vk : : Format : : eAstc8x8SrgbBlock ,
vk : : Format : : eAstc8x6SrgbBlock ,
vk : : Format : : eAstc5x4SrgbBlock ,
vk : : Format : : eAstc5x5UnormBlock ,
vk : : Format : : eAstc5x5SrgbBlock ,
vk : : Format : : eAstc10x8UnormBlock ,
vk : : Format : : eAstc10x8SrgbBlock } ;
static constexpr std : : array formats { vk : : Format : : eA8B8G8R8UnormPack32 ,
vk : : Format : : eA8B8G8R8SnormPack32 ,
vk : : Format : : eA8B8G8R8SrgbPack32 ,
vk : : Format : : eB5G6R5UnormPack16 ,
vk : : Format : : eA2B10G10R10UnormPack32 ,
vk : : Format : : eA1R5G5B5UnormPack16 ,
vk : : Format : : eR32G32B32A32Sfloat ,
vk : : Format : : eR32G32B32A32Uint ,
vk : : Format : : eR32G32Sfloat ,
vk : : Format : : eR32G32Uint ,
vk : : Format : : eR16G16B16A16Uint ,
vk : : Format : : eR16G16B16A16Unorm ,
vk : : Format : : eR16G16Unorm ,
vk : : Format : : eR16G16Snorm ,
vk : : Format : : eR16G16Sfloat ,
vk : : Format : : eR16Unorm ,
vk : : Format : : eR8G8B8A8Srgb ,
vk : : Format : : eR8G8Unorm ,
vk : : Format : : eR8G8Snorm ,
vk : : Format : : eR8Unorm ,
vk : : Format : : eR8Uint ,
vk : : Format : : eB10G11R11UfloatPack32 ,
vk : : Format : : eR32Sfloat ,
vk : : Format : : eR32Uint ,
vk : : Format : : eR16Sfloat ,
vk : : Format : : eR16G16B16A16Sfloat ,
vk : : Format : : eB8G8R8A8Unorm ,
vk : : Format : : eR4G4B4A4UnormPack16 ,
vk : : Format : : eD32Sfloat ,
vk : : Format : : eD16Unorm ,
vk : : Format : : eD16UnormS8Uint ,
vk : : Format : : eD24UnormS8Uint ,
vk : : Format : : eD32SfloatS8Uint ,
vk : : Format : : eBc1RgbaUnormBlock ,
vk : : Format : : eBc2UnormBlock ,
vk : : Format : : eBc3UnormBlock ,
vk : : Format : : eBc4UnormBlock ,
vk : : Format : : eBc5UnormBlock ,
vk : : Format : : eBc5SnormBlock ,
vk : : Format : : eBc7UnormBlock ,
vk : : Format : : eBc6HUfloatBlock ,
vk : : Format : : eBc6HSfloatBlock ,
vk : : Format : : eBc1RgbaSrgbBlock ,
vk : : Format : : eBc3SrgbBlock ,
vk : : Format : : eBc7SrgbBlock ,
vk : : Format : : eAstc4x4SrgbBlock ,
vk : : Format : : eAstc8x8SrgbBlock ,
vk : : Format : : eAstc8x5SrgbBlock ,
vk : : Format : : eAstc5x4SrgbBlock ,
vk : : Format : : eAstc5x5UnormBlock ,
vk : : Format : : eAstc5x5SrgbBlock ,
vk : : Format : : eAstc10x8UnormBlock ,
vk : : Format : : eAstc10x8SrgbBlock ,
vk : : Format : : eAstc6x6UnormBlock ,
vk : : Format : : eAstc6x6SrgbBlock ,
vk : : Format : : eAstc10x10UnormBlock ,
vk : : Format : : eAstc10x10SrgbBlock ,
vk : : Format : : eAstc12x12UnormBlock ,
vk : : Format : : eAstc12x12SrgbBlock ,
vk : : Format : : eAstc8x6UnormBlock ,
vk : : Format : : eAstc8x6SrgbBlock ,
vk : : Format : : eAstc6x5UnormBlock ,
vk : : Format : : eAstc6x5SrgbBlock ,
vk : : Format : : eE5B9G9R9UfloatPack32 } ;
std : : unordered_map < vk : : Format , vk : : FormatProperties > format_properties ;
for ( const auto format : formats ) {
format_properties . emplace ( format , physical . getFormatProperties ( format , dldi ) ) ;