Changeset 44f23af in opengl-game


Ignore:
Timestamp:
Feb 25, 2020, 9:29:36 PM (5 years ago)
Author:
Dmitry Portnoy <dmitry.portnoy@…>
Branches:
feature/imgui-sdl, master, points-test
Children:
0807aeb
Parents:
3b84bb6
Message:

In VulkanGame, add code to resize the storage buffer and update the right descriptor info when the storage buffer becomes full

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • graphics-pipeline_vulkan.hpp

    r3b84bb6 r44f23af  
    4141class GraphicsPipeline_Vulkan : public GraphicsPipeline {
    4242   public:
     43      string vertShaderFile, fragShaderFile;
     44
    4345      GraphicsPipeline_Vulkan();
    4446
     
    116118      void resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
    117119      void resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
     120      void resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue);
    118121};
    119122
     
    233236template<class VertexType, class SSBOType>
    234237void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createPipeline(string vertShaderFile, string fragShaderFile) {
     238   this->vertShaderFile = vertShaderFile;
     239   this->fragShaderFile = fragShaderFile;
     240
    235241   vector<char> vertShaderCode = readFile(vertShaderFile);
    236242   vector<char> fragShaderCode = readFile(fragShaderFile);
     
    492498      resizeVertexBuffer(commandPool, graphicsQueue);
    493499   }
    494    if (numIndices + indices.size() > indexCapacity) {
    495       resizeIndexBuffer(commandPool, graphicsQueue);
    496    }
    497 
    498500   VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, vertices, vertexBuffer, numVertices,
    499501      graphicsQueue);
    500502   numVertices += vertices.size();
    501503
     504   if (numIndices + indices.size() > indexCapacity) {
     505      resizeIndexBuffer(commandPool, graphicsQueue);
     506   }
    502507   VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, indices, indexBuffer, numIndices,
    503508      graphicsQueue);
     
    505510
    506511   bool resizedStorageBuffer = false;
     512
     513   if (!is_same_v<SSBOType, void*>) {
     514      if (this->numObjects == this->objectCapacity) {
     515         resizeStorageBufferSet(storageBufferSet, commandPool, graphicsQueue);
     516         cleanup();
     517
     518         // Assume the SSBO is always the 2nd binding
     519         this->descriptorInfoList[1].bufferDataList = &storageBufferSet.infoSet;
     520         resizedStorageBuffer = true;
     521
     522         cout << "SSBO resized, New object capacity: " << this->objectCapacity << endl;
     523
     524         // TODO: I'll need to correctly update the descriptor set array instead of appending to it
     525         // Then, I'll have to call createDescriptorSets() and finally createCommandBuffers() (from vulkan-game)
     526         // This isn't too bad actually, since I have to call createCommandBuffers() every time I add a newobject
     527         // anyway. So, in this function, I'll just have to call createDescriptorSets()
     528      }
     529
     530      updateObject(this->numObjects, ssbo);
     531   }
     532
     533   this->numObjects++;
    507534
    508535   return resizedStorageBuffer;
     
    621648}
    622649
     650template<class VertexType, class SSBOType>
     651void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeStorageBufferSet(StorageBufferSet& set,
     652      VkCommandPool commandPool, VkQueue graphicsQueue) {
     653   this->objectCapacity *= 2;
     654   VkDeviceSize bufferSize = objectCapacity * sizeof(SSBOType);
     655
     656   for (size_t i = 0; i < set.buffers.size(); i++) {
     657      VkBuffer newStorageBuffer;
     658      VkDeviceMemory newStorageBufferMemory;
     659
     660      VulkanUtils::createBuffer(this->device, this->physicalDevice, bufferSize,
     661         VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
     662         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
     663         newStorageBuffer, newStorageBufferMemory);
     664
     665      VulkanUtils::copyBuffer(this->device, commandPool, set.buffers[i], newStorageBuffer,
     666         0, 0, this->numObjects * sizeof(SSBOType), graphicsQueue);
     667
     668      vkDestroyBuffer(this->device, set.buffers[i], nullptr);
     669      vkFreeMemory(this->device, set.memory[i], nullptr);
     670
     671      set.buffers[i] = newStorageBuffer;
     672      set.memory[i] = newStorageBufferMemory;
     673
     674      set.infoSet[i].buffer = set.buffers[i];
     675      set.infoSet[i].offset = 0; // This is the offset from the start of the buffer, so always 0 for now
     676      set.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE
     677   }
     678}
     679
    623680#endif // _GRAPHICS_PIPELINE_VULKAN_H
  • vulkan-game.cpp

    r3b84bb6 r44f23af  
    742742      if (gui->keyPressed(SDL_SCANCODE_X)) {
    743743         if (asteroidObjects.size() > 0 && !asteroidObjects[0].ssbo.deleted) {
     744            asteroidObjects[0].model_transform = translate(mat4(1.0f), vec3(0.0f, 0.0f, asteroidSpeed * elapsedTime))
     745               * asteroidObjects[0].model_transform;
     746
     747            vec3 obj_center = vec3(asteroid_VP_mats.view * vec4(asteroidObjects[0].center, 1.0f));
     748
     749            float closest = obj_center.z - asteroidObjects[0].radius;
     750            cout << closest << " ? " << -NEAR_CLIP << endl;
     751
    744752            updateObject(asteroidObjects, asteroidPipeline, 0);
    745753         }
  • vulkan-game.hpp

    r3b84bb6 r44f23af  
    269269
    270270   if (pipelinesCreated) {
     271      vkDeviceWaitIdle(device);
     272      vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
     273
     274      // TODO: The pipeline recreation only has to be done once per frame where at least
     275      // one SSBO is resized.
     276      // Refactor the logic to check for any resized SSBOs after all objects for the frame
     277      // are created and then recreate each of the corresponding pipelines only once per frame
    271278      if (storageBufferResized) {
     279         pipeline.createPipeline(pipeline.vertShaderFile, pipeline.fragShaderFile);
     280         pipeline.createDescriptorPool(swapChainImages);
     281         pipeline.createDescriptorSets(swapChainImages);
    272282      }
    273283
Note: See TracChangeset for help on using the changeset viewer.