source: opengl-game/graphics-pipeline_vulkan.hpp@ 2d87297

feature/imgui-sdl points-test
Last change on this file since 2d87297 was 2d87297, checked in by Dmitry Portnoy <dmitry.portnoy@…>, 5 years ago

In VulkanGame, add an ssbo field to SceneObject to hold per-object ssbo info, and add a new SSBOType template parameter to SceneObject and GraphicsPipeline_Vulkan

  • Property mode set to 100644
File size: 21.6 KB
Line 
1#ifndef _GRAPHICS_PIPELINE_VULKAN_H
2#define _GRAPHICS_PIPELINE_VULKAN_H
3
4#include "graphics-pipeline.hpp"
5
6#include <fstream>
7#include <stdexcept>
8#include <vector>
9
10#include <vulkan/vulkan.h>
11
12#define GLM_FORCE_RADIANS
13#define GLM_FORCE_DEPTH_ZERO_TO_ONE // Since, in Vulkan, the depth range is 0 to 1 instead of -1 to 1
14#define GLM_FORCE_RIGHT_HANDED
15
16#include <glm/glm.hpp>
17#include <glm/gtc/matrix_transform.hpp>
18
19#include "vulkan-utils.hpp"
20
21using namespace glm;
22
23// TODO: Maybe change the name of this struct so I can call the list something other than descriptorInfoList
24struct DescriptorInfo {
25 VkDescriptorType type;
26 VkShaderStageFlags stageFlags;
27
28 // Only one of the below properties should be set
29 vector<VkDescriptorBufferInfo>* bufferDataList;
30 VkDescriptorImageInfo* imageData;
31};
32
33template<class VertexType, class SSBOType>
34class GraphicsPipeline_Vulkan : public GraphicsPipeline {
35 public:
36 GraphicsPipeline_Vulkan();
37 GraphicsPipeline_Vulkan(VkPhysicalDevice physicalDevice, VkDevice device, VkRenderPass renderPass,
38 Viewport viewport, size_t vertexCapacity, size_t indexCapacity);
39 ~GraphicsPipeline_Vulkan();
40
41 size_t getNumVertices();
42
43 void updateRenderPass(VkRenderPass renderPass);
44
45 // Maybe I should rename these to addVertexAttribute (addVaryingAttribute) and addUniformAttribute
46
47 void addAttribute(VkFormat format, size_t offset);
48
49 void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, vector<VkDescriptorBufferInfo>* bufferData);
50 void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData);
51
52 void createPipeline(string vertShaderFile, string fragShaderFile);
53 void createDescriptorSetLayout();
54 void createDescriptorPool(vector<VkImage>& swapChainImages);
55 void createDescriptorSets(vector<VkImage>& swapChainImages);
56
57 void createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage);
58
59 void addVertices(const vector<VertexType>& vertices, vector<uint16_t> indices, VkCommandPool commandPool,
60 VkQueue graphicsQueue);
61
62 void cleanup();
63 void cleanupBuffers();
64
65 private:
66 VkPhysicalDevice physicalDevice;
67 VkDevice device;
68 VkRenderPass renderPass;
69
70 VkPipeline pipeline;
71 VkPipelineLayout pipelineLayout;
72
73 VkVertexInputBindingDescription bindingDescription;
74
75 vector<VkVertexInputAttributeDescription> attributeDescriptions;
76 vector<DescriptorInfo> descriptorInfoList;
77
78 VkDescriptorSetLayout descriptorSetLayout;
79 VkDescriptorPool descriptorPool;
80 vector<VkDescriptorSet> descriptorSets;
81
82 size_t numVertices;
83 size_t vertexCapacity;
84 VkBuffer vertexBuffer;
85 VkDeviceMemory vertexBufferMemory;
86
87 size_t numIndices;
88 size_t indexCapacity;
89 VkBuffer indexBuffer;
90 VkDeviceMemory indexBufferMemory;
91
92 VkShaderModule createShaderModule(const vector<char>& code);
93 vector<char> readFile(const string& filename);
94
95 void resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
96 void resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
97};
98
99/*** PUBLIC METHODS ***/
100
101template<class VertexType, class SSBOType>
102GraphicsPipeline_Vulkan<VertexType, SSBOType>::GraphicsPipeline_Vulkan() {
103}
104
105// TODO: Verify that vertex capacity and index capacity are both > 0
106template<class VertexType, class SSBOType>
107GraphicsPipeline_Vulkan<VertexType, SSBOType>::GraphicsPipeline_Vulkan(
108 VkPhysicalDevice physicalDevice, VkDevice device,
109 VkRenderPass renderPass, Viewport viewport, size_t vertexCapacity, size_t indexCapacity) {
110 this->physicalDevice = physicalDevice;
111 this->device = device;
112 this->renderPass = renderPass;
113 this->viewport = viewport;
114
115 // Since there is only one array of vertex data, we use binding = 0
116 // I'll probably do that for the foreseeable future
117 // I can calculate the stride myself given info about all the varying attributes
118 this->bindingDescription.binding = 0;
119 this->bindingDescription.stride = sizeof(VertexType);
120 this->bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
121
122 this->numVertices = 0;
123 this->vertexCapacity = vertexCapacity;
124
125 VulkanUtils::createBuffer(device, physicalDevice, vertexCapacity * sizeof(VertexType),
126 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
127 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);
128
129 this->numIndices = 0;
130 this->indexCapacity = indexCapacity;
131
132 VulkanUtils::createBuffer(device, physicalDevice, indexCapacity * sizeof(uint16_t),
133 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
134 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory);
135}
136
137template<class VertexType, class SSBOType>
138GraphicsPipeline_Vulkan<VertexType, SSBOType>::~GraphicsPipeline_Vulkan() {
139}
140
141template<class VertexType, class SSBOType>
142size_t GraphicsPipeline_Vulkan<VertexType, SSBOType>::getNumVertices() {
143 return numVertices;
144}
145
146template<class VertexType, class SSBOType>
147void GraphicsPipeline_Vulkan<VertexType, SSBOType>::updateRenderPass(VkRenderPass renderPass) {
148 this->renderPass = renderPass;
149}
150
151template<class VertexType, class SSBOType>
152void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addAttribute(VkFormat format, size_t offset) {
153 VkVertexInputAttributeDescription attributeDesc = {};
154
155 attributeDesc.binding = 0;
156 attributeDesc.location = this->attributeDescriptions.size();
157 attributeDesc.format = format;
158 attributeDesc.offset = offset;
159
160 this->attributeDescriptions.push_back(attributeDesc);
161}
162
163template<class VertexType, class SSBOType>
164void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, vector<VkDescriptorBufferInfo>* bufferData) {
165 this->descriptorInfoList.push_back({ type, stageFlags, bufferData, nullptr });
166}
167
168template<class VertexType, class SSBOType>
169void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData) {
170 this->descriptorInfoList.push_back({ type, stageFlags, nullptr, imageData });
171}
172
173template<class VertexType, class SSBOType>
174void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createPipeline(string vertShaderFile, string fragShaderFile) {
175 vector<char> vertShaderCode = readFile(vertShaderFile);
176 vector<char> fragShaderCode = readFile(fragShaderFile);
177
178 VkShaderModule vertShaderModule = createShaderModule(vertShaderCode);
179 VkShaderModule fragShaderModule = createShaderModule(fragShaderCode);
180
181 VkPipelineShaderStageCreateInfo vertShaderStageInfo = {};
182 vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
183 vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
184 vertShaderStageInfo.module = vertShaderModule;
185 vertShaderStageInfo.pName = "main";
186
187 VkPipelineShaderStageCreateInfo fragShaderStageInfo = {};
188 fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
189 fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
190 fragShaderStageInfo.module = fragShaderModule;
191 fragShaderStageInfo.pName = "main";
192
193 VkPipelineShaderStageCreateInfo shaderStages[] = { vertShaderStageInfo, fragShaderStageInfo };
194
195 VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
196 vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
197
198 vertexInputInfo.vertexBindingDescriptionCount = 1;
199 vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(this->attributeDescriptions.size());
200 vertexInputInfo.pVertexBindingDescriptions = &this->bindingDescription;
201 vertexInputInfo.pVertexAttributeDescriptions = this->attributeDescriptions.data();
202
203 VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
204 inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
205 inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
206 inputAssembly.primitiveRestartEnable = VK_FALSE;
207
208 VkViewport viewport = {};
209 viewport.x = (float)this->viewport.x;
210 viewport.y = (float)this->viewport.y;
211 viewport.width = (float)this->viewport.width;
212 viewport.height = (float)this->viewport.height;
213 viewport.minDepth = 0.0f;
214 viewport.maxDepth = 1.0f;
215
216 VkRect2D scissor = {};
217 scissor.offset = { 0, 0 };
218 scissor.extent = { (uint32_t)this->viewport.width, (uint32_t)this->viewport.height };
219
220 VkPipelineViewportStateCreateInfo viewportState = {};
221 viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
222 viewportState.viewportCount = 1;
223 viewportState.pViewports = &viewport;
224 viewportState.scissorCount = 1;
225 viewportState.pScissors = &scissor;
226
227 VkPipelineRasterizationStateCreateInfo rasterizer = {};
228 rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
229 rasterizer.depthClampEnable = VK_FALSE;
230 rasterizer.rasterizerDiscardEnable = VK_FALSE;
231 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
232 rasterizer.lineWidth = 1.0f;
233 rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
234 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
235 rasterizer.depthBiasEnable = VK_FALSE;
236
237 VkPipelineMultisampleStateCreateInfo multisampling = {};
238 multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
239 multisampling.sampleShadingEnable = VK_FALSE;
240 multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
241
242 VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
243 colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
244 colorBlendAttachment.blendEnable = VK_TRUE;
245 colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
246 colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
247 colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
248 colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
249 colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
250 colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
251
252 VkPipelineColorBlendStateCreateInfo colorBlending = {};
253 colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
254 colorBlending.logicOpEnable = VK_FALSE;
255 colorBlending.logicOp = VK_LOGIC_OP_COPY;
256 colorBlending.attachmentCount = 1;
257 colorBlending.pAttachments = &colorBlendAttachment;
258 colorBlending.blendConstants[0] = 0.0f;
259 colorBlending.blendConstants[1] = 0.0f;
260 colorBlending.blendConstants[2] = 0.0f;
261 colorBlending.blendConstants[3] = 0.0f;
262
263 VkPipelineDepthStencilStateCreateInfo depthStencil = {};
264 depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
265 depthStencil.depthTestEnable = VK_TRUE;
266 depthStencil.depthWriteEnable = VK_TRUE;
267 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
268 depthStencil.depthBoundsTestEnable = VK_FALSE;
269 depthStencil.minDepthBounds = 0.0f;
270 depthStencil.maxDepthBounds = 1.0f;
271 depthStencil.stencilTestEnable = VK_FALSE;
272 depthStencil.front = {};
273 depthStencil.back = {};
274
275 VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
276 pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
277 pipelineLayoutInfo.setLayoutCount = 1;
278 pipelineLayoutInfo.pSetLayouts = &this->descriptorSetLayout;
279 pipelineLayoutInfo.pushConstantRangeCount = 0;
280
281 if (vkCreatePipelineLayout(this->device, &pipelineLayoutInfo, nullptr, &this->pipelineLayout) != VK_SUCCESS) {
282 throw runtime_error("failed to create pipeline layout!");
283 }
284
285 VkGraphicsPipelineCreateInfo pipelineInfo = {};
286 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
287 pipelineInfo.stageCount = 2;
288 pipelineInfo.pStages = shaderStages;
289 pipelineInfo.pVertexInputState = &vertexInputInfo;
290 pipelineInfo.pInputAssemblyState = &inputAssembly;
291 pipelineInfo.pViewportState = &viewportState;
292 pipelineInfo.pRasterizationState = &rasterizer;
293 pipelineInfo.pMultisampleState = &multisampling;
294 pipelineInfo.pDepthStencilState = &depthStencil;
295 pipelineInfo.pColorBlendState = &colorBlending;
296 pipelineInfo.pDynamicState = nullptr;
297 pipelineInfo.layout = this->pipelineLayout;
298 pipelineInfo.renderPass = this->renderPass;
299 pipelineInfo.subpass = 0;
300 pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
301 pipelineInfo.basePipelineIndex = -1;
302
303 if (vkCreateGraphicsPipelines(this->device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &this->pipeline) != VK_SUCCESS) {
304 throw runtime_error("failed to create graphics pipeline!");
305 }
306
307 vkDestroyShaderModule(this->device, vertShaderModule, nullptr);
308 vkDestroyShaderModule(this->device, fragShaderModule, nullptr);
309}
310
311template<class VertexType, class SSBOType>
312void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createDescriptorSetLayout() {
313 vector<VkDescriptorSetLayoutBinding> bindings(this->descriptorInfoList.size());
314
315 for (size_t i = 0; i < bindings.size(); i++) {
316 bindings[i].binding = i;
317 bindings[i].descriptorCount = 1;
318 bindings[i].descriptorType = this->descriptorInfoList[i].type;
319 bindings[i].stageFlags = this->descriptorInfoList[i].stageFlags;
320 bindings[i].pImmutableSamplers = nullptr;
321 }
322
323 VkDescriptorSetLayoutCreateInfo layoutInfo = {};
324 layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
325 layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
326 layoutInfo.pBindings = bindings.data();
327
328 if (vkCreateDescriptorSetLayout(this->device, &layoutInfo, nullptr, &this->descriptorSetLayout) != VK_SUCCESS) {
329 throw runtime_error("failed to create descriptor set layout!");
330 }
331}
332
333template<class VertexType, class SSBOType>
334void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createDescriptorPool(vector<VkImage>& swapChainImages) {
335 vector<VkDescriptorPoolSize> poolSizes(this->descriptorInfoList.size());
336
337 for (size_t i = 0; i < poolSizes.size(); i++) {
338 poolSizes[i].type = this->descriptorInfoList[i].type;
339 poolSizes[i].descriptorCount = static_cast<uint32_t>(swapChainImages.size());
340 }
341
342 VkDescriptorPoolCreateInfo poolInfo = {};
343 poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
344 poolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
345 poolInfo.pPoolSizes = poolSizes.data();
346 poolInfo.maxSets = static_cast<uint32_t>(swapChainImages.size());
347
348 if (vkCreateDescriptorPool(this->device, &poolInfo, nullptr, &this->descriptorPool) != VK_SUCCESS) {
349 throw runtime_error("failed to create descriptor pool!");
350 }
351}
352
353template<class VertexType, class SSBOType>
354void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createDescriptorSets(vector<VkImage>& swapChainImages) {
355 vector<VkDescriptorSetLayout> layouts(swapChainImages.size(), this->descriptorSetLayout);
356
357 VkDescriptorSetAllocateInfo allocInfo = {};
358 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
359 allocInfo.descriptorPool = this->descriptorPool;
360 allocInfo.descriptorSetCount = static_cast<uint32_t>(swapChainImages.size());
361 allocInfo.pSetLayouts = layouts.data();
362
363 this->descriptorSets.resize(swapChainImages.size());
364 if (vkAllocateDescriptorSets(device, &allocInfo, this->descriptorSets.data()) != VK_SUCCESS) {
365 throw runtime_error("failed to allocate descriptor sets!");
366 }
367
368 for (size_t i = 0; i < swapChainImages.size(); i++) {
369 vector<VkWriteDescriptorSet> descriptorWrites(this->descriptorInfoList.size());
370
371 for (size_t j = 0; j < descriptorWrites.size(); j++) {
372 descriptorWrites[j].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
373 descriptorWrites[j].dstSet = this->descriptorSets[i];
374 descriptorWrites[j].dstBinding = j;
375 descriptorWrites[j].dstArrayElement = 0;
376 descriptorWrites[j].descriptorType = this->descriptorInfoList[j].type;
377 descriptorWrites[j].descriptorCount = 1;
378 descriptorWrites[j].pBufferInfo = nullptr;
379 descriptorWrites[j].pImageInfo = nullptr;
380 descriptorWrites[j].pTexelBufferView = nullptr;
381
382 switch (descriptorWrites[j].descriptorType) {
383 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
384 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
385 descriptorWrites[j].pBufferInfo = &(*this->descriptorInfoList[j].bufferDataList)[i];
386 break;
387 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
388 descriptorWrites[j].pImageInfo = this->descriptorInfoList[j].imageData;
389 break;
390 default:
391 throw runtime_error("Unknown descriptor type: " + to_string(descriptorWrites[j].descriptorType));
392 }
393 }
394
395 vkUpdateDescriptorSets(this->device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
396 }
397}
398
399template<class VertexType, class SSBOType>
400void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage) {
401 vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
402 vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1,
403 &descriptorSets[currentImage], 0, nullptr);
404
405 VkBuffer vertexBuffers[] = { vertexBuffer };
406 VkDeviceSize offsets[] = { 0 };
407 vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
408
409 vkCmdBindIndexBuffer(commandBuffer, indexBuffer, 0, VK_INDEX_TYPE_UINT16);
410
411 vkCmdDrawIndexed(commandBuffer, static_cast<uint32_t>(numIndices), 1, 0, 0, 0);
412}
413
414template<class VertexType, class SSBOType>
415void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addVertices(const vector<VertexType>& vertices, vector<uint16_t> indices,
416 VkCommandPool commandPool, VkQueue graphicsQueue) {
417
418 if (numVertices + vertices.size() > vertexCapacity) {
419 resizeVertexBuffer(commandPool, graphicsQueue);
420 }
421 if (numIndices + indices.size() > indexCapacity) {
422 resizeIndexBuffer(commandPool, graphicsQueue);
423 }
424
425 VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, vertices, vertexBuffer, numVertices,
426 graphicsQueue);
427 numVertices += vertices.size();
428
429 VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, indices, indexBuffer, numIndices,
430 graphicsQueue);
431 numIndices += indices.size();
432}
433
434template<class VertexType, class SSBOType>
435void GraphicsPipeline_Vulkan<VertexType, SSBOType>::cleanup() {
436 vkDestroyPipeline(device, pipeline, nullptr);
437 vkDestroyDescriptorPool(device, descriptorPool, nullptr);
438 vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
439}
440
441template<class VertexType, class SSBOType>
442void GraphicsPipeline_Vulkan<VertexType, SSBOType>::cleanupBuffers() {
443 vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
444
445 vkDestroyBuffer(device, vertexBuffer, nullptr);
446 vkFreeMemory(device, vertexBufferMemory, nullptr);
447 vkDestroyBuffer(device, indexBuffer, nullptr);
448 vkFreeMemory(device, indexBufferMemory, nullptr);
449}
450
451/*** PRIVATE METHODS ***/
452
453template<class VertexType, class SSBOType>
454VkShaderModule GraphicsPipeline_Vulkan<VertexType, SSBOType>::createShaderModule(const vector<char>& code) {
455 VkShaderModuleCreateInfo createInfo = {};
456 createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
457 createInfo.codeSize = code.size();
458 createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
459
460 VkShaderModule shaderModule;
461 if (vkCreateShaderModule(this->device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
462 throw runtime_error("failed to create shader module!");
463 }
464
465 return shaderModule;
466}
467
468template<class VertexType, class SSBOType>
469vector<char> GraphicsPipeline_Vulkan<VertexType, SSBOType>::readFile(const string& filename) {
470 ifstream file(filename, ios::ate | ios::binary);
471
472 if (!file.is_open()) {
473 throw runtime_error("failed to open file!");
474 }
475
476 size_t fileSize = (size_t)file.tellg();
477 vector<char> buffer(fileSize);
478
479 file.seekg(0);
480 file.read(buffer.data(), fileSize);
481
482 file.close();
483
484 return buffer;
485}
486
487template<class VertexType, class SSBOType>
488void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
489 VkBuffer newVertexBuffer;
490 VkDeviceMemory newVertexBufferMemory;
491 vertexCapacity *= 2;
492
493 VulkanUtils::createBuffer(device, physicalDevice, vertexCapacity * sizeof(VertexType),
494 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
495 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, newVertexBuffer, newVertexBufferMemory);
496
497 VulkanUtils::copyBuffer(device, commandPool, vertexBuffer, newVertexBuffer, 0, 0, numVertices * sizeof(VertexType), graphicsQueue);
498
499 vkDestroyBuffer(device, vertexBuffer, nullptr);
500 vkFreeMemory(device, vertexBufferMemory, nullptr);
501
502 vertexBuffer = newVertexBuffer;
503 vertexBufferMemory = newVertexBufferMemory;
504}
505
506template<class VertexType, class SSBOType>
507void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
508 VkBuffer newIndexBuffer;
509 VkDeviceMemory newIndexBufferMemory;
510 indexCapacity *= 2;
511
512 VulkanUtils::createBuffer(device, physicalDevice, indexCapacity * sizeof(uint16_t),
513 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
514 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, newIndexBuffer, newIndexBufferMemory);
515
516 VulkanUtils::copyBuffer(device, commandPool, indexBuffer, newIndexBuffer, 0, 0, numIndices * sizeof(uint16_t), graphicsQueue);
517
518 vkDestroyBuffer(device, indexBuffer, nullptr);
519 vkFreeMemory(device, indexBufferMemory, nullptr);
520
521 indexBuffer = newIndexBuffer;
522 indexBufferMemory = newIndexBufferMemory;
523}
524
525#endif // _GRAPHICS_PIPELINE_VULKAN_H
Note: See TracBrowser for help on using the repository browser.