Changeset a3cefaa in opengl-game for vulkan-game.hpp


Ignore:
Timestamp:
May 17, 2021, 4:06:33 PM (3 years ago)
Author:
Dmitry Portnoy <dportnoy@…>
Branches:
feature/imgui-sdl
Children:
1abebc1
Parents:
996dd3e
Message:

Move SSBO resizing and pipeline recreation checks out of addObject() and into updateScene() so that those operations are only done at most once per pipeline per frame, using vkUpdateDescriptorSets() instead of recreating the whole graphics pipeline, and create a VulkanBuffer class for managing data related to uniform buffers and shader storage buffers, move objectCapacity and numObjects out of GraphicsPipeline_vulkan and use VulkanBuffer to manage them instead

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vulkan-game.hpp

    r996dd3e ra3cefaa  
    2222
    2323#include "consts.hpp"
     24#include "utils.hpp"
     25#include "vulkan-utils.hpp"
     26#include "vulkan-buffer.hpp"
    2427#include "graphics-pipeline_vulkan.hpp"
    2528#include "game-gui-sdl.hpp"
    26 #include "utils.hpp"
    27 #include "vulkan-utils.hpp"
    2829
    2930using namespace glm;
     
    101102// Also, probably better to make this a vector of structs where each struct
    102103// has a VkBuffer, VkDeviceMemory, and VkDescriptorBufferInfo
     104// TODO: Maybe change the structure here since VkDescriptorBufferInfo already stores a reference to the VkBuffer
    103105struct StorageBufferSet {
    104106   vector<VkBuffer> buffers;
     
    316318
    317319      StorageBufferSet storageBuffers_modelPipeline;
     320      VulkanBuffer<SSBO_ModelObject> objects_modelPipeline;
     321
    318322      StorageBufferSet storageBuffers_shipPipeline;
     323      VulkanBuffer<SSBO_ModelObject> objects_shipPipeline;
     324
    319325      StorageBufferSet storageBuffers_asteroidPipeline;
     326      VulkanBuffer<SSBO_Asteroid> objects_asteroidPipeline;
     327
    320328      StorageBufferSet storageBuffers_laserPipeline;
     329      VulkanBuffer<SSBO_Laser> objects_laserPipeline;
     330
    321331      StorageBufferSet storageBuffers_explosionPipeline;
     332      VulkanBuffer<SSBO_Explosion> objects_explosionPipeline;
    322333
    323334      // TODO: Maybe make the ubo objects part of the pipeline class since there's only one ubo
     
    443454      // TODO: Remove the need for templating, which is only there so a GraphicsPupeline_Vulkan can be passed in
    444455      template<class VertexType, class SSBOType>
    445       void resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue,
    446                                   GraphicsPipeline_Vulkan<VertexType>& pipeline);
     456      void resizeStorageBufferSet(StorageBufferSet& set, VulkanBuffer<SSBOType>& buffer,
     457                                  GraphicsPipeline_Vulkan<VertexType>& pipeline,
     458                                  VkCommandPool commandPool, VkQueue graphicsQueue);
    447459
    448460      template<class SSBOType>
     
    455467                                                   GraphicsPipeline_Vulkan<VertexType>& pipeline,
    456468                                                   const vector<VertexType>& vertices, vector<uint16_t> indices,
    457                                                    SSBOType ssbo, StorageBufferSet& storageBuffers,
    458                                                    bool pipelinesCreated);
     469                                                   SSBOType ssbo, StorageBufferSet& storageBuffers);
    459470
    460471      template<class VertexType>
     
    511522
    512523template<class VertexType, class SSBOType>
    513 void VulkanGame::resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue,
    514                                         GraphicsPipeline_Vulkan<VertexType>& pipeline) {
    515    pipeline.objectCapacity *= 2;
    516    VkDeviceSize bufferSize = pipeline.objectCapacity * sizeof(SSBOType);
     524void VulkanGame::resizeStorageBufferSet(StorageBufferSet& set, VulkanBuffer<SSBOType>& buffer,
     525                                        GraphicsPipeline_Vulkan<VertexType>& pipeline,
     526                                        VkCommandPool commandPool, VkQueue graphicsQueue) {
     527   size_t numObjects = buffer.numObjects < buffer.capacity ? buffer.numObjects : buffer.capacity;
     528
     529   do {
     530      buffer.capacity *= 2;
     531   } while (buffer.capacity < buffer.numObjects);
     532
     533   VkDeviceSize bufferSize = buffer.capacity * sizeof(SSBOType);
    517534
    518535   for (size_t i = 0; i < set.buffers.size(); i++) {
     
    526543
    527544      VulkanUtils::copyBuffer(device, commandPool, set.buffers[i], newStorageBuffer,
    528          0, 0, pipeline.numObjects * sizeof(SSBOType), graphicsQueue);
     545         0, 0, numObjects * sizeof(SSBOType), graphicsQueue);
    529546
    530547      vkDestroyBuffer(device, set.buffers[i], nullptr);
     
    538555      set.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE
    539556   }
     557
     558   // Assume the SSBO is always the 2nd binding
     559   // TODO: Figure out a way to make this more flexible
     560   pipeline.updateDescriptorInfo(1, &set.infoSet, swapChainImages);
    540561}
    541562
     
    551572// and to change the model matrix later by setting model_transform and then calling updateObject()
    552573// Figure out a better way to allow the model matrix to be set during object creation
    553 
    554 // TODO: Maybe return a reference to the object from this method if I decide that updating it
    555 // immediately after creation is a good idea (such as setting model_base)
    556 // Currently, model_base is set like this in a few places and the radius is set for asteroids
    557 // to account for scaling
    558574template<class VertexType, class SSBOType>
    559575SceneObject<VertexType, SSBOType>& VulkanGame::addObject(vector<SceneObject<VertexType, SSBOType>>& objects,
    560576                                                         GraphicsPipeline_Vulkan<VertexType>& pipeline,
    561577                                                         const vector<VertexType>& vertices, vector<uint16_t> indices,
    562                                                          SSBOType ssbo, StorageBufferSet& storageBuffers,
    563                                                          bool pipelinesCreated) {
     578                                                         SSBOType ssbo, StorageBufferSet& storageBuffers) {
    564579   // TODO: Use the model field of ssbo to set the object's model_base
    565580   // currently, the passed in model is useless since it gets overridden in updateObject() anyway
     
    582597
    583598   pipeline.addObject(obj.vertices, obj.indices, resourceCommandPool, graphicsQueue);
    584 
    585    // TODO: Probably move the resizing to the VulkanBuffer class
    586    // First, try moving this out of addObject
    587    bool resizeStorageBuffer = pipeline.numObjects == pipeline.objectCapacity;
    588 
    589    if (resizeStorageBuffer) {
    590       resizeStorageBufferSet<VertexType, SSBOType>(storageBuffers, resourceCommandPool, graphicsQueue, pipeline);
    591       pipeline.cleanup();
    592 
    593       // Assume the SSBO is always the 2nd binding
    594       // TODO: Figure out a way to make this more flexible
    595       pipeline.updateDescriptorInfo(1, &storageBuffers.infoSet);
    596    }
    597 
    598    pipeline.numObjects++;
    599 
    600    // TODO: Figure out why I am destroying and recreating the ubos when the swap chain is recreated,
    601    // but am reusing the same ssbos. Maybe I don't need to recreate the ubos.
    602 
    603    if (pipelinesCreated) {
    604       // TODO: See if I can avoid doing this when recreating the pipeline
    605       vkDeviceWaitIdle(device);
    606 
    607       for (uint32_t i = 0; i < swapChainImageCount; i++) {
    608          vkFreeCommandBuffers(device, commandPools[i], 1, &commandBuffers[i]);
    609       }
    610 
    611       // TODO: The pipeline recreation only has to be done once per frame where at least
    612       // one SSBO is resized.
    613       // Refactor the logic to check for any resized SSBOs after all objects for the frame
    614       // are created and then recreate each of the corresponding pipelines only once per frame
    615 
    616       // TODO: Also, verify if I actually need to recreate all of these, or maybe just the descriptor sets, for instance
    617 
    618       if (resizeStorageBuffer) {
    619          pipeline.createPipeline(pipeline.vertShaderFile, pipeline.fragShaderFile);
    620          pipeline.createDescriptorPool(swapChainImages);
    621          pipeline.createDescriptorSets(swapChainImages);
    622       }
    623 
    624       createCommandBuffers();
    625    }
    626599
    627600   return obj;
Note: See TracChangeset for help on using the changeset viewer.