1 module sbylib.wrapper.vulkan.physicaldevice;
2 
3 import std;
4 import erupted;
5 import sbylib.wrapper.vulkan.enums;
6 import sbylib.wrapper.vulkan.formatproperties;
7 import sbylib.wrapper.vulkan.memoryproperties;
8 import sbylib.wrapper.vulkan.queuefamilyproperties;
9 import sbylib.wrapper.vulkan.surface;
10 import sbylib.wrapper.vulkan.surfacecapabilities;
11 import sbylib.wrapper.vulkan.util;
12 
13 class PhysicalDevice {
14 
15     package VkPhysicalDevice physDevice;
16 
17     this(VkPhysicalDevice physDevice) {
18         this.physDevice = physDevice;
19     }
20 
21     QueueFamilyProperties[] getQueueFamilyProperties() {
22         import std.exception : enforce;
23 
24         uint numQueues;
25         vkGetPhysicalDeviceQueueFamilyProperties(physDevice, &numQueues, null);
26         enforce(numQueues >= 1, "No queue was found");
27 
28         auto queueFamilyProperties = new VkQueueFamilyProperties[](numQueues);
29         vkGetPhysicalDeviceQueueFamilyProperties(physDevice, &numQueues,
30                 queueFamilyProperties.ptr);
31         assert(numQueues == queueFamilyProperties.length);
32 
33         return queueFamilyProperties.map!(p => QueueFamilyProperties(p)).array;
34     }
35 
36     bool getSurfaceSupport(ref Surface surface) {
37         VkBool32 surfaceSupport;
38         enforceVK(vkGetPhysicalDeviceSurfaceSupportKHR(physDevice, 0,
39                 surface.surface, &surfaceSupport));
40         return surfaceSupport == VK_TRUE;
41     }
42 
43     SurfaceCapabilities getSurfaceCapabilities(ref Surface surface) {
44         VkSurfaceCapabilitiesKHR surfaceCapabilities;
45         vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physDevice, surface.surface,
46                 &surfaceCapabilities);
47         return SurfaceCapabilities(surfaceCapabilities);
48     }
49 
50     VkSurfaceFormatKHR[] getSurfaceFormats(ref Surface surface) {
51         uint numSurfaceFormats;
52         vkGetPhysicalDeviceSurfaceFormatsKHR(physDevice, surface.surface,
53                 &numSurfaceFormats, null);
54 
55         auto surfaceFormats = new VkSurfaceFormatKHR[numSurfaceFormats];
56         vkGetPhysicalDeviceSurfaceFormatsKHR(physDevice, surface.surface,
57                 &numSurfaceFormats, surfaceFormats.ptr);
58 
59         return surfaceFormats;
60     }
61 
62     PresentMode[] getSurfacePresentModes(ref Surface surface) {
63         uint numPresentMode;
64         vkGetPhysicalDeviceSurfacePresentModesKHR(physDevice, surface.surface,
65                 &numPresentMode, null);
66 
67         auto presentModes = new VkPresentModeKHR[numPresentMode];
68         vkGetPhysicalDeviceSurfacePresentModesKHR(physDevice, surface.surface,
69                 &numPresentMode, presentModes.ptr);
70 
71         return presentModes
72             .map!(pm => cast(uint)pm)
73             .map!(to!PresentMode)
74             .array;
75     }
76 
77     MemoryProperties getMemoryProperties() {
78         VkPhysicalDeviceMemoryProperties memProps;
79         vkGetPhysicalDeviceMemoryProperties(physDevice, &memProps);
80         return MemoryProperties(memProps);
81     }
82 
83     FeatureType getFeature2(FeatureType)() {
84         FeatureType t;
85         VkPhysicalDeviceFeatures2 result;
86         result.pNext = &t;
87         vkGetPhysicalDeviceFeatures2KHR(physDevice, &result);
88         return t;
89     }
90 
91     FormatProperties getFormatProperties(VkFormat format) {
92         VkFormatProperties props;
93         vkGetPhysicalDeviceFormatProperties(physDevice, format, &props);
94         return FormatProperties(props);
95     }
96 }
97 
98 uint findQueueFamilyIndex(alias pred)(PhysicalDevice dev) {
99     import std : countUntil, enforce;
100 
101     const queueFamilyProperties = dev.getQueueFamilyProperties();
102     auto queueFamilyIndex = queueFamilyProperties.countUntil!(pred);
103     enforce(queueFamilyIndex != -1, "There are no queue family with Graphics support.");
104 
105     return cast(uint)queueFamilyIndex;
106 }