1 module sbylib.wrapper.vulkan.commandbuffer; 2 3 import std; 4 import erupted; 5 import sbylib.wrapper.vulkan.buffer; 6 import sbylib.wrapper.vulkan.commandpool; 7 import sbylib.wrapper.vulkan.descriptorset; 8 import sbylib.wrapper.vulkan.device; 9 import sbylib.wrapper.vulkan.enums; 10 import sbylib.wrapper.vulkan.framebuffer; 11 import sbylib.wrapper.vulkan.image; 12 import sbylib.wrapper.vulkan.renderpass; 13 import sbylib.wrapper.vulkan.pipeline; 14 import sbylib.wrapper.vulkan.pipelinelayout; 15 import sbylib.wrapper.vulkan.util; 16 17 class CommandBuffer { 18 static struct AllocateInfo { 19 @vkProp() { 20 CommandPool commandPool; 21 immutable CommandBufferLevel level; 22 immutable uint commandBufferCount; 23 } 24 25 mixin VkTo!(VkCommandBufferAllocateInfo); 26 } 27 28 static struct BeginInfo { 29 @vkProp() { 30 immutable BitFlags!Flags flags; 31 } 32 33 @vkProp("pInheritanceInfo") { 34 InheritanceInfo inheritanceInfo; 35 } 36 37 enum Flags { 38 OneTimeSubmit = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, 39 RenderPassContinue = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, 40 SimultaneousUse = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, 41 } 42 43 mixin VkTo!(VkCommandBufferBeginInfo); 44 } 45 46 static struct InheritanceInfo { 47 @vkProp() { 48 RenderPass renderPass; 49 immutable uint subpass; 50 Framebuffer framebuffer; 51 immutable bool occlusionQueryEnable; 52 immutable VkQueryControlFlags queryFlags; 53 immutable VkQueryPipelineStatisticFlags pipelineStatistics; 54 } 55 56 mixin VkTo!(VkCommandBufferInheritanceInfo); 57 } 58 59 static struct RenderPassBeginInfo { 60 @vkProp() { 61 RenderPass renderPass; 62 Framebuffer framebuffer; 63 VkRect2D renderArea; 64 } 65 66 @vkProp("pClearValues", "clearValueCount") { 67 const VkClearValue[] clearValues; 68 } 69 70 mixin VkTo!(VkRenderPassBeginInfo); 71 } 72 73 private Device device; 74 private CommandPool commandPool; 75 private VkCommandBuffer commandBuffer; 76 77 mixin ImplNameSetter!(device, commandBuffer, DebugReportObjectType.CommandBuffer); 78 79 private this(Device device, CommandPool commandPool, VkCommandBuffer commandBuffer) { 80 import std.exception : enforce; 81 82 this.device = device; 83 this.commandPool = commandPool; 84 this.commandBuffer = commandBuffer; 85 } 86 87 ~this() { 88 vkFreeCommandBuffers(device.device, commandPool.commandPool, 1, &commandBuffer); 89 } 90 91 mixin VkTo!(VkCommandBuffer); 92 93 static CommandBuffer[] allocate(Device device, AllocateInfo _info) { 94 VkCommandBuffer[] commandBuffers = new VkCommandBuffer[_info.commandBufferCount]; 95 96 auto info = _info.vkTo(); 97 98 enforceVK(vkAllocateCommandBuffers(device.device, &info, commandBuffers.ptr)); 99 100 return commandBuffers.map!(cb => new CommandBuffer(device, _info.commandPool, cb)).array; 101 } 102 103 void begin(BeginInfo _info) { 104 auto info = _info.vkTo(); 105 vkBeginCommandBuffer(commandBuffer, &info); 106 } 107 108 void end() { 109 enforceVK(vkEndCommandBuffer(commandBuffer)); 110 } 111 112 void cmdPipelineBarrier(PipelineStage srcStageMask, 113 PipelineStage dstStageMask, VkDependencyFlags dependencyFlags, 114 VkMemoryBarrier[] memoryBarriers, VkBufferMemoryBarrier[] bufferMemoryBarriers, 115 VkImageMemoryBarrier[] imageMemoryBarriers) { 116 117 vkCmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 118 dependencyFlags, cast(uint) memoryBarriers.length, 119 memoryBarriers.ptr, cast(uint) bufferMemoryBarriers.length, bufferMemoryBarriers.ptr, 120 cast(uint) imageMemoryBarriers.length, imageMemoryBarriers.ptr); 121 } 122 123 void cmdBeginRenderPass(RenderPassBeginInfo _info, SubpassContents subpassContents) { 124 auto info = _info.vkTo(); 125 vkCmdBeginRenderPass(commandBuffer, &info, subpassContents); 126 } 127 128 void cmdEndRenderPass() { 129 vkCmdEndRenderPass(commandBuffer); 130 } 131 132 void cmdBindPipeline(PipelineBindPoint pipelineBindPoint, Pipeline pipeline) { 133 vkCmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline.pipeline); 134 } 135 136 void cmdSetViewport(uint N)(uint firstViewport, const VkViewport[N] viewports) { 137 vkCmdSetViewport(commandBuffer, firstViewport, N, viewports.ptr); 138 } 139 140 void cmdSetScissor(uint N)(uint firstScissor, const VkRect2D[N] scissors) { 141 vkCmdSetScissor(commandBuffer, firstScissor, N, scissors.ptr); 142 } 143 144 void cmdBindVertexBuffers(uint N)(uint firstBinding, Buffer[N] _buffers, 145 const VkDeviceSize[N] offsets) { 146 VkBuffer[N] buffers; 147 static foreach (i; 0 .. N) 148 buffers[i] = _buffers[i].buffer; 149 150 vkCmdBindVertexBuffers(commandBuffer, firstBinding, N, buffers.ptr, offsets.ptr); 151 } 152 153 void cmdBindIndexBuffer(Buffer buffer,VkDeviceSize offset, IndexType indexType) { 154 vkCmdBindIndexBuffer(commandBuffer, buffer.buffer, offset, indexType); 155 } 156 157 void cmdBindDescriptorSets(uint N, uint M)(PipelineBindPoint pipelineBindPoint, PipelineLayout layout, 158 uint firstSet, const DescriptorSet[N] _descriptorSets, const uint[M] dynamicOffsets) { 159 VkDescriptorSet[N] descriptorSets; 160 static foreach (i; 0..N) 161 descriptorSets[i] = cast(VkDescriptorSet)_descriptorSets[i].vkTo(); 162 163 vkCmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout.pipelineLayout, firstSet, 164 cast(uint) descriptorSets.length, descriptorSets.ptr, 165 cast(uint) dynamicOffsets.length, dynamicOffsets.ptr); 166 } 167 168 void cmdBindDescriptorSets(uint N)(PipelineBindPoint pipelineBindPoint, PipelineLayout layout, 169 uint firstSet, const DescriptorSet[N] _descriptorSets) { 170 uint[0] dummy; 171 cmdBindDescriptorSets(pipelineBindPoint, layout, firstSet, _descriptorSets, dummy); 172 } 173 174 void cmdDraw(uint vertexCount, uint instanceCount, uint firstVertex, uint firstInstance) { 175 vkCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance); 176 } 177 178 void cmdDrawIndexed(uint indexCount, uint instanceCount, uint firstIndex, int vertexOffset, uint firstInstance) { 179 vkCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance); 180 } 181 182 void cmdDispatch(uint groupCountX, uint groupCountY, uint groupCountZ) { 183 vkCmdDispatch(commandBuffer, groupCountX, groupCountY, groupCountZ); 184 } 185 186 void cmdCopyBuffer(Buffer src, Buffer dst, const VkBufferCopy[] regions) { 187 vkCmdCopyBuffer(commandBuffer, src.buffer, dst.buffer, cast(uint)regions.length, regions.ptr); 188 } 189 190 void cmdCopyImage(Image src, ImageLayout srcImageLayout, Image dst, ImageLayout dstImageLayout, const VkImageCopy[] regions) { 191 vkCmdCopyImage(commandBuffer, src.image, srcImageLayout, dst.image, dstImageLayout, cast(uint)regions.length, regions.ptr); 192 } 193 194 void cmdCopyBufferToImage(uint N)(Buffer src, Image dst, ImageLayout layout, const VkBufferImageCopy[N] regions) { 195 vkCmdCopyBufferToImage(commandBuffer, src.buffer, dst.image, layout, N, regions.ptr); 196 } 197 198 void cmdBlitImage(uint N)(Image srcImage, ImageLayout srcImageLayout, Image dstImage, ImageLayout dstImageLayout, VkImageBlit[N] regions, SamplerFilter filter) { 199 vkCmdBlitImage(commandBuffer, srcImage.image, srcImageLayout, dstImage.image, dstImageLayout, N, regions.ptr, filter); 200 } 201 202 void cmdClearAttachments(uint N, uint M)(const VkClearAttachment[N] attachments, const VkClearRect[M] rects) { 203 vkCmdClearAttachments(commandBuffer, N, attachments.ptr, M, rects.ptr); 204 } 205 206 void cmdExecuteCommands(uint N)(CommandBuffer[N] _commandBuffers) { 207 VkCommandBuffer[N] commandBuffers; 208 static foreach (i; 0..N) { 209 commandBuffers[i] = _commandBuffers[i].vkTo(); 210 } 211 vkCmdExecuteCommands(commandBuffer, N, commandBuffers.ptr); 212 } 213 214 void cmdExecuteCommands(CommandBuffer[] _commandBuffers) { 215 VkCommandBuffer[256] commandBuffers; 216 foreach (i; 0.._commandBuffers.length) { 217 commandBuffers[i] = _commandBuffers[i].vkTo(); 218 } 219 vkCmdExecuteCommands(commandBuffer, cast(uint)_commandBuffers.length, commandBuffers.ptr); 220 } 221 222 // utilities, not just a wrapper 223 224 void begin(BeginInfo.Flags[] flags...) { 225 BitFlags!(BeginInfo.Flags) infoFlags; 226 foreach (flag; flags) infoFlags |= flag; 227 begin(BeginInfo(infoFlags)); 228 } 229 }