1 module sbylib.graphics.compute.compute;
2 
3 public import std;
4 public import sbylib.math;
5 public import sbylib.wrapper.vulkan;
6 import sbylib.graphics.core.descriptor;
7 import sbylib.graphics.util.own;
8 
9 class Compute {
10     
11     mixin Descriptor;
12 
13     protected @own {
14         PipelineLayout pipelineLayout;
15         Pipeline pipeline;
16     }
17 
18     mixin ImplReleaseOwn;
19 
20     mixin template Instance() {
21         import std : getSymbolsByUDA;
22         import sbylib.wrapper.vulkan;
23         import sbylib.graphics.core;
24         import sbylib.graphics.util;
25         import sbylib.graphics.wrapper;
26 
27         alias This = typeof(this);
28 
29         mixin ImplDescriptor;
30 
31         this() {
32             initializeDescriptor();
33 
34             PipelineLayout.CreateInfo pipelineLayoutCreateInfo = {
35                 setLayouts: [descriptorSetLayout]
36             };
37             this.pipelineLayout = new PipelineLayout(VDevice(), pipelineLayoutCreateInfo);
38 
39             Pipeline.ComputeCreateInfo pipelineCreateInfo = {
40                 stage: getSymbolsByUDA!(typeof(this), stages)[0](),
41                 layout: pipelineLayout,
42             };
43 
44             this.pipeline = Pipeline.create(VDevice(), [pipelineCreateInfo])[0];
45         }
46 
47         private static typeof(this) inst;
48 
49         static Inst opCall(VQueue queue = null) {
50             if (queue is null) queue = VQueue(VQueue.Type.Compute);
51             if (inst is null) {
52                 inst = new typeof(this);
53                 VDevice().pushResource(inst);
54             }
55             return Inst(queue, inst.pipeline, inst.pipelineLayout, inst.descriptorPool, inst.descriptorSetLayout);
56         }
57 
58         static struct Inst {
59             mixin ImplReleaseOwn;
60             mixin DefineInstanceMembers!(This);
61 
62             private @own {
63                 DescriptorSet descriptorSet;
64                 VCommandBuffer commandBuffer;
65             }
66             private Pipeline pipeline;
67             private PipelineLayout pipelineLayout;
68             private VQueue queue;
69 
70             this(VQueue queue, Pipeline pipeline, PipelineLayout pipelineLayout, DescriptorPool descriptorPool, DescriptorSetLayout descriptorSetLayout) {
71                 this.queue = queue;
72                 this.pipeline = pipeline;
73                 this.pipelineLayout = pipelineLayout;
74                 initializeDefinedBuffers();
75                 this.descriptorSet = createDescriptorSet(descriptorPool, descriptorSetLayout);
76                 this.commandBuffer = VCommandBuffer.allocate(VCommandBuffer.Type.Compute);
77             }
78 
79             auto dispatch(int[3] xyz) {
80                 record(xyz);
81                 auto fence = queue.submitWithFence(commandBuffer, "dispatch");
82                 struct Job {
83                     VFence fence;
84 
85                     ~this() {
86                         if (!fence.signaled) wait();
87                         fence.destroy();
88                     }
89 
90                     void wait() {
91                         fence.wait();
92                     }
93                 }
94                 return Job(fence);
95             }
96 
97             auto dispatch(int[3] xyz, VFence fence) {
98                 record(xyz);
99                 struct Job {
100                     VFence fence;
101 
102                     void wait() {
103                         fence.wait();
104                     }
105                 }
106                 return Job(fence);
107             }
108 
109             private void record(int[3] xyz) {
110                 with (commandBuffer()) {
111                     cmdBindPipeline(PipelineBindPoint.Compute, pipeline);
112                     cmdBindDescriptorSets(PipelineBindPoint.Compute, pipelineLayout, 0, [descriptorSet]);
113                     cmdDispatch(xyz[0], xyz[1], xyz[2]);
114                 }
115             }
116         }
117     }
118 }