From fe9c49949a1329bc964ab10ff2a97abd5507ef6a Mon Sep 17 00:00:00 2001 From: Mary Date: Mon, 13 Feb 2023 23:04:55 +0100 Subject: [PATCH] vulkan: Enforce Vulkan 1.2+ at instance API level and 1.1+ at device level (#4408) * vulkan: Enforce Vulkan 1.2+ at instance API level and 1.1+ at device level This ensure we don't end up trying to initialize with anything currently incompatible. * Address riperiperi's comment --- .../VulkanInitialization.cs | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs b/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs index ab5a0acfb7..b8b48f6ca0 100644 --- a/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs +++ b/Ryujinx.Graphics.Vulkan/VulkanInitialization.cs @@ -14,6 +14,9 @@ namespace Ryujinx.Graphics.Vulkan public unsafe static class VulkanInitialization { private const uint InvalidIndex = uint.MaxValue; + private static uint MinimalVulkanVersion = Vk.Version11.Value; + private static uint MinimalInstanceVulkanVersion = Vk.Version12.Value; + private static uint MaximumVulkanVersion = Vk.Version12.Value; private const string AppName = "Ryujinx.Graphics.Vulkan"; private const int QueuesCount = 2; @@ -99,7 +102,7 @@ namespace Ryujinx.Graphics.Vulkan ApplicationVersion = 1, PEngineName = (byte*)appName, EngineVersion = 1, - ApiVersion = Vk.Version12.Value + ApiVersion = MaximumVulkanVersion }; IntPtr* ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length]; @@ -224,7 +227,7 @@ namespace Ryujinx.Graphics.Vulkan ApplicationVersion = 1, PEngineName = (byte*)appName, EngineVersion = 1, - ApiVersion = Vk.Version12.Value + ApiVersion = MaximumVulkanVersion }; var instanceCreateInfo = new InstanceCreateInfo @@ -239,6 +242,27 @@ namespace Ryujinx.Graphics.Vulkan api.CreateInstance(in instanceCreateInfo, null, out var instance).ThrowOnError(); + // We ensure that vkEnumerateInstanceVersion is present (added in 1.1). + // If the instance doesn't support it, no device is going to be 1.1 compatible. + if (api.GetInstanceProcAddr(instance, "vkEnumerateInstanceVersion") == IntPtr.Zero) + { + api.DestroyInstance(instance, null); + + return Array.Empty(); + } + + // We currently assume that the instance is compatible with Vulkan 1.2 + // TODO: Remove this once we relax our initialization codepaths. + uint instanceApiVerison = 0; + api.EnumerateInstanceVersion(ref instanceApiVerison).ThrowOnError(); + + if (instanceApiVerison < MinimalInstanceVulkanVersion) + { + api.DestroyInstance(instance, null); + + return Array.Empty(); + } + Marshal.FreeHGlobal(appName); uint physicalDeviceCount; @@ -259,6 +283,11 @@ namespace Ryujinx.Graphics.Vulkan var physicalDevice = physicalDevices[i]; api.GetPhysicalDeviceProperties(physicalDevice, out var properties); + if (properties.ApiVersion < MinimalVulkanVersion) + { + continue; + } + devices[i] = new DeviceInfo( StringFromIdPair(properties.VendorID, properties.DeviceID), VendorUtils.GetNameFromId(properties.VendorID),