Explorar el Código

vk_device: Use Vulkan 1.0 properly

Enable the required capabilities to use Vulkan 1.0 without validation
errors and disable those that are not compatible with it.
ReinUsesLisp hace 6 años
padre
commit
c5a78f4480

+ 10 - 9
src/video_core/renderer_vulkan/renderer_vulkan.cpp

@@ -92,9 +92,9 @@ Common::DynamicLibrary OpenVulkanLibrary() {
     return library;
 }
 
-vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatch& dld,
-                            WindowSystemType window_type = WindowSystemType::Headless,
-                            bool enable_layers = false) {
+std::pair<vk::Instance, u32> CreateInstance(
+    Common::DynamicLibrary& library, vk::InstanceDispatch& dld,
+    WindowSystemType window_type = WindowSystemType::Headless, bool enable_layers = false) {
     if (!library.IsOpen()) {
         LOG_ERROR(Render_Vulkan, "Vulkan library not available");
         return {};
@@ -191,7 +191,7 @@ vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatc
     if (!vk::Load(*instance, dld)) {
         LOG_ERROR(Render_Vulkan, "Failed to load Vulkan instance function pointers");
     }
-    return instance;
+    return std::make_pair(std::move(instance), version);
 }
 
 std::string GetReadableVersion(u32 version) {
@@ -289,8 +289,8 @@ bool RendererVulkan::TryPresent(int /*timeout_ms*/) {
 
 bool RendererVulkan::Init() {
     library = OpenVulkanLibrary();
-    instance = CreateInstance(library, dld, render_window.GetWindowInfo().type,
-                              Settings::values.renderer_debug);
+    std::tie(instance, instance_version) = CreateInstance(
+        library, dld, render_window.GetWindowInfo().type, Settings::values.renderer_debug);
     if (!instance || !CreateDebugCallback() || !CreateSurface() || !PickDevices()) {
         return false;
     }
@@ -423,7 +423,8 @@ bool RendererVulkan::PickDevices() {
         return false;
     }
 
-    device = std::make_unique<VKDevice>(*instance, physical_device, *surface, dld);
+    device =
+        std::make_unique<VKDevice>(*instance, instance_version, physical_device, *surface, dld);
     return device->Create();
 }
 
@@ -433,7 +434,7 @@ void RendererVulkan::Report() const {
     const std::string driver_version = GetDriverVersion(*device);
     const std::string driver_name = fmt::format("{} {}", vendor_name, driver_version);
 
-    const std::string api_version = GetReadableVersion(device->GetApiVersion());
+    const std::string api_version = GetReadableVersion(device->ApiVersion());
 
     const std::string extensions = BuildCommaSeparatedExtensions(device->GetAvailableExtensions());
 
@@ -453,7 +454,7 @@ void RendererVulkan::Report() const {
 std::vector<std::string> RendererVulkan::EnumerateDevices() {
     vk::InstanceDispatch dld;
     Common::DynamicLibrary library = OpenVulkanLibrary();
-    vk::Instance instance = CreateInstance(library, dld);
+    vk::Instance instance = CreateInstance(library, dld).first;
     if (!instance) {
         return {};
     }

+ 2 - 0
src/video_core/renderer_vulkan/renderer_vulkan.h

@@ -63,6 +63,8 @@ private:
     vk::InstanceDispatch dld;
 
     vk::Instance instance;
+    u32 instance_version{};
+
     vk::SurfaceKHR surface;
 
     VKScreenInfo screen_info;

+ 35 - 38
src/video_core/renderer_vulkan/vk_device.cpp

@@ -38,6 +38,9 @@ constexpr std::array Depth16UnormS8_UINT{
 
 constexpr std::array REQUIRED_EXTENSIONS{
     VK_KHR_SWAPCHAIN_EXTENSION_NAME,
+    VK_KHR_MAINTENANCE1_EXTENSION_NAME,
+    VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME,
+    VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME,
     VK_KHR_16BIT_STORAGE_EXTENSION_NAME,
     VK_KHR_8BIT_STORAGE_EXTENSION_NAME,
     VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME,
@@ -171,10 +174,10 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(
 
 } // Anonymous namespace
 
-VKDevice::VKDevice(VkInstance instance, vk::PhysicalDevice physical, VkSurfaceKHR surface,
-                   const vk::InstanceDispatch& dld)
-    : dld{dld}, physical{physical}, properties{physical.GetProperties()},
-      format_properties{GetFormatProperties(physical, dld)} {
+VKDevice::VKDevice(VkInstance instance_, u32 instance_version_, vk::PhysicalDevice physical_,
+                   VkSurfaceKHR surface, const vk::InstanceDispatch& dld_)
+    : dld{dld_}, physical{physical_}, properties{physical.GetProperties()},
+      instance_version{instance_version_}, format_properties{GetFormatProperties(physical, dld)} {
     SetupFamilies(surface);
     SetupFeatures();
 }
@@ -565,20 +568,6 @@ bool VKDevice::IsSuitable(vk::PhysicalDevice physical, VkSurfaceKHR surface) {
 
 std::vector<const char*> VKDevice::LoadExtensions() {
     std::vector<const char*> extensions;
-    const auto Test = [&](const VkExtensionProperties& extension,
-                          std::optional<std::reference_wrapper<bool>> status, const char* name,
-                          bool push) {
-        if (extension.extensionName != std::string_view(name)) {
-            return;
-        }
-        if (push) {
-            extensions.push_back(name);
-        }
-        if (status) {
-            status->get() = true;
-        }
-    };
-
     extensions.reserve(7 + REQUIRED_EXTENSIONS.size());
     extensions.insert(extensions.begin(), REQUIRED_EXTENSIONS.begin(), REQUIRED_EXTENSIONS.end());
 
@@ -587,28 +576,36 @@ std::vector<const char*> VKDevice::LoadExtensions() {
     bool has_ext_transform_feedback{};
     bool has_ext_custom_border_color{};
     bool has_ext_extended_dynamic_state{};
-    for (const auto& extension : physical.EnumerateDeviceExtensionProperties()) {
-        Test(extension, nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true);
-        Test(extension, khr_uniform_buffer_standard_layout,
+    for (const VkExtensionProperties& extension : physical.EnumerateDeviceExtensionProperties()) {
+        const auto test = [&](std::optional<std::reference_wrapper<bool>> status, const char* name,
+                              bool push) {
+            if (extension.extensionName != std::string_view(name)) {
+                return;
+            }
+            if (push) {
+                extensions.push_back(name);
+            }
+            if (status) {
+                status->get() = true;
+            }
+        };
+        test(nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true);
+        test(khr_uniform_buffer_standard_layout,
              VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true);
-        Test(extension, has_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, has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME,
-             false);
-        Test(extension, has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME,
-             false);
-        Test(extension, has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME,
-             false);
-        Test(extension, has_ext_extended_dynamic_state,
-             VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false);
+        test(has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false);
+        test(ext_depth_range_unrestricted, VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true);
+        test(ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true);
+        test(ext_shader_viewport_index_layer, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME,
+             true);
+        test(has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, false);
+        test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false);
+        test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false);
+        if (instance_version >= VK_API_VERSION_1_1) {
+            test(has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, false);
+        }
         if (Settings::values.renderer_debug) {
-            Test(extension, nv_device_diagnostics_config,
-                 VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, true);
+            test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME,
+                 true);
         }
     }
 

+ 9 - 3
src/video_core/renderer_vulkan/vk_device.h

@@ -24,8 +24,8 @@ const u32 GuestWarpSize = 32;
 /// Handles data specific to a physical device.
 class VKDevice final {
 public:
-    explicit VKDevice(VkInstance instance, vk::PhysicalDevice physical, VkSurfaceKHR surface,
-                      const vk::InstanceDispatch& dld);
+    explicit VKDevice(VkInstance instance, u32 instance_version, vk::PhysicalDevice physical,
+                      VkSurfaceKHR surface, const vk::InstanceDispatch& dld);
     ~VKDevice();
 
     /// Initializes the device. Returns true on success.
@@ -82,8 +82,13 @@ public:
         return present_family;
     }
 
+    /// Returns the current instance Vulkan API version in Vulkan-formatted version numbers.
+    u32 InstanceApiVersion() const {
+        return instance_version;
+    }
+
     /// Returns the current Vulkan API version provided in Vulkan-formatted version numbers.
-    u32 GetApiVersion() const {
+    u32 ApiVersion() const {
         return properties.apiVersion;
     }
 
@@ -239,6 +244,7 @@ private:
     vk::Device logical;                     ///< Logical device.
     vk::Queue graphics_queue;               ///< Main graphics queue.
     vk::Queue present_queue;                ///< Main present queue.
+    u32 instance_version{};                 ///< Vulkan onstance version.
     u32 graphics_family{};                  ///< Main graphics queue family index.
     u32 present_family{};                   ///< Main present queue family index.
     VkDriverIdKHR driver_id{};              ///< Driver ID.

+ 10 - 2
src/video_core/renderer_vulkan/vk_shader_decompiler.cpp

@@ -272,12 +272,19 @@ bool IsPrecise(Operation operand) {
     return false;
 }
 
+u32 ShaderVersion(const VKDevice& device) {
+    if (device.InstanceApiVersion() < VK_API_VERSION_1_1) {
+        return 0x00010000;
+    }
+    return 0x00010300;
+}
+
 class SPIRVDecompiler final : public Sirit::Module {
 public:
     explicit SPIRVDecompiler(const VKDevice& device, const ShaderIR& ir, ShaderType stage,
                              const Registry& registry, const Specialization& specialization)
-        : Module(0x00010300), device{device}, ir{ir}, stage{stage}, header{ir.GetHeader()},
-          registry{registry}, specialization{specialization} {
+        : Module(ShaderVersion(device)), device{device}, ir{ir}, stage{stage},
+          header{ir.GetHeader()}, registry{registry}, specialization{specialization} {
         if (stage != ShaderType::Compute) {
             transform_feedback = BuildTransformFeedback(registry.GetGraphicsInfo());
         }
@@ -293,6 +300,7 @@ public:
         AddCapability(spv::Capability::DrawParameters);
         AddCapability(spv::Capability::SubgroupBallotKHR);
         AddCapability(spv::Capability::SubgroupVoteKHR);
+        AddExtension("SPV_KHR_16bit_storage");
         AddExtension("SPV_KHR_shader_ballot");
         AddExtension("SPV_KHR_subgroup_vote");
         AddExtension("SPV_KHR_storage_buffer_storage_class");