source: opengl-game/graphics-pipeline_vulkan.hpp@ 055750a

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

In VulkanGame, use SSBOs in the ship and scene shaders to store per-object data (currently just the model matrix)

  • 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
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 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
379 descriptorWrites[j].pBufferInfo = &(*this->descriptorInfoList[j].bufferDataList)[i];
380 break;
381 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
382 descriptorWrites[j].pImageInfo = this->descriptorInfoList[j].imageData;
383 break;
384 default:
385 throw runtime_error("Unknown descriptor type: " + to_string(descriptorWrites[j].descriptorType));
386 }
387 }
388
389 vkUpdateDescriptorSets(this->device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
390 }
391}
392
393template<class VertexType>
394void GraphicsPipeline_Vulkan<VertexType>::createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage) {
395 vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
396 vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1,
397 &descriptorSets[currentImage], 0, nullptr);
398
399 VkBuffer vertexBuffers[] = { vertexBuffer };
400 VkDeviceSize offsets[] = { 0 };
401 vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
402
403 vkCmdBindIndexBuffer(commandBuffer, indexBuffer, 0, VK_INDEX_TYPE_UINT16);
404
405 vkCmdDrawIndexed(commandBuffer, static_cast<uint32_t>(numIndices), 1, 0, 0, 0);
406}
407
408template<class VertexType>
409const vector<SceneObject<VertexType>>& GraphicsPipeline_Vulkan<VertexType>::getObjects() {
410 return objects;
411}
412
413template<class VertexType>
414void GraphicsPipeline_Vulkan<VertexType>::addObject(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 for (uint16_t& idx : indices) {
425 idx += numVertices;
426 }
427 objects.push_back({ vertices, indices });
428
429 VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, vertices, vertexBuffer, numVertices,
430 graphicsQueue);
431 numVertices += vertices.size();
432
433 VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, indices, indexBuffer, numIndices,
434 graphicsQueue);
435 numIndices += indices.size();
436}
437
438template<class VertexType>
439void GraphicsPipeline_Vulkan<VertexType>::cleanup() {
440 vkDestroyPipeline(device, pipeline, nullptr);
441 vkDestroyDescriptorPool(device, descriptorPool, nullptr);
442 vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
443}
444
445template<class VertexType>
446void GraphicsPipeline_Vulkan<VertexType>::cleanupBuffers() {
447 vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
448
449 vkDestroyBuffer(device, vertexBuffer, nullptr);
450 vkFreeMemory(device, vertexBufferMemory, nullptr);
451 vkDestroyBuffer(device, indexBuffer, nullptr);
452 vkFreeMemory(device, indexBufferMemory, nullptr);
453}
454
455/*** PRIVATE METHODS ***/
456
457template<class VertexType>
458VkShaderModule GraphicsPipeline_Vulkan<VertexType>::createShaderModule(const vector<char>& code) {
459 VkShaderModuleCreateInfo createInfo = {};
460 createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
461 createInfo.codeSize = code.size();
462 createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
463
464 VkShaderModule shaderModule;
465 if (vkCreateShaderModule(this->device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
466 throw runtime_error("failed to create shader module!");
467 }
468
469 return shaderModule;
470}
471
472template<class VertexType>
473vector<char> GraphicsPipeline_Vulkan<VertexType>::readFile(const string& filename) {
474 ifstream file(filename, ios::ate | ios::binary);
475
476 if (!file.is_open()) {
477 throw runtime_error("failed to open file!");
478 }
479
480 size_t fileSize = (size_t)file.tellg();
481 vector<char> buffer(fileSize);
482
483 file.seekg(0);
484 file.read(buffer.data(), fileSize);
485
486 file.close();
487
488 return buffer;
489}
490
491template<class VertexType>
492void GraphicsPipeline_Vulkan<VertexType>::resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
493 VkBuffer newVertexBuffer;
494 VkDeviceMemory newVertexBufferMemory;
495 vertexCapacity *= 2;
496
497 VulkanUtils::createBuffer(device, physicalDevice, vertexCapacity * sizeof(VertexType),
498 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
499 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, newVertexBuffer, newVertexBufferMemory);
500
501 VulkanUtils::copyBuffer(device, commandPool, vertexBuffer, newVertexBuffer, 0, 0, numVertices * sizeof(VertexType), graphicsQueue);
502
503 vkDestroyBuffer(device, vertexBuffer, nullptr);
504 vkFreeMemory(device, vertexBufferMemory, nullptr);
505
506 vertexBuffer = newVertexBuffer;
507 vertexBufferMemory = newVertexBufferMemory;
508}
509
510template<class VertexType>
511void GraphicsPipeline_Vulkan<VertexType>::resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
512 VkBuffer newIndexBuffer;
513 VkDeviceMemory newIndexBufferMemory;
514 indexCapacity *= 2;
515
516 VulkanUtils::createBuffer(device, physicalDevice, indexCapacity * sizeof(uint16_t),
517 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
518 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, newIndexBuffer, newIndexBufferMemory);
519
520 VulkanUtils::copyBuffer(device, commandPool, indexBuffer, newIndexBuffer, 0, 0, numIndices * sizeof(uint16_t), graphicsQueue);
521
522 vkDestroyBuffer(device, indexBuffer, nullptr);
523 vkFreeMemory(device, indexBufferMemory, nullptr);
524
525 indexBuffer = newIndexBuffer;
526 indexBufferMemory = newIndexBufferMemory;
527}
528
529#endif // _GRAPHICS_PIPELINE_VULKAN_H
Note: See TracBrowser for help on using the repository browser.