diff options
| author | 2019-12-09 01:04:48 -0300 | |
|---|---|---|
| committer | 2019-12-09 01:04:48 -0300 | |
| commit | 19ce0d4f1a149787a48c56ad3d400de1cdb19ad6 (patch) | |
| tree | 5a4d90d94218035d3c0ddc0e94ca69d6e0c56503 /src/video_core | |
| parent | Merge pull request #3198 from ReinUsesLisp/tessellation-maxwell (diff) | |
| download | yuzu-19ce0d4f1a149787a48c56ad3d400de1cdb19ad6.tar.gz yuzu-19ce0d4f1a149787a48c56ad3d400de1cdb19ad6.tar.xz yuzu-19ce0d4f1a149787a48c56ad3d400de1cdb19ad6.zip | |
vk_device: Misc changes
- Setup more features and requirements.
- Improve logging for missing features.
- Collect telemetry parameters.
- Add queries for more image formats.
- Query push constants limits.
- Optionally enable some extensions.
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_device.cpp | 299 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_device.h | 94 |
2 files changed, 276 insertions, 117 deletions
diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp index 6e58736a3..92854a4b3 100644 --- a/src/video_core/renderer_vulkan/vk_device.cpp +++ b/src/video_core/renderer_vulkan/vk_device.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <bitset> | 5 | #include <bitset> |
| 6 | #include <cstdlib> | ||
| 6 | #include <optional> | 7 | #include <optional> |
| 7 | #include <set> | 8 | #include <set> |
| 8 | #include <string_view> | 9 | #include <string_view> |
| @@ -15,6 +16,15 @@ namespace Vulkan { | |||
| 15 | 16 | ||
| 16 | namespace { | 17 | namespace { |
| 17 | 18 | ||
| 19 | namespace Alternatives { | ||
| 20 | |||
| 21 | constexpr std::array Depth24UnormS8Uint = {vk::Format::eD32SfloatS8Uint, | ||
| 22 | vk::Format::eD16UnormS8Uint, vk::Format{}}; | ||
| 23 | constexpr std::array Depth16UnormS8Uint = {vk::Format::eD24UnormS8Uint, | ||
| 24 | vk::Format::eD32SfloatS8Uint, vk::Format{}}; | ||
| 25 | |||
| 26 | } // namespace Alternatives | ||
| 27 | |||
| 18 | template <typename T> | 28 | template <typename T> |
| 19 | void SetNext(void**& next, T& data) { | 29 | void SetNext(void**& next, T& data) { |
| 20 | *next = &data; | 30 | *next = &data; |
| @@ -22,7 +32,7 @@ void SetNext(void**& next, T& data) { | |||
| 22 | } | 32 | } |
| 23 | 33 | ||
| 24 | template <typename T> | 34 | template <typename T> |
| 25 | T GetFeatures(vk::PhysicalDevice physical, vk::DispatchLoaderDynamic dldi) { | 35 | T GetFeatures(vk::PhysicalDevice physical, const vk::DispatchLoaderDynamic& dldi) { |
| 26 | vk::PhysicalDeviceFeatures2 features; | 36 | vk::PhysicalDeviceFeatures2 features; |
| 27 | T extension_features; | 37 | T extension_features; |
| 28 | features.pNext = &extension_features; | 38 | features.pNext = &extension_features; |
| @@ -30,17 +40,14 @@ T GetFeatures(vk::PhysicalDevice physical, vk::DispatchLoaderDynamic dldi) { | |||
| 30 | return extension_features; | 40 | return extension_features; |
| 31 | } | 41 | } |
| 32 | 42 | ||
| 33 | } // Anonymous namespace | 43 | template <typename T> |
| 34 | 44 | T GetProperties(vk::PhysicalDevice physical, const vk::DispatchLoaderDynamic& dldi) { | |
| 35 | namespace Alternatives { | 45 | vk::PhysicalDeviceProperties2 properties; |
| 36 | 46 | T extension_properties; | |
| 37 | constexpr std::array Depth24UnormS8Uint = {vk::Format::eD32SfloatS8Uint, | 47 | properties.pNext = &extension_properties; |
| 38 | vk::Format::eD16UnormS8Uint, vk::Format{}}; | 48 | physical.getProperties2(&properties, dldi); |
| 39 | constexpr std::array Depth16UnormS8Uint = {vk::Format::eD24UnormS8Uint, | 49 | return extension_properties; |
| 40 | vk::Format::eD32SfloatS8Uint, vk::Format{}}; | 50 | } |
| 41 | constexpr std::array Astc = {vk::Format::eA8B8G8R8UnormPack32, vk::Format{}}; | ||
| 42 | |||
| 43 | } // namespace Alternatives | ||
| 44 | 51 | ||
| 45 | constexpr const vk::Format* GetFormatAlternatives(vk::Format format) { | 52 | constexpr const vk::Format* GetFormatAlternatives(vk::Format format) { |
| 46 | switch (format) { | 53 | switch (format) { |
| @@ -66,11 +73,13 @@ vk::FormatFeatureFlags GetFormatFeatures(vk::FormatProperties properties, Format | |||
| 66 | } | 73 | } |
| 67 | } | 74 | } |
| 68 | 75 | ||
| 76 | } // Anonymous namespace | ||
| 77 | |||
| 69 | VKDevice::VKDevice(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDevice physical, | 78 | VKDevice::VKDevice(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDevice physical, |
| 70 | vk::SurfaceKHR surface) | 79 | vk::SurfaceKHR surface) |
| 71 | : physical{physical}, format_properties{GetFormatProperties(dldi, physical)} { | 80 | : physical{physical}, properties{physical.getProperties(dldi)}, |
| 81 | format_properties{GetFormatProperties(dldi, physical)} { | ||
| 72 | SetupFamilies(dldi, surface); | 82 | SetupFamilies(dldi, surface); |
| 73 | SetupProperties(dldi); | ||
| 74 | SetupFeatures(dldi); | 83 | SetupFeatures(dldi); |
| 75 | } | 84 | } |
| 76 | 85 | ||
| @@ -88,12 +97,22 @@ bool VKDevice::Create(const vk::DispatchLoaderDynamic& dldi, vk::Instance instan | |||
| 88 | features.depthClamp = true; | 97 | features.depthClamp = true; |
| 89 | features.samplerAnisotropy = true; | 98 | features.samplerAnisotropy = true; |
| 90 | features.largePoints = true; | 99 | features.largePoints = true; |
| 100 | features.multiViewport = true; | ||
| 101 | features.depthBiasClamp = true; | ||
| 102 | features.geometryShader = true; | ||
| 103 | features.tessellationShader = true; | ||
| 104 | features.fragmentStoresAndAtomics = true; | ||
| 105 | features.shaderImageGatherExtended = true; | ||
| 106 | features.shaderStorageImageWriteWithoutFormat = true; | ||
| 91 | features.textureCompressionASTC_LDR = is_optimal_astc_supported; | 107 | features.textureCompressionASTC_LDR = is_optimal_astc_supported; |
| 92 | 108 | ||
| 93 | vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor; | 109 | vk::PhysicalDevice16BitStorageFeaturesKHR bit16_storage; |
| 94 | vertex_divisor.vertexAttributeInstanceRateDivisor = true; | 110 | bit16_storage.uniformAndStorageBuffer16BitAccess = true; |
| 95 | vertex_divisor.vertexAttributeInstanceRateZeroDivisor = true; | 111 | SetNext(next, bit16_storage); |
| 96 | SetNext(next, vertex_divisor); | 112 | |
| 113 | vk::PhysicalDevice8BitStorageFeaturesKHR bit8_storage; | ||
| 114 | bit8_storage.uniformAndStorageBuffer8BitAccess = true; | ||
| 115 | SetNext(next, bit8_storage); | ||
| 97 | 116 | ||
| 98 | vk::PhysicalDeviceFloat16Int8FeaturesKHR float16_int8; | 117 | vk::PhysicalDeviceFloat16Int8FeaturesKHR float16_int8; |
| 99 | if (is_float16_supported) { | 118 | if (is_float16_supported) { |
| @@ -119,6 +138,10 @@ bool VKDevice::Create(const vk::DispatchLoaderDynamic& dldi, vk::Instance instan | |||
| 119 | LOG_INFO(Render_Vulkan, "Device doesn't support uint8 indexes"); | 138 | LOG_INFO(Render_Vulkan, "Device doesn't support uint8 indexes"); |
| 120 | } | 139 | } |
| 121 | 140 | ||
| 141 | if (!ext_depth_range_unrestricted) { | ||
| 142 | LOG_INFO(Render_Vulkan, "Device doesn't support depth range unrestricted"); | ||
| 143 | } | ||
| 144 | |||
| 122 | vk::DeviceCreateInfo device_ci({}, static_cast<u32>(queue_cis.size()), queue_cis.data(), 0, | 145 | vk::DeviceCreateInfo device_ci({}, static_cast<u32>(queue_cis.size()), queue_cis.data(), 0, |
| 123 | nullptr, static_cast<u32>(extensions.size()), extensions.data(), | 146 | nullptr, static_cast<u32>(extensions.size()), extensions.data(), |
| 124 | nullptr); | 147 | nullptr); |
| @@ -134,16 +157,7 @@ bool VKDevice::Create(const vk::DispatchLoaderDynamic& dldi, vk::Instance instan | |||
| 134 | logical = UniqueDevice( | 157 | logical = UniqueDevice( |
| 135 | dummy_logical, vk::ObjectDestroy<vk::NoParent, vk::DispatchLoaderDynamic>(nullptr, dld)); | 158 | dummy_logical, vk::ObjectDestroy<vk::NoParent, vk::DispatchLoaderDynamic>(nullptr, dld)); |
| 136 | 159 | ||
| 137 | if (khr_driver_properties) { | 160 | CollectTelemetryParameters(); |
| 138 | vk::PhysicalDeviceDriverPropertiesKHR driver; | ||
| 139 | vk::PhysicalDeviceProperties2 properties; | ||
| 140 | properties.pNext = &driver; | ||
| 141 | physical.getProperties2(&properties, dld); | ||
| 142 | driver_id = driver.driverID; | ||
| 143 | LOG_INFO(Render_Vulkan, "Driver: {} {}", driver.driverName, driver.driverInfo); | ||
| 144 | } else { | ||
| 145 | LOG_INFO(Render_Vulkan, "Driver: Unknown"); | ||
| 146 | } | ||
| 147 | 161 | ||
| 148 | graphics_queue = logical->getQueue(graphics_family, 0, dld); | 162 | graphics_queue = logical->getQueue(graphics_family, 0, dld); |
| 149 | present_queue = logical->getQueue(present_family, 0, dld); | 163 | present_queue = logical->getQueue(present_family, 0, dld); |
| @@ -189,6 +203,18 @@ vk::Format VKDevice::GetSupportedFormat(vk::Format wanted_format, | |||
| 189 | 203 | ||
| 190 | bool VKDevice::IsOptimalAstcSupported(const vk::PhysicalDeviceFeatures& features, | 204 | bool VKDevice::IsOptimalAstcSupported(const vk::PhysicalDeviceFeatures& features, |
| 191 | const vk::DispatchLoaderDynamic& dldi) const { | 205 | const vk::DispatchLoaderDynamic& dldi) const { |
| 206 | // Disable for now to avoid converting ASTC twice. | ||
| 207 | return false; | ||
| 208 | static constexpr std::array astc_formats = { | ||
| 209 | vk::Format::eAstc4x4SrgbBlock, vk::Format::eAstc8x8SrgbBlock, | ||
| 210 | vk::Format::eAstc8x5SrgbBlock, vk::Format::eAstc5x4SrgbBlock, | ||
| 211 | vk::Format::eAstc5x5UnormBlock, vk::Format::eAstc5x5SrgbBlock, | ||
| 212 | vk::Format::eAstc10x8UnormBlock, vk::Format::eAstc10x8SrgbBlock, | ||
| 213 | vk::Format::eAstc6x6UnormBlock, vk::Format::eAstc6x6SrgbBlock, | ||
| 214 | vk::Format::eAstc10x10UnormBlock, vk::Format::eAstc10x10SrgbBlock, | ||
| 215 | vk::Format::eAstc12x12UnormBlock, vk::Format::eAstc12x12SrgbBlock, | ||
| 216 | vk::Format::eAstc8x6UnormBlock, vk::Format::eAstc8x6SrgbBlock, | ||
| 217 | vk::Format::eAstc6x5UnormBlock, vk::Format::eAstc6x5SrgbBlock}; | ||
| 192 | if (!features.textureCompressionASTC_LDR) { | 218 | if (!features.textureCompressionASTC_LDR) { |
| 193 | return false; | 219 | return false; |
| 194 | } | 220 | } |
| @@ -196,12 +222,6 @@ bool VKDevice::IsOptimalAstcSupported(const vk::PhysicalDeviceFeatures& features | |||
| 196 | vk::FormatFeatureFlagBits::eSampledImage | vk::FormatFeatureFlagBits::eBlitSrc | | 222 | vk::FormatFeatureFlagBits::eSampledImage | vk::FormatFeatureFlagBits::eBlitSrc | |
| 197 | vk::FormatFeatureFlagBits::eBlitDst | vk::FormatFeatureFlagBits::eTransferSrc | | 223 | vk::FormatFeatureFlagBits::eBlitDst | vk::FormatFeatureFlagBits::eTransferSrc | |
| 198 | vk::FormatFeatureFlagBits::eTransferDst}; | 224 | vk::FormatFeatureFlagBits::eTransferDst}; |
| 199 | constexpr std::array astc_formats = { | ||
| 200 | vk::Format::eAstc4x4UnormBlock, vk::Format::eAstc4x4SrgbBlock, | ||
| 201 | vk::Format::eAstc8x8SrgbBlock, vk::Format::eAstc8x6SrgbBlock, | ||
| 202 | vk::Format::eAstc5x4SrgbBlock, vk::Format::eAstc5x5UnormBlock, | ||
| 203 | vk::Format::eAstc5x5SrgbBlock, vk::Format::eAstc10x8UnormBlock, | ||
| 204 | vk::Format::eAstc10x8SrgbBlock}; | ||
| 205 | for (const auto format : astc_formats) { | 225 | for (const auto format : astc_formats) { |
| 206 | const auto format_properties{physical.getFormatProperties(format, dldi)}; | 226 | const auto format_properties{physical.getFormatProperties(format, dldi)}; |
| 207 | if (!(format_properties.optimalTilingFeatures & format_feature_usage)) { | 227 | if (!(format_properties.optimalTilingFeatures & format_feature_usage)) { |
| @@ -224,11 +244,17 @@ bool VKDevice::IsFormatSupported(vk::Format wanted_format, vk::FormatFeatureFlag | |||
| 224 | 244 | ||
| 225 | bool VKDevice::IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDevice physical, | 245 | bool VKDevice::IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDevice physical, |
| 226 | vk::SurfaceKHR surface) { | 246 | vk::SurfaceKHR surface) { |
| 227 | LOG_INFO(Render_Vulkan, "{}", physical.getProperties(dldi).deviceName); | ||
| 228 | bool is_suitable = true; | 247 | bool is_suitable = true; |
| 229 | 248 | ||
| 230 | constexpr std::array required_extensions = {VK_KHR_SWAPCHAIN_EXTENSION_NAME, | 249 | constexpr std::array required_extensions = { |
| 231 | VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME}; | 250 | VK_KHR_SWAPCHAIN_EXTENSION_NAME, |
| 251 | VK_KHR_16BIT_STORAGE_EXTENSION_NAME, | ||
| 252 | VK_KHR_8BIT_STORAGE_EXTENSION_NAME, | ||
| 253 | VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, | ||
| 254 | VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, | ||
| 255 | VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME, | ||
| 256 | VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME, | ||
| 257 | }; | ||
| 232 | std::bitset<required_extensions.size()> available_extensions{}; | 258 | std::bitset<required_extensions.size()> available_extensions{}; |
| 233 | 259 | ||
| 234 | for (const auto& prop : physical.enumerateDeviceExtensionProperties(nullptr, dldi)) { | 260 | for (const auto& prop : physical.enumerateDeviceExtensionProperties(nullptr, dldi)) { |
| @@ -245,7 +271,7 @@ bool VKDevice::IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDev | |||
| 245 | if (available_extensions[i]) { | 271 | if (available_extensions[i]) { |
| 246 | continue; | 272 | continue; |
| 247 | } | 273 | } |
| 248 | LOG_INFO(Render_Vulkan, "Missing required extension: {}", required_extensions[i]); | 274 | LOG_ERROR(Render_Vulkan, "Missing required extension: {}", required_extensions[i]); |
| 249 | is_suitable = false; | 275 | is_suitable = false; |
| 250 | } | 276 | } |
| 251 | } | 277 | } |
| @@ -262,7 +288,7 @@ bool VKDevice::IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDev | |||
| 262 | has_present |= physical.getSurfaceSupportKHR(i, surface, dldi) != 0; | 288 | has_present |= physical.getSurfaceSupportKHR(i, surface, dldi) != 0; |
| 263 | } | 289 | } |
| 264 | if (!has_graphics || !has_present) { | 290 | if (!has_graphics || !has_present) { |
| 265 | LOG_INFO(Render_Vulkan, "Device lacks a graphics and present queue"); | 291 | LOG_ERROR(Render_Vulkan, "Device lacks a graphics and present queue"); |
| 266 | is_suitable = false; | 292 | is_suitable = false; |
| 267 | } | 293 | } |
| 268 | 294 | ||
| @@ -272,8 +298,15 @@ bool VKDevice::IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDev | |||
| 272 | 298 | ||
| 273 | constexpr u32 required_ubo_size = 65536; | 299 | constexpr u32 required_ubo_size = 65536; |
| 274 | if (limits.maxUniformBufferRange < required_ubo_size) { | 300 | if (limits.maxUniformBufferRange < required_ubo_size) { |
| 275 | LOG_INFO(Render_Vulkan, "Device UBO size {} is too small, {} is required)", | 301 | LOG_ERROR(Render_Vulkan, "Device UBO size {} is too small, {} is required", |
| 276 | limits.maxUniformBufferRange, required_ubo_size); | 302 | limits.maxUniformBufferRange, required_ubo_size); |
| 303 | is_suitable = false; | ||
| 304 | } | ||
| 305 | |||
| 306 | constexpr u32 required_num_viewports = 16; | ||
| 307 | if (limits.maxViewports < required_num_viewports) { | ||
| 308 | LOG_INFO(Render_Vulkan, "Device number of viewports {} is too small, {} is required", | ||
| 309 | limits.maxViewports, required_num_viewports); | ||
| 277 | is_suitable = false; | 310 | is_suitable = false; |
| 278 | } | 311 | } |
| 279 | 312 | ||
| @@ -284,24 +317,32 @@ bool VKDevice::IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDev | |||
| 284 | std::make_pair(features.depthClamp, "depthClamp"), | 317 | std::make_pair(features.depthClamp, "depthClamp"), |
| 285 | std::make_pair(features.samplerAnisotropy, "samplerAnisotropy"), | 318 | std::make_pair(features.samplerAnisotropy, "samplerAnisotropy"), |
| 286 | std::make_pair(features.largePoints, "largePoints"), | 319 | std::make_pair(features.largePoints, "largePoints"), |
| 320 | std::make_pair(features.multiViewport, "multiViewport"), | ||
| 321 | std::make_pair(features.depthBiasClamp, "depthBiasClamp"), | ||
| 322 | std::make_pair(features.geometryShader, "geometryShader"), | ||
| 323 | std::make_pair(features.tessellationShader, "tessellationShader"), | ||
| 324 | std::make_pair(features.fragmentStoresAndAtomics, "fragmentStoresAndAtomics"), | ||
| 325 | std::make_pair(features.shaderImageGatherExtended, "shaderImageGatherExtended"), | ||
| 326 | std::make_pair(features.shaderStorageImageWriteWithoutFormat, | ||
| 327 | "shaderStorageImageWriteWithoutFormat"), | ||
| 287 | }; | 328 | }; |
| 288 | for (const auto& [supported, name] : feature_report) { | 329 | for (const auto& [supported, name] : feature_report) { |
| 289 | if (supported) { | 330 | if (supported) { |
| 290 | continue; | 331 | continue; |
| 291 | } | 332 | } |
| 292 | LOG_INFO(Render_Vulkan, "Missing required feature: {}", name); | 333 | LOG_ERROR(Render_Vulkan, "Missing required feature: {}", name); |
| 293 | is_suitable = false; | 334 | is_suitable = false; |
| 294 | } | 335 | } |
| 295 | 336 | ||
| 337 | if (!is_suitable) { | ||
| 338 | LOG_ERROR(Render_Vulkan, "{} is not suitable", properties.deviceName); | ||
| 339 | } | ||
| 340 | |||
| 296 | return is_suitable; | 341 | return is_suitable; |
| 297 | } | 342 | } |
| 298 | 343 | ||
| 299 | std::vector<const char*> VKDevice::LoadExtensions(const vk::DispatchLoaderDynamic& dldi) { | 344 | std::vector<const char*> VKDevice::LoadExtensions(const vk::DispatchLoaderDynamic& dldi) { |
| 300 | std::vector<const char*> extensions; | 345 | std::vector<const char*> extensions; |
| 301 | extensions.reserve(7); | ||
| 302 | extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); | ||
| 303 | extensions.push_back(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME); | ||
| 304 | |||
| 305 | const auto Test = [&](const vk::ExtensionProperties& extension, | 346 | const auto Test = [&](const vk::ExtensionProperties& extension, |
| 306 | std::optional<std::reference_wrapper<bool>> status, const char* name, | 347 | std::optional<std::reference_wrapper<bool>> status, const char* name, |
| 307 | bool push) { | 348 | bool push) { |
| @@ -316,13 +357,30 @@ std::vector<const char*> VKDevice::LoadExtensions(const vk::DispatchLoaderDynami | |||
| 316 | } | 357 | } |
| 317 | }; | 358 | }; |
| 318 | 359 | ||
| 360 | extensions.reserve(13); | ||
| 361 | extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); | ||
| 362 | extensions.push_back(VK_KHR_16BIT_STORAGE_EXTENSION_NAME); | ||
| 363 | extensions.push_back(VK_KHR_8BIT_STORAGE_EXTENSION_NAME); | ||
| 364 | extensions.push_back(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME); | ||
| 365 | extensions.push_back(VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME); | ||
| 366 | extensions.push_back(VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME); | ||
| 367 | extensions.push_back(VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME); | ||
| 368 | |||
| 369 | [[maybe_unused]] const bool nsight = | ||
| 370 | std::getenv("NVTX_INJECTION64_PATH") || std::getenv("NSIGHT_LAUNCHED"); | ||
| 319 | bool khr_shader_float16_int8{}; | 371 | bool khr_shader_float16_int8{}; |
| 372 | bool ext_subgroup_size_control{}; | ||
| 320 | for (const auto& extension : physical.enumerateDeviceExtensionProperties(nullptr, dldi)) { | 373 | for (const auto& extension : physical.enumerateDeviceExtensionProperties(nullptr, dldi)) { |
| 321 | Test(extension, khr_uniform_buffer_standard_layout, | 374 | Test(extension, khr_uniform_buffer_standard_layout, |
| 322 | VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true); | 375 | VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true); |
| 323 | Test(extension, ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true); | ||
| 324 | Test(extension, khr_driver_properties, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, true); | ||
| 325 | Test(extension, khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false); | 376 | Test(extension, khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false); |
| 377 | Test(extension, ext_depth_range_unrestricted, | ||
| 378 | VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true); | ||
| 379 | Test(extension, ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true); | ||
| 380 | Test(extension, ext_shader_viewport_index_layer, | ||
| 381 | VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, true); | ||
| 382 | Test(extension, ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, | ||
| 383 | false); | ||
| 326 | } | 384 | } |
| 327 | 385 | ||
| 328 | if (khr_shader_float16_int8) { | 386 | if (khr_shader_float16_int8) { |
| @@ -331,6 +389,23 @@ std::vector<const char*> VKDevice::LoadExtensions(const vk::DispatchLoaderDynami | |||
| 331 | extensions.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME); | 389 | extensions.push_back(VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME); |
| 332 | } | 390 | } |
| 333 | 391 | ||
| 392 | if (ext_subgroup_size_control) { | ||
| 393 | const auto features = | ||
| 394 | GetFeatures<vk::PhysicalDeviceSubgroupSizeControlFeaturesEXT>(physical, dldi); | ||
| 395 | const auto properties = | ||
| 396 | GetProperties<vk::PhysicalDeviceSubgroupSizeControlPropertiesEXT>(physical, dldi); | ||
| 397 | |||
| 398 | is_warp_potentially_bigger = properties.maxSubgroupSize > GuestWarpSize; | ||
| 399 | |||
| 400 | if (features.subgroupSizeControl && properties.minSubgroupSize <= GuestWarpSize && | ||
| 401 | properties.maxSubgroupSize >= GuestWarpSize) { | ||
| 402 | extensions.push_back(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME); | ||
| 403 | guest_warp_stages = properties.requiredSubgroupSizeStages; | ||
| 404 | } | ||
| 405 | } else { | ||
| 406 | is_warp_potentially_bigger = true; | ||
| 407 | } | ||
| 408 | |||
| 334 | return extensions; | 409 | return extensions; |
| 335 | } | 410 | } |
| 336 | 411 | ||
| @@ -357,19 +432,23 @@ void VKDevice::SetupFamilies(const vk::DispatchLoaderDynamic& dldi, vk::SurfaceK | |||
| 357 | present_family = *present_family_; | 432 | present_family = *present_family_; |
| 358 | } | 433 | } |
| 359 | 434 | ||
| 360 | void VKDevice::SetupProperties(const vk::DispatchLoaderDynamic& dldi) { | ||
| 361 | const auto props = physical.getProperties(dldi); | ||
| 362 | device_type = props.deviceType; | ||
| 363 | uniform_buffer_alignment = static_cast<u64>(props.limits.minUniformBufferOffsetAlignment); | ||
| 364 | storage_buffer_alignment = static_cast<u64>(props.limits.minStorageBufferOffsetAlignment); | ||
| 365 | max_storage_buffer_range = static_cast<u64>(props.limits.maxStorageBufferRange); | ||
| 366 | } | ||
| 367 | |||
| 368 | void VKDevice::SetupFeatures(const vk::DispatchLoaderDynamic& dldi) { | 435 | void VKDevice::SetupFeatures(const vk::DispatchLoaderDynamic& dldi) { |
| 369 | const auto supported_features{physical.getFeatures(dldi)}; | 436 | const auto supported_features{physical.getFeatures(dldi)}; |
| 370 | is_optimal_astc_supported = IsOptimalAstcSupported(supported_features, dldi); | 437 | is_optimal_astc_supported = IsOptimalAstcSupported(supported_features, dldi); |
| 371 | } | 438 | } |
| 372 | 439 | ||
| 440 | void VKDevice::CollectTelemetryParameters() { | ||
| 441 | const auto driver = GetProperties<vk::PhysicalDeviceDriverPropertiesKHR>(physical, dld); | ||
| 442 | driver_id = driver.driverID; | ||
| 443 | vendor_name = driver.driverName; | ||
| 444 | |||
| 445 | const auto extensions = physical.enumerateDeviceExtensionProperties(nullptr, dld); | ||
| 446 | reported_extensions.reserve(std::size(extensions)); | ||
| 447 | for (const auto& extension : extensions) { | ||
| 448 | reported_extensions.push_back(extension.extensionName); | ||
| 449 | } | ||
| 450 | } | ||
| 451 | |||
| 373 | std::vector<vk::DeviceQueueCreateInfo> VKDevice::GetDeviceQueueCreateInfos() const { | 452 | std::vector<vk::DeviceQueueCreateInfo> VKDevice::GetDeviceQueueCreateInfos() const { |
| 374 | static const float QUEUE_PRIORITY = 1.0f; | 453 | static const float QUEUE_PRIORITY = 1.0f; |
| 375 | 454 | ||
| @@ -384,50 +463,70 @@ std::vector<vk::DeviceQueueCreateInfo> VKDevice::GetDeviceQueueCreateInfos() con | |||
| 384 | 463 | ||
| 385 | std::unordered_map<vk::Format, vk::FormatProperties> VKDevice::GetFormatProperties( | 464 | std::unordered_map<vk::Format, vk::FormatProperties> VKDevice::GetFormatProperties( |
| 386 | const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDevice physical) { | 465 | const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDevice physical) { |
| 387 | constexpr std::array formats{vk::Format::eA8B8G8R8UnormPack32, | 466 | static constexpr std::array formats{vk::Format::eA8B8G8R8UnormPack32, |
| 388 | vk::Format::eA8B8G8R8SnormPack32, | 467 | vk::Format::eA8B8G8R8SnormPack32, |
| 389 | vk::Format::eA8B8G8R8SrgbPack32, | 468 | vk::Format::eA8B8G8R8SrgbPack32, |
| 390 | vk::Format::eB5G6R5UnormPack16, | 469 | vk::Format::eB5G6R5UnormPack16, |
| 391 | vk::Format::eA2B10G10R10UnormPack32, | 470 | vk::Format::eA2B10G10R10UnormPack32, |
| 392 | vk::Format::eR32G32B32A32Sfloat, | 471 | vk::Format::eA1R5G5B5UnormPack16, |
| 393 | vk::Format::eR16G16B16A16Uint, | 472 | vk::Format::eR32G32B32A32Sfloat, |
| 394 | vk::Format::eR16G16Unorm, | 473 | vk::Format::eR32G32B32A32Uint, |
| 395 | vk::Format::eR16G16Snorm, | 474 | vk::Format::eR32G32Sfloat, |
| 396 | vk::Format::eR16G16Sfloat, | 475 | vk::Format::eR32G32Uint, |
| 397 | vk::Format::eR16Unorm, | 476 | vk::Format::eR16G16B16A16Uint, |
| 398 | vk::Format::eR8G8B8A8Srgb, | 477 | vk::Format::eR16G16B16A16Unorm, |
| 399 | vk::Format::eR8G8Unorm, | 478 | vk::Format::eR16G16Unorm, |
| 400 | vk::Format::eR8G8Snorm, | 479 | vk::Format::eR16G16Snorm, |
| 401 | vk::Format::eR8Unorm, | 480 | vk::Format::eR16G16Sfloat, |
| 402 | vk::Format::eB10G11R11UfloatPack32, | 481 | vk::Format::eR16Unorm, |
| 403 | vk::Format::eR32Sfloat, | 482 | vk::Format::eR8G8B8A8Srgb, |
| 404 | vk::Format::eR16Sfloat, | 483 | vk::Format::eR8G8Unorm, |
| 405 | vk::Format::eR16G16B16A16Sfloat, | 484 | vk::Format::eR8G8Snorm, |
| 406 | vk::Format::eB8G8R8A8Unorm, | 485 | vk::Format::eR8Unorm, |
| 407 | vk::Format::eD32Sfloat, | 486 | vk::Format::eR8Uint, |
| 408 | vk::Format::eD16Unorm, | 487 | vk::Format::eB10G11R11UfloatPack32, |
| 409 | vk::Format::eD16UnormS8Uint, | 488 | vk::Format::eR32Sfloat, |
| 410 | vk::Format::eD24UnormS8Uint, | 489 | vk::Format::eR32Uint, |
| 411 | vk::Format::eD32SfloatS8Uint, | 490 | vk::Format::eR16Sfloat, |
| 412 | vk::Format::eBc1RgbaUnormBlock, | 491 | vk::Format::eR16G16B16A16Sfloat, |
| 413 | vk::Format::eBc2UnormBlock, | 492 | vk::Format::eB8G8R8A8Unorm, |
| 414 | vk::Format::eBc3UnormBlock, | 493 | vk::Format::eR4G4B4A4UnormPack16, |
| 415 | vk::Format::eBc4UnormBlock, | 494 | vk::Format::eD32Sfloat, |
| 416 | vk::Format::eBc5UnormBlock, | 495 | vk::Format::eD16Unorm, |
| 417 | vk::Format::eBc5SnormBlock, | 496 | vk::Format::eD16UnormS8Uint, |
| 418 | vk::Format::eBc7UnormBlock, | 497 | vk::Format::eD24UnormS8Uint, |
| 419 | vk::Format::eBc1RgbaSrgbBlock, | 498 | vk::Format::eD32SfloatS8Uint, |
| 420 | vk::Format::eBc3SrgbBlock, | 499 | vk::Format::eBc1RgbaUnormBlock, |
| 421 | vk::Format::eBc7SrgbBlock, | 500 | vk::Format::eBc2UnormBlock, |
| 422 | vk::Format::eAstc4x4UnormBlock, | 501 | vk::Format::eBc3UnormBlock, |
| 423 | vk::Format::eAstc4x4SrgbBlock, | 502 | vk::Format::eBc4UnormBlock, |
| 424 | vk::Format::eAstc8x8SrgbBlock, | 503 | vk::Format::eBc5UnormBlock, |
| 425 | vk::Format::eAstc8x6SrgbBlock, | 504 | vk::Format::eBc5SnormBlock, |
| 426 | vk::Format::eAstc5x4SrgbBlock, | 505 | vk::Format::eBc7UnormBlock, |
| 427 | vk::Format::eAstc5x5UnormBlock, | 506 | vk::Format::eBc6HUfloatBlock, |
| 428 | vk::Format::eAstc5x5SrgbBlock, | 507 | vk::Format::eBc6HSfloatBlock, |
| 429 | vk::Format::eAstc10x8UnormBlock, | 508 | vk::Format::eBc1RgbaSrgbBlock, |
| 430 | vk::Format::eAstc10x8SrgbBlock}; | 509 | vk::Format::eBc3SrgbBlock, |
| 510 | vk::Format::eBc7SrgbBlock, | ||
| 511 | vk::Format::eAstc4x4SrgbBlock, | ||
| 512 | vk::Format::eAstc8x8SrgbBlock, | ||
| 513 | vk::Format::eAstc8x5SrgbBlock, | ||
| 514 | vk::Format::eAstc5x4SrgbBlock, | ||
| 515 | vk::Format::eAstc5x5UnormBlock, | ||
| 516 | vk::Format::eAstc5x5SrgbBlock, | ||
| 517 | vk::Format::eAstc10x8UnormBlock, | ||
| 518 | vk::Format::eAstc10x8SrgbBlock, | ||
| 519 | vk::Format::eAstc6x6UnormBlock, | ||
| 520 | vk::Format::eAstc6x6SrgbBlock, | ||
| 521 | vk::Format::eAstc10x10UnormBlock, | ||
| 522 | vk::Format::eAstc10x10SrgbBlock, | ||
| 523 | vk::Format::eAstc12x12UnormBlock, | ||
| 524 | vk::Format::eAstc12x12SrgbBlock, | ||
| 525 | vk::Format::eAstc8x6UnormBlock, | ||
| 526 | vk::Format::eAstc8x6SrgbBlock, | ||
| 527 | vk::Format::eAstc6x5UnormBlock, | ||
| 528 | vk::Format::eAstc6x5SrgbBlock, | ||
| 529 | vk::Format::eE5B9G9R9UfloatPack32}; | ||
| 431 | std::unordered_map<vk::Format, vk::FormatProperties> format_properties; | 530 | std::unordered_map<vk::Format, vk::FormatProperties> format_properties; |
| 432 | for (const auto format : formats) { | 531 | for (const auto format : formats) { |
| 433 | format_properties.emplace(format, physical.getFormatProperties(format, dldi)); | 532 | format_properties.emplace(format, physical.getFormatProperties(format, dldi)); |
diff --git a/src/video_core/renderer_vulkan/vk_device.h b/src/video_core/renderer_vulkan/vk_device.h index 010d4c3d6..a844c52df 100644 --- a/src/video_core/renderer_vulkan/vk_device.h +++ b/src/video_core/renderer_vulkan/vk_device.h | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <string> | ||
| 8 | #include <string_view> | ||
| 7 | #include <unordered_map> | 9 | #include <unordered_map> |
| 8 | #include <vector> | 10 | #include <vector> |
| 9 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| @@ -14,6 +16,9 @@ namespace Vulkan { | |||
| 14 | /// Format usage descriptor. | 16 | /// Format usage descriptor. |
| 15 | enum class FormatType { Linear, Optimal, Buffer }; | 17 | enum class FormatType { Linear, Optimal, Buffer }; |
| 16 | 18 | ||
| 19 | /// Subgroup size of the guest emulated hardware (Nvidia has 32 threads per subgroup). | ||
| 20 | const u32 GuestWarpSize = 32; | ||
| 21 | |||
| 17 | /// Handles data specific to a physical device. | 22 | /// Handles data specific to a physical device. |
| 18 | class VKDevice final { | 23 | class VKDevice final { |
| 19 | public: | 24 | public: |
| @@ -71,7 +76,22 @@ public: | |||
| 71 | 76 | ||
| 72 | /// Returns true if the device is integrated with the host CPU. | 77 | /// Returns true if the device is integrated with the host CPU. |
| 73 | bool IsIntegrated() const { | 78 | bool IsIntegrated() const { |
| 74 | return device_type == vk::PhysicalDeviceType::eIntegratedGpu; | 79 | return properties.deviceType == vk::PhysicalDeviceType::eIntegratedGpu; |
| 80 | } | ||
| 81 | |||
| 82 | /// Returns the current Vulkan API version provided in Vulkan-formatted version numbers. | ||
| 83 | u32 GetApiVersion() const { | ||
| 84 | return properties.apiVersion; | ||
| 85 | } | ||
| 86 | |||
| 87 | /// Returns the current driver version provided in Vulkan-formatted version numbers. | ||
| 88 | u32 GetDriverVersion() const { | ||
| 89 | return properties.driverVersion; | ||
| 90 | } | ||
| 91 | |||
| 92 | /// Returns the device name. | ||
| 93 | std::string_view GetModelName() const { | ||
| 94 | return properties.deviceName; | ||
| 75 | } | 95 | } |
| 76 | 96 | ||
| 77 | /// Returns the driver ID. | 97 | /// Returns the driver ID. |
| @@ -80,18 +100,23 @@ public: | |||
| 80 | } | 100 | } |
| 81 | 101 | ||
| 82 | /// Returns uniform buffer alignment requeriment. | 102 | /// Returns uniform buffer alignment requeriment. |
| 83 | u64 GetUniformBufferAlignment() const { | 103 | vk::DeviceSize GetUniformBufferAlignment() const { |
| 84 | return uniform_buffer_alignment; | 104 | return properties.limits.minUniformBufferOffsetAlignment; |
| 85 | } | 105 | } |
| 86 | 106 | ||
| 87 | /// Returns storage alignment requeriment. | 107 | /// Returns storage alignment requeriment. |
| 88 | u64 GetStorageBufferAlignment() const { | 108 | vk::DeviceSize GetStorageBufferAlignment() const { |
| 89 | return storage_buffer_alignment; | 109 | return properties.limits.minStorageBufferOffsetAlignment; |
| 90 | } | 110 | } |
| 91 | 111 | ||
| 92 | /// Returns the maximum range for storage buffers. | 112 | /// Returns the maximum range for storage buffers. |
| 93 | u64 GetMaxStorageBufferRange() const { | 113 | vk::DeviceSize GetMaxStorageBufferRange() const { |
| 94 | return max_storage_buffer_range; | 114 | return properties.limits.maxStorageBufferRange; |
| 115 | } | ||
| 116 | |||
| 117 | /// Returns the maximum size for push constants. | ||
| 118 | vk::DeviceSize GetMaxPushConstantsSize() const { | ||
| 119 | return properties.limits.maxPushConstantsSize; | ||
| 95 | } | 120 | } |
| 96 | 121 | ||
| 97 | /// Returns true if ASTC is natively supported. | 122 | /// Returns true if ASTC is natively supported. |
| @@ -104,6 +129,16 @@ public: | |||
| 104 | return is_float16_supported; | 129 | return is_float16_supported; |
| 105 | } | 130 | } |
| 106 | 131 | ||
| 132 | /// Returns true if the device warp size can potentially be bigger than guest's warp size. | ||
| 133 | bool IsWarpSizePotentiallyBiggerThanGuest() const { | ||
| 134 | return is_warp_potentially_bigger; | ||
| 135 | } | ||
| 136 | |||
| 137 | /// Returns true if the device can be forced to use the guest warp size. | ||
| 138 | bool IsGuestWarpSizeSupported(vk::ShaderStageFlagBits stage) const { | ||
| 139 | return (guest_warp_stages & stage) != vk::ShaderStageFlags{}; | ||
| 140 | } | ||
| 141 | |||
| 107 | /// Returns true if the device supports VK_EXT_scalar_block_layout. | 142 | /// Returns true if the device supports VK_EXT_scalar_block_layout. |
| 108 | bool IsKhrUniformBufferStandardLayoutSupported() const { | 143 | bool IsKhrUniformBufferStandardLayoutSupported() const { |
| 109 | return khr_uniform_buffer_standard_layout; | 144 | return khr_uniform_buffer_standard_layout; |
| @@ -114,6 +149,26 @@ public: | |||
| 114 | return ext_index_type_uint8; | 149 | return ext_index_type_uint8; |
| 115 | } | 150 | } |
| 116 | 151 | ||
| 152 | /// Returns true if the device supports VK_EXT_depth_range_unrestricted. | ||
| 153 | bool IsExtDepthRangeUnrestrictedSupported() const { | ||
| 154 | return ext_depth_range_unrestricted; | ||
| 155 | } | ||
| 156 | |||
| 157 | /// Returns true if the device supports VK_EXT_shader_viewport_index_layer. | ||
| 158 | bool IsExtShaderViewportIndexLayerSupported() const { | ||
| 159 | return ext_shader_viewport_index_layer; | ||
| 160 | } | ||
| 161 | |||
| 162 | /// Returns the vendor name reported from Vulkan. | ||
| 163 | std::string_view GetVendorName() const { | ||
| 164 | return vendor_name; | ||
| 165 | } | ||
| 166 | |||
| 167 | /// Returns the list of available extensions. | ||
| 168 | const std::vector<std::string>& GetAvailableExtensions() const { | ||
| 169 | return reported_extensions; | ||
| 170 | } | ||
| 171 | |||
| 117 | /// Checks if the physical device is suitable. | 172 | /// Checks if the physical device is suitable. |
| 118 | static bool IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDevice physical, | 173 | static bool IsSuitable(const vk::DispatchLoaderDynamic& dldi, vk::PhysicalDevice physical, |
| 119 | vk::SurfaceKHR surface); | 174 | vk::SurfaceKHR surface); |
| @@ -125,12 +180,12 @@ private: | |||
| 125 | /// Sets up queue families. | 180 | /// Sets up queue families. |
| 126 | void SetupFamilies(const vk::DispatchLoaderDynamic& dldi, vk::SurfaceKHR surface); | 181 | void SetupFamilies(const vk::DispatchLoaderDynamic& dldi, vk::SurfaceKHR surface); |
| 127 | 182 | ||
| 128 | /// Sets up device properties. | ||
| 129 | void SetupProperties(const vk::DispatchLoaderDynamic& dldi); | ||
| 130 | |||
| 131 | /// Sets up device features. | 183 | /// Sets up device features. |
| 132 | void SetupFeatures(const vk::DispatchLoaderDynamic& dldi); | 184 | void SetupFeatures(const vk::DispatchLoaderDynamic& dldi); |
| 133 | 185 | ||
| 186 | /// Collects telemetry information from the device. | ||
| 187 | void CollectTelemetryParameters(); | ||
| 188 | |||
| 134 | /// Returns a list of queue initialization descriptors. | 189 | /// Returns a list of queue initialization descriptors. |
| 135 | std::vector<vk::DeviceQueueCreateInfo> GetDeviceQueueCreateInfos() const; | 190 | std::vector<vk::DeviceQueueCreateInfo> GetDeviceQueueCreateInfos() const; |
| 136 | 191 | ||
| @@ -148,23 +203,28 @@ private: | |||
| 148 | 203 | ||
| 149 | const vk::PhysicalDevice physical; ///< Physical device. | 204 | const vk::PhysicalDevice physical; ///< Physical device. |
| 150 | vk::DispatchLoaderDynamic dld; ///< Device function pointers. | 205 | vk::DispatchLoaderDynamic dld; ///< Device function pointers. |
| 206 | vk::PhysicalDeviceProperties properties; ///< Device properties. | ||
| 151 | UniqueDevice logical; ///< Logical device. | 207 | UniqueDevice logical; ///< Logical device. |
| 152 | vk::Queue graphics_queue; ///< Main graphics queue. | 208 | vk::Queue graphics_queue; ///< Main graphics queue. |
| 153 | vk::Queue present_queue; ///< Main present queue. | 209 | vk::Queue present_queue; ///< Main present queue. |
| 154 | u32 graphics_family{}; ///< Main graphics queue family index. | 210 | u32 graphics_family{}; ///< Main graphics queue family index. |
| 155 | u32 present_family{}; ///< Main present queue family index. | 211 | u32 present_family{}; ///< Main present queue family index. |
| 156 | vk::PhysicalDeviceType device_type; ///< Physical device type. | ||
| 157 | vk::DriverIdKHR driver_id{}; ///< Driver ID. | 212 | vk::DriverIdKHR driver_id{}; ///< Driver ID. |
| 158 | u64 uniform_buffer_alignment{}; ///< Uniform buffer alignment requeriment. | 213 | vk::ShaderStageFlags guest_warp_stages{}; ///< Stages where the guest warp size can be forced. |
| 159 | u64 storage_buffer_alignment{}; ///< Storage buffer alignment requeriment. | ||
| 160 | u64 max_storage_buffer_range{}; ///< Max storage buffer size. | ||
| 161 | bool is_optimal_astc_supported{}; ///< Support for native ASTC. | 214 | bool is_optimal_astc_supported{}; ///< Support for native ASTC. |
| 162 | bool is_float16_supported{}; ///< Support for float16 arithmetics. | 215 | bool is_float16_supported{}; ///< Support for float16 arithmetics. |
| 216 | bool is_warp_potentially_bigger{}; ///< Host warp size can be bigger than guest. | ||
| 163 | bool khr_uniform_buffer_standard_layout{}; ///< Support for std430 on UBOs. | 217 | bool khr_uniform_buffer_standard_layout{}; ///< Support for std430 on UBOs. |
| 164 | bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8. | 218 | bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8. |
| 165 | bool khr_driver_properties{}; ///< Support for VK_KHR_driver_properties. | 219 | bool ext_depth_range_unrestricted{}; ///< Support for VK_EXT_depth_range_unrestricted. |
| 166 | std::unordered_map<vk::Format, vk::FormatProperties> | 220 | bool ext_shader_viewport_index_layer{}; ///< Support for VK_EXT_shader_viewport_index_layer. |
| 167 | format_properties; ///< Format properties dictionary. | 221 | |
| 222 | // Telemetry parameters | ||
| 223 | std::string vendor_name; ///< Device's driver name. | ||
| 224 | std::vector<std::string> reported_extensions; ///< Reported Vulkan extensions. | ||
| 225 | |||
| 226 | /// Format properties dictionary. | ||
| 227 | std::unordered_map<vk::Format, vk::FormatProperties> format_properties; | ||
| 168 | }; | 228 | }; |
| 169 | 229 | ||
| 170 | } // namespace Vulkan | 230 | } // namespace Vulkan |