1 module sbylib.wrapper.vulkan.instance;
2 
3 import std;
4 import erupted;
5 import sbylib.wrapper.vulkan.physicaldevice;
6 import sbylib.wrapper.vulkan.util;
7 
8 class Instance {
9     static struct ApplicationInfo {
10         @vkProp() immutable {
11             uint applicationVersion;
12             uint engineVersion;
13             uint apiVersion;
14         }
15 
16         @vkProp("pApplicationName") {
17             string applicationName;
18         }
19 
20         @vkProp("pEngineName") {
21             string engineName;
22         }
23 
24         const mixin VkTo!(VkApplicationInfo);
25     }
26 
27     static struct CreateInfo {
28         @vkProp() {
29             immutable VkInstanceCreateFlags flags;
30         }
31 
32         @vkProp("pApplicationInfo") {
33             const ApplicationInfo applicationInfo;
34         }
35 
36         @vkProp("ppEnabledLayerNames", "enabledLayerCount") {
37             const string[] enabledLayerNames;
38         }
39 
40         @vkProp("ppEnabledExtensionNames", "enabledExtensionCount") {
41             const string[] enabledExtensionNames;
42         }
43 
44         const mixin VkTo!(VkInstanceCreateInfo);
45     }
46 
47     package VkInstance instance;
48 
49     this(CreateInfo info) {
50         auto vkInfo = info.vkTo();
51         enforceVK(vkCreateInstance(&vkInfo, null, &instance));
52         enforce(instance != VK_NULL_HANDLE);
53 
54         loadInstanceLevelFunctions(instance);
55     }
56 
57     ~this() {
58         vkDestroyInstance(instance, null);
59     }
60 
61     auto enumeratePhysicalDevices() {
62         import std : map, array;
63 
64         uint numPhysDevices;
65         enforceVK(vkEnumeratePhysicalDevices(instance, &numPhysDevices, null));
66 
67         auto physDevices = new VkPhysicalDevice[](numPhysDevices);
68         enforceVK(vkEnumeratePhysicalDevices(instance, &numPhysDevices, physDevices.ptr));
69         assert(physDevices.length == numPhysDevices);
70 
71         return physDevices.map!(dev => new PhysicalDevice(dev)).array;
72     }
73 }
74 
75 PhysicalDevice findPhysicalDevice(alias pred)(Instance inst) {
76     import std : countUntil, enforce;
77 
78     auto physDevices = inst.enumeratePhysicalDevices();
79     const gpuIndex = physDevices.countUntil!(pred);
80     enforce(gpuIndex != -1, "There are no GPUs with Surface support.");
81     return physDevices[gpuIndex];
82 }