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