VulkanPhysicalDevice.cs
1 using Ryujinx.Common.Utilities; 2 using Ryujinx.Graphics.GAL; 3 using Silk.NET.Vulkan; 4 using System; 5 using System.Collections.Generic; 6 using System.Collections.Immutable; 7 using System.Linq; 8 using System.Runtime.InteropServices; 9 10 namespace Ryujinx.Graphics.Vulkan 11 { 12 readonly struct VulkanPhysicalDevice 13 { 14 public readonly PhysicalDevice PhysicalDevice; 15 public readonly PhysicalDeviceFeatures PhysicalDeviceFeatures; 16 public readonly PhysicalDeviceProperties PhysicalDeviceProperties; 17 public readonly PhysicalDeviceMemoryProperties PhysicalDeviceMemoryProperties; 18 public readonly QueueFamilyProperties[] QueueFamilyProperties; 19 public readonly string DeviceName; 20 public readonly IReadOnlySet<string> DeviceExtensions; 21 22 public VulkanPhysicalDevice(Vk api, PhysicalDevice physicalDevice) 23 { 24 PhysicalDevice = physicalDevice; 25 PhysicalDeviceFeatures = api.GetPhysicalDeviceFeature(PhysicalDevice); 26 27 api.GetPhysicalDeviceProperties(PhysicalDevice, out var physicalDeviceProperties); 28 PhysicalDeviceProperties = physicalDeviceProperties; 29 30 api.GetPhysicalDeviceMemoryProperties(PhysicalDevice, out PhysicalDeviceMemoryProperties); 31 32 unsafe 33 { 34 DeviceName = Marshal.PtrToStringAnsi((IntPtr)physicalDeviceProperties.DeviceName); 35 } 36 37 uint propertiesCount = 0; 38 39 api.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, SpanHelpers.AsSpan(ref propertiesCount), Span<QueueFamilyProperties>.Empty); 40 41 QueueFamilyProperties = new QueueFamilyProperties[propertiesCount]; 42 43 api.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, SpanHelpers.AsSpan(ref propertiesCount), QueueFamilyProperties); 44 45 api.EnumerateDeviceExtensionProperties(PhysicalDevice, Span<byte>.Empty, SpanHelpers.AsSpan(ref propertiesCount), Span<ExtensionProperties>.Empty).ThrowOnError(); 46 47 ExtensionProperties[] extensionProperties = new ExtensionProperties[propertiesCount]; 48 49 api.EnumerateDeviceExtensionProperties(PhysicalDevice, Span<byte>.Empty, SpanHelpers.AsSpan(ref propertiesCount), extensionProperties).ThrowOnError(); 50 51 unsafe 52 { 53 DeviceExtensions = extensionProperties.Select(x => Marshal.PtrToStringAnsi((IntPtr)x.ExtensionName)).ToImmutableHashSet(); 54 } 55 } 56 57 public string Id => $"0x{PhysicalDeviceProperties.VendorID:X}_0x{PhysicalDeviceProperties.DeviceID:X}"; 58 59 public bool IsDeviceExtensionPresent(string extension) => DeviceExtensions.Contains(extension); 60 61 public unsafe bool TryGetPhysicalDeviceDriverPropertiesKHR(Vk api, out PhysicalDeviceDriverPropertiesKHR res) 62 { 63 if (!IsDeviceExtensionPresent("VK_KHR_driver_properties")) 64 { 65 res = default; 66 67 return false; 68 } 69 70 PhysicalDeviceDriverPropertiesKHR physicalDeviceDriverProperties = new() 71 { 72 SType = StructureType.PhysicalDeviceDriverPropertiesKhr 73 }; 74 75 PhysicalDeviceProperties2 physicalDeviceProperties2 = new() 76 { 77 SType = StructureType.PhysicalDeviceProperties2, 78 PNext = &physicalDeviceDriverProperties 79 }; 80 81 api.GetPhysicalDeviceProperties2(PhysicalDevice, &physicalDeviceProperties2); 82 83 res = physicalDeviceDriverProperties; 84 85 return true; 86 } 87 88 public DeviceInfo ToDeviceInfo() 89 { 90 return new DeviceInfo( 91 Id, 92 VendorUtils.GetNameFromId(PhysicalDeviceProperties.VendorID), 93 DeviceName, 94 PhysicalDeviceProperties.DeviceType == PhysicalDeviceType.DiscreteGpu); 95 } 96 } 97 }