source: opengl-game/graphics-pipeline_vulkan.hpp@ 0fe8433

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

Create an addObject() method in VulkanGame (which wraps the old addObject() method in GraphicsPipeline_Vulkan), and move the list of objects and other code to manage objects from the pipeline to the VulkanGame class

  • Property mode set to 100644
File size: 21.0 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>
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>
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>
141size_t GraphicsPipeline_Vulkan<VertexType>::getNumVertices() {
142 return numVertices;
143}
144
145template<class VertexType>
146void GraphicsPipeline_Vulkan<VertexType>::updateRenderPass(VkRenderPass renderPass) {
147 this->renderPass = renderPass;
148}
149
150template<class VertexType>
151void GraphicsPipeline_Vulkan<VertexType>::addAttribute(VkFormat format, size_t offset) {
152 VkVertexInputAttributeDescription attributeDesc = {};
153
154 attributeDesc.binding = 0;
155 attributeDesc.location = this->attributeDescriptions.size();
156 attributeDesc.format = format;
157 attributeDesc.offset = offset;
158
159 this->attributeDescriptions.push_back(attributeDesc);
160}
161
162template<class VertexType>
163void GraphicsPipeline_Vulkan<VertexType>::addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, vector<VkDescriptorBufferInfo>* bufferData) {
164 this->descriptorInfoList.push_back({ type, stageFlags, bufferData, nullptr });
165}
166
167template<class VertexType>
168void GraphicsPipeline_Vulkan<VertexType>::addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData) {
169 this->descriptorInfoList.push_back({ type, stageFlags, nullptr, imageData });
170}
171
172template<class VertexType>
173void GraphicsPipeline_Vulkan<VertexType>::createPipeline(string vertShaderFile, string fragShaderFile) {
174 vector<char> vertShaderCode = readFile(vertShaderFile);
175 vector<char> fragShaderCode = readFile(fragShaderFile);
176
177 VkShaderModule vertShaderModule = createShaderModule(vertShaderCode);
178 VkShaderModule fragShaderModule = createShaderModule(fragShaderCode);
179
180 VkPipelineShaderStageCreateInfo vertShaderStageInfo = {};
181 vertShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
182 vertShaderStageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT;
183 vertShaderStageInfo.module = vertShaderModule;
184 vertShaderStageInfo.pName = "main";
185
186 VkPipelineShaderStageCreateInfo fragShaderStageInfo = {};
187 fragShaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
188 fragShaderStageInfo.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
189 fragShaderStageInfo.module = fragShaderModule;
190 fragShaderStageInfo.pName = "main";
191
192 VkPipelineShaderStageCreateInfo shaderStages[] = { vertShaderStageInfo, fragShaderStageInfo };
193
194 VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
195 vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
196
197 vertexInputInfo.vertexBindingDescriptionCount = 1;
198 vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(this->attributeDescriptions.size());
199 vertexInputInfo.pVertexBindingDescriptions = &this->bindingDescription;
200 vertexInputInfo.pVertexAttributeDescriptions = this->attributeDescriptions.data();
201
202 VkPipelineInputAssemblyStateCreateInfo inputAssembly = {};
203 inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
204 inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
205 inputAssembly.primitiveRestartEnable = VK_FALSE;
206
207 VkViewport viewport = {};
208 viewport.x = (float)this->viewport.x;
209 viewport.y = (float)this->viewport.y;
210 viewport.width = (float)this->viewport.width;
211 viewport.height = (float)this->viewport.height;
212 viewport.minDepth = 0.0f;
213 viewport.maxDepth = 1.0f;
214
215 VkRect2D scissor = {};
216 scissor.offset = { 0, 0 };
217 scissor.extent = { (uint32_t)this->viewport.width, (uint32_t)this->viewport.height };
218
219 VkPipelineViewportStateCreateInfo viewportState = {};
220 viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
221 viewportState.viewportCount = 1;
222 viewportState.pViewports = &viewport;
223 viewportState.scissorCount = 1;
224 viewportState.pScissors = &scissor;
225
226 VkPipelineRasterizationStateCreateInfo rasterizer = {};
227 rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
228 rasterizer.depthClampEnable = VK_FALSE;
229 rasterizer.rasterizerDiscardEnable = VK_FALSE;
230 rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
231 rasterizer.lineWidth = 1.0f;
232 rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
233 rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
234 rasterizer.depthBiasEnable = VK_FALSE;
235
236 VkPipelineMultisampleStateCreateInfo multisampling = {};
237 multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
238 multisampling.sampleShadingEnable = VK_FALSE;
239 multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
240
241 VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
242 colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
243 colorBlendAttachment.blendEnable = VK_TRUE;
244 colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
245 colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
246 colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
247 colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
248 colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
249 colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
250
251 VkPipelineColorBlendStateCreateInfo colorBlending = {};
252 colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
253 colorBlending.logicOpEnable = VK_FALSE;
254 colorBlending.logicOp = VK_LOGIC_OP_COPY;
255 colorBlending.attachmentCount = 1;
256 colorBlending.pAttachments = &colorBlendAttachment;
257 colorBlending.blendConstants[0] = 0.0f;
258 colorBlending.blendConstants[1] = 0.0f;
259 colorBlending.blendConstants[2] = 0.0f;
260 colorBlending.blendConstants[3] = 0.0f;
261
262 VkPipelineDepthStencilStateCreateInfo depthStencil = {};
263 depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
264 depthStencil.depthTestEnable = VK_TRUE;
265 depthStencil.depthWriteEnable = VK_TRUE;
266 depthStencil.depthCompareOp = VK_COMPARE_OP_LESS;
267 depthStencil.depthBoundsTestEnable = VK_FALSE;
268 depthStencil.minDepthBounds = 0.0f;
269 depthStencil.maxDepthBounds = 1.0f;
270 depthStencil.stencilTestEnable = VK_FALSE;
271 depthStencil.front = {};
272 depthStencil.back = {};
273
274 VkPipelineLayoutCreateInfo pipelineLayoutInfo = {};
275 pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
276 pipelineLayoutInfo.setLayoutCount = 1;
277 pipelineLayoutInfo.pSetLayouts = &this->descriptorSetLayout;
278 pipelineLayoutInfo.pushConstantRangeCount = 0;
279
280 if (vkCreatePipelineLayout(this->device, &pipelineLayoutInfo, nullptr, &this->pipelineLayout) != VK_SUCCESS) {
281 throw runtime_error("failed to create pipeline layout!");
282 }
283
284 VkGraphicsPipelineCreateInfo pipelineInfo = {};
285 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
286 pipelineInfo.stageCount = 2;
287 pipelineInfo.pStages = shaderStages;
288 pipelineInfo.pVertexInputState = &vertexInputInfo;
289 pipelineInfo.pInputAssemblyState = &inputAssembly;
290 pipelineInfo.pViewportState = &viewportState;
291 pipelineInfo.pRasterizationState = &rasterizer;
292 pipelineInfo.pMultisampleState = &multisampling;
293 pipelineInfo.pDepthStencilState = &depthStencil;
294 pipelineInfo.pColorBlendState = &colorBlending;
295 pipelineInfo.pDynamicState = nullptr;
296 pipelineInfo.layout = this->pipelineLayout;
297 pipelineInfo.renderPass = this->renderPass;
298 pipelineInfo.subpass = 0;
299 pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
300 pipelineInfo.basePipelineIndex = -1;
301
302 if (vkCreateGraphicsPipelines(this->device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &this->pipeline) != VK_SUCCESS) {
303 throw runtime_error("failed to create graphics pipeline!");
304 }
305
306 vkDestroyShaderModule(this->device, vertShaderModule, nullptr);
307 vkDestroyShaderModule(this->device, fragShaderModule, nullptr);
308}
309
310template<class VertexType>
311void GraphicsPipeline_Vulkan<VertexType>::createDescriptorSetLayout() {
312 vector<VkDescriptorSetLayoutBinding> bindings(this->descriptorInfoList.size());
313
314 for (size_t i = 0; i < bindings.size(); i++) {
315 bindings[i].binding = i;
316 bindings[i].descriptorCount = 1;
317 bindings[i].descriptorType = this->descriptorInfoList[i].type;
318 bindings[i].stageFlags = this->descriptorInfoList[i].stageFlags;
319 bindings[i].pImmutableSamplers = nullptr;
320 }
321
322 VkDescriptorSetLayoutCreateInfo layoutInfo = {};
323 layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
324 layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
325 layoutInfo.pBindings = bindings.data();
326
327 if (vkCreateDescriptorSetLayout(this->device, &layoutInfo, nullptr, &this->descriptorSetLayout) != VK_SUCCESS) {
328 throw runtime_error("failed to create descriptor set layout!");
329 }
330}
331
332template<class VertexType>
333void GraphicsPipeline_Vulkan<VertexType>::createDescriptorPool(vector<VkImage>& swapChainImages) {
334 vector<VkDescriptorPoolSize> poolSizes(this->descriptorInfoList.size());
335
336 for (size_t i = 0; i < poolSizes.size(); i++) {
337 poolSizes[i].type = this->descriptorInfoList[i].type;
338 poolSizes[i].descriptorCount = static_cast<uint32_t>(swapChainImages.size());
339 }
340
341 VkDescriptorPoolCreateInfo poolInfo = {};
342 poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
343 poolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
344 poolInfo.pPoolSizes = poolSizes.data();
345 poolInfo.maxSets = static_cast<uint32_t>(swapChainImages.size());
346
347 if (vkCreateDescriptorPool(this->device, &poolInfo, nullptr, &this->descriptorPool) != VK_SUCCESS) {
348 throw runtime_error("failed to create descriptor pool!");
349 }
350}
351
352template<class VertexType>
353void GraphicsPipeline_Vulkan<VertexType>::createDescriptorSets(vector<VkImage>& swapChainImages) {
354 vector<VkDescriptorSetLayout> layouts(swapChainImages.size(), this->descriptorSetLayout);
355
356 VkDescriptorSetAllocateInfo allocInfo = {};
357 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
358 allocInfo.descriptorPool = this->descriptorPool;
359 allocInfo.descriptorSetCount = static_cast<uint32_t>(swapChainImages.size());
360 allocInfo.pSetLayouts = layouts.data();
361
362 this->descriptorSets.resize(swapChainImages.size());
363 if (vkAllocateDescriptorSets(device, &allocInfo, this->descriptorSets.data()) != VK_SUCCESS) {
364 throw runtime_error("failed to allocate descriptor sets!");
365 }
366
367 for (size_t i = 0; i < swapChainImages.size(); i++) {
368 vector<VkWriteDescriptorSet> descriptorWrites(this->descriptorInfoList.size());
369
370 for (size_t j = 0; j < descriptorWrites.size(); j++) {
371 descriptorWrites[j].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
372 descriptorWrites[j].dstSet = this->descriptorSets[i];
373 descriptorWrites[j].dstBinding = j;
374 descriptorWrites[j].dstArrayElement = 0;
375 descriptorWrites[j].descriptorType = this->descriptorInfoList[j].type;
376 descriptorWrites[j].descriptorCount = 1;
377 descriptorWrites[j].pBufferInfo = nullptr;
378 descriptorWrites[j].pImageInfo = nullptr;
379 descriptorWrites[j].pTexelBufferView = nullptr;
380
381 switch (descriptorWrites[j].descriptorType) {
382 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
383 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
384 descriptorWrites[j].pBufferInfo = &(*this->descriptorInfoList[j].bufferDataList)[i];
385 break;
386 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
387 descriptorWrites[j].pImageInfo = this->descriptorInfoList[j].imageData;
388 break;
389 default:
390 throw runtime_error("Unknown descriptor type: " + to_string(descriptorWrites[j].descriptorType));
391 }
392 }
393
394 vkUpdateDescriptorSets(this->device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
395 }
396}
397
398template<class VertexType>
399void GraphicsPipeline_Vulkan<VertexType>::createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage) {
400 vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
401 vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1,
402 &descriptorSets[currentImage], 0, nullptr);
403
404 VkBuffer vertexBuffers[] = { vertexBuffer };
405 VkDeviceSize offsets[] = { 0 };
406 vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
407
408 vkCmdBindIndexBuffer(commandBuffer, indexBuffer, 0, VK_INDEX_TYPE_UINT16);
409
410 vkCmdDrawIndexed(commandBuffer, static_cast<uint32_t>(numIndices), 1, 0, 0, 0);
411}
412
413template<class VertexType>
414void GraphicsPipeline_Vulkan<VertexType>::addVertices(const vector<VertexType>& vertices, vector<uint16_t> indices,
415 VkCommandPool commandPool, VkQueue graphicsQueue) {
416
417 if (numVertices + vertices.size() > vertexCapacity) {
418 resizeVertexBuffer(commandPool, graphicsQueue);
419 }
420 if (numIndices + indices.size() > indexCapacity) {
421 resizeIndexBuffer(commandPool, graphicsQueue);
422 }
423
424 VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, vertices, vertexBuffer, numVertices,
425 graphicsQueue);
426 numVertices += vertices.size();
427
428 VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, indices, indexBuffer, numIndices,
429 graphicsQueue);
430 numIndices += indices.size();
431}
432
433template<class VertexType>
434void GraphicsPipeline_Vulkan<VertexType>::cleanup() {
435 vkDestroyPipeline(device, pipeline, nullptr);
436 vkDestroyDescriptorPool(device, descriptorPool, nullptr);
437 vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
438}
439
440template<class VertexType>
441void GraphicsPipeline_Vulkan<VertexType>::cleanupBuffers() {
442 vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
443
444 vkDestroyBuffer(device, vertexBuffer, nullptr);
445 vkFreeMemory(device, vertexBufferMemory, nullptr);
446 vkDestroyBuffer(device, indexBuffer, nullptr);
447 vkFreeMemory(device, indexBufferMemory, nullptr);
448}
449
450/*** PRIVATE METHODS ***/
451
452template<class VertexType>
453VkShaderModule GraphicsPipeline_Vulkan<VertexType>::createShaderModule(const vector<char>& code) {
454 VkShaderModuleCreateInfo createInfo = {};
455 createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
456 createInfo.codeSize = code.size();
457 createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
458
459 VkShaderModule shaderModule;
460 if (vkCreateShaderModule(this->device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
461 throw runtime_error("failed to create shader module!");
462 }
463
464 return shaderModule;
465}
466
467template<class VertexType>
468vector<char> GraphicsPipeline_Vulkan<VertexType>::readFile(const string& filename) {
469 ifstream file(filename, ios::ate | ios::binary);
470
471 if (!file.is_open()) {
472 throw runtime_error("failed to open file!");
473 }
474
475 size_t fileSize = (size_t)file.tellg();
476 vector<char> buffer(fileSize);
477
478 file.seekg(0);
479 file.read(buffer.data(), fileSize);
480
481 file.close();
482
483 return buffer;
484}
485
486template<class VertexType>
487void GraphicsPipeline_Vulkan<VertexType>::resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
488 VkBuffer newVertexBuffer;
489 VkDeviceMemory newVertexBufferMemory;
490 vertexCapacity *= 2;
491
492 VulkanUtils::createBuffer(device, physicalDevice, vertexCapacity * sizeof(VertexType),
493 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
494 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, newVertexBuffer, newVertexBufferMemory);
495
496 VulkanUtils::copyBuffer(device, commandPool, vertexBuffer, newVertexBuffer, 0, 0, numVertices * sizeof(VertexType), graphicsQueue);
497
498 vkDestroyBuffer(device, vertexBuffer, nullptr);
499 vkFreeMemory(device, vertexBufferMemory, nullptr);
500
501 vertexBuffer = newVertexBuffer;
502 vertexBufferMemory = newVertexBufferMemory;
503}
504
505template<class VertexType>
506void GraphicsPipeline_Vulkan<VertexType>::resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
507 VkBuffer newIndexBuffer;
508 VkDeviceMemory newIndexBufferMemory;
509 indexCapacity *= 2;
510
511 VulkanUtils::createBuffer(device, physicalDevice, indexCapacity * sizeof(uint16_t),
512 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
513 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, newIndexBuffer, newIndexBufferMemory);
514
515 VulkanUtils::copyBuffer(device, commandPool, indexBuffer, newIndexBuffer, 0, 0, numIndices * sizeof(uint16_t), graphicsQueue);
516
517 vkDestroyBuffer(device, indexBuffer, nullptr);
518 vkFreeMemory(device, indexBufferMemory, nullptr);
519
520 indexBuffer = newIndexBuffer;
521 indexBufferMemory = newIndexBufferMemory;
522}
523
524#endif // _GRAPHICS_PIPELINE_VULKAN_H
Note: See TracBrowser for help on using the repository browser.