source: opengl-game/graphics-pipeline_vulkan.hpp@ 06d959f

feature/imgui-sdl points-test
Last change on this file since 06d959f was 06d959f, checked in by Dmitry Portnoy <dmp1488@…>, 5 years ago

Add an addVertexNormals method to VulkanGame that calculates the normals given a list of vertices

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