1 module sbylib.wrapper.vulkan.device;
2 
3 import erupted;
4 import sbylib.wrapper.vulkan.buffer;
5 import sbylib.wrapper.vulkan.enums;
6 import sbylib.wrapper.vulkan.physicaldevice;
7 import sbylib.wrapper.vulkan.queue;
8 import sbylib.wrapper.vulkan.image;
9 import sbylib.wrapper.vulkan.util;
10 
11 class Device {
12     static struct QueueCreateInfo {
13         @vkProp("pQueuePriorities", "queueCount") {
14             const float[] queuePriorities;
15         }
16         @vkProp() {
17             immutable uint queueFamilyIndex;
18         }
19 
20         const mixin VkTo!(VkDeviceQueueCreateInfo);
21     }
22 
23     static struct DeviceCreateInfo {
24         @vkProp() {
25             immutable VkDeviceCreateFlags flags;
26             const(VkPhysicalDeviceFeatures)* pEnabledFeatures;
27             void* pNext;
28         }
29         @vkProp("pQueueCreateInfos", "queueCreateInfoCount") {
30             QueueCreateInfo[] queueCreateInfos;
31         }
32         @vkProp("ppEnabledLayerNames", "enabledLayerCount") {
33             const string[] enabledLayerNames;
34         }
35         @vkProp("ppEnabledExtensionNames", "enabledExtensionCount") {
36             const string[] enabledExtensionNames;
37         }
38 
39         const mixin VkTo!(VkDeviceCreateInfo);
40     }
41 
42     static struct MemoryRequirements {
43         @vkProp() {
44             VkDeviceSize    size;
45             VkDeviceSize    alignment;
46             uint32_t        memoryTypeBits;
47         }
48 
49         mixin VkFrom!(VkMemoryRequirements);
50 
51         bool acceptable(size_t memoryTypeIndex) const {
52             return (memoryTypeBits & (1 << memoryTypeIndex)) > 0;
53         }
54     }
55 
56     package VkDevice device;
57     private PhysicalDevice gpu;
58 
59     // mixin ImplNameSetter!(this, device, DebugReportObjectType.Device);
60 
61     this(PhysicalDevice gpu, DeviceCreateInfo info) {
62         import std.exception : enforce;
63 
64         this.gpu = gpu;
65 
66         VkDeviceCreateInfo deviceCreateInfo = info.vkTo();
67         enforceVK(vkCreateDevice(gpu.physDevice, &deviceCreateInfo, null, &device));
68         enforce(device != VK_NULL_HANDLE);
69 
70         loadDeviceLevelFunctions(device);
71     }
72 
73     ~this() {
74         vkDeviceWaitIdle(device);
75         vkDestroyDevice(device, null);
76     }
77 
78     Queue getQueue(uint queueFamilyIndex, uint queueIndex) {
79         VkQueue queue;
80         vkGetDeviceQueue(device, queueFamilyIndex, queueIndex, &queue);
81         return new Queue(this, queue);
82     }
83 
84     MemoryRequirements getBufferMemoryRequirements(Buffer buffer) {
85         VkMemoryRequirements memreq;
86         vkGetBufferMemoryRequirements(device, buffer.buffer, &memreq);
87         return MemoryRequirements(memreq);
88     }
89 
90     MemoryRequirements getImageMemoryRequirements(Image image) {
91         VkMemoryRequirements memreq;
92         vkGetImageMemoryRequirements(device, image.image, &memreq);
93         return MemoryRequirements(memreq);
94     }
95 }