VulkanPhysicalDevice.cs 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. namespace Ryujinx.Graphics.Vulkan
  10. {
  11. readonly struct VulkanPhysicalDevice
  12. {
  13. public readonly PhysicalDevice PhysicalDevice;
  14. public readonly PhysicalDeviceFeatures PhysicalDeviceFeatures;
  15. public readonly PhysicalDeviceProperties PhysicalDeviceProperties;
  16. public readonly PhysicalDeviceMemoryProperties PhysicalDeviceMemoryProperties;
  17. public readonly QueueFamilyProperties[] QueueFamilyProperties;
  18. public readonly string DeviceName;
  19. public readonly IReadOnlySet<string> DeviceExtensions;
  20. public VulkanPhysicalDevice(Vk api, PhysicalDevice physicalDevice)
  21. {
  22. PhysicalDevice = physicalDevice;
  23. PhysicalDeviceFeatures = api.GetPhysicalDeviceFeature(PhysicalDevice);
  24. api.GetPhysicalDeviceProperties(PhysicalDevice, out var physicalDeviceProperties);
  25. PhysicalDeviceProperties = physicalDeviceProperties;
  26. api.GetPhysicalDeviceMemoryProperties(PhysicalDevice, out PhysicalDeviceMemoryProperties);
  27. unsafe
  28. {
  29. DeviceName = Marshal.PtrToStringAnsi((IntPtr)physicalDeviceProperties.DeviceName);
  30. }
  31. uint propertiesCount = 0;
  32. api.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, SpanHelpers.AsSpan(ref propertiesCount), Span<QueueFamilyProperties>.Empty);
  33. QueueFamilyProperties = new QueueFamilyProperties[propertiesCount];
  34. api.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, SpanHelpers.AsSpan(ref propertiesCount), QueueFamilyProperties);
  35. api.EnumerateDeviceExtensionProperties(PhysicalDevice, Span<byte>.Empty, SpanHelpers.AsSpan(ref propertiesCount), Span<ExtensionProperties>.Empty).ThrowOnError();
  36. ExtensionProperties[] extensionProperties = new ExtensionProperties[propertiesCount];
  37. api.EnumerateDeviceExtensionProperties(PhysicalDevice, Span<byte>.Empty, SpanHelpers.AsSpan(ref propertiesCount), extensionProperties).ThrowOnError();
  38. unsafe
  39. {
  40. DeviceExtensions = extensionProperties.Select(x => Marshal.PtrToStringAnsi((IntPtr)x.ExtensionName)).ToImmutableHashSet();
  41. }
  42. }
  43. public string Id => $"0x{PhysicalDeviceProperties.VendorID:X}_0x{PhysicalDeviceProperties.DeviceID:X}";
  44. public bool IsDeviceExtensionPresent(string extension) => DeviceExtensions.Contains(extension);
  45. public unsafe bool TryGetPhysicalDeviceDriverPropertiesKHR(Vk api, out PhysicalDeviceDriverPropertiesKHR res)
  46. {
  47. if (!IsDeviceExtensionPresent("VK_KHR_driver_properties"))
  48. {
  49. res = default;
  50. return false;
  51. }
  52. PhysicalDeviceDriverPropertiesKHR physicalDeviceDriverProperties = new()
  53. {
  54. SType = StructureType.PhysicalDeviceDriverPropertiesKhr
  55. };
  56. PhysicalDeviceProperties2 physicalDeviceProperties2 = new()
  57. {
  58. SType = StructureType.PhysicalDeviceProperties2,
  59. PNext = &physicalDeviceDriverProperties
  60. };
  61. api.GetPhysicalDeviceProperties2(PhysicalDevice, &physicalDeviceProperties2);
  62. res = physicalDeviceDriverProperties;
  63. return true;
  64. }
  65. public DeviceInfo ToDeviceInfo()
  66. {
  67. return new DeviceInfo(
  68. Id,
  69. VendorUtils.GetNameFromId(PhysicalDeviceProperties.VendorID),
  70. DeviceName,
  71. PhysicalDeviceProperties.DeviceType == PhysicalDeviceType.DiscreteGpu);
  72. }
  73. }
  74. }