1 /// command buffer module 2 module gfx.graal.cmd; 3 4 import gfx.core.rc; 5 import gfx.core.typecons; 6 import gfx.graal.buffer; 7 import gfx.graal.image; 8 import gfx.graal.renderpass; 9 import gfx.graal.pipeline; 10 import gfx.graal.types; 11 12 import std.typecons : Flag, No; 13 14 interface CommandPool : AtomicRefCounted 15 { 16 void reset(); 17 18 CommandBuffer[] allocate(size_t count); 19 20 void free(CommandBuffer[] buffers) 21 in { 22 import std.algorithm : all; 23 assert(buffers.all!(b => b.pool is this)); 24 } 25 } 26 27 enum Access { 28 none = 0x00000000, 29 indirectCommandRead = 0x00000001, 30 indexRead = 0x00000002, 31 vertexAttributeRead = 0x00000004, 32 uniformRead = 0x00000008, 33 inputAttachmentRead = 0x00000010, 34 shaderRead = 0x00000020, 35 shaderWrite = 0x00000040, 36 colorAttachmentRead = 0x00000080, 37 colorAttachmentWrite = 0x00000100, 38 depthStencilAttachmentRead = 0x00000200, 39 depthStencilAttachmentWrite = 0x00000400, 40 transferRead = 0x00000800, 41 transferWrite = 0x00001000, 42 hostRead = 0x00002000, 43 hostWrite = 0x00004000, 44 memoryRead = 0x00008000, 45 memoryWrite = 0x00010000, 46 } 47 48 enum queueFamilyIgnored = 0xffffffff; 49 50 struct ImageMemoryBarrier { 51 Trans!Access accessMaskTrans; 52 Trans!ImageLayout layoutTrans; 53 Trans!uint queueFamIndexTrans; 54 ImageBase image; 55 ImageSubresourceRange range; 56 } 57 58 struct BufferMemoryBarrier { 59 Trans!Access accessMaskTrans; 60 Trans!uint queueFamIndexTrans; 61 Buffer buffer; 62 size_t offset; 63 size_t size; 64 } 65 66 enum PipelineStage { 67 topOfPipe = 0x00000001, 68 drawIndirect = 0x00000002, 69 vertexInput = 0x00000004, 70 vertexShader = 0x00000008, 71 tessellationControlShader = 0x00000010, 72 tessellationEvalShader = 0x00000020, 73 geometryShader = 0x00000040, 74 fragmentShader = 0x00000080, 75 earlyFragmentTests = 0x00000100, 76 lateFragmentTests = 0x00000200, 77 colorAttachmentOutput = 0x00000400, 78 computeShader = 0x00000800, 79 transfer = 0x00001000, 80 bottomOfPipe = 0x00002000, 81 host = 0x00004000, 82 allGraphics = 0x00008000, 83 allCommands = 0x00010000, 84 } 85 86 enum PipelineBindPoint { 87 graphics, compute 88 } 89 90 /// Values to be given to a clear image color command 91 /// The type should be f32, unless the image format has numeric format of sInt or uInt. 92 struct ClearColorValues 93 { 94 enum Type { 95 f32, i32, u32 96 } 97 union Values { 98 float[4] f32; 99 int[4] i32; 100 uint[4] u32; 101 } 102 Type type; 103 Values values; 104 105 this (float r, float g, float b, float a) { 106 type = Type.f32; 107 values.f32 = [ r, g, b, a ]; 108 } 109 110 this (int r, int g, int b, int a) { 111 type = Type.i32; 112 values.i32 = [ r, g, b, a ]; 113 } 114 115 this (uint r, uint g, uint b, uint a) { 116 type = Type.u32; 117 values.u32 = [ r, g, b, a ]; 118 } 119 } 120 121 struct ClearDepthStencilValues 122 { 123 float depth; 124 uint stencil; 125 } 126 127 struct ClearValues 128 { 129 enum Type { undefined, color, depthStencil } 130 union Values { 131 ClearColorValues color; 132 ClearDepthStencilValues depthStencil; 133 } 134 Type type; 135 Values values; 136 137 this (ClearColorValues color) { 138 type = Type.color; 139 values.color = color; 140 } 141 this (ClearDepthStencilValues depthStencil) { 142 type = Type.depthStencil; 143 values.depthStencil = depthStencil; 144 } 145 146 static ClearValues color(in float r, in float g, in float b, in float a) { 147 return ClearValues(ClearColorValues(r, g, b, a)); 148 } 149 150 static ClearValues color(in int r, in int g, in int b, in int a) { 151 return ClearValues(ClearColorValues(r, g, b, a)); 152 } 153 154 static ClearValues color(in uint r, in uint g, in uint b, in uint a) { 155 return ClearValues(ClearColorValues(r, g, b, a)); 156 } 157 158 static ClearValues depthStencil(in float depth, in uint stencil) { 159 return ClearValues(ClearDepthStencilValues(depth, stencil)); 160 } 161 } 162 163 struct VertexBinding { 164 Buffer buffer; 165 size_t offset; 166 } 167 168 struct CopyRegion 169 { 170 Trans!size_t offset; 171 size_t size; 172 } 173 174 struct ImageCopyRegion 175 { 176 Trans!ImageSubresourceRange isr; 177 Trans!(float[3]) offset; 178 } 179 180 struct BufferImageCopy 181 { 182 ulong bufferOffset; 183 uint bufferWidth; 184 uint bufferHeight; 185 ImageSubresourceLayer imageLayers; 186 int[3] offset; 187 uint[3] extent; 188 } 189 190 enum StencilFace 191 { 192 front = 1, 193 back = 2, 194 frontAndBack = 3, 195 } 196 197 enum wholeSize = uint.max; 198 199 interface CommandBuffer 200 { 201 @property CommandPool pool(); 202 203 void reset(); 204 205 void begin(Flag!"persistent" persistent=No.persistent); 206 void end(); 207 208 void pipelineBarrier(Trans!PipelineStage stageTrans, 209 BufferMemoryBarrier[] bufMbs, 210 ImageMemoryBarrier[] imgMbs); 211 212 void clearColorImage(ImageBase image, ImageLayout layout, 213 in ClearColorValues clearValues, 214 ImageSubresourceRange[] ranges); 215 216 void clearDepthStencilImage(ImageBase image, ImageLayout layout, 217 in ClearDepthStencilValues clearValues, 218 ImageSubresourceRange[] ranges); 219 220 /// Fills buffer from offset to offset+size with value 221 /// Params: 222 /// dst = the buffer to fill. 223 /// offset = Byte offset from where to fill the buffer. 224 /// Must be a multiple of 4. 225 /// size = Number of bytes to fill. Must be a multiple of 4 or 226 /// wholeSize to fill until the end of the buffer. 227 /// value = Value to copy into the buffer, in host endianess. 228 /// Can only be used outside of a render pass. 229 void fillBuffer(Buffer dst, in size_t offset, in size_t size, uint value) 230 in { 231 assert(offset % 4 == 0); 232 assert(size == wholeSize || size % 4 == 0); 233 } 234 /// Update buffer with the data passed as argument 235 /// Params: 236 /// dst = the buffer to update. 237 /// offset = Byte offset from where to update the buffer. 238 /// Must be a multiple of 4. 239 /// data = The data to copy into the buffer. 240 /// The data is duplicated into the command buffer, so it is legal to pass a slice 241 /// to local on-stack data, or to let GC collect the data right after the call. 242 /// Can only be used outside of a render pass. 243 void updateBuffer(Buffer dst, in size_t offset, in uint[] data); 244 void copyBuffer(Trans!Buffer buffers, in CopyRegion[] regions); 245 void copyBufferToImage(Buffer srcBuffer, ImageBase dstImage, 246 in ImageLayout dstLayout, in BufferImageCopy[] regions); 247 248 void setViewport(in uint firstViewport, in Viewport[] viewports); 249 void setScissor(in uint firstScissor, in Rect[] scissors); 250 void setDepthBounds(in float minDepth, in float maxDepth); 251 void setLineWidth(in float lineWidth); 252 void setDepthBias(in float constFactor, in float clamp, in float slopeFactor); 253 void setStencilCompareMask(in StencilFace faceMask, in uint compareMask); 254 void setStencilWriteMask(in StencilFace faceMask, in uint writeMask); 255 void setStencilReference(in StencilFace faceMask, in uint reference); 256 void setBlendConstants(in float[4] blendConstants); 257 258 void beginRenderPass(RenderPass rp, Framebuffer fb, 259 Rect area, ClearValues[] clearValues); 260 261 void nextSubpass(); 262 263 void endRenderPass(); 264 265 void bindPipeline(Pipeline pipeline); 266 void bindVertexBuffers(uint firstBinding, VertexBinding[] bindings); 267 void bindIndexBuffer(Buffer indexBuf, size_t offset, IndexType type); 268 269 void bindDescriptorSets(PipelineBindPoint bindPoint, PipelineLayout layout, 270 uint firstSet, DescriptorSet[] sets, in size_t[] dynamicOffsets); 271 272 void pushConstants(PipelineLayout layout, ShaderStage stages, 273 size_t offset, size_t size, const(void)* data); 274 275 void draw(uint vertexCount, uint instanceCount, uint firstVertex, uint firstInstance); 276 void drawIndexed(uint indexCount, uint instanceCount, uint firstVertex, int vertexOffset, uint firstInstance); 277 }