source: opengl-game/graphics-pipeline_vulkan.hpp@ cd1cb0f

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

In VulkanGame, make the ship move when the player holds down the right or left arrow keys

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