summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-12-30 04:58:38 -0300
committerGravatar ReinUsesLisp2020-12-31 02:07:34 -0300
commitcdbee27692d73046cecf56fdea1c90f72ebbc0ce (patch)
treee360cc51563b7bee53e67587a421a1d15be3221e
parentvk_device: Use an array to report lacking device limits (diff)
downloadyuzu-cdbee27692d73046cecf56fdea1c90f72ebbc0ce.tar.gz
yuzu-cdbee27692d73046cecf56fdea1c90f72ebbc0ce.tar.xz
yuzu-cdbee27692d73046cecf56fdea1c90f72ebbc0ce.zip
vulkan_instance: Allow different Vulkan versions and enforce 1.1
For listing the available physical devices we can use Vulkan 1.0. Now that MoltenVK supports 1.1 we can require it for running games. Add missing documentation.
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp9
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.h1
-rw-r--r--src/video_core/renderer_vulkan/vk_device.cpp10
-rw-r--r--src/video_core/renderer_vulkan/vk_device.h9
-rw-r--r--src/video_core/renderer_vulkan/vk_shader_decompiler.cpp11
-rw-r--r--src/video_core/vulkan_common/vulkan_instance.cpp21
-rw-r--r--src/video_core/vulkan_common/vulkan_instance.h19
7 files changed, 39 insertions, 41 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index fdce11b06..5b35cb407 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -127,8 +127,8 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
127 127
128bool RendererVulkan::Init() try { 128bool RendererVulkan::Init() try {
129 library = OpenLibrary(); 129 library = OpenLibrary();
130 std::tie(instance, instance_version) = CreateInstance( 130 instance = CreateInstance(library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type,
131 library, dld, render_window.GetWindowInfo().type, true, Settings::values.renderer_debug); 131 true, Settings::values.renderer_debug);
132 if (Settings::values.renderer_debug) { 132 if (Settings::values.renderer_debug) {
133 debug_callback = CreateDebugCallback(instance); 133 debug_callback = CreateDebugCallback(instance);
134 } 134 }
@@ -184,8 +184,7 @@ void RendererVulkan::InitializeDevice() {
184 throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); 184 throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
185 } 185 }
186 const vk::PhysicalDevice physical_device(devices[static_cast<size_t>(device_index)], dld); 186 const vk::PhysicalDevice physical_device(devices[static_cast<size_t>(device_index)], dld);
187 device = 187 device = std::make_unique<VKDevice>(*instance, physical_device, *surface, dld);
188 std::make_unique<VKDevice>(*instance, instance_version, physical_device, *surface, dld);
189} 188}
190 189
191void RendererVulkan::Report() const { 190void RendererVulkan::Report() const {
@@ -213,7 +212,7 @@ void RendererVulkan::Report() const {
213std::vector<std::string> RendererVulkan::EnumerateDevices() try { 212std::vector<std::string> RendererVulkan::EnumerateDevices() try {
214 vk::InstanceDispatch dld; 213 vk::InstanceDispatch dld;
215 const Common::DynamicLibrary library = OpenLibrary(); 214 const Common::DynamicLibrary library = OpenLibrary();
216 const vk::Instance instance = CreateInstance(library, dld).first; 215 const vk::Instance instance = CreateInstance(library, dld, VK_API_VERSION_1_0);
217 const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices(); 216 const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices();
218 std::vector<std::string> names; 217 std::vector<std::string> names;
219 names.reserve(physical_devices.size()); 218 names.reserve(physical_devices.size());
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h
index a05b3bd38..f22f50709 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.h
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.h
@@ -68,7 +68,6 @@ private:
68 vk::InstanceDispatch dld; 68 vk::InstanceDispatch dld;
69 69
70 vk::Instance instance; 70 vk::Instance instance;
71 u32 instance_version{};
72 71
73 vk::SurfaceKHR surface; 72 vk::SurfaceKHR surface;
74 73
diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp
index 024d5c2de..fd55ca8a8 100644
--- a/src/video_core/renderer_vulkan/vk_device.cpp
+++ b/src/video_core/renderer_vulkan/vk_device.cpp
@@ -206,10 +206,10 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(
206 206
207} // Anonymous namespace 207} // Anonymous namespace
208 208
209VKDevice::VKDevice(VkInstance instance_, u32 instance_version_, vk::PhysicalDevice physical_, 209VKDevice::VKDevice(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR surface,
210 VkSurfaceKHR surface, const vk::InstanceDispatch& dld_) 210 const vk::InstanceDispatch& dld_)
211 : instance{instance_}, dld{dld_}, physical{physical_}, properties{physical.GetProperties()}, 211 : instance{instance_}, dld{dld_}, physical{physical_}, properties{physical.GetProperties()},
212 instance_version{instance_version_}, format_properties{GetFormatProperties(physical, dld)} { 212 format_properties{GetFormatProperties(physical, dld)} {
213 CheckSuitability(); 213 CheckSuitability();
214 SetupFamilies(surface); 214 SetupFamilies(surface);
215 SetupFeatures(); 215 SetupFeatures();
@@ -653,9 +653,7 @@ std::vector<const char*> VKDevice::LoadExtensions() {
653 test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false); 653 test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false);
654 test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false); 654 test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false);
655 test(has_ext_robustness2, VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, false); 655 test(has_ext_robustness2, VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, false);
656 if (instance_version >= VK_API_VERSION_1_1) { 656 test(has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, false);
657 test(has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, false);
658 }
659 if (Settings::values.renderer_debug) { 657 if (Settings::values.renderer_debug) {
660 test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, 658 test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME,
661 true); 659 true);
diff --git a/src/video_core/renderer_vulkan/vk_device.h b/src/video_core/renderer_vulkan/vk_device.h
index 63e123d02..146acbe24 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.
25class VKDevice final { 25class VKDevice final {
26public: 26public:
27 explicit VKDevice(VkInstance instance, u32 instance_version, vk::PhysicalDevice physical, 27 explicit VKDevice(VkInstance instance, vk::PhysicalDevice physical, VkSurfaceKHR surface,
28 VkSurfaceKHR surface, const vk::InstanceDispatch& dld); 28 const vk::InstanceDispatch& dld);
29 ~VKDevice(); 29 ~VKDevice();
30 30
31 /** 31 /**
@@ -79,11 +79,6 @@ public:
79 return present_family; 79 return present_family;
80 } 80 }
81 81
82 /// Returns the current instance Vulkan API version in Vulkan-formatted version numbers.
83 u32 InstanceApiVersion() const {
84 return instance_version;
85 }
86
87 /// Returns the current Vulkan API version provided in Vulkan-formatted version numbers. 82 /// Returns the current Vulkan API version provided in Vulkan-formatted version numbers.
88 u32 ApiVersion() const { 83 u32 ApiVersion() const {
89 return properties.apiVersion; 84 return properties.apiVersion;
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
index 09d6f9f35..571460c2f 100644
--- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
+++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp
@@ -272,19 +272,12 @@ bool IsPrecise(Operation operand) {
272 return false; 272 return false;
273} 273}
274 274
275u32 ShaderVersion(const VKDevice& device) {
276 if (device.InstanceApiVersion() < VK_API_VERSION_1_1) {
277 return 0x00010000;
278 }
279 return 0x00010300;
280}
281
282class SPIRVDecompiler final : public Sirit::Module { 275class SPIRVDecompiler final : public Sirit::Module {
283public: 276public:
284 explicit SPIRVDecompiler(const VKDevice& device_, const ShaderIR& ir_, ShaderType stage_, 277 explicit SPIRVDecompiler(const VKDevice& device_, const ShaderIR& ir_, ShaderType stage_,
285 const Registry& registry_, const Specialization& specialization_) 278 const Registry& registry_, const Specialization& specialization_)
286 : Module(ShaderVersion(device_)), device{device_}, ir{ir_}, stage{stage_}, 279 : Module(0x00010300), device{device_}, ir{ir_}, stage{stage_}, header{ir_.GetHeader()},
287 header{ir_.GetHeader()}, registry{registry_}, specialization{specialization_} { 280 registry{registry_}, specialization{specialization_} {
288 if (stage_ != ShaderType::Compute) { 281 if (stage_ != ShaderType::Compute) {
289 transform_feedback = BuildTransformFeedback(registry_.GetGraphicsInfo()); 282 transform_feedback = BuildTransformFeedback(registry_.GetGraphicsInfo());
290 } 283 }
diff --git a/src/video_core/vulkan_common/vulkan_instance.cpp b/src/video_core/vulkan_common/vulkan_instance.cpp
index ee46fc6cc..889ecda0c 100644
--- a/src/video_core/vulkan_common/vulkan_instance.cpp
+++ b/src/video_core/vulkan_common/vulkan_instance.cpp
@@ -111,10 +111,9 @@ void RemoveUnavailableLayers(const vk::InstanceDispatch& dld, std::vector<const
111} 111}
112} // Anonymous namespace 112} // Anonymous namespace
113 113
114std::pair<vk::Instance, u32> CreateInstance(const Common::DynamicLibrary& library, 114vk::Instance CreateInstance(const Common::DynamicLibrary& library, vk::InstanceDispatch& dld,
115 vk::InstanceDispatch& dld, 115 u32 required_version, Core::Frontend::WindowSystemType window_type,
116 Core::Frontend::WindowSystemType window_type, 116 bool enable_debug_utils, bool enable_layers) {
117 bool enable_debug_utils, bool enable_layers) {
118 if (!library.IsOpen()) { 117 if (!library.IsOpen()) {
119 LOG_ERROR(Render_Vulkan, "Vulkan library not available"); 118 LOG_ERROR(Render_Vulkan, "Vulkan library not available");
120 throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); 119 throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
@@ -134,15 +133,19 @@ std::pair<vk::Instance, u32> CreateInstance(const Common::DynamicLibrary& librar
134 std::vector<const char*> layers = Layers(enable_layers); 133 std::vector<const char*> layers = Layers(enable_layers);
135 RemoveUnavailableLayers(dld, layers); 134 RemoveUnavailableLayers(dld, layers);
136 135
137 // Limit the maximum version of Vulkan to avoid using untested version. 136 const u32 available_version = vk::AvailableVersion(dld);
138 const u32 version = std::min(vk::AvailableVersion(dld), VK_API_VERSION_1_1); 137 if (available_version < required_version) {
139 138 LOG_ERROR(Render_Vulkan, "Vulkan {}.{} is not supported, {}.{} is required",
140 vk::Instance instance = vk::Instance::Create(version, layers, extensions, dld); 139 VK_VERSION_MAJOR(available_version), VK_VERSION_MINOR(available_version),
140 VK_VERSION_MAJOR(required_version), VK_VERSION_MINOR(required_version));
141 throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER);
142 }
143 vk::Instance instance = vk::Instance::Create(required_version, layers, extensions, dld);
141 if (!vk::Load(*instance, dld)) { 144 if (!vk::Load(*instance, dld)) {
142 LOG_ERROR(Render_Vulkan, "Failed to load Vulkan instance function pointers"); 145 LOG_ERROR(Render_Vulkan, "Failed to load Vulkan instance function pointers");
143 throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); 146 throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
144 } 147 }
145 return std::make_pair(std::move(instance), version); 148 return instance;
146} 149}
147 150
148} // namespace Vulkan 151} // namespace Vulkan
diff --git a/src/video_core/vulkan_common/vulkan_instance.h b/src/video_core/vulkan_common/vulkan_instance.h
index 5acca9756..e5e3a7144 100644
--- a/src/video_core/vulkan_common/vulkan_instance.h
+++ b/src/video_core/vulkan_common/vulkan_instance.h
@@ -4,8 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <utility>
8
9#include "common/common_types.h" 7#include "common/common_types.h"
10#include "common/dynamic_library.h" 8#include "common/dynamic_library.h"
11#include "core/frontend/emu_window.h" 9#include "core/frontend/emu_window.h"
@@ -13,8 +11,21 @@
13 11
14namespace Vulkan { 12namespace Vulkan {
15 13
16[[nodiscard]] std::pair<vk::Instance, u32> CreateInstance( 14/**
17 const Common::DynamicLibrary& library, vk::InstanceDispatch& dld, 15 * Create a Vulkan instance
16 *
17 * @param library Dynamic library to load the Vulkan instance from
18 * @param dld Dispatch table to load function pointers into
19 * @param required_version Required Vulkan version (for example, VK_API_VERSION_1_1)
20 * @param window_type Window system type's enabled extension
21 * @param enable_debug_utils Whether to enable VK_EXT_debug_utils_extension_name or not
22 * @param enable_layers Whether to enable Vulkan validation layers or not
23 *
24 * @return A new Vulkan instance
25 * @throw vk::Exception on failure
26 */
27[[nodiscard]] vk::Instance CreateInstance(
28 const Common::DynamicLibrary& library, vk::InstanceDispatch& dld, u32 required_version,
18 Core::Frontend::WindowSystemType window_type = Core::Frontend::WindowSystemType::Headless, 29 Core::Frontend::WindowSystemType window_type = Core::Frontend::WindowSystemType::Headless,
19 bool enable_debug_utils = false, bool enable_layers = false); 30 bool enable_debug_utils = false, bool enable_layers = false);
20 31