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 }