Changeset 9d21aac in opengl-game for graphics-pipeline_vulkan.hpp


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

File:
1 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
Note: See TracChangeset for help on using the changeset viewer.