Changeset 5a0242e in opengl-game


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
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • VulkanGame.vcxproj

    rb8777b7 r5a0242e  
    135135    <ClCompile Include="FileStackWalker.cpp" />
    136136    <ClCompile Include="game-gui-sdl.cpp" />
    137     <ClCompile Include="graphics-pipeline_vulkan.cpp" />
    138137    <ClCompile Include="logger.cpp" />
    139138    <ClCompile Include="main-vulkan.cpp" />
  • 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
  • vulkan-game.cpp

    rb8777b7 r5a0242e  
    194194   createUniformBuffers();
    195195
    196    vector<ModelVertex> sceneVertices = {
    197       {{-0.5f, -0.5f, -2.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
    198       {{ 0.5f, -0.5f, -2.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
    199       {{ 0.5f,  0.5f, -2.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
    200       {{-0.5f,  0.5f, -2.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
    201 
    202       {{-0.5f, -0.5f, -1.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
    203       {{ 0.5f, -0.5f, -1.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
    204       {{ 0.5f,  0.5f, -1.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
    205       {{-0.5f,  0.5f, -1.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}
    206    };
    207    vector<uint16_t> sceneIndices = {
    208       0, 1, 2, 2, 3, 0,
    209       4, 5, 6, 6, 7, 4
    210    };
    211 
    212196   modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>(physicalDevice, device, renderPass,
    213       { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, sizeof(ModelVertex));
    214 
    215    modelPipeline.bindData(sceneVertices, sceneIndices, commandPool, graphicsQueue);
     197      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 16, 24);
     198
     199   modelPipeline.addObject({
     200         {{-0.5f, -0.5f, -2.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
     201         {{ 0.5f, -0.5f, -2.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
     202         {{ 0.5f,  0.5f, -2.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
     203         {{-0.5f,  0.5f, -2.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}
     204      }, {
     205         0, 1, 2, 2, 3, 0
     206      }, commandPool, graphicsQueue);
     207
     208   modelPipeline.addObject({
     209         {{-0.5f, -0.5f, -1.5f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
     210         {{ 0.5f, -0.5f, -1.5f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
     211         {{ 0.5f,  0.5f, -1.5f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
     212         {{-0.5f,  0.5f, -1.5f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}
     213      }, {
     214         0, 1, 2, 2, 3, 0
     215      }, commandPool, graphicsQueue);
    216216
    217217   modelPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ModelVertex::pos));
     
    229229   modelPipeline.createDescriptorSets(swapChainImages);
    230230
    231    vector<OverlayVertex> overlayVertices = {
    232       {{-1.0f,  1.0f,  0.0f}, {0.0f, 1.0f}},
    233       {{ 1.0f,  1.0f,  0.0f}, {1.0f, 1.0f}},
    234       {{ 1.0f, -1.0f,  0.0f}, {1.0f, 0.0f}},
    235       {{-1.0f, -1.0f,  0.0f}, {0.0f, 0.0f}}
    236    };
    237    vector<uint16_t> overlayIndices = {
    238       0, 1, 2, 2, 3, 0
    239    };
    240 
    241231   overlayPipeline = GraphicsPipeline_Vulkan<OverlayVertex>(physicalDevice, device, renderPass,
    242       { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, sizeof(OverlayVertex));
    243 
    244    overlayPipeline.bindData(overlayVertices, overlayIndices, commandPool, graphicsQueue);
     232      { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 4, 6);
     233
     234   overlayPipeline.addObject({
     235         {{-1.0f,  1.0f,  0.0f}, {0.0f, 1.0f}},
     236         {{ 1.0f,  1.0f,  0.0f}, {1.0f, 1.0f}},
     237         {{ 1.0f, -1.0f,  0.0f}, {1.0f, 0.0f}},
     238         {{-1.0f, -1.0f,  0.0f}, {0.0f, 0.0f}}
     239      }, {
     240         0, 1, 2, 2, 3, 0
     241      }, commandPool, graphicsQueue);
    245242
    246243   overlayPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&OverlayVertex::pos));
     
    291288                  cout << "Adding a plane" << endl;
    292289                  float zOffset = -2.0f + (0.5f * numPlanes);
    293                   vector<ModelVertex> vertices = {
     290
     291                  vkDeviceWaitIdle(device);
     292                  vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
     293
     294                  modelPipeline.addObject({
    294295                     {{-0.5f, -0.5f,  zOffset}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
    295296                     {{ 0.5f, -0.5f,  zOffset}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
    296297                     {{ 0.5f,  0.5f,  zOffset}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
    297298                     {{-0.5f,  0.5f,  zOffset}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}}
    298                   };
    299                   vector<uint16_t> indices = {
     299                  }, {
    300300                     0, 1, 2, 2, 3, 0
    301                   };
    302 
    303                   // TODO: Encapsulate these lines into an addObject() function in vulkan-game
    304 
    305                   vkDeviceWaitIdle(device);
    306                   vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data());
    307 
    308                   modelPipeline.addObject(vertices, indices, commandPool, graphicsQueue);
     301                  }, commandPool, graphicsQueue);
    309302
    310303                  createCommandBuffers();
     
    314307                  cout << "Key event detected" << endl;
    315308               }
     309               break;
     310            case UI_EVENT_KEYUP:
    316311               break;
    317312            case UI_EVENT_MOUSEBUTTONDOWN:
Note: See TracChangeset for help on using the changeset viewer.