Changeset a3cefaa in opengl-game for sdl-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
  • sdl-game.hpp

    r996dd3e ra3cefaa  
    2121#include "consts.hpp"
    2222#include "vulkan-utils.hpp"
     23#include "vulkan-buffer.hpp"
    2324#include "graphics-pipeline_vulkan.hpp"
    2425#include "game-gui-sdl.hpp"
     
    7778// Also, probably better to make this a vector of structs where each struct
    7879// has a VkBuffer, VkDeviceMemory, and VkDescriptorBufferInfo
     80// TODO: Maybe change the structure here since VkDescriptorBufferInfo already stores a reference to the VkBuffer
    7981struct StorageBufferSet {
    8082   vector<VkBuffer> buffers;
     
    219221
    220222      StorageBufferSet storageBuffers_modelPipeline;
     223      VulkanBuffer<SSBO_ModelObject> objects_modelPipeline;
    221224
    222225      // TODO: Maybe make the ubo objects part of the pipeline class since there's only one ubo
     
    296299      // TODO: Remove the need for templating, which is only there so a GraphicsPupeline_Vulkan can be passed in
    297300      template<class VertexType, class SSBOType>
    298       void resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue,
    299                                   GraphicsPipeline_Vulkan<VertexType>& pipeline);
     301      void resizeStorageBufferSet(StorageBufferSet& set, VulkanBuffer<SSBOType>& buffer,
     302                                  GraphicsPipeline_Vulkan<VertexType>& pipeline,
     303                                  VkCommandPool commandPool, VkQueue graphicsQueue);
    300304
    301305      template<class SSBOType>
     
    308312                                                   GraphicsPipeline_Vulkan<VertexType>& pipeline,
    309313                                                   const vector<VertexType>& vertices, vector<uint16_t> indices,
    310                                                    SSBOType ssbo, StorageBufferSet& storageBuffers,
    311                                                    bool pipelinesCreated);
     314                                                   SSBOType ssbo, StorageBufferSet& storageBuffers);
    312315
    313316      template<class VertexType>
     
    344347
    345348template<class VertexType, class SSBOType>
    346 void VulkanGame::resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue,
    347                                         GraphicsPipeline_Vulkan<VertexType>& pipeline) {
    348    pipeline.objectCapacity *= 2;
    349    VkDeviceSize bufferSize = pipeline.objectCapacity * sizeof(SSBOType);
     349void VulkanGame::resizeStorageBufferSet(StorageBufferSet& set, VulkanBuffer<SSBOType>& buffer,
     350                                        GraphicsPipeline_Vulkan<VertexType>& pipeline,
     351                                        VkCommandPool commandPool, VkQueue graphicsQueue) {
     352   size_t numObjects = buffer.numObjects < buffer.capacity ? buffer.numObjects : buffer.capacity;
     353
     354   do {
     355      buffer.capacity *= 2;
     356   } while (buffer.capacity < buffer.numObjects);
     357
     358   VkDeviceSize bufferSize = buffer.capacity * sizeof(SSBOType);
    350359
    351360   for (size_t i = 0; i < set.buffers.size(); i++) {
     
    359368
    360369      VulkanUtils::copyBuffer(device, commandPool, set.buffers[i], newStorageBuffer,
    361          0, 0, pipeline.numObjects * sizeof(SSBOType), graphicsQueue);
     370         0, 0, numObjects * sizeof(SSBOType), graphicsQueue);
    362371
    363372      vkDestroyBuffer(device, set.buffers[i], nullptr);
     
    371380      set.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE
    372381   }
     382
     383   // Assume the SSBO is always the 2nd binding
     384   // TODO: Figure out a way to make this more flexible
     385   pipeline.updateDescriptorInfo(1, &set.infoSet, swapChainImages);
    373386}
    374387
     
    384397// and to change the model matrix later by setting model_transform and then calling updateObject()
    385398// Figure out a better way to allow the model matrix to be set during object creation
    386 
    387 // TODO: Maybe return a reference to the object from this method if I decide that updating it
    388 // immediately after creation is a good idea (such as setting model_base)
    389 // Currently, model_base is set like this in a few places and the radius is set for asteroids
    390 // to account for scaling
    391399template<class VertexType, class SSBOType>
    392400SceneObject<VertexType, SSBOType>& VulkanGame::addObject(vector<SceneObject<VertexType, SSBOType>>& objects,
    393401                                                         GraphicsPipeline_Vulkan<VertexType>& pipeline,
    394402                                                         const vector<VertexType>& vertices, vector<uint16_t> indices,
    395                                                          SSBOType ssbo, StorageBufferSet& storageBuffers,
    396                                                          bool pipelinesCreated) {
     403                                                         SSBOType ssbo, StorageBufferSet& storageBuffers) {
    397404   // TODO: Use the model field of ssbo to set the object's model_base
    398405   // currently, the passed in model is useless since it gets overridden in updateObject() anyway
     
    415422
    416423   pipeline.addObject(obj.vertices, obj.indices, resourceCommandPool, graphicsQueue);
    417 
    418    // TODO: Probably move the resizing to the VulkanBuffer class
    419    // First, try moving this out of addObject
    420    bool resizeStorageBuffer = pipeline.numObjects == pipeline.objectCapacity;
    421 
    422    if (resizeStorageBuffer) {
    423       resizeStorageBufferSet<VertexType, SSBOType>(storageBuffers, resourceCommandPool, graphicsQueue, pipeline);
    424       pipeline.cleanup();
    425 
    426       // Assume the SSBO is always the 2nd binding
    427       // TODO: Figure out a way to make this more flexible
    428       pipeline.updateDescriptorInfo(1, &storageBuffers.infoSet);
    429    }
    430 
    431    pipeline.numObjects++;
    432 
    433    // TODO: Figure out why I am destroying and recreating the ubos when the swap chain is recreated,
    434    // but am reusing the same ssbos. Maybe I don't need to recreate the ubos.
    435 
    436    if (pipelinesCreated) {
    437       // TODO: See if I can avoid doing this when recreating the pipeline
    438       vkDeviceWaitIdle(device);
    439 
    440       for (uint32_t i = 0; i < swapChainImageCount; i++) {
    441          vkFreeCommandBuffers(device, commandPools[i], 1, &commandBuffers[i]);
    442       }
    443 
    444       // TODO: The pipeline recreation only has to be done once per frame where at least
    445       // one SSBO is resized.
    446       // Refactor the logic to check for any resized SSBOs after all objects for the frame
    447       // are created and then recreate each of the corresponding pipelines only once per frame
    448 
    449       // TODO: Also, verify if I actually need to recreate all of these, or maybe just the descriptor sets, for instance
    450 
    451       if (resizeStorageBuffer) {
    452          pipeline.createPipeline(pipeline.vertShaderFile, pipeline.fragShaderFile);
    453          pipeline.createDescriptorPool(swapChainImages);
    454          pipeline.createDescriptorSets(swapChainImages);
    455       }
    456 
    457       createCommandBuffers();
    458    }
    459424
    460425   return obj;
Note: See TracChangeset for help on using the changeset viewer.