1 /// command buffer module
2 module gfx.graal.cmd;
3 
4 import gfx.core.rc;
5 import gfx.core.typecons;
6 import gfx.core.types;
7 import gfx.graal.buffer;
8 import gfx.graal.image;
9 import gfx.graal.renderpass;
10 import gfx.graal.pipeline;
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     colorAttachment             = 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 interface CommandBuffer
198 {
199     @property CommandPool pool();
200 
201     void reset();
202 
203     void begin(Flag!"persistent" persistent=No.persistent);
204     void end();
205 
206     void pipelineBarrier(Trans!PipelineStage stageTrans,
207                          BufferMemoryBarrier[] bufMbs,
208                          ImageMemoryBarrier[] imgMbs);
209 
210     void clearColorImage(ImageBase image, ImageLayout layout,
211                          in ClearColorValues clearValues,
212                          ImageSubresourceRange[] ranges);
213 
214     void clearDepthStencilImage(ImageBase image, ImageLayout layout,
215                                 in ClearDepthStencilValues clearValues,
216                                 ImageSubresourceRange[] ranges);
217 
218     void copyBuffer(Trans!Buffer buffers, CopyRegion[] regions);
219     void copyBufferToImage(Buffer srcBuffer, ImageBase dstImage,
220                            in ImageLayout dstLayout, in BufferImageCopy[] regions);
221 
222     void setViewport(in uint firstViewport, in Viewport[] viewports);
223     void setScissor(in uint firstScissor, in Rect[] scissors);
224     void setDepthBounds(in float minDepth, in float maxDepth);
225     void setLineWidth(in float lineWidth);
226     void setDepthBias(in float constFactor, in float clamp, in float slopeFactor);
227     void setStencilCompareMask(in StencilFace faceMask, in uint compareMask);
228     void setStencilWriteMask(in StencilFace faceMask, in uint writeMask);
229     void setStencilReference(in StencilFace faceMask, in uint reference);
230     void setBlendConstants(in float[4] blendConstants);
231 
232     void beginRenderPass(RenderPass rp, Framebuffer fb,
233                          Rect area, ClearValues[] clearValues);
234 
235     void nextSubpass();
236 
237     void endRenderPass();
238 
239     void bindPipeline(Pipeline pipeline);
240     void bindVertexBuffers(uint firstBinding, VertexBinding[] bindings);
241     void bindIndexBuffer(Buffer indexBuf, size_t offset, IndexType type);
242 
243     void bindDescriptorSets(PipelineBindPoint bindPoint, PipelineLayout layout,
244                             uint firstSet, DescriptorSet[] sets, in size_t[] dynamicOffsets);
245 
246     void pushConstants(PipelineLayout layout, ShaderStage stages,
247                        size_t offset, size_t size, const(void)* data);
248 
249     void draw(uint vertexCount, uint instanceCount, uint firstVertex, uint firstInstance);
250     void drawIndexed(uint indexCount, uint instanceCount, uint firstVertex, int vertexOffset, uint firstInstance);
251 }