Engine
Frameworkcreatedbymeusableforthecreationofsimplegames.CurrentlysupportsOpenGL(Verysimple)andVulkan.
VulkanComputePipeline.cpp
Go to the documentation of this file.
2 #ifdef USING_VULKAN
3 
6 
8 
9 #include <stdio.h>
10 
11 namespace Engine {
12 
13  VulkanComputePipeline::VulkanComputePipeline(VulkanLogicalDevice * logicalDevice)
14  {
15  this->device_ = logicalDevice;
16  }
17 
18  VulkanComputePipeline::~VulkanComputePipeline()
19  {
20  vkDestroyPipeline(device_->GetDevice(), pipeline_, nullptr);
21 
22  vkDestroyPipelineLayout(device_->GetDevice(), pipelineLayout_, nullptr);
23 
24  for (size_t i = 0, size = descriptorSets_.size(); i < size; ++i) {
25  vkDestroyDescriptorSetLayout(device_->GetDevice(), descriptorSets_[i].descriptorSet, nullptr);
26  }
27 
28  vkDestroyShaderModule(device_->GetDevice(), computeShader_, nullptr);
29  }
30 
31  void VulkanComputePipeline::SetComputeShader(eastl::string name)
32  {
33  eastl::string path = "Resources/Shaders/Vulkan/Compiled/" + name;
34 
35  FILE* file = fopen(path.c_str(), "rb");
36  if (!file) {
37  eastl::string s = "Opening shader file " + path + " failed";
38  debug_error("VulkanComputePipeline", "SetComputeShader", s);
39  return;
40  }
41 
42  fseek(file, 0L, SEEK_END);
43  size_t fileSize = static_cast<size_t>(ftell(file));
44  computeShaderData_.resize(fileSize);
45  fseek(file, 0L, SEEK_SET);
46  fread(computeShaderData_.data(), sizeof(char), fileSize, file);
47 
48  VkShaderModuleCreateInfo createInfo = {};
49  createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
50  createInfo.codeSize = computeShaderData_.size();
51  createInfo.pCode = reinterpret_cast<const uint32_t*>(computeShaderData_.data());
52 
53  vkCreateShaderModule(device_->GetDevice(), &createInfo, nullptr, &computeShader_);
54  }
55 
56  void VulkanComputePipeline::AddSpecializationMapEntry(uint32_t constantID, eastl::vector<uint32_t> data)
57  {
58  VkSpecializationMapEntry entry = {};
59  entry.constantID = constantID;
60  entry.offset = static_cast<uint32_t>(sizeof(uint32_t)*specializationData_.size());
61  entry.size = static_cast<uint32_t>(sizeof(uint32_t)*data.size());
62 
63  specializationData_.insert(specializationData_.end(), data.begin(), data.end());
64  }
65 
66  void VulkanComputePipeline::AddDescriptorSetBinding(descriptorSetHandle set, uint32_t binding, VkDescriptorType type, uint32_t descriptorCount, VkShaderStageFlags shaderStage, const VkSampler * immutableSamplers)
67  {
68  VkDescriptorSetLayoutBinding descriptorBinding = {};
69  descriptorBinding.binding = binding;
70  descriptorBinding.descriptorCount = descriptorCount;
71  descriptorBinding.descriptorType = type;
72  descriptorBinding.stageFlags = shaderStage;
73  descriptorBinding.pImmutableSamplers = immutableSamplers;
74 
75  if (set<descriptorSets_.size()) {
76  descriptorSets_[set].descriptionSetLayoutBindings.push_back(descriptorBinding);
77  }
78  }
79 
80  VulkanComputePipeline::descriptorSetHandle VulkanComputePipeline::CreateDescriptorSet()
81  {
82  DescriptorSet set = {};
83  descriptorSets_.push_back(set);
84  return descriptorSets_.size() - 1;
85  }
86 
87  VulkanComputePipeline::descriptorSetHandle VulkanComputePipeline::AddDescriptorSetLayout(VkDescriptorSetLayout layout)
88  {
89  DescriptorSet set = {};
90  set.descriptorSet = layout;
91  set.external = true;
92  descriptorSets_.push_back(set);
93  return descriptorSets_.size() - 1;
94  }
95 
96  VkDescriptorSetLayout VulkanComputePipeline::GetDescriptorSetLayout(descriptorSetHandle handle)
97  {
98  return descriptorSets_[handle].descriptorSet;
99  }
100 
101  void VulkanComputePipeline::AddPushConstantRange(VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size)
102  {
103  VkPushConstantRange range = {};
104  range.stageFlags = stageFlags;
105  range.size = size;
106  range.offset = offset;
107 
108  pushConstantRanges_.push_back(range);
109  }
110 
111  VkPipelineLayout VulkanComputePipeline::GetPipelineLayout() const
112  {
113  return pipelineLayout_;
114  }
115 
116  void VulkanComputePipeline::Compile()
117  {
118  computeShaderSpecializationInfo_ = {};
119  computeShaderSpecializationInfo_.mapEntryCount = static_cast<uint32_t>(specializationMapEntries_.size());
120  computeShaderSpecializationInfo_.pMapEntries = specializationMapEntries_.data();
121  computeShaderSpecializationInfo_.dataSize = static_cast<uint32_t>(specializationData_.size() * sizeof(uint32_t));
122  computeShaderSpecializationInfo_.pData = specializationData_.data();
123 
124  VkPipelineShaderStageCreateInfo shaderInfo = {};
125  shaderInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
126  shaderInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT;
127  shaderInfo.module = computeShader_;
128  shaderInfo.pName = "main";
129  shaderInfo.pSpecializationInfo = &computeShaderSpecializationInfo_;
130 
131  eastl::vector<VkDescriptorSetLayout> descriptorLayouts;
132 
133  for (size_t i = 0, size = descriptorSets_.size(); i < size; ++i) {
134  if (descriptorSets_[i].descriptorSet == 0) {
135  VkDescriptorSetLayoutCreateInfo createInfo = {};
136  createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
137  createInfo.bindingCount = static_cast<uint32_t>(descriptorSets_[i].descriptionSetLayoutBindings.size());
138  createInfo.pBindings = descriptorSets_[i].descriptionSetLayoutBindings.data();
139 
140  vkCreateDescriptorSetLayout(device_->GetDevice(), &createInfo, nullptr, &descriptorSets_[i].descriptorSet);
141  }
142  descriptorLayouts.push_back(descriptorSets_[i].descriptorSet);
143  }
144 
145  pipelineLayoutInfo_ = {};
146  pipelineLayoutInfo_.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
147  pipelineLayoutInfo_.pPushConstantRanges = pushConstantRanges_.data();
148  pipelineLayoutInfo_.pushConstantRangeCount = static_cast<uint32_t>(pushConstantRanges_.size());
149  pipelineLayoutInfo_.setLayoutCount = static_cast<uint32_t>(descriptorLayouts.size());
150  pipelineLayoutInfo_.pSetLayouts = descriptorLayouts.data();
151 
152  vkCreatePipelineLayout(device_->GetDevice(), &pipelineLayoutInfo_, nullptr, &pipelineLayout_);
153 
154  VkComputePipelineCreateInfo pipelineInfo = {};
155  pipelineInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
156  pipelineInfo.stage = shaderInfo;
157  pipelineInfo.layout = pipelineLayout_;
158  pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
159  pipelineInfo.basePipelineIndex = -1;
160 
161  vkCreateComputePipelines(device_->GetDevice(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline_);
162  }
163 
164  VkPipeline VulkanComputePipeline::GetPipeline() const
165  {
166  return pipeline_;
167  }
168 
169 } // namespace Engine
170 
171 #endif // USING_VULKAN
#define debug_error(debug_class, function, value)
This functions logs a debug error to the log and console. This does not halt the program! ...
Definition: Logging.hpp:30