1 module sbylib.wrapper.vulkan.queue;
2 
3 import erupted;
4 import sbylib.wrapper.vulkan.commandbuffer;
5 import sbylib.wrapper.vulkan.device;
6 import sbylib.wrapper.vulkan.enums;
7 import sbylib.wrapper.vulkan.fence;
8 import sbylib.wrapper.vulkan.swapchain;
9 import sbylib.wrapper.vulkan.util;
10 
11 class Queue {
12 
13     /*
14        1. Wait all `waitSemaphores` at each corresponding stage specified by `waitDstStageMask`
15        2. Execute `commandBuffers`
16        3. Signal all `signalSemaphores`
17      */
18     static struct SubmitInfo {
19         @vkProp("pWaitSemaphores", "waitSemaphoreCount") {
20             const VkSemaphore[] waitSemaphores;
21         }
22 
23         @vkProp("pWaitDstStageMask") {
24             const VkPipelineStageFlags[] waitDstStageMask;
25         }
26 
27         @vkProp("pCommandBuffers", "commandBufferCount") {
28             const CommandBuffer[] commandBuffers;
29         }
30 
31         @vkProp("pSignalSemaphores", "signalSemaphoreCount") {
32             const VkSemaphore[] signalSemaphores;
33         }
34 
35         const mixin VkTo!(VkSubmitInfo);
36     }
37 
38     static struct PresentInfo {
39         @vkProp("pWaitSemaphores", "waitSemaphoreCount") {
40             const VkSemaphore[] waitSemaphores;
41         }
42 
43         @vkProp("pSwapchains", "swapchainCount") {
44             const Swapchain[] swapchains;
45         }
46 
47         @vkProp("pImageIndices") {
48             const uint[] imageIndices;
49         }
50 
51         @vkProp("pResults") {
52             VkResult[] results;
53         }
54 
55         invariant(swapchains.length == imageIndices.length);
56         invariant(results is null || swapchains.length == results.length);
57 
58         mixin VkTo!(VkPresentInfoKHR);
59     }
60 
61     private Device device;
62     package VkQueue queue;
63 
64     mixin ImplNameSetter!(device, queue, DebugReportObjectType.Queue);
65 
66     package this(Device device, VkQueue queue) {
67         this.device = device;
68         this.queue = queue;
69     }
70 
71     void submit(uint N)(SubmitInfo[N] _info, Fence _fence) {
72         VkFence fence;
73         if (_fence)
74             fence = _fence.fence;
75 
76         VkSubmitInfo[N] info;
77         static foreach (i; 0 .. N)
78             info[i] = _info[i].vkTo();
79 
80         enforceVK(vkQueueSubmit(queue, N, info.ptr, fence));
81     }
82 
83     void waitIdle() {
84         enforceVK(vkQueueWaitIdle(queue));
85     }
86 
87     void present(PresentInfo _info) {
88         auto info = _info.vkTo();
89         enforceVK(vkQueuePresentKHR(queue, &info));
90     }
91 
92     mixin VkTo!(VkQueue);
93 }