1 module sbylib.graphics.wrapper.commandbuffer;
2 
3 import std;
4 import sbylib.wrapper.vulkan;
5 import sbylib.graphics.wrapper.device;
6 import sbylib.graphics.util.own;
7 import erupted : VkCommandBuffer;
8 
9 class VCommandBuffer {
10 
11     enum Type {
12         Graphics = QueueFamilyProperties.Flags.Graphics,
13         Compute = QueueFamilyProperties.Flags.Compute,
14     }
15 
16     private static CommandPool[Type] pools;
17 
18     private static CommandPool pool(Type type) {
19         if (auto p = type in pools) return *p;
20         with (VDevice()) {
21             auto queueFamilyIndex = findQueueFamilyIndex(type);
22             CommandPool.CreateInfo commandPoolCreateInfo = {
23                 flags: CommandPool.CreateInfo.Flags.ResetCommandBuffer
24                      | CommandPool.CreateInfo.Flags.Protected,
25                 queueFamilyIndex: queueFamilyIndex
26             };
27             auto pool = new CommandPool(device, commandPoolCreateInfo);
28             pushResource(pool);
29             return pools[type] = pool;
30         }
31     }
32 
33     static VCommandBuffer[] allocate(Type type, CommandBufferLevel level, int count) {
34         CommandBuffer.AllocateInfo commandbufferAllocInfo = {
35             commandPool: pool(type),
36             level: level,
37             commandBufferCount: count,
38         };
39         return CommandBuffer.allocate(VDevice(), commandbufferAllocInfo).map!(c => new VCommandBuffer(c)).array;
40     }
41 
42     static VCommandBuffer allocate(Type type, CommandBufferLevel level = CommandBufferLevel.Primary) {
43         return allocate(type, level, 1)[0];
44     }
45 
46     @own CommandBuffer commandBuffer;
47     mixin ImplReleaseOwn;
48     alias commandBuffer this;
49 
50     private this(CommandBuffer commandBuffer) {
51         this.commandBuffer = commandBuffer;
52     }
53 
54     void begin() {
55         CommandBuffer.BeginInfo info;
56         commandBuffer.begin(info);
57     }
58 
59     void begin(CommandBuffer.BeginInfo.Flags flags) {
60         CommandBuffer.BeginInfo info = {
61             flags: flags
62         };
63         commandBuffer.begin(info);
64     }
65 
66     auto opCall(Args...)(Args args) {
67         this.begin(args);
68 
69         struct S {
70             VCommandBuffer cb;
71             alias cb this;
72 
73             ~this() {
74                 cb.end();
75             }
76         }
77         return S(this);
78     }
79 }