Changeset 9d21aac in opengl-game


Ignore:
Timestamp:
May 6, 2021, 3:24:42 AM (3 years ago)
Author:
Dmitry Portnoy <dportnoy@…>
Branches:
feature/imgui-sdl
Children:
996dd3e
Parents:
756162f
Message:

Remove the SSBOType template parameter from GraphicsPipeline_Vulkan

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • graphics-pipeline_vulkan.hpp

    r756162f r9d21aac  
    2121
    2222using namespace glm;
    23 
    24 // TODO: Maybe change the name of this struct so I can call the list something other than descriptorInfoList
    25 struct DescriptorInfo {
    26    VkDescriptorType type;
    27    VkShaderStageFlags stageFlags;
    28 
    29    // Only one of the below properties should be set
    30    vector<VkDescriptorBufferInfo>* bufferDataList;
    31    VkDescriptorImageInfo* imageData;
    32 };
    3323
    3424// TODO: Use this struct for uniform buffers as well and rename it to VulkanBuffer (maybe move it to VulkanUtils)
     
    4131};
    4232
    43 template<class VertexType, class SSBOType>
     33// TODO: Maybe change the name of this struct so I can call the list something other than descriptorInfoList
     34struct DescriptorInfo {
     35   VkDescriptorType type;
     36   VkShaderStageFlags stageFlags;
     37
     38   // Only one of the below properties should be set
     39   vector<VkDescriptorBufferInfo>* bufferDataList;
     40   VkDescriptorImageInfo* imageData;
     41};
     42
     43template<class VertexType>
    4444class GraphicsPipeline_Vulkan : public GraphicsPipeline {
    4545   public:
    4646      string vertShaderFile, fragShaderFile;
     47
     48      // TODO: Move this outside this classs, since it is no longer used here
     49      StorageBufferSet storageBufferSet;
     50
     51      // Both of these are only used for managing the SSBO, so move them out as well
     52      size_t objectCapacity;
     53      size_t numObjects;
    4754
    4855      GraphicsPipeline_Vulkan();
     
    6471      void addAttribute(VkFormat format, size_t offset);
    6572
    66       void addStorageDescriptor(VkShaderStageFlags stageFlags);
    67 
    6873      // TODO: I might be able to use a single VkDescriptorBufferInfo here and reuse it when creating the descriptor sets
    6974      void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags,
     
    7176      void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData);
    7277
     78      void updateDescriptorInfo(uint32_t index, vector<VkDescriptorBufferInfo>* bufferData);
     79      // TODO: Maybe make an analogous one for updating image info
     80
    7381      void createPipeline(string vertShaderFile, string fragShaderFile);
    7482      void createDescriptorSetLayout();
     
    7886      void createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage);
    7987
    80       bool addObject(const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType& ssbo,
    81                      VkCommandPool commandPool, VkQueue graphicsQueue);
    82 
    83       void updateObject(size_t objIndex, SSBOType& ssbo);
     88      void addObject(const vector<VertexType>& vertices, vector<uint16_t> indices, VkCommandPool commandPool,
     89                     VkQueue graphicsQueue);
    8490
    8591      void updateObjectVertices(size_t objIndex, const vector<VertexType>& vertices, VkCommandPool commandPool,
     
    117123      VkDeviceMemory indexBufferMemory;
    118124
    119       size_t numObjects;
    120       size_t objectCapacity;
    121 
    122       StorageBufferSet storageBufferSet;
    123 
    124125      VkShaderModule createShaderModule(const vector<char>& code);
    125126      vector<char> readFile(const string& filename);
     
    127128      void resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
    128129      void resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
    129       void resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue);
    130130};
    131131
    132132/*** PUBLIC METHODS ***/
    133133
    134 template<class VertexType, class SSBOType>
    135 GraphicsPipeline_Vulkan<VertexType, SSBOType>::GraphicsPipeline_Vulkan() {
     134template<class VertexType>
     135GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan() {
    136136}
    137137
     
    139139// TODO: See if it would be feasible to move code in the createPipeline method
    140140// into the constructor. That way, I can also put relevant cleanup code into the destructor
    141 template<class VertexType, class SSBOType>
    142 GraphicsPipeline_Vulkan<VertexType, SSBOType>::GraphicsPipeline_Vulkan(
     141template<class VertexType>
     142GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan(
    143143      VkPrimitiveTopology topology, VkPhysicalDevice physicalDevice, VkDevice device,
    144144      VkRenderPass renderPass, Viewport viewport, vector<VkImage>& swapChainImages,
     
    173173   this->numObjects = 0;
    174174   this->objectCapacity = objectCapacity;
    175 
    176    // Hacky way to allow an SSBO to be optional
    177    // Specifying void* as the SSBOType will skip allocating the related buffers
    178    if (!is_same_v<SSBOType, void*>) {
    179       VkDeviceSize bufferSize = objectCapacity * sizeof(SSBOType);
    180       cout << "NUM SWAP CHAIN IMAGES: " << swapChainImages.size() << endl;
    181 
    182       storageBufferSet.buffers.resize(swapChainImages.size());
    183       storageBufferSet.memory.resize(swapChainImages.size());
    184       storageBufferSet.infoSet.resize(swapChainImages.size());
    185 
    186       for (size_t i = 0; i < swapChainImages.size(); i++) {
    187          VulkanUtils::createBuffer(this->device, this->physicalDevice, bufferSize,
    188             VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
    189             VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    190             storageBufferSet.buffers[i], storageBufferSet.memory[i]);
    191 
    192          storageBufferSet.infoSet[i].buffer = storageBufferSet.buffers[i];
    193          storageBufferSet.infoSet[i].offset = 0; // This is the offset from the start of the buffer, so always 0 for now
    194          storageBufferSet.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE
    195       }
    196    }
    197175}
    198176
    199177// TODO: Move as much cleanup as I can into the destructor
    200 template<class VertexType, class SSBOType>
    201 GraphicsPipeline_Vulkan<VertexType, SSBOType>::~GraphicsPipeline_Vulkan() {
    202 }
    203 
    204 template<class VertexType, class SSBOType>
    205 size_t GraphicsPipeline_Vulkan<VertexType, SSBOType>::getNumVertices() {
     178template<class VertexType>
     179GraphicsPipeline_Vulkan<VertexType>::~GraphicsPipeline_Vulkan() {
     180}
     181
     182template<class VertexType>
     183size_t GraphicsPipeline_Vulkan<VertexType>::getNumVertices() {
    206184   return numVertices;
    207185}
    208186
    209 template<class VertexType, class SSBOType>
    210 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::updateRenderPass(VkRenderPass renderPass) {
     187template<class VertexType>
     188void GraphicsPipeline_Vulkan<VertexType>::updateRenderPass(VkRenderPass renderPass) {
    211189   this->renderPass = renderPass;
    212190}
    213191
    214 template<class VertexType, class SSBOType>
    215 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addAttribute(VkFormat format, size_t offset) {
     192template<class VertexType>
     193void GraphicsPipeline_Vulkan<VertexType>::addAttribute(VkFormat format, size_t offset) {
    216194   VkVertexInputAttributeDescription attributeDesc = {};
    217195
     
    224202}
    225203
    226 // TODO: The SSBOType check isn't really needed since I call this function in VulkanGame explicitly
    227 template<class VertexType, class SSBOType>
    228 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addStorageDescriptor(VkShaderStageFlags stageFlags) {
    229    if (!is_same_v<SSBOType, void*>) {
    230       addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
    231          stageFlags, &storageBufferSet.infoSet);
    232    }
    233 }
    234 
    235 template<class VertexType, class SSBOType>
    236 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addDescriptorInfo(VkDescriptorType type,
     204template<class VertexType>
     205void GraphicsPipeline_Vulkan<VertexType>::addDescriptorInfo(VkDescriptorType type,
    237206      VkShaderStageFlags stageFlags, vector<VkDescriptorBufferInfo>* bufferData) {
    238207   this->descriptorInfoList.push_back({ type, stageFlags, bufferData, nullptr });
    239208}
    240209
    241 template<class VertexType, class SSBOType>
    242 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addDescriptorInfo(VkDescriptorType type,
     210template<class VertexType>
     211void GraphicsPipeline_Vulkan<VertexType>::addDescriptorInfo(VkDescriptorType type,
    243212      VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData) {
    244213   this->descriptorInfoList.push_back({ type, stageFlags, nullptr, imageData });
    245214}
    246215
    247 template<class VertexType, class SSBOType>
    248 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createPipeline(string vertShaderFile, string fragShaderFile) {
     216template<class VertexType>
     217void GraphicsPipeline_Vulkan<VertexType>::updateDescriptorInfo(uint32_t index,
     218                                                                         vector<VkDescriptorBufferInfo>* bufferData) {
     219   this->descriptorInfoList[index].bufferDataList = bufferData;
     220}
     221
     222template<class VertexType>
     223void GraphicsPipeline_Vulkan<VertexType>::createPipeline(string vertShaderFile, string fragShaderFile) {
    249224   this->vertShaderFile = vertShaderFile;
    250225   this->fragShaderFile = fragShaderFile;
     
    386361}
    387362
    388 template<class VertexType, class SSBOType>
    389 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createDescriptorSetLayout() {
     363template<class VertexType>
     364void GraphicsPipeline_Vulkan<VertexType>::createDescriptorSetLayout() {
    390365   vector<VkDescriptorSetLayoutBinding> bindings(this->descriptorInfoList.size());
    391366
     
    408383}
    409384
    410 template<class VertexType, class SSBOType>
    411 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createDescriptorPool(vector<VkImage>& swapChainImages) {
     385template<class VertexType>
     386void GraphicsPipeline_Vulkan<VertexType>::createDescriptorPool(vector<VkImage>& swapChainImages) {
    412387   vector<VkDescriptorPoolSize> poolSizes(this->descriptorInfoList.size());
    413388
     
    429404
    430405// TODO: Since I only need the size of the swapChainImages array, I should just pass that in instead of the whole array
    431 template<class VertexType, class SSBOType>
    432 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createDescriptorSets(vector<VkImage>& swapChainImages) {
     406template<class VertexType>
     407void GraphicsPipeline_Vulkan<VertexType>::createDescriptorSets(vector<VkImage>& swapChainImages) {
    433408   vector<VkDescriptorSetLayout> layouts(swapChainImages.size(), this->descriptorSetLayout);
    434409
     
    476451}
    477452
    478 template<class VertexType, class SSBOType>
    479 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createRenderCommands(VkCommandBuffer& commandBuffer,
    480       uint32_t currentImage) {
    481 
     453template<class VertexType>
     454void GraphicsPipeline_Vulkan<VertexType>::createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage) {
    482455   vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
    483456
     
    494467}
    495468
    496 template<class VertexType, class SSBOType>
    497 bool GraphicsPipeline_Vulkan<VertexType, SSBOType>::addObject(
    498       const vector<VertexType>& vertices, vector<uint16_t> indices,
    499       SSBOType& ssbo, VkCommandPool commandPool, VkQueue graphicsQueue) {
    500 
     469template<class VertexType>
     470void GraphicsPipeline_Vulkan<VertexType>::addObject(const vector<VertexType>& vertices, vector<uint16_t> indices,
     471                                                    VkCommandPool commandPool, VkQueue graphicsQueue) {
    501472   // TODO: When resizing the vertex or index buffer, take deleted objects into account.
    502473   // Remove their data from the buffer and determine the new size of the bufer based on # of remining objects
     
    522493      this->indexBuffer, this->numIndices, graphicsQueue);
    523494   this->numIndices += indices.size();
    524 
    525    bool resizedStorageBuffer = false;
    526 
    527    if (!is_same_v<SSBOType, void*>) {
    528       if (this->numObjects == this->objectCapacity) {
    529          resizeStorageBufferSet(storageBufferSet, commandPool, graphicsQueue);
    530          cleanup();
    531 
    532          // Assume the SSBO is always the 2nd binding
    533          this->descriptorInfoList[1].bufferDataList = &storageBufferSet.infoSet;
    534          resizedStorageBuffer = true;
    535 
    536          cout << "SSBO resized, New object capacity: " << this->objectCapacity << endl;
    537 
    538          // TODO: I'll need to correctly update the descriptor set array instead of appending to it
    539          // Then, I'll have to call createDescriptorSets() and finally createCommandBuffers() (from vulkan-game)
    540          // This isn't too bad actually, since I have to call createCommandBuffers() every time I add a newobject
    541          // anyway. So, in this function, I'll just have to call createDescriptorSets()
    542       }
    543 
    544       updateObject(this->numObjects, ssbo);
    545    }
    546 
    547    this->numObjects++;
    548 
    549    return resizedStorageBuffer;
    550 }
    551 
    552 // TODO: Allow a swapchain index to be passed in instead of updating all of them
    553 // Actually, since I'm in the process of replacing SSBOs with dynamic UBOs, I can ignore that for this function
    554 template<class VertexType, class SSBOType>
    555 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::updateObject(size_t objIndex, SSBOType& ssbo) {
    556    if (!is_same_v<SSBOType, void*>) {
    557       for (size_t i = 0; i < storageBufferSet.memory.size(); i++) {
    558          VulkanUtils::copyDataToMemory(this->device, ssbo, storageBufferSet.memory[i], objIndex * sizeof(SSBOType));
    559       }
    560    }
    561495}
    562496
    563497// Should only be used if the number of vertices has not changed
    564 template<class VertexType, class SSBOType>
    565 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::updateObjectVertices(size_t objIndex,
     498template<class VertexType>
     499void GraphicsPipeline_Vulkan<VertexType>::updateObjectVertices(size_t objIndex,
    566500      const vector<VertexType>& vertices, VkCommandPool commandPool, VkQueue graphicsQueue) {
    567501   VulkanUtils::copyDataToBuffer(this->device, this->physicalDevice, commandPool, vertices,
     
    569503}
    570504
    571 template<class VertexType, class SSBOType>
    572 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::cleanup() {
     505template<class VertexType>
     506void GraphicsPipeline_Vulkan<VertexType>::cleanup() {
    573507   vkDestroyPipeline(device, pipeline, nullptr);
    574508   vkDestroyDescriptorPool(device, descriptorPool, nullptr);
     
    579513}
    580514
    581 template<class VertexType, class SSBOType>
    582 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::cleanupBuffers() {
     515template<class VertexType>
     516void GraphicsPipeline_Vulkan<VertexType>::cleanupBuffers() {
    583517   vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
    584518
     
    587521   vkDestroyBuffer(device, indexBuffer, nullptr);
    588522   vkFreeMemory(device, indexBufferMemory, nullptr);
    589 
    590    if (!is_same_v<SSBOType, void*>) {
    591       for (size_t i = 0; i < storageBufferSet.buffers.size(); i++) {
    592          vkDestroyBuffer(device, storageBufferSet.buffers[i], nullptr);
    593          vkFreeMemory(device, storageBufferSet.memory[i], nullptr);
    594       }
    595    }
    596523}
    597524
    598525/*** PRIVATE METHODS ***/
    599526
    600 template<class VertexType, class SSBOType>
    601 VkShaderModule GraphicsPipeline_Vulkan<VertexType, SSBOType>::createShaderModule(const vector<char>& code) {
     527template<class VertexType>
     528VkShaderModule GraphicsPipeline_Vulkan<VertexType>::createShaderModule(const vector<char>& code) {
    602529   VkShaderModuleCreateInfo createInfo = {};
    603530   createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
     
    613540}
    614541
    615 template<class VertexType, class SSBOType>
    616 vector<char> GraphicsPipeline_Vulkan<VertexType, SSBOType>::readFile(const string& filename) {
     542template<class VertexType>
     543vector<char> GraphicsPipeline_Vulkan<VertexType>::readFile(const string& filename) {
    617544   ifstream file(filename, ios::ate | ios::binary);
    618545
     
    632559}
    633560
    634 template<class VertexType, class SSBOType>
    635 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeVertexBuffer(VkCommandPool commandPool,
    636       VkQueue graphicsQueue) {
     561template<class VertexType>
     562void GraphicsPipeline_Vulkan<VertexType>::resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
    637563   VkBuffer newVertexBuffer;
    638564   VkDeviceMemory newVertexBufferMemory;
     
    652578}
    653579
    654 template<class VertexType, class SSBOType>
    655 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeIndexBuffer(VkCommandPool commandPool,
    656       VkQueue graphicsQueue) {
     580template<class VertexType>
     581void GraphicsPipeline_Vulkan<VertexType>::resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
    657582   VkBuffer newIndexBuffer;
    658583   VkDeviceMemory newIndexBufferMemory;
     
    672597}
    673598
    674 template<class VertexType, class SSBOType>
    675 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeStorageBufferSet(StorageBufferSet& set,
    676       VkCommandPool commandPool, VkQueue graphicsQueue) {
    677    this->objectCapacity *= 2;
    678    VkDeviceSize bufferSize = objectCapacity * sizeof(SSBOType);
    679 
    680    for (size_t i = 0; i < set.buffers.size(); i++) {
    681       VkBuffer newStorageBuffer;
    682       VkDeviceMemory newStorageBufferMemory;
    683 
    684       VulkanUtils::createBuffer(this->device, this->physicalDevice, bufferSize,
    685          VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
    686          VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    687          newStorageBuffer, newStorageBufferMemory);
    688 
    689       VulkanUtils::copyBuffer(this->device, commandPool, set.buffers[i], newStorageBuffer,
    690          0, 0, this->numObjects * sizeof(SSBOType), graphicsQueue);
    691 
    692       vkDestroyBuffer(this->device, set.buffers[i], nullptr);
    693       vkFreeMemory(this->device, set.memory[i], nullptr);
    694 
    695       set.buffers[i] = newStorageBuffer;
    696       set.memory[i] = newStorageBufferMemory;
    697 
    698       set.infoSet[i].buffer = set.buffers[i];
    699       set.infoSet[i].offset = 0; // This is the offset from the start of the buffer, so always 0 for now
    700       set.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE
    701    }
    702 }
    703 
    704599#endif // _GRAPHICS_PIPELINE_VULKAN_H
  • sdl-game.cpp

    r756162f r9d21aac  
    103103   modelPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex));
    104104
    105    createBufferSet(uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, sizeof(UBO_VP_mats),
     105   createBufferSet(sizeof(UBO_VP_mats),
    106106      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    107       uniformBufferInfoList_modelPipeline);
     107      uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline);
    108108
    109109   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
    110110      VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_modelPipeline);
    111    modelPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
     111   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
     112      VK_SHADER_STAGE_VERTEX_BIT, &modelPipeline.storageBufferSet.infoSet);
    112113   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
    113114      VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor);
     
    256257
    257258void VulkanGame::initGraphicsPipelines() {
    258    modelPipeline = GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject>(
     259   modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>(
    259260      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass,
    260261      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 16, 24, 10);
     262
     263   createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_ModelObject),
     264      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
     265      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
     266      modelPipeline.storageBufferSet.buffers, modelPipeline.storageBufferSet.memory,
     267      modelPipeline.storageBufferSet.infoSet);
    261268}
    262269
     
    468475   modelPipeline.cleanupBuffers();
    469476
     477   for (size_t i = 0; i < modelPipeline.storageBufferSet.buffers.size(); i++) {
     478      vkDestroyBuffer(device, modelPipeline.storageBufferSet.buffers[i], nullptr);
     479      vkFreeMemory(device, modelPipeline.storageBufferSet.memory[i], nullptr);
     480   }
     481
    470482   // END UNREVIEWED SECTION
    471483
     
    10831095}
    10841096
    1085 void VulkanGame::createBufferSet(vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
    1086                                  VkDeviceSize bufferSize, VkBufferUsageFlags flags, VkMemoryPropertyFlags properties,
     1097void VulkanGame::createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, VkMemoryPropertyFlags properties,
     1098                                 vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
    10871099                                 vector<VkDescriptorBufferInfo>& bufferInfoList) {
    10881100   buffers.resize(swapChainImageCount);
     
    12301242   // instead of recreated every time
    12311243
    1232    createBufferSet(uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, sizeof(UBO_VP_mats),
     1244   createBufferSet(sizeof(UBO_VP_mats),
    12331245      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    1234       uniformBufferInfoList_modelPipeline);
     1246      uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline);
    12351247
    12361248   modelPipeline.updateRenderPass(renderPass);
  • sdl-game.hpp

    r756162f r9d21aac  
    207207      // the same pipeline, but use different textures, the approach I took when initially creating GraphicsPipeline_Vulkan
    208208      // wouldn't work since the whole pipeline couldn't have a common set of descriptors for the textures
    209       GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject> modelPipeline;
     209      GraphicsPipeline_Vulkan<ModelVertex> modelPipeline;
    210210
    211211      // TODO: Maybe make the ubo objects part of the pipeline class since there's only one ubo
     
    276276      void cleanupImGuiOverlay();
    277277
    278       void createBufferSet(vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, VkDeviceSize bufferSize,
    279                            VkBufferUsageFlags flags, VkMemoryPropertyFlags properties,
     278      // TODO: Maybe move these to a different class, possibly VulkanBuffer or some new related class
     279
     280      void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, VkMemoryPropertyFlags properties,
     281                           vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
    280282                           vector<VkDescriptorBufferInfo>& bufferInfoList);
     283
     284      // TODO: See if it makes sense to rename this to resizeBufferSet() and use it to resize other types of buffers as well
     285      // TODO: Remove the need for templating, which is only there so a GraphicsPupeline_Vulkan can be passed in
     286      template<class VertexType, class SSBOType>
     287      void resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue,
     288                                  GraphicsPipeline_Vulkan<VertexType>& pipeline);
     289
     290      template<class SSBOType>
     291      void updateStorageBuffer(StorageBufferSet& storageBufferSet, size_t objIndex, SSBOType& ssbo);
    281292
    282293      // TODO: Since addObject() returns a reference to the new object now,
     
    284295      template<class VertexType, class SSBOType>
    285296      SceneObject<VertexType, SSBOType>& addObject(vector<SceneObject<VertexType, SSBOType>>& objects,
    286                                                    GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline,
     297                                                   GraphicsPipeline_Vulkan<VertexType>& pipeline,
    287298                                                   const vector<VertexType>& vertices, vector<uint16_t> indices,
    288299                                                   SSBOType ssbo, bool pipelinesCreated);
     
    298309
    299310      template<class VertexType, class SSBOType>
    300       void updateObject(vector<SceneObject<VertexType, SSBOType>>& objects, GraphicsPipeline_Vulkan<VertexType,
    301                         SSBOType>& pipeline, size_t index);
     311      void updateObject(vector<SceneObject<VertexType, SSBOType>>& objects,
     312                        GraphicsPipeline_Vulkan<VertexType>& pipeline, size_t index);
    302313
    303314      void renderFrame(ImDrawData* draw_data);
     
    320331};
    321332
     333template<class VertexType, class SSBOType>
     334void VulkanGame::resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue,
     335                                        GraphicsPipeline_Vulkan<VertexType>& pipeline) {
     336   pipeline.objectCapacity *= 2;
     337   VkDeviceSize bufferSize = pipeline.objectCapacity * sizeof(SSBOType);
     338
     339   for (size_t i = 0; i < set.buffers.size(); i++) {
     340      VkBuffer newStorageBuffer;
     341      VkDeviceMemory newStorageBufferMemory;
     342
     343      VulkanUtils::createBuffer(device, physicalDevice, bufferSize,
     344         VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
     345         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
     346         newStorageBuffer, newStorageBufferMemory);
     347
     348      VulkanUtils::copyBuffer(device, commandPool, set.buffers[i], newStorageBuffer,
     349         0, 0, pipeline.numObjects * sizeof(SSBOType), graphicsQueue);
     350
     351      vkDestroyBuffer(device, set.buffers[i], nullptr);
     352      vkFreeMemory(device, set.memory[i], nullptr);
     353
     354      set.buffers[i] = newStorageBuffer;
     355      set.memory[i] = newStorageBufferMemory;
     356
     357      set.infoSet[i].buffer = set.buffers[i];
     358      set.infoSet[i].offset = 0; // This is the offset from the start of the buffer, so always 0 for now
     359      set.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE
     360   }
     361}
     362
     363// TODO: See if it makes sense to pass in the current swapchain index instead of updating all of them
     364template<class SSBOType>
     365void VulkanGame::updateStorageBuffer(StorageBufferSet& storageBufferSet, size_t objIndex, SSBOType& ssbo) {
     366   for (size_t i = 0; i < storageBufferSet.memory.size(); i++) {
     367      VulkanUtils::copyDataToMemory(device, ssbo, storageBufferSet.memory[i], objIndex * sizeof(SSBOType));
     368   }
     369}
     370
    322371// TODO: Right now, it's basically necessary to pass the identity matrix in for ssbo.model
    323372// and to change the model matrix later by setting model_transform and then calling updateObject()
    324 // Figure out a better way to allow the model matrix to be set during objecting creation
     373// Figure out a better way to allow the model matrix to be set during object creation
    325374
    326375// TODO: Maybe return a reference to the object from this method if I decide that updating it
     
    329378// to account for scaling
    330379template<class VertexType, class SSBOType>
    331 SceneObject<VertexType, SSBOType>& VulkanGame::addObject(
    332    vector<SceneObject<VertexType, SSBOType>>& objects,
    333    GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline,
    334    const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo,
    335    bool pipelinesCreated) {
     380SceneObject<VertexType, SSBOType>& VulkanGame::addObject(vector<SceneObject<VertexType, SSBOType>>& objects,
     381                                                         GraphicsPipeline_Vulkan<VertexType>& pipeline,
     382                                                         const vector<VertexType>& vertices, vector<uint16_t> indices,
     383                                                         SSBOType ssbo, bool pipelinesCreated) {
    336384   // TODO: Use the model field of ssbo to set the object's model_base
    337385   // currently, the passed in model is useless since it gets overridden in updateObject() anyway
     
    353401   }
    354402
    355    bool storageBufferResized = pipeline.addObject(obj.vertices, obj.indices, obj.ssbo,
    356       resourceCommandPool, graphicsQueue);
     403   pipeline.addObject(obj.vertices, obj.indices, resourceCommandPool, graphicsQueue);
     404
     405   bool resizeStorageBuffer = pipeline.numObjects == pipeline.objectCapacity;
     406
     407   if (resizeStorageBuffer) {
     408      resizeStorageBufferSet<VertexType, SSBOType>(pipeline.storageBufferSet, resourceCommandPool, graphicsQueue, pipeline);
     409      pipeline.cleanup();
     410
     411      // Assume the SSBO is always the 2nd binding
     412      pipeline.updateDescriptorInfo(1, &pipeline.storageBufferSet.infoSet);
     413   }
     414
     415   pipeline.numObjects++;
     416
     417   updateStorageBuffer(pipeline.storageBufferSet, pipeline.numObjects - 1, obj.ssbo);
     418
     419   // TODO: Figure out why I am destroying and recreating the ubos when the swap chain is recreated,
     420   // but am reusing the same ssbos. Maybe I don't need to recreate the ubos.
    357421
    358422   if (pipelinesCreated) {
     
    367431      // Refactor the logic to check for any resized SSBOs after all objects for the frame
    368432      // are created and then recreate each of the corresponding pipelines only once per frame
    369       if (storageBufferResized) {
     433
     434      // TODO: Also, verify if I actually need to recreate all of these, or maybe just the descriptor sets, for instance
     435
     436      if (resizeStorageBuffer) {
    370437         pipeline.createPipeline(pipeline.vertShaderFile, pipeline.fragShaderFile);
    371438         pipeline.createDescriptorPool(swapChainImages);
     
    457524// TODO: Just pass in the single object instead of a list of all of them
    458525template<class VertexType, class SSBOType>
    459 void VulkanGame::updateObject(vector<SceneObject<VertexType, SSBOType>>& objects, GraphicsPipeline_Vulkan<VertexType,
    460                               SSBOType>& pipeline, size_t index) {
     526void VulkanGame::updateObject(vector<SceneObject<VertexType, SSBOType>>& objects,
     527                              GraphicsPipeline_Vulkan<VertexType>& pipeline, size_t index) {
    461528   SceneObject<VertexType, SSBOType>& obj = objects[index];
    462529
     
    464531   obj.center = vec3(obj.ssbo.model * vec4(0.0f, 0.0f, 0.0f, 1.0f));
    465532
    466    pipeline.updateObject(index, obj.ssbo);
     533   updateStorageBuffer(pipeline.storageBufferSet, index, obj.ssbo);
    467534
    468535   obj.modified = false;
  • vulkan-game.cpp

    r756162f r9d21aac  
    119119   modelPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex));
    120120
    121    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     121   createBufferSet(sizeof(UBO_VP_mats),
     122      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    122123      uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline);
    123124
    124125   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
    125126      VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_modelPipeline);
    126    modelPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
     127   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
     128      VK_SHADER_STAGE_VERTEX_BIT, &modelPipeline.storageBufferSet.infoSet);
    127129   modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
    128130      VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor);
     
    180182   shipPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex));
    181183
    182    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     184   createBufferSet(sizeof(UBO_VP_mats),
     185      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    183186      uniformBuffers_shipPipeline, uniformBuffersMemory_shipPipeline, uniformBufferInfoList_shipPipeline);
    184187
    185188   shipPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
    186189      VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_shipPipeline);
    187    shipPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
     190   shipPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
     191      VK_SHADER_STAGE_VERTEX_BIT, &shipPipeline.storageBufferSet.infoSet);
    188192
    189193   // TODO: With the normals, indexing basically becomes pointless since no vertices will have exactly
     
    438442   asteroidPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex));
    439443
    440    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     444   createBufferSet(sizeof(UBO_VP_mats),
     445      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    441446      uniformBuffers_asteroidPipeline, uniformBuffersMemory_asteroidPipeline, uniformBufferInfoList_asteroidPipeline);
    442447
    443448   asteroidPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
    444449      VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_asteroidPipeline);
    445    asteroidPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
     450   asteroidPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
     451      VK_SHADER_STAGE_VERTEX_BIT, &asteroidPipeline.storageBufferSet.infoSet);
    446452
    447453   asteroidPipeline.createDescriptorSetLayout();
     
    454460   laserPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&LaserVertex::objIndex));
    455461
    456    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     462   createBufferSet(sizeof(UBO_VP_mats),
     463      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    457464      uniformBuffers_laserPipeline, uniformBuffersMemory_laserPipeline, uniformBufferInfoList_laserPipeline);
    458465
    459466   laserPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
    460467      VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_laserPipeline);
    461    laserPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
     468   laserPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
     469      VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, &laserPipeline.storageBufferSet.infoSet);
    462470   laserPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
    463471      VK_SHADER_STAGE_FRAGMENT_BIT, &laserTextureImageDescriptor);
     
    472480   explosionPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ExplosionVertex::objIndex));
    473481
    474    createBufferSet(sizeof(UBO_Explosion), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     482   createBufferSet(sizeof(UBO_Explosion),
     483      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    475484      uniformBuffers_explosionPipeline, uniformBuffersMemory_explosionPipeline, uniformBufferInfoList_explosionPipeline);
    476485
    477486   explosionPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
    478487      VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_explosionPipeline);
    479    explosionPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT);
     488   explosionPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
     489      VK_SHADER_STAGE_VERTEX_BIT, &explosionPipeline.storageBufferSet.infoSet);
    480490
    481491   explosionPipeline.createDescriptorSetLayout();
     
    582592
    583593void VulkanGame::initGraphicsPipelines() {
    584    modelPipeline = GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject>(
     594   modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>(
    585595      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass,
    586596      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 24, 24, 10);
    587597
    588    shipPipeline = GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject>(
     598   createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_ModelObject),
     599      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
     600      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
     601      modelPipeline.storageBufferSet.buffers, modelPipeline.storageBufferSet.memory,
     602      modelPipeline.storageBufferSet.infoSet);
     603
     604   shipPipeline = GraphicsPipeline_Vulkan<ModelVertex>(
    589605      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass,
    590606      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 138, 138, 10);
    591607
    592    asteroidPipeline = GraphicsPipeline_Vulkan<ModelVertex, SSBO_Asteroid>(
     608   createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_ModelObject),
     609      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
     610      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
     611      shipPipeline.storageBufferSet.buffers, shipPipeline.storageBufferSet.memory,
     612      shipPipeline.storageBufferSet.infoSet);
     613
     614   asteroidPipeline = GraphicsPipeline_Vulkan<ModelVertex>(
    593615      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass,
    594616      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 24, 36, 10);
    595617
    596    laserPipeline = GraphicsPipeline_Vulkan<LaserVertex, SSBO_Laser>(
     618   createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_Asteroid),
     619      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
     620      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
     621      asteroidPipeline.storageBufferSet.buffers, asteroidPipeline.storageBufferSet.memory,
     622      asteroidPipeline.storageBufferSet.infoSet);
     623
     624   laserPipeline = GraphicsPipeline_Vulkan<LaserVertex>(
    597625      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass,
    598626      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 8, 18, 2);
    599627
    600    explosionPipeline = GraphicsPipeline_Vulkan<ExplosionVertex, SSBO_Explosion>(
     628   createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_Laser),
     629      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
     630      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
     631      laserPipeline.storageBufferSet.buffers, laserPipeline.storageBufferSet.memory,
     632      laserPipeline.storageBufferSet.infoSet);
     633
     634   explosionPipeline = GraphicsPipeline_Vulkan<ExplosionVertex>(
    601635      VK_PRIMITIVE_TOPOLOGY_POINT_LIST, physicalDevice, device, renderPass,
    602636      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height },
    603637      swapChainImages, EXPLOSION_PARTICLE_COUNT, EXPLOSION_PARTICLE_COUNT, 2);
     638
     639   createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_Explosion),
     640      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
     641      VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
     642      explosionPipeline.storageBufferSet.buffers, explosionPipeline.storageBufferSet.memory,
     643      explosionPipeline.storageBufferSet.infoSet);
    604644}
    605645
     
    10911131   explosionPipeline.cleanupBuffers();
    10921132
     1133   for (size_t i = 0; i < modelPipeline.storageBufferSet.buffers.size(); i++) {
     1134      vkDestroyBuffer(device, modelPipeline.storageBufferSet.buffers[i], nullptr);
     1135      vkFreeMemory(device, modelPipeline.storageBufferSet.memory[i], nullptr);
     1136   }
     1137
     1138   for (size_t i = 0; i < shipPipeline.storageBufferSet.buffers.size(); i++) {
     1139      vkDestroyBuffer(device, shipPipeline.storageBufferSet.buffers[i], nullptr);
     1140      vkFreeMemory(device, shipPipeline.storageBufferSet.memory[i], nullptr);
     1141   }
     1142
     1143   for (size_t i = 0; i < asteroidPipeline.storageBufferSet.buffers.size(); i++) {
     1144      vkDestroyBuffer(device, asteroidPipeline.storageBufferSet.buffers[i], nullptr);
     1145      vkFreeMemory(device, asteroidPipeline.storageBufferSet.memory[i], nullptr);
     1146   }
     1147
     1148   for (size_t i = 0; i < laserPipeline.storageBufferSet.buffers.size(); i++) {
     1149      vkDestroyBuffer(device, laserPipeline.storageBufferSet.buffers[i], nullptr);
     1150      vkFreeMemory(device, laserPipeline.storageBufferSet.memory[i], nullptr);
     1151   }
     1152
     1153   for (size_t i = 0; i < explosionPipeline.storageBufferSet.buffers.size(); i++) {
     1154      vkDestroyBuffer(device, explosionPipeline.storageBufferSet.buffers[i], nullptr);
     1155      vkFreeMemory(device, explosionPipeline.storageBufferSet.memory[i], nullptr);
     1156   }
     1157
    10931158   // END UNREVIEWED SECTION
    10941159
     
    18101875}
    18111876
    1812 void VulkanGame::createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags,
    1813    vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, vector<VkDescriptorBufferInfo>& bufferInfoList) {
     1877void VulkanGame::createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, VkMemoryPropertyFlags properties,
     1878                                 vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
     1879                                 vector<VkDescriptorBufferInfo>& bufferInfoList) {
    18141880   buffers.resize(swapChainImageCount);
    18151881   buffersMemory.resize(swapChainImageCount);
     
    18171883
    18181884   for (size_t i = 0; i < swapChainImageCount; i++) {
    1819       VulkanUtils::createBuffer(device, physicalDevice, bufferSize, flags,
    1820          VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    1821          buffers[i], buffersMemory[i]);
     1885      VulkanUtils::createBuffer(device, physicalDevice, bufferSize, flags, properties, buffers[i], buffersMemory[i]);
    18221886
    18231887      bufferInfoList[i].buffer = buffers[i];
     
    20932157   // instead of recreated every time
    20942158
    2095    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     2159   createBufferSet(sizeof(UBO_VP_mats),
     2160      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    20962161      uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline);
    20972162
     
    21012166   modelPipeline.createDescriptorSets(swapChainImages);
    21022167
    2103    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     2168   createBufferSet(sizeof(UBO_VP_mats),
     2169      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    21042170      uniformBuffers_shipPipeline, uniformBuffersMemory_shipPipeline, uniformBufferInfoList_shipPipeline);
    21052171
     
    21092175   shipPipeline.createDescriptorSets(swapChainImages);
    21102176
    2111    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     2177   createBufferSet(sizeof(UBO_VP_mats),
     2178      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    21122179      uniformBuffers_asteroidPipeline, uniformBuffersMemory_asteroidPipeline, uniformBufferInfoList_asteroidPipeline);
    21132180
     
    21172184   asteroidPipeline.createDescriptorSets(swapChainImages);
    21182185
    2119    createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     2186   createBufferSet(sizeof(UBO_VP_mats),
     2187      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    21202188      uniformBuffers_laserPipeline, uniformBuffersMemory_laserPipeline, uniformBufferInfoList_laserPipeline);
    21212189
     
    21252193   laserPipeline.createDescriptorSets(swapChainImages);
    21262194
    2127    createBufferSet(sizeof(UBO_Explosion), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
     2195   createBufferSet(sizeof(UBO_Explosion),
     2196      VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    21282197      uniformBuffers_explosionPipeline, uniformBuffersMemory_explosionPipeline, uniformBufferInfoList_explosionPipeline);
    21292198
  • vulkan-game.hpp

    r756162f r9d21aac  
    142142template<class VertexType, class SSBOType>
    143143struct EffectOverTime : public BaseEffectOverTime {
    144    GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline;
     144   GraphicsPipeline_Vulkan<VertexType>& pipeline;
    145145   vector<SceneObject<VertexType, SSBOType>>& objects;
    146146   unsigned int objectIndex;
     
    150150   float changePerSecond;
    151151
    152    EffectOverTime(GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline,
    153          vector<SceneObject<VertexType, SSBOType>>& objects, unsigned int objectIndex,
    154          size_t effectedFieldOffset, float startTime, float changePerSecond) :
    155          pipeline(pipeline),
    156          objects(objects),
    157          objectIndex(objectIndex),
    158          effectedFieldOffset(effectedFieldOffset),
    159          startTime(startTime),
    160          changePerSecond(changePerSecond) {
     152   EffectOverTime(GraphicsPipeline_Vulkan<VertexType>& pipeline, vector<SceneObject<VertexType, SSBOType>>& objects,
     153                  unsigned int objectIndex, size_t effectedFieldOffset, float startTime, float changePerSecond)
     154               : pipeline(pipeline)
     155               , objects(objects)
     156               , objectIndex(objectIndex)
     157               , effectedFieldOffset(effectedFieldOffset)
     158               , startTime(startTime)
     159               , changePerSecond(changePerSecond) {
    161160      size_t ssboOffset = offset_of(&SceneObject<VertexType, SSBOType>::ssbo);
    162161
     
    301300      // the same pipeline, but use different textures, the approach I took when initially creating GraphicsPipeline_Vulkan
    302301      // wouldn't work since the whole pipeline couldn't have a common set of descriptors for the textures
    303       GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject> modelPipeline;
    304       GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject> shipPipeline;
    305       GraphicsPipeline_Vulkan<ModelVertex, SSBO_Asteroid> asteroidPipeline;
    306       GraphicsPipeline_Vulkan<LaserVertex, SSBO_Laser> laserPipeline;
    307       GraphicsPipeline_Vulkan<ExplosionVertex, SSBO_Explosion> explosionPipeline;
     302      GraphicsPipeline_Vulkan<ModelVertex> modelPipeline;
     303      GraphicsPipeline_Vulkan<ModelVertex> shipPipeline;
     304      GraphicsPipeline_Vulkan<ModelVertex> asteroidPipeline;
     305      GraphicsPipeline_Vulkan<LaserVertex> laserPipeline;
     306      GraphicsPipeline_Vulkan<ExplosionVertex> explosionPipeline;
    308307
    309308      // TODO: Maybe make the ubo objects part of the pipeline class since there's only one ubo
     
    420419      void cleanupImGuiOverlay();
    421420
    422       void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags,
    423          vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
    424          vector<VkDescriptorBufferInfo>& bufferInfoList);
     421      // TODO: Maybe move these to a different class, possibly VulkanBuffer or some new related class
     422
     423      void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, VkMemoryPropertyFlags properties,
     424                           vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,
     425                           vector<VkDescriptorBufferInfo>& bufferInfoList);
     426
     427      // TODO: See if it makes sense to rename this to resizeBufferSet() and use it to resize other types of buffers as well
     428      // TODO: Remove the need for templating, which is only there so a GraphicsPupeline_Vulkan can be passed in
     429      template<class VertexType, class SSBOType>
     430      void resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue,
     431                                  GraphicsPipeline_Vulkan<VertexType>& pipeline);
     432
     433      template<class SSBOType>
     434      void updateStorageBuffer(StorageBufferSet& storageBufferSet, size_t objIndex, SSBOType& ssbo);
    425435
    426436      // TODO: Since addObject() returns a reference to the new object now,
    427437      // stop using objects.back() to access the object that was just created
    428438      template<class VertexType, class SSBOType>
    429       SceneObject<VertexType, SSBOType>& addObject(
    430             vector<SceneObject<VertexType, SSBOType>>& objects,
    431             GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline,
    432             const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo,
    433             bool pipelinesCreated);
     439      SceneObject<VertexType, SSBOType>& addObject(vector<SceneObject<VertexType, SSBOType>>& objects,
     440                                                   GraphicsPipeline_Vulkan<VertexType>& pipeline,
     441                                                   const vector<VertexType>& vertices, vector<uint16_t> indices,
     442                                                   SSBOType ssbo, bool pipelinesCreated);
    434443
    435444      template<class VertexType>
     
    444453      template<class VertexType, class SSBOType>
    445454      void updateObject(vector<SceneObject<VertexType, SSBOType>>& objects,
    446             GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, size_t index);
     455            GraphicsPipeline_Vulkan<VertexType>& pipeline, size_t index);
    447456
    448457      template<class VertexType, class SSBOType>
    449       void updateObjectVertices(GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline,
     458      void updateObjectVertices(GraphicsPipeline_Vulkan<VertexType>& pipeline,
    450459            SceneObject<VertexType, SSBOType>& obj, size_t index);
    451460
     
    485494// End of specialized no-op functions
    486495
     496template<class VertexType, class SSBOType>
     497void VulkanGame::resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue,
     498                                        GraphicsPipeline_Vulkan<VertexType>& pipeline) {
     499   pipeline.objectCapacity *= 2;
     500   VkDeviceSize bufferSize = pipeline.objectCapacity * sizeof(SSBOType);
     501
     502   for (size_t i = 0; i < set.buffers.size(); i++) {
     503      VkBuffer newStorageBuffer;
     504      VkDeviceMemory newStorageBufferMemory;
     505
     506      VulkanUtils::createBuffer(device, physicalDevice, bufferSize,
     507         VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
     508         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
     509         newStorageBuffer, newStorageBufferMemory);
     510
     511      VulkanUtils::copyBuffer(device, commandPool, set.buffers[i], newStorageBuffer,
     512         0, 0, pipeline.numObjects * sizeof(SSBOType), graphicsQueue);
     513
     514      vkDestroyBuffer(device, set.buffers[i], nullptr);
     515      vkFreeMemory(device, set.memory[i], nullptr);
     516
     517      set.buffers[i] = newStorageBuffer;
     518      set.memory[i] = newStorageBufferMemory;
     519
     520      set.infoSet[i].buffer = set.buffers[i];
     521      set.infoSet[i].offset = 0; // This is the offset from the start of the buffer, so always 0 for now
     522      set.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE
     523   }
     524}
     525
     526// TODO: See if it makes sense to pass in the current swapchain index instead of updating all of them
     527template<class SSBOType>
     528void VulkanGame::updateStorageBuffer(StorageBufferSet& storageBufferSet, size_t objIndex, SSBOType& ssbo) {
     529   for (size_t i = 0; i < storageBufferSet.memory.size(); i++) {
     530      VulkanUtils::copyDataToMemory(device, ssbo, storageBufferSet.memory[i], objIndex * sizeof(SSBOType));
     531   }
     532}
     533
    487534// TODO: Right now, it's basically necessary to pass the identity matrix in for ssbo.model
    488535// and to change the model matrix later by setting model_transform and then calling updateObject()
    489 // Figure out a better way to allow the model matrix to be set during objecting creation
     536// Figure out a better way to allow the model matrix to be set during object creation
    490537
    491538// TODO: Maybe return a reference to the object from this method if I decide that updating it
     
    494541// to account for scaling
    495542template<class VertexType, class SSBOType>
    496 SceneObject<VertexType, SSBOType>& VulkanGame::addObject(
    497       vector<SceneObject<VertexType, SSBOType>>& objects,
    498       GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline,
    499       const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo,
    500       bool pipelinesCreated) {
     543SceneObject<VertexType, SSBOType>& VulkanGame::addObject(vector<SceneObject<VertexType, SSBOType>>& objects,
     544                                                         GraphicsPipeline_Vulkan<VertexType>& pipeline,
     545                                                         const vector<VertexType>& vertices, vector<uint16_t> indices,
     546                                                         SSBOType ssbo, bool pipelinesCreated) {
    501547   // TODO: Use the model field of ssbo to set the object's model_base
    502548   // currently, the passed in model is useless since it gets overridden in updateObject() anyway
     
    518564   }
    519565
    520    bool storageBufferResized = pipeline.addObject(obj.vertices, obj.indices, obj.ssbo,
    521       resourceCommandPool, graphicsQueue);
     566   pipeline.addObject(obj.vertices, obj.indices, resourceCommandPool, graphicsQueue);
     567
     568   bool resizeStorageBuffer = pipeline.numObjects == pipeline.objectCapacity;
     569
     570   if (resizeStorageBuffer) {
     571      resizeStorageBufferSet<VertexType, SSBOType>(pipeline.storageBufferSet, resourceCommandPool, graphicsQueue, pipeline);
     572      pipeline.cleanup();
     573
     574      // Assume the SSBO is always the 2nd binding
     575      pipeline.updateDescriptorInfo(1, &pipeline.storageBufferSet.infoSet);
     576   }
     577
     578   pipeline.numObjects++;
     579
     580   updateStorageBuffer(pipeline.storageBufferSet, pipeline.numObjects - 1, obj.ssbo);
     581
     582   // TODO: Figure out why I am destroying and recreating the ubos when the swap chain is recreated,
     583   // but am reusing the same ssbos. Maybe I don't need to recreate the ubos.
    522584
    523585   if (pipelinesCreated) {
     
    532594      // Refactor the logic to check for any resized SSBOs after all objects for the frame
    533595      // are created and then recreate each of the corresponding pipelines only once per frame
    534       if (storageBufferResized) {
     596
     597      // TODO: Also, verify if I actually need to recreate all of these, or maybe just the descriptor sets, for instance
     598
     599      if (resizeStorageBuffer) {
    535600         pipeline.createPipeline(pipeline.vertShaderFile, pipeline.fragShaderFile);
    536601         pipeline.createDescriptorPool(swapChainImages);
     
    628693template<class VertexType, class SSBOType>
    629694void VulkanGame::updateObject(vector<SceneObject<VertexType, SSBOType>>& objects,
    630       GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, size_t index) {
     695      GraphicsPipeline_Vulkan<VertexType>& pipeline, size_t index) {
    631696   SceneObject<VertexType, SSBOType>& obj = objects[index];
    632697
     
    634699   obj.center = vec3(obj.ssbo.model * vec4(0.0f, 0.0f, 0.0f, 1.0f));
    635700
    636    pipeline.updateObject(index, obj.ssbo);
     701   updateStorageBuffer(pipeline.storageBufferSet, index, obj.ssbo);
    637702
    638703   obj.modified = false;
     
    640705
    641706template<class VertexType, class SSBOType>
    642 void VulkanGame::updateObjectVertices(GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline,
     707void VulkanGame::updateObjectVertices(GraphicsPipeline_Vulkan<VertexType>& pipeline,
    643708      SceneObject<VertexType, SSBOType>& obj, size_t index) {
    644709   pipeline.updateObjectVertices(index, obj.vertices, resourceCommandPool, graphicsQueue);
Note: See TracChangeset for help on using the changeset viewer.