Changeset 5a0242e in opengl-game for graphics-pipeline_vulkan.hpp


Ignore:
Timestamp:
Nov 17, 2019, 6:56:16 PM (5 years ago)
Author:
Dmitry Portnoy <dmp1488@…>
Branches:
feature/imgui-sdl, master, points-test
Children:
5ab1b20
Parents:
b8777b7
Message:

Refactor GraphicsPipeline_Vulkan to allow adding new data after creation:

  • Create the initial vertex and index buffers in the constructor
  • Add an addObject() method to add new vertex and index data and resize bufffers when needed
  • Remove the bindData() function, since addObject() can replace it
File:
1 edited

Legend:

Unmodified
Added
Removed
  • graphics-pipeline_vulkan.hpp

    rb8777b7 r5a0242e  
    2424};
    2525
     26// TODO: Change the index type to uint32_t and check the Vulkan Tutorial loading model section as a reference
     27// TODO: Create a typedef for index type so I can easily change uin16_t to something else later
    2628template<class VertexType>
    2729struct SceneObject {
    2830   vector<VertexType> vertices;
    29    vector<uint16_t> indices; // TODO: Create a typedef for index type so I can easily change uin16_t to something else later
     31   vector<uint16_t> indices;
    3032};
    3133
     
    3537      GraphicsPipeline_Vulkan();
    3638      GraphicsPipeline_Vulkan(VkPhysicalDevice physicalDevice, VkDevice device, VkRenderPass renderPass,
    37          Viewport viewport, int vertexSize);
     39         Viewport viewport, size_t vertexCapacity, size_t indexCapacity);
    3840      ~GraphicsPipeline_Vulkan();
    3941
    4042      void updateRenderPass(VkRenderPass renderPass);
    41 
    42       void bindData(const vector<VertexType>& vertices, const vector<uint16_t>& indices,
    43          VkCommandPool commandPool, VkQueue graphicsQueue);
    44 
    45       void createVertexBuffer(const void* bufferData, int vertexSize, VkCommandPool commandPool,
    46          VkQueue graphicsQueue);
    47       void createIndexBuffer(const void* bufferData, int indexSize, VkCommandPool commandPool,
    48          VkQueue graphicsQueue);
    4943
    5044      // Maybe I should rename these to addVertexAttribute (addVaryingAttribute) and addUniformAttribute
     
    6256      void createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage);
    6357
    64       bool addObject(const vector<VertexType>& vertices, vector<uint16_t>& indices, VkCommandPool commandPool,
     58      bool addObject(const vector<VertexType>& vertices, vector<uint16_t> indices, VkCommandPool commandPool,
    6559         VkQueue graphicsQueue);
    6660
     
    10094      vector<char> readFile(const string& filename);
    10195
    102       void resizeDataBuffers();
     96      void resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
     97      void resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue);
    10398};
    10499
     
    111106template<class VertexType>
    112107GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan(VkPhysicalDevice physicalDevice, VkDevice device,
    113       VkRenderPass renderPass, Viewport viewport, int vertexSize) {
     108      VkRenderPass renderPass, Viewport viewport, size_t vertexCapacity, size_t indexCapacity) {
    114109   this->physicalDevice = physicalDevice;
    115110   this->device = device;
     
    121116   // I can calculate the stride myself given info about all the varying attributes
    122117   this->bindingDescription.binding = 0;
    123    this->bindingDescription.stride = vertexSize;
     118   this->bindingDescription.stride = sizeof(VertexType);
    124119   this->bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
     120
     121   this->numVertices = 0;
     122   this->vertexCapacity = vertexCapacity;
     123
     124   VulkanUtils::createBuffer(device, physicalDevice, vertexCapacity * sizeof(VertexType),
     125      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
     126      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);
     127
     128   this->numIndices = 0;
     129   this->indexCapacity = indexCapacity;
     130
     131   VulkanUtils::createBuffer(device, physicalDevice, indexCapacity * sizeof(uint16_t),
     132      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
     133      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory);
    125134}
    126135
     
    132141void GraphicsPipeline_Vulkan<VertexType>::updateRenderPass(VkRenderPass renderPass) {
    133142   this->renderPass = renderPass;
    134 }
    135 
    136 // TODO: Probably better to template the whole class
    137 // TODO: Change the index type to uint32_t and check the Vulkan Tutorial loading model section as a reference
    138 
    139 // TODO: combine this function and the constructor since I call this right after the constructor anyway
    140 // TODO: Creating the initial buffers could occur in the constructor and instead of calling this function
    141 // and passing in vertices and indices, addObject() could be called instead and this function could be
    142 // removed
    143 template<class VertexType>
    144 void GraphicsPipeline_Vulkan<VertexType>::bindData(const vector<VertexType>& vertices, const vector<uint16_t>& indices,
    145       VkCommandPool commandPool, VkQueue graphicsQueue) {
    146    numVertices = vertices.size();
    147    vertexCapacity = numVertices * 2;
    148    createVertexBuffer(vertices.data(), sizeof(VertexType), commandPool, graphicsQueue);
    149 
    150    numIndices = indices.size();
    151    indexCapacity = numIndices * 2;
    152    createIndexBuffer(indices.data(), sizeof(uint16_t), commandPool, graphicsQueue);
    153 }
    154 
    155 template<class VertexType>
    156 void GraphicsPipeline_Vulkan<VertexType>::createVertexBuffer(const void* bufferData, int vertexSize,
    157       VkCommandPool commandPool, VkQueue graphicsQueue) {
    158    VkDeviceSize bufferSize = numVertices * vertexSize;
    159    VkDeviceSize bufferCapacity = vertexCapacity * vertexSize;
    160 
    161    VkBuffer stagingBuffer;
    162    VkDeviceMemory stagingBufferMemory;
    163    VulkanUtils::createBuffer(device, physicalDevice, bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
    164       VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    165       stagingBuffer, stagingBufferMemory);
    166 
    167    void* data;
    168    vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data);
    169    memcpy(data, bufferData, (size_t) bufferSize);
    170    vkUnmapMemory(device, stagingBufferMemory);
    171 
    172    VulkanUtils::createBuffer(device, physicalDevice, bufferCapacity,
    173       VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
    174       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);
    175 
    176    VulkanUtils::copyBuffer(device, commandPool, stagingBuffer, vertexBuffer, 0, 0, bufferSize, graphicsQueue);
    177 
    178    vkDestroyBuffer(device, stagingBuffer, nullptr);
    179    vkFreeMemory(device, stagingBufferMemory, nullptr);
    180 }
    181 
    182 template<class VertexType>
    183 void GraphicsPipeline_Vulkan<VertexType>::createIndexBuffer(const void* bufferData, int indexSize,
    184       VkCommandPool commandPool, VkQueue graphicsQueue) {
    185    VkDeviceSize bufferSize = numIndices * indexSize;
    186    VkDeviceSize bufferCapacity = indexCapacity * indexSize;
    187 
    188    VkBuffer stagingBuffer;
    189    VkDeviceMemory stagingBufferMemory;
    190    VulkanUtils::createBuffer(device, physicalDevice, bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
    191       VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
    192       stagingBuffer, stagingBufferMemory);
    193 
    194    void* data;
    195    vkMapMemory(device, stagingBufferMemory, 0, bufferSize, 0, &data);
    196    memcpy(data, bufferData, (size_t) bufferSize);
    197    vkUnmapMemory(device, stagingBufferMemory);
    198 
    199    VulkanUtils::createBuffer(device, physicalDevice, bufferCapacity,
    200       VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
    201       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory);
    202 
    203    VulkanUtils::copyBuffer(device, commandPool, stagingBuffer, indexBuffer, 0, 0, bufferSize, graphicsQueue);
    204 
    205    vkDestroyBuffer(device, stagingBuffer, nullptr);
    206    vkFreeMemory(device, stagingBufferMemory, nullptr);
    207143}
    208144
     
    470406
    471407template<class VertexType>
    472 bool GraphicsPipeline_Vulkan<VertexType>::addObject(const vector<VertexType>& vertices, vector<uint16_t>& indices,
     408bool GraphicsPipeline_Vulkan<VertexType>::addObject(const vector<VertexType>& vertices, vector<uint16_t> indices,
    473409      VkCommandPool commandPool, VkQueue graphicsQueue) {
    474410
    475    if (numVertices + vertices.size() > vertexCapacity ||
    476        numIndices + indices.size() > indexCapacity) {
    477       resizeDataBuffers();
    478 
    479       throw runtime_error("ERROR: Need to resize data buffers");
     411   if (numVertices + vertices.size() > vertexCapacity) {
     412      resizeVertexBuffer(commandPool, graphicsQueue);
     413   }
     414   if (numIndices + indices.size() > indexCapacity) {
     415      resizeIndexBuffer(commandPool, graphicsQueue);
    480416   }
    481417
     
    483419      idx += numVertices;
    484420   }
     421   objects.push_back({vertices, indices });
    485422
    486423   VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, vertices, vertexBuffer, numVertices,
     
    549486
    550487template<class VertexType>
    551 void GraphicsPipeline_Vulkan<VertexType>::resizeDataBuffers() {
    552    
     488void GraphicsPipeline_Vulkan<VertexType>::resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
     489   VkBuffer newVertexBuffer;
     490   VkDeviceMemory newVertexBufferMemory;
     491   vertexCapacity *= 2;
     492
     493   VulkanUtils::createBuffer(device, physicalDevice, vertexCapacity * sizeof(VertexType),
     494      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
     495      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, newVertexBuffer, newVertexBufferMemory);
     496
     497   VulkanUtils::copyBuffer(device, commandPool, vertexBuffer, newVertexBuffer, 0, 0, numVertices * sizeof(VertexType), graphicsQueue);
     498
    553499   vkDestroyBuffer(device, vertexBuffer, nullptr);
    554500   vkFreeMemory(device, vertexBufferMemory, nullptr);
     501
     502   vertexBuffer = newVertexBuffer;
     503   vertexBufferMemory = newVertexBufferMemory;
     504}
     505
     506template<class VertexType>
     507void GraphicsPipeline_Vulkan<VertexType>::resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) {
     508   VkBuffer newIndexBuffer;
     509   VkDeviceMemory newIndexBufferMemory;
     510   indexCapacity *= 2;
     511
     512   VulkanUtils::createBuffer(device, physicalDevice, indexCapacity * sizeof(uint16_t),
     513      VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
     514      VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, newIndexBuffer, newIndexBufferMemory);
     515
     516   VulkanUtils::copyBuffer(device, commandPool, indexBuffer, newIndexBuffer, 0, 0, numIndices * sizeof(uint16_t), graphicsQueue);
     517
    555518   vkDestroyBuffer(device, indexBuffer, nullptr);
    556519   vkFreeMemory(device, indexBufferMemory, nullptr);
    557520
    558    vertexCapacity *= 2;
    559    indexCapacity *= 2;
    560 
    561    VulkanUtils::createBuffer(device, physicalDevice, vertexCapacity * sizeof(VertexType),
    562       VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
    563       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBuffer, vertexBufferMemory);
    564 
    565    VulkanUtils::createBuffer(device, physicalDevice, indexCapacity * sizeof(uint16_t),
    566       VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
    567       VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory);
     521   indexBuffer = newIndexBuffer;
     522   indexBufferMemory = newIndexBufferMemory;
    568523}
    569524
Note: See TracChangeset for help on using the changeset viewer.