source: opengl-game/graphics-pipeline_vulkan.hpp@ 5ab1b20

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

Refactor GraphicsPipeline_Vulkan to allow adding new data after creation:

  • Create the initial vertex and index buffers in the constructor
  • Add an addObject() method to add new vertex and index data and resize bufffers when needed
  • Remove the bindData() function, since addObject() can replace it
  • 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#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 bool addObject(const vector<VertexType>& vertices, vector<uint16_t> indices, VkCommandPool commandPool,
59 VkQueue graphicsQueue);
60
61 void cleanup();
62 void cleanupBuffers();
63
64 private:
65 VkPhysicalDevice physicalDevice;
66 VkDevice device;
67 VkRenderPass renderPass;
68
69 VkPipeline pipeline;
70 VkPipelineLayout pipelineLayout;
71
72 VkVertexInputBindingDescription bindingDescription;
73
74 vector<VkVertexInputAttributeDescription> attributeDescriptions;
75 vector<DescriptorInfo> descriptorInfoList;
76
77 VkDescriptorSetLayout descriptorSetLayout;
78 VkDescriptorPool descriptorPool;
79 vector<VkDescriptorSet> descriptorSets;
80
81 size_t numVertices;
82 size_t vertexCapacity;
83 VkBuffer vertexBuffer;
84 VkDeviceMemory vertexBufferMemory;
85
86 size_t numIndices;
87 size_t indexCapacity;
88 VkBuffer indexBuffer;
89 VkDeviceMemory indexBufferMemory;
90
91 vector<SceneObject<VertexType>> objects;
92
93 VkShaderModule createShaderModule(const vector<char>& code);
94 vector<char> readFile(const string& filename);
95
96 void resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
97 void resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
98};
99
100/*** PUBLIC METHODS ***/
101
102template<class VertexType>
103GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan() {
104}
105
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>
408bool GraphicsPipeline_Vulkan<VertexType>::addObject(const vector<VertexType>& vertices, vector<uint16_t> indices,
409 VkCommandPool commandPool, VkQueue graphicsQueue) {
410
411 if (numVertices + vertices.size() > vertexCapacity) {
412 resizeVertexBuffer(commandPool, graphicsQueue);
413 }
414 if (numIndices + indices.size() > indexCapacity) {
415 resizeIndexBuffer(commandPool, graphicsQueue);
416 }
417
418 for (uint16_t& idx : indices) {
419 idx += numVertices;
420 }
421 objects.push_back({vertices, indices });
422
423 VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, vertices, vertexBuffer, numVertices,
424 graphicsQueue);
425 numVertices += vertices.size();
426
427 VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, indices, indexBuffer, numIndices,
428 graphicsQueue);
429 numIndices += indices.size();
430
431 return true;
432}
433
434template<class VertexType>
435void GraphicsPipeline_Vulkan<VertexType>::cleanup() {
436 vkDestroyPipeline(device, pipeline, nullptr);
437 vkDestroyDescriptorPool(device, descriptorPool, nullptr);
438 vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
439}
440
441template<class VertexType>
442void GraphicsPipeline_Vulkan<VertexType>::cleanupBuffers() {
443 vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
444
445 vkDestroyBuffer(device, vertexBuffer, nullptr);
446 vkFreeMemory(device, vertexBufferMemory, nullptr);
447 vkDestroyBuffer(device, indexBuffer, nullptr);
448 vkFreeMemory(device, indexBufferMemory, nullptr);
449}
450
451/*** PRIVATE METHODS ***/
452
453template<class VertexType>
454VkShaderModule GraphicsPipeline_Vulkan<VertexType>::createShaderModule(const vector<char>& code) {
455 VkShaderModuleCreateInfo createInfo = {};
456 createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
457 createInfo.codeSize = code.size();
458 createInfo.pCode = reinterpret_cast<const uint32_t*>(code.data());
459
460 VkShaderModule shaderModule;
461 if (vkCreateShaderModule(this->device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
462 throw runtime_error("failed to create shader module!");
463 }
464
465 return shaderModule;
466}
467
468template<class VertexType>
469vector<char> GraphicsPipeline_Vulkan<VertexType>::readFile(const string& filename) {
470 ifstream file(filename, ios::ate | ios::binary);
471
472 if (!file.is_open()) {
473 throw runtime_error("failed to open file!");
474 }
475
476 size_t fileSize = (size_t)file.tellg();
477 vector<char> buffer(fileSize);
478
479 file.seekg(0);
480 file.read(buffer.data(), fileSize);
481
482 file.close();
483
484 return buffer;
485}
486
487template<class VertexType>
488void GraphicsPipeline_Vulkan<VertexType>::resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
489 VkBuffer newVertexBuffer;
490 VkDeviceMemory newVertexBufferMemory;
491 vertexCapacity *= 2;
492
493 VulkanUtils::createBuffer(device, physicalDevice, vertexCapacity * sizeof(VertexType),
494 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
495 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, newVertexBuffer, newVertexBufferMemory);
496
497 VulkanUtils::copyBuffer(device, commandPool, vertexBuffer, newVertexBuffer, 0, 0, numVertices * sizeof(VertexType), graphicsQueue);
498
499 vkDestroyBuffer(device, vertexBuffer, nullptr);
500 vkFreeMemory(device, vertexBufferMemory, nullptr);
501
502 vertexBuffer = newVertexBuffer;
503 vertexBufferMemory = newVertexBufferMemory;
504}
505
506template<class VertexType>
507void GraphicsPipeline_Vulkan<VertexType>::resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
508 VkBuffer newIndexBuffer;
509 VkDeviceMemory newIndexBufferMemory;
510 indexCapacity *= 2;
511
512 VulkanUtils::createBuffer(device, physicalDevice, indexCapacity * sizeof(uint16_t),
513 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
514 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, newIndexBuffer, newIndexBufferMemory);
515
516 VulkanUtils::copyBuffer(device, commandPool, indexBuffer, newIndexBuffer, 0, 0, numIndices * sizeof(uint16_t), graphicsQueue);
517
518 vkDestroyBuffer(device, indexBuffer, nullptr);
519 vkFreeMemory(device, indexBufferMemory, nullptr);
520
521 indexBuffer = newIndexBuffer;
522 indexBufferMemory = newIndexBufferMemory;
523}
524
525#endif // _GRAPHICS_PIPELINE_VULKAN_H
Note: See TracBrowser for help on using the repository browser.