diff options
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.cpp | 19 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_device.cpp | 73 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_device.h | 12 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | 12 |
5 files changed, 66 insertions, 52 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 6f9eadbeb..7ffc90cd0 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -92,9 +92,9 @@ Common::DynamicLibrary OpenVulkanLibrary() { | |||
| 92 | return library; | 92 | return library; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatch& dld, | 95 | std::pair<vk::Instance, u32> CreateInstance( |
| 96 | WindowSystemType window_type = WindowSystemType::Headless, | 96 | Common::DynamicLibrary& library, vk::InstanceDispatch& dld, |
| 97 | bool enable_layers = false) { | 97 | WindowSystemType window_type = WindowSystemType::Headless, bool enable_layers = false) { |
| 98 | if (!library.IsOpen()) { | 98 | if (!library.IsOpen()) { |
| 99 | LOG_ERROR(Render_Vulkan, "Vulkan library not available"); | 99 | LOG_ERROR(Render_Vulkan, "Vulkan library not available"); |
| 100 | return {}; | 100 | return {}; |
| @@ -191,7 +191,7 @@ vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatc | |||
| 191 | if (!vk::Load(*instance, dld)) { | 191 | if (!vk::Load(*instance, dld)) { |
| 192 | LOG_ERROR(Render_Vulkan, "Failed to load Vulkan instance function pointers"); | 192 | LOG_ERROR(Render_Vulkan, "Failed to load Vulkan instance function pointers"); |
| 193 | } | 193 | } |
| 194 | return instance; | 194 | return std::make_pair(std::move(instance), version); |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | std::string GetReadableVersion(u32 version) { | 197 | std::string GetReadableVersion(u32 version) { |
| @@ -289,8 +289,8 @@ bool RendererVulkan::TryPresent(int /*timeout_ms*/) { | |||
| 289 | 289 | ||
| 290 | bool RendererVulkan::Init() { | 290 | bool RendererVulkan::Init() { |
| 291 | library = OpenVulkanLibrary(); | 291 | library = OpenVulkanLibrary(); |
| 292 | instance = CreateInstance(library, dld, render_window.GetWindowInfo().type, | 292 | std::tie(instance, instance_version) = CreateInstance( |
| 293 | Settings::values.renderer_debug); | 293 | library, dld, render_window.GetWindowInfo().type, Settings::values.renderer_debug); |
| 294 | if (!instance || !CreateDebugCallback() || !CreateSurface() || !PickDevices()) { | 294 | if (!instance || !CreateDebugCallback() || !CreateSurface() || !PickDevices()) { |
| 295 | return false; | 295 | return false; |
| 296 | } | 296 | } |
| @@ -423,7 +423,8 @@ bool RendererVulkan::PickDevices() { | |||
| 423 | return false; | 423 | return false; |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | device = std::make_unique<VKDevice>(*instance, physical_device, *surface, dld); | 426 | device = |
| 427 | std::make_unique<VKDevice>(*instance, instance_version, physical_device, *surface, dld); | ||
| 427 | return device->Create(); | 428 | return device->Create(); |
| 428 | } | 429 | } |
| 429 | 430 | ||
| @@ -433,7 +434,7 @@ void RendererVulkan::Report() const { | |||
| 433 | const std::string driver_version = GetDriverVersion(*device); | 434 | const std::string driver_version = GetDriverVersion(*device); |
| 434 | const std::string driver_name = fmt::format("{} {}", vendor_name, driver_version); | 435 | const std::string driver_name = fmt::format("{} {}", vendor_name, driver_version); |
| 435 | 436 | ||
| 436 | const std::string api_version = GetReadableVersion(device->GetApiVersion()); | 437 | const std::string api_version = GetReadableVersion(device->ApiVersion()); |
| 437 | 438 | ||
| 438 | const std::string extensions = BuildCommaSeparatedExtensions(device->GetAvailableExtensions()); | 439 | const std::string extensions = BuildCommaSeparatedExtensions(device->GetAvailableExtensions()); |
| 439 | 440 | ||
| @@ -453,7 +454,7 @@ void RendererVulkan::Report() const { | |||
| 453 | std::vector<std::string> RendererVulkan::EnumerateDevices() { | 454 | std::vector<std::string> RendererVulkan::EnumerateDevices() { |
| 454 | vk::InstanceDispatch dld; | 455 | vk::InstanceDispatch dld; |
| 455 | Common::DynamicLibrary library = OpenVulkanLibrary(); | 456 | Common::DynamicLibrary library = OpenVulkanLibrary(); |
| 456 | vk::Instance instance = CreateInstance(library, dld); | 457 | vk::Instance instance = CreateInstance(library, dld).first; |
| 457 | if (!instance) { | 458 | if (!instance) { |
| 458 | return {}; | 459 | return {}; |
| 459 | } | 460 | } |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 522b5bff8..9617a93e9 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h | |||
| @@ -63,6 +63,8 @@ private: | |||
| 63 | vk::InstanceDispatch dld; | 63 | vk::InstanceDispatch dld; |
| 64 | 64 | ||
| 65 | vk::Instance instance; | 65 | vk::Instance instance; |
| 66 | u32 instance_version{}; | ||
| 67 | |||
| 66 | vk::SurfaceKHR surface; | 68 | vk::SurfaceKHR surface; |
| 67 | 69 | ||
| 68 | VKScreenInfo screen_info; | 70 | VKScreenInfo screen_info; |
diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp index ebcfaa0e3..90916ee0e 100644 --- a/src/video_core/renderer_vulkan/vk_device.cpp +++ b/src/video_core/renderer_vulkan/vk_device.cpp | |||
| @@ -38,6 +38,9 @@ constexpr std::array Depth16UnormS8_UINT{ | |||
| 38 | 38 | ||
| 39 | constexpr std::array REQUIRED_EXTENSIONS{ | 39 | constexpr std::array REQUIRED_EXTENSIONS{ |
| 40 | VK_KHR_SWAPCHAIN_EXTENSION_NAME, | 40 | VK_KHR_SWAPCHAIN_EXTENSION_NAME, |
| 41 | VK_KHR_MAINTENANCE1_EXTENSION_NAME, | ||
| 42 | VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, | ||
| 43 | VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, | ||
| 41 | VK_KHR_16BIT_STORAGE_EXTENSION_NAME, | 44 | VK_KHR_16BIT_STORAGE_EXTENSION_NAME, |
| 42 | VK_KHR_8BIT_STORAGE_EXTENSION_NAME, | 45 | VK_KHR_8BIT_STORAGE_EXTENSION_NAME, |
| 43 | VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, | 46 | VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, |
| @@ -171,10 +174,10 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties( | |||
| 171 | 174 | ||
| 172 | } // Anonymous namespace | 175 | } // Anonymous namespace |
| 173 | 176 | ||
| 174 | VKDevice::VKDevice(VkInstance instance, vk::PhysicalDevice physical, VkSurfaceKHR surface, | 177 | VKDevice::VKDevice(VkInstance instance_, u32 instance_version_, vk::PhysicalDevice physical_, |
| 175 | const vk::InstanceDispatch& dld) | 178 | VkSurfaceKHR surface, const vk::InstanceDispatch& dld_) |
| 176 | : dld{dld}, physical{physical}, properties{physical.GetProperties()}, | 179 | : dld{dld_}, physical{physical_}, properties{physical.GetProperties()}, |
| 177 | format_properties{GetFormatProperties(physical, dld)} { | 180 | instance_version{instance_version_}, format_properties{GetFormatProperties(physical, dld)} { |
| 178 | SetupFamilies(surface); | 181 | SetupFamilies(surface); |
| 179 | SetupFeatures(); | 182 | SetupFeatures(); |
| 180 | } | 183 | } |
| @@ -565,20 +568,6 @@ bool VKDevice::IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface) { | |||
| 565 | 568 | ||
| 566 | std::vector<const char*> VKDevice::LoadExtensions() { | 569 | std::vector<const char*> VKDevice::LoadExtensions() { |
| 567 | std::vector<const char*> extensions; | 570 | std::vector<const char*> extensions; |
| 568 | const auto Test = [&](const VkExtensionProperties& extension, | ||
| 569 | std::optional<std::reference_wrapper<bool>> status, const char* name, | ||
| 570 | bool push) { | ||
| 571 | if (extension.extensionName != std::string_view(name)) { | ||
| 572 | return; | ||
| 573 | } | ||
| 574 | if (push) { | ||
| 575 | extensions.push_back(name); | ||
| 576 | } | ||
| 577 | if (status) { | ||
| 578 | status->get() = true; | ||
| 579 | } | ||
| 580 | }; | ||
| 581 | |||
| 582 | extensions.reserve(7 + REQUIRED_EXTENSIONS.size()); | 571 | extensions.reserve(7 + REQUIRED_EXTENSIONS.size()); |
| 583 | extensions.insert(extensions.begin(), REQUIRED_EXTENSIONS.begin(), REQUIRED_EXTENSIONS.end()); | 572 | extensions.insert(extensions.begin(), REQUIRED_EXTENSIONS.begin(), REQUIRED_EXTENSIONS.end()); |
| 584 | 573 | ||
| @@ -587,28 +576,36 @@ std::vector<const char*> VKDevice::LoadExtensions() { | |||
| 587 | bool has_ext_transform_feedback{}; | 576 | bool has_ext_transform_feedback{}; |
| 588 | bool has_ext_custom_border_color{}; | 577 | bool has_ext_custom_border_color{}; |
| 589 | bool has_ext_extended_dynamic_state{}; | 578 | bool has_ext_extended_dynamic_state{}; |
| 590 | for (const auto& extension : physical.EnumerateDeviceExtensionProperties()) { | 579 | for (const VkExtensionProperties& extension : physical.EnumerateDeviceExtensionProperties()) { |
| 591 | Test(extension, nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true); | 580 | const auto test = [&](std::optional<std::reference_wrapper<bool>> status, const char* name, |
| 592 | Test(extension, khr_uniform_buffer_standard_layout, | 581 | bool push) { |
| 582 | if (extension.extensionName != std::string_view(name)) { | ||
| 583 | return; | ||
| 584 | } | ||
| 585 | if (push) { | ||
| 586 | extensions.push_back(name); | ||
| 587 | } | ||
| 588 | if (status) { | ||
| 589 | status->get() = true; | ||
| 590 | } | ||
| 591 | }; | ||
| 592 | test(nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true); | ||
| 593 | test(khr_uniform_buffer_standard_layout, | ||
| 593 | VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true); | 594 | VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true); |
| 594 | Test(extension, has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, | 595 | test(has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false); |
| 595 | false); | 596 | test(ext_depth_range_unrestricted, VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true); |
| 596 | Test(extension, ext_depth_range_unrestricted, | 597 | test(ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true); |
| 597 | VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true); | 598 | test(ext_shader_viewport_index_layer, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, |
| 598 | Test(extension, ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true); | 599 | true); |
| 599 | Test(extension, ext_shader_viewport_index_layer, | 600 | test(has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, false); |
| 600 | VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, true); | 601 | test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false); |
| 601 | Test(extension, has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, | 602 | test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false); |
| 602 | false); | 603 | if (instance_version >= VK_API_VERSION_1_1) { |
| 603 | Test(extension, has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, | 604 | test(has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, false); |
| 604 | false); | 605 | } |
| 605 | Test(extension, has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, | ||
| 606 | false); | ||
| 607 | Test(extension, has_ext_extended_dynamic_state, | ||
| 608 | VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false); | ||
| 609 | if (Settings::values.renderer_debug) { | 606 | if (Settings::values.renderer_debug) { |
| 610 | Test(extension, nv_device_diagnostics_config, | 607 | test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, |
| 611 | VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, true); | 608 | true); |
| 612 | } | 609 | } |
| 613 | } | 610 | } |
| 614 | 611 | ||
diff --git a/src/video_core/renderer_vulkan/vk_device.h b/src/video_core/renderer_vulkan/vk_device.h index 26a233db1..4286673d9 100644 --- a/src/video_core/renderer_vulkan/vk_device.h +++ b/src/video_core/renderer_vulkan/vk_device.h | |||
| @@ -24,8 +24,8 @@ const u32 GuestWarpSize = 32; | |||
| 24 | /// Handles data specific to a physical device. | 24 | /// Handles data specific to a physical device. |
| 25 | class VKDevice final { | 25 | class VKDevice final { |
| 26 | public: | 26 | public: |
| 27 | explicit VKDevice(VkInstance instance, vk::PhysicalDevice physical, VkSurfaceKHR surface, | 27 | explicit VKDevice(VkInstance instance, u32 instance_version, vk::PhysicalDevice physical, |
| 28 | const vk::InstanceDispatch& dld); | 28 | VkSurfaceKHR surface, const vk::InstanceDispatch& dld); |
| 29 | ~VKDevice(); | 29 | ~VKDevice(); |
| 30 | 30 | ||
| 31 | /// Initializes the device. Returns true on success. | 31 | /// Initializes the device. Returns true on success. |
| @@ -82,8 +82,13 @@ public: | |||
| 82 | return present_family; | 82 | return present_family; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | /// Returns the current instance Vulkan API version in Vulkan-formatted version numbers. | ||
| 86 | u32 InstanceApiVersion() const { | ||
| 87 | return instance_version; | ||
| 88 | } | ||
| 89 | |||
| 85 | /// Returns the current Vulkan API version provided in Vulkan-formatted version numbers. | 90 | /// Returns the current Vulkan API version provided in Vulkan-formatted version numbers. |
| 86 | u32 GetApiVersion() const { | 91 | u32 ApiVersion() const { |
| 87 | return properties.apiVersion; | 92 | return properties.apiVersion; |
| 88 | } | 93 | } |
| 89 | 94 | ||
| @@ -239,6 +244,7 @@ private: | |||
| 239 | vk::Device logical; ///< Logical device. | 244 | vk::Device logical; ///< Logical device. |
| 240 | vk::Queue graphics_queue; ///< Main graphics queue. | 245 | vk::Queue graphics_queue; ///< Main graphics queue. |
| 241 | vk::Queue present_queue; ///< Main present queue. | 246 | vk::Queue present_queue; ///< Main present queue. |
| 247 | u32 instance_version{}; ///< Vulkan onstance version. | ||
| 242 | u32 graphics_family{}; ///< Main graphics queue family index. | 248 | u32 graphics_family{}; ///< Main graphics queue family index. |
| 243 | u32 present_family{}; ///< Main present queue family index. | 249 | u32 present_family{}; ///< Main present queue family index. |
| 244 | VkDriverIdKHR driver_id{}; ///< Driver ID. | 250 | VkDriverIdKHR driver_id{}; ///< Driver ID. |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index cd7d7a4e4..a20452b87 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -272,12 +272,19 @@ bool IsPrecise(Operation operand) { | |||
| 272 | return false; | 272 | return false; |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | u32 ShaderVersion(const VKDevice& device) { | ||
| 276 | if (device.InstanceApiVersion() < VK_API_VERSION_1_1) { | ||
| 277 | return 0x00010000; | ||
| 278 | } | ||
| 279 | return 0x00010300; | ||
| 280 | } | ||
| 281 | |||
| 275 | class SPIRVDecompiler final : public Sirit::Module { | 282 | class SPIRVDecompiler final : public Sirit::Module { |
| 276 | public: | 283 | public: |
| 277 | explicit SPIRVDecompiler(const VKDevice& device, const ShaderIR& ir, ShaderType stage, | 284 | explicit SPIRVDecompiler(const VKDevice& device, const ShaderIR& ir, ShaderType stage, |
| 278 | const Registry& registry, const Specialization& specialization) | 285 | const Registry& registry, const Specialization& specialization) |
| 279 | : Module(0x00010300), device{device}, ir{ir}, stage{stage}, header{ir.GetHeader()}, | 286 | : Module(ShaderVersion(device)), device{device}, ir{ir}, stage{stage}, |
| 280 | registry{registry}, specialization{specialization} { | 287 | header{ir.GetHeader()}, registry{registry}, specialization{specialization} { |
| 281 | if (stage != ShaderType::Compute) { | 288 | if (stage != ShaderType::Compute) { |
| 282 | transform_feedback = BuildTransformFeedback(registry.GetGraphicsInfo()); | 289 | transform_feedback = BuildTransformFeedback(registry.GetGraphicsInfo()); |
| 283 | } | 290 | } |
| @@ -293,6 +300,7 @@ public: | |||
| 293 | AddCapability(spv::Capability::DrawParameters); | 300 | AddCapability(spv::Capability::DrawParameters); |
| 294 | AddCapability(spv::Capability::SubgroupBallotKHR); | 301 | AddCapability(spv::Capability::SubgroupBallotKHR); |
| 295 | AddCapability(spv::Capability::SubgroupVoteKHR); | 302 | AddCapability(spv::Capability::SubgroupVoteKHR); |
| 303 | AddExtension("SPV_KHR_16bit_storage"); | ||
| 296 | AddExtension("SPV_KHR_shader_ballot"); | 304 | AddExtension("SPV_KHR_shader_ballot"); |
| 297 | AddExtension("SPV_KHR_subgroup_vote"); | 305 | AddExtension("SPV_KHR_subgroup_vote"); |
| 298 | AddExtension("SPV_KHR_storage_buffer_storage_class"); | 306 | AddExtension("SPV_KHR_storage_buffer_storage_class"); |