/ src / Ryujinx.Graphics.Vulkan / VulkanPhysicalDevice.cs
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  }