PeriDyno 1.0.0
Loading...
Searching...
No Matches
VkProgram.cpp
Go to the documentation of this file.
1#include "VkProgram.h"
2#include "VulkanTools.h"
3
4#include <assert.h>
5
6namespace dyno
7{
9 {
10 mAllArgs.clear();
11 mBufferArgs.clear();
12 mUniformArgs.clear();
13 mConstArgs.clear();
14
15 for (auto& shderModule : shaderModules) {
16 vkDestroyShaderModule(ctx->deviceHandle(), shderModule, nullptr);
17 }
18
19 vkDestroyPipeline(ctx->deviceHandle(), pipeline, nullptr);
20 vkDestroyPipelineLayout(ctx->deviceHandle(), pipelineLayout, nullptr);
21 vkDestroyDescriptorSetLayout(ctx->deviceHandle(), descriptorSetLayout, nullptr);
22 vkDestroyDescriptorPool(ctx->deviceHandle(), descriptorPool, nullptr);
23
24 vkDestroyCommandPool(ctx->deviceHandle(), mCommandPool, nullptr);
25 vkDestroyFence(ctx->deviceHandle(), mFence, nullptr);
26 vkDestroySemaphore(ctx->deviceHandle(), compute.semaphores.ready, nullptr);
27 vkDestroySemaphore(ctx->deviceHandle(), compute.semaphores.complete, nullptr);
28 }
29
31 {
32 VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
33 cmdBufInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
34
35 VK_CHECK_RESULT(vkBeginCommandBuffer(mCommandBuffers, &cmdBufInfo));
36 //vkCmdBindPipeline(mCommandBuffers, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
37 }
38
39 void VkProgram::dispatch(dim3 groupSize)
40 {
41 vkCmdBindDescriptorSets(mCommandBuffers, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descriptorSet, 0, 0);
42 uint32_t offset = 0;
43 for (size_t i = 0; i < mAllArgs.size(); i++)
44 {
45 auto variable = mAllArgs[i];
46 if (variable->type() == VariableType::Constant) {
47 vkCmdPushConstants(mCommandBuffers, pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, offset, variable->bufferSize(), variable->data());
48 offset += variable->bufferSize();
49 }
50 }
51
52 vkCmdBindPipeline(mCommandBuffers, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
53 vkCmdDispatch(mCommandBuffers, groupSize.x, groupSize.y, groupSize.z);
54
56 }
57
59 {
60 vkEndCommandBuffer(mCommandBuffers);
61 }
62
63 void VkProgram::update(bool sync)
64 {
65 vkResetFences(ctx->deviceHandle(), 1, &mFence);
66
67 static bool firstDraw = true;
68 VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo();
69 // FIXME find a better way to do this (without using fences, which is much slower)
70 VkPipelineStageFlags computeWaitDstStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
71 if (!firstDraw) {
72 // TODO: semaphore should use in different submit queue.
73 //computeSubmitInfo.waitSemaphoreCount = 1;
74 //computeSubmitInfo.pWaitSemaphores = &compute.semaphores.ready;
75 //computeSubmitInfo.pWaitDstStageMask = &computeWaitDstStageMask;
76 }
77 else {
78 firstDraw = false;
79 }
80 //computeSubmitInfo.signalSemaphoreCount = 1;
81 //computeSubmitInfo.pSignalSemaphores = &compute.semaphores.complete;
82 computeSubmitInfo.commandBufferCount = 1;
83 computeSubmitInfo.pCommandBuffers = &mCommandBuffers;
84
85 if (sync) {
86 VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &computeSubmitInfo, mFence));
87 }
88 else {
89 VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &computeSubmitInfo, VK_NULL_HANDLE));
90 }
91 }
92
94 {
95 VK_CHECK_RESULT(vkWaitForFences(ctx->deviceHandle(), 1, &mFence, VK_TRUE, UINT64_MAX));
96 }
97
98 void VkProgram::addGraphicsToComputeBarriers(VkCommandBuffer commandBuffer)
99 {
100 if (ctx->isComputeQueueSpecial()) {
101 VkBufferMemoryBarrier bufferBarrier = vks::initializers::bufferMemoryBarrier();
102 bufferBarrier.srcAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
103 bufferBarrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
104 bufferBarrier.srcQueueFamilyIndex = ctx->queueFamilyIndices.graphics;
105 bufferBarrier.dstQueueFamilyIndex = ctx->queueFamilyIndices.compute;
106 bufferBarrier.size = VK_WHOLE_SIZE;
107
108 std::vector<VkBufferMemoryBarrier> bufferBarriers;
109 for (size_t i = 0; i < mBufferArgs.size(); i++)
110 {
111 bufferBarrier.buffer = mBufferArgs[i]->bufferHandle();
112 bufferBarriers.push_back(bufferBarrier);
113 }
114 // bufferBarrier.buffer = input->bufferHandle();
115 // bufferBarriers.push_back(bufferBarrier);
116 // bufferBarrier.buffer = output->bufferHandle();
117 // bufferBarriers.push_back(bufferBarrier);
118 vkCmdPipelineBarrier(commandBuffer,
119 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
120 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
122 0, nullptr,
123 static_cast<uint32_t>(bufferBarriers.size()), bufferBarriers.data(),
124 0, nullptr);
125 }
126 }
127
128 void VkProgram::addComputeToComputeBarriers(VkCommandBuffer commandBuffer)
129 {
130 VkBufferMemoryBarrier bufferBarrier = vks::initializers::bufferMemoryBarrier();
131 bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
132 bufferBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
133 bufferBarrier.srcQueueFamilyIndex = ctx->queueFamilyIndices.compute;
134 bufferBarrier.dstQueueFamilyIndex = ctx->queueFamilyIndices.compute;
135 bufferBarrier.size = VK_WHOLE_SIZE;
136 std::vector<VkBufferMemoryBarrier> bufferBarriers;
137 for (size_t i = 0; i < mBufferArgs.size(); i++)
138 {
139 bufferBarrier.buffer = mBufferArgs[i]->bufferHandle();
140 bufferBarriers.push_back(bufferBarrier);
141 }
142
143 vkCmdPipelineBarrier(
144 commandBuffer,
145 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
146 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
148 0, nullptr,
149 static_cast<uint32_t>(bufferBarriers.size()), bufferBarriers.data(),
150 0, nullptr);
151 }
152
153 void VkProgram::addComputeToGraphicsBarriers(VkCommandBuffer commandBuffer)
154 {
155 if (ctx->isComputeQueueSpecial()) {
156 VkBufferMemoryBarrier bufferBarrier = vks::initializers::bufferMemoryBarrier();
157 bufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
158 bufferBarrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
159 bufferBarrier.srcQueueFamilyIndex = ctx->queueFamilyIndices.compute;
160 bufferBarrier.dstQueueFamilyIndex = ctx->queueFamilyIndices.graphics;
161 bufferBarrier.size = VK_WHOLE_SIZE;
162 std::vector<VkBufferMemoryBarrier> bufferBarriers;
163 for (size_t i = 0; i < mBufferArgs.size(); i++)
164 {
165 bufferBarrier.buffer = mBufferArgs[i]->bufferHandle();
166 bufferBarriers.push_back(bufferBarrier);
167 }
168 // std::vector<VkBufferMemoryBarrier> bufferBarriers;
169 // bufferBarrier.buffer = input->bufferHandle();
170 // bufferBarriers.push_back(bufferBarrier);
171 // bufferBarrier.buffer = output->bufferHandle();
172 // bufferBarriers.push_back(bufferBarrier);
173 vkCmdPipelineBarrier(
174 commandBuffer,
175 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
176 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
178 0, nullptr,
179 static_cast<uint32_t>(bufferBarriers.size()), bufferBarriers.data(),
180 0, nullptr);
181 }
182 }
183
184
186 {
187 vkCmdBindPipeline(mCommandBuffers, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
188 }
189
190 void VkProgram::suspendInherentCmdBuffer(VkCommandBuffer cmdBuffer)
191 {
193 mCommandBuffers = cmdBuffer;
194 }
195
200
201 bool VkProgram::load(std::string fileName)
202 {
203 //Create pipeline layout
204 std::vector<VkPushConstantRange> pushConstantRanges;
205 for (size_t i = 0; i < mFormalConstants.size(); i++)
206 {
207 pushConstantRanges.push_back(vks::initializers::pushConstantRange(VK_SHADER_STAGE_COMPUTE_BIT, mFormalConstants[i]->bufferSize(), i));
208 }
209
210 VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
212 pipelineLayoutCreateInfo.pushConstantRangeCount = pushConstantRanges.size();
213 pipelineLayoutCreateInfo.pPushConstantRanges = pushConstantRanges.data();
214
215 VK_CHECK_RESULT(vkCreatePipelineLayout(ctx->deviceHandle(), &pipelineLayoutCreateInfo, nullptr, &pipelineLayout));
216
217 // Create pipeline
218 VkComputePipelineCreateInfo computePipelineCreateInfo = vks::initializers::computePipelineCreateInfo(pipelineLayout, 0);
219 computePipelineCreateInfo.stage = this->createComputeStage(fileName);
220 VK_CHECK_RESULT(vkCreateComputePipelines(ctx->deviceHandle(), ctx->pipelineCacheHandle(), 1, &computePipelineCreateInfo, nullptr, &pipeline));
221
222 return true;
223 }
224
225 VkPipelineShaderStageCreateInfo VkProgram::createComputeStage(std::string fileName)
226 {
227 VkPipelineShaderStageCreateInfo shaderStage = {};
228 shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
229 shaderStage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
230 shaderStage.module = vks::tools::loadShaderModule(fileName, ctx->deviceHandle());
231 shaderStage.pName = "main";
232 assert(shaderStage.module != VK_NULL_HANDLE);
233 shaderModules.push_back(shaderStage.module);
234 return shaderStage;
235 }
236
241
243 {
244 mFormalConstants.push_back(arg);
245
246 this->pushFormalParameter(arg);
247 }
248
250 {
251 mAllArgs.push_back(arg);
252 }
253
255 {
256 assert(arg != nullptr && arg->type() == VariableType::Constant);
257
258 mConstArgs.push_back(arg);
259 this->pushArgument(arg);
260 }
261
263 {
264 assert(arg != nullptr && arg->type() == VariableType::DeviceBuffer);
265
266 mBufferArgs.push_back(arg);
267 this->pushArgument(arg);
268 }
269
271 {
272 assert(arg != nullptr && arg->type() == VariableType::Uniform);
273
274 mUniformArgs.push_back(arg);
275 this->pushArgument(arg);
276 }
277
279 {
280 auto inst = VkSystem::instance();
282
283 // Create the command pool
284 VkCommandPoolCreateInfo cmdPoolInfo = {};
285 cmdPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
286 cmdPoolInfo.queueFamilyIndex = ctx->queueFamilyIndices.compute;
287 cmdPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
288 VK_CHECK_RESULT(vkCreateCommandPool(ctx->deviceHandle(), &cmdPoolInfo, nullptr, &commandPool));
289
290 // Create a command buffer for compute operations
291 VkCommandBufferAllocateInfo cmdBufAllocateInfo =
292 vks::initializers::commandBufferAllocateInfo(commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1);
293
294 VK_CHECK_RESULT(vkAllocateCommandBuffers(ctx->deviceHandle(), &cmdBufAllocateInfo, &commandBuffers));
295
296 VkFenceCreateInfo fenceInfo = vks::initializers::fenceCreateInfo(VK_FLAGS_NONE);
297 VK_CHECK_RESULT(vkCreateFence(ctx->deviceHandle(), &fenceInfo, nullptr, &mFence));
298
299 // Semaphores for graphics / compute synchronization
300 VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
301 VK_CHECK_RESULT(vkCreateSemaphore(ctx->deviceHandle(), &semaphoreCreateInfo, nullptr, &compute.semaphores.ready));
302 VK_CHECK_RESULT(vkCreateSemaphore(ctx->deviceHandle(), &semaphoreCreateInfo, nullptr, &compute.semaphores.complete));
303
304 // Create a compute capable device queue
305 vkGetDeviceQueue(ctx->deviceHandle(), ctx->queueFamilyIndices.compute, 0, &queue);
306 }
307
312
313 void VkMultiProgram::add(std::string name, std::shared_ptr<VkProgram> program)
314 {
315 assert(program != nullptr);
316 mPrograms[name] = program;
317 program->setVkCommandBuffer(commandBuffers);
318 }
319
321 {
322 VkCommandBufferBeginInfo cmdBufInfo = vks::initializers::commandBufferBeginInfo();
323 cmdBufInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
324
325 VK_CHECK_RESULT(vkBeginCommandBuffer(commandBuffers, &cmdBufInfo));
326
327 for (auto &pgm : mPrograms) {
328 pgm.second->suspendInherentCmdBuffer(commandBuffers);
329 }
330 //vkCmdBindPipeline(commandBuffers, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
331 }
332
334 {
335 vkResetFences(ctx->deviceHandle(), 1, &mFence);
336
337 // static bool firstDraw = true;
338 VkSubmitInfo computeSubmitInfo = vks::initializers::submitInfo();
339 // FIXME find a better way to do this (without using fences, which is much slower)
340 VkPipelineStageFlags computeWaitDstStageMask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
341 // if (!firstDraw) {
342 // computeSubmitInfo.waitSemaphoreCount = 1;
343 // computeSubmitInfo.pWaitSemaphores = &compute.semaphores.ready;
344 // computeSubmitInfo.pWaitDstStageMask = &computeWaitDstStageMask;
345 // }
346 // else {
347 // firstDraw = false;
348 // }
349 // computeSubmitInfo.signalSemaphoreCount = 1;
350 // computeSubmitInfo.pSignalSemaphores = &compute.semaphores.complete;
351 computeSubmitInfo.commandBufferCount = 1;
352 computeSubmitInfo.pCommandBuffers = &commandBuffers;
353
354 if (sync) {
355 VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &computeSubmitInfo, mFence));
356 VK_CHECK_RESULT(vkWaitForFences(ctx->deviceHandle(), 1, &mFence, VK_TRUE, UINT64_MAX));
357 }
358 else {
359 VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &computeSubmitInfo, VK_NULL_HANDLE));
360 }
361 }
362
364 {
365 for (auto &pgm : mPrograms) {
366 pgm.second->restoreInherentCmdBuffer();
367 }
368
369 // release the storage buffers back to the graphics queue
370 vkEndCommandBuffer(commandBuffers);
371 }
372
374 {
375 VK_CHECK_RESULT(vkWaitForFences(ctx->deviceHandle(), 1, &mFence, VK_TRUE, UINT64_MAX));
376 }
377}
assert(queueCount >=1)
#define VK_CHECK_RESULT(f)
Definition VulkanTools.h:55
#define VK_FLAGS_NONE
Definition VulkanTools.h:39
struct dyno::VkMultiProgram::@016024047062303122011057236362361021214245030321 compute
std::map< std::string, std::shared_ptr< VkProgram > > mPrograms
Definition VkProgram.h:437
void update(bool sync=false)
VkCommandBuffer commandBuffers
Definition VkProgram.h:444
void add(std::string name, std::shared_ptr< VkProgram > program)
VkCommandPool commandPool
Definition VkProgram.h:443
void pushArgument(VkVariable *arg)
VkPipeline pipeline
Definition VkProgram.h:190
void pushUniform(VkVariable *arg)
std::vector< VkVariable * > mFormalParamters
Definition VkProgram.h:177
VkDescriptorSetLayout descriptorSetLayout
Definition VkProgram.h:187
void update(bool sync=false)
Definition VkProgram.cpp:63
VkDescriptorSet descriptorSet
Definition VkProgram.h:188
std::vector< VkVariable * > mAllArgs
Definition VkProgram.h:180
bool load(std::string fileName)
std::vector< VkVariable * > mUniformArgs
Definition VkProgram.h:182
VkPipelineLayout pipelineLayout
Definition VkProgram.h:189
void pushConstant(VkVariable *arg)
VkCommandPool mCommandPool
Definition VkProgram.h:194
VkDescriptorPool descriptorPool
Definition VkProgram.h:186
void pushFormalParameter(VkVariable *arg)
std::vector< VkVariable * > mBufferArgs
Definition VkProgram.h:181
void addGraphicsToComputeBarriers(VkCommandBuffer commandBuffer)
Definition VkProgram.cpp:98
VkCommandBuffer mCommandBuffers
Definition VkProgram.h:195
struct dyno::VkProgram::@173005120305027326137125156036200106005335301235 compute
void addComputeToComputeBarriers(VkCommandBuffer commandBuffer)
void restoreInherentCmdBuffer()
void addComputeToGraphicsBarriers(VkCommandBuffer commandBuffer)
std::vector< VkVariable * > mFormalConstants
Definition VkProgram.h:178
std::vector< VkShaderModule > shaderModules
Definition VkProgram.h:198
VkPipelineShaderStageCreateInfo createComputeStage(std::string fileName)
void pushDeviceBuffer(VkVariable *arg)
std::vector< VkVariable * > mConstArgs
Definition VkProgram.h:183
void dispatch(dim3 groupSize)
Definition VkProgram.cpp:39
void pushFormalConstant(VkVariable *arg)
VkContext * ctx
Definition VkProgram.h:175
VkCommandBuffer mCmdBufferCopy
Definition VkProgram.h:197
void suspendInherentCmdBuffer(VkCommandBuffer cmdBuffer)
VkContext * currentContext()
Definition VkSystem.h:21
static VkSystem * instance()
Definition VkSystem.cpp:10
This is an implementation of AdditiveCCD based on peridyno.
Definition Array.h:25
DYN_FUNC Real arg(const Complex< Real > &)
Definition Complex.inl:273
@ DeviceBuffer
Device buffer.
Definition VkVariable.h:15
@ Uniform
Uniform variable.
Definition VkVariable.h:18
@ Constant
Constant variable.
Definition VkVariable.h:17
VkComputePipelineCreateInfo computePipelineCreateInfo(VkPipelineLayout layout, VkPipelineCreateFlags flags=0)
VkCommandBufferAllocateInfo commandBufferAllocateInfo(VkCommandPool commandPool, VkCommandBufferLevel level, uint32_t bufferCount)
VkPushConstantRange pushConstantRange(VkShaderStageFlags stageFlags, uint32_t size, uint32_t offset)
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo(const VkDescriptorSetLayout *pSetLayouts, uint32_t setLayoutCount=1)
VkFenceCreateInfo fenceCreateInfo(VkFenceCreateFlags flags=0)
VkCommandBufferBeginInfo commandBufferBeginInfo()
VkSemaphoreCreateInfo semaphoreCreateInfo()
VkBufferMemoryBarrier bufferMemoryBarrier()
Initialize a buffer memory barrier with no image transfer ownership.
VkShaderModule loadShaderModule(const std::string fileName, VkDevice device)