1 module sbylib.wrapper.vulkan.pipeline;
2 
3 import std;
4 import erupted;
5 import sbylib.wrapper.vulkan.device;
6 import sbylib.wrapper.vulkan.enums;
7 import sbylib.wrapper.vulkan.pipelinelayout;
8 import sbylib.wrapper.vulkan.renderpass;
9 import sbylib.wrapper.vulkan.shadermodule;
10 import sbylib.wrapper.vulkan.util;
11 
12 class Pipeline {
13     static struct ShaderStageCreateInfo {
14 
15         @vkProp() {
16             immutable VkPipelineShaderStageCreateFlags flags;
17             BitFlags!ShaderStage stage;
18             ShaderModule _module;
19             string pName;
20             const(VkSpecializationInfo)* pSpecializationInfo;
21         }
22 
23         mixin VkTo!(VkPipelineShaderStageCreateInfo);
24     }
25 
26     static struct VertexInputStateCreateInfo {
27         static struct VertexInputBindingDescription {
28             @vkProp() {
29                 uint binding;
30                 uint stride;
31                 VertexInputRate inputRate;
32             }
33 
34             const mixin VkTo!(VkVertexInputBindingDescription);
35         }
36 
37         @vkProp() {
38             immutable VkPipelineVertexInputStateCreateFlags flags;
39         }
40 
41         @vkProp("pVertexBindingDescriptions", "vertexBindingDescriptionCount") {
42             const VertexInputBindingDescription[] vertexBindingDescriptions;
43         }
44 
45         @vkProp("pVertexAttributeDescriptions", "vertexAttributeDescriptionCount") {
46             const VkVertexInputAttributeDescription[] vertexAttributeDescriptions;
47         }
48 
49         const mixin VkTo!(VkPipelineVertexInputStateCreateInfo);
50     }
51 
52     static struct InputAssemblyStateCreateInfo {
53         @vkProp() {
54             VkPipelineInputAssemblyStateCreateFlags flags;
55             PrimitiveTopology topology;
56             bool primitiveRestartEnable;
57         }
58 
59         const mixin VkTo!(VkPipelineInputAssemblyStateCreateInfo);
60     }
61 
62     alias TessellationStateCreateInfo = VkPipelineTessellationStateCreateInfo;
63 
64     static struct RasterizationStateCreateInfo {
65         @vkProp() {
66             VkPipelineRasterizationStateCreateFlags flags;
67             bool depthClampEnable;
68             bool rasterizerDiscardEnable;
69             PolygonMode polygonMode;
70             CullMode cullMode;
71             FrontFace frontFace;
72             bool depthBiasEnable;
73             float depthBiasConstantFactor;
74             float depthBiasClamp;
75             float depthBiasSlopeFactor;
76             float lineWidth;
77         }
78 
79         const mixin VkTo!(VkPipelineRasterizationStateCreateInfo);
80     }
81 
82     static struct MultisampleStateCreateInfo {
83         @vkProp() {
84             VkPipelineMultisampleStateCreateFlags flags;
85             SampleCount rasterizationSamples;
86             bool sampleShadingEnable;
87             float minSampleShading;
88             const(VkSampleMask)* pSampleMask;
89             bool alphaToCoverageEnable;
90             bool alphaToOneEnable;
91         }
92 
93         const mixin VkTo!(VkPipelineMultisampleStateCreateInfo);
94     }
95 
96     alias DepthStencilStateCreateInfo = VkPipelineDepthStencilStateCreateInfo;
97 
98     static struct ViewportStateCreateInfo {
99         @vkProp() {
100             immutable VkPipelineViewportStateCreateFlags flags;
101         }
102 
103         @vkProp("pViewports", "viewportCount") {
104             const VkViewport[] viewports;
105         }
106 
107         @vkProp("pScissors", "scissorCount") {
108             const VkRect2D[] scissors;
109         }
110 
111         const mixin VkTo!(VkPipelineViewportStateCreateInfo);
112     }
113 
114     static struct ColorBlendStateCreateInfo {
115         static struct AttachmentState {
116             @vkProp() {
117                 bool blendEnable;
118                 BlendFactor srcColorBlendFactor;
119                 BlendFactor dstColorBlendFactor;
120                 BlendOp colorBlendOp;
121                 BlendFactor srcAlphaBlendFactor;
122                 BlendFactor dstAlphaBlendFactor;
123                 BlendOp alphaBlendOp;
124                 BitFlags!ColorComponent colorWriteMask;
125             }
126 
127             const mixin VkTo!(VkPipelineColorBlendAttachmentState);
128         }
129 
130         @vkProp() immutable {
131             VkPipelineColorBlendStateCreateFlags flags;
132             bool logicOpEnable;
133             LogicOp logicOp;
134             float[4] blendConstants;
135         }
136 
137         @vkProp("pAttachments", "attachmentCount") {
138             const AttachmentState[] attachments;
139         }
140 
141         const mixin VkTo!(VkPipelineColorBlendStateCreateInfo);
142     }
143 
144     static struct DynamicStateCreateInfo {
145         @vkProp() immutable {
146             VkPipelineDynamicStateCreateFlags flags;
147         }
148 
149         @vkProp("pDynamicStates", "dynamicStateCount") {
150             const VkDynamicState[] dynamicStates;
151         }
152 
153         const mixin VkTo!(VkPipelineDynamicStateCreateInfo);
154     }
155 
156     static struct GraphicsCreateInfo {
157         @vkProp() {
158             immutable VkPipelineCreateFlags flags;
159             PipelineLayout layout;
160             RenderPass renderPass;
161             immutable uint subpass;
162             Pipeline basePipelineHandle;
163             immutable int basePipelineIndex;
164         }
165 
166         @vkProp("pStages", "stageCount") {
167             ShaderStageCreateInfo[] stages;
168         }
169 
170         @vkProp("pVertexInputState") {
171             const VertexInputStateCreateInfo vertexInputState;
172         }
173 
174         @vkProp("pInputAssemblyState") {
175             const InputAssemblyStateCreateInfo inputAssemblyState;
176         }
177 
178         @vkProp("pTessellationState") {
179             const VkPipelineTessellationStateCreateInfo tessellationState;
180         }
181 
182         @vkProp("pViewportState") {
183             const ViewportStateCreateInfo viewportState;
184         }
185 
186         @vkProp("pRasterizationState") {
187             const RasterizationStateCreateInfo rasterizationState;
188         }
189 
190         @vkProp("pMultisampleState") {
191             const MultisampleStateCreateInfo multisampleState;
192         }
193 
194         @vkProp("pDepthStencilState") {
195             const VkPipelineDepthStencilStateCreateInfo depthStencilState;
196         }
197 
198         @vkProp("pColorBlendState") {
199             const ColorBlendStateCreateInfo colorBlendState;
200         }
201 
202         @vkProp("pDynamicState") {
203             const DynamicStateCreateInfo dynamicState;
204         }
205 
206         mixin VkTo!(VkGraphicsPipelineCreateInfo);
207     }
208 
209     static struct ComputeCreateInfo {
210         @vkProp() {
211             VkPipelineCreateFlags flags;
212             ShaderStageCreateInfo stage;
213             PipelineLayout layout;
214             Pipeline basePipelineHandle;
215             int basePipelineIndex;
216         }
217 
218         mixin VkTo!(VkComputePipelineCreateInfo);
219     }
220 
221     private Device device;
222     package VkPipeline pipeline;
223 
224     mixin ImplNameSetter!(device, pipeline, DebugReportObjectType.Pipeline);
225 
226     this(Device device, VkPipeline pipeline) {
227         this.device = device;
228         this.pipeline = pipeline;
229     }
230 
231     ~this() {
232         vkDestroyPipeline(device.device, pipeline, null);
233     }
234 
235     mixin VkTo!(VkPipeline);
236 
237     static Pipeline[] create(Device device, GraphicsCreateInfo[] _infos) {
238 
239         auto infos = _infos.map!(i => i.vkTo()).array;
240         VkPipeline[] pipelines = new VkPipeline[_infos.length];
241 
242         enforceVK(vkCreateGraphicsPipelines(device.device, null  /*pipeline cache */ ,
243                 cast(uint) infos.length, infos.ptr, null, pipelines.ptr));
244 
245         return pipelines.map!(p => new Pipeline(device, p)).array;
246     }
247 
248     static Pipeline[] create(Device device, ComputeCreateInfo[] _infos) {
249 
250         auto infos = _infos.map!(i => i.vkTo()).array;
251         VkPipeline[] pipelines = new VkPipeline[_infos.length];
252 
253         enforceVK(vkCreateComputePipelines(device.device, null  /*pipeline cache */ ,
254                 cast(uint) infos.length, infos.ptr, null, pipelines.ptr));
255 
256         return pipelines.map!(p => new Pipeline(device, p)).array;
257     }
258 }