source: opengl-game/graphics-pipeline_vulkan.hpp@ 7c929fc

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

In VulkanGame, add an objectIndex vertex attribute to the ship shader so it can be used as an index into the ssbo object array

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