source: opengl-game/graphics-pipeline_vulkan.hpp@ 683dd55

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

Add a getObjects() method to the GraphicsPipeline_Vulkan class that returns a reference to the list of objects added to the pipeline, and use that method instead of the numPlanes variable to keep track of the number of textured planes. Also, update the shader compilation batch file and add header files as dependencies to the vulkangame target in the makefile.

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