Changeset 9d21aac in opengl-game
- Timestamp:
- May 6, 2021, 3:24:42 AM (4 years ago)
- Branches:
- feature/imgui-sdl
- Children:
- 996dd3e
- Parents:
- 756162f
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
graphics-pipeline_vulkan.hpp
r756162f r9d21aac 21 21 22 22 using namespace glm; 23 24 // TODO: Maybe change the name of this struct so I can call the list something other than descriptorInfoList25 struct DescriptorInfo {26 VkDescriptorType type;27 VkShaderStageFlags stageFlags;28 29 // Only one of the below properties should be set30 vector<VkDescriptorBufferInfo>* bufferDataList;31 VkDescriptorImageInfo* imageData;32 };33 23 34 24 // TODO: Use this struct for uniform buffers as well and rename it to VulkanBuffer (maybe move it to VulkanUtils) … … 41 31 }; 42 32 43 template<class VertexType, class SSBOType> 33 // TODO: Maybe change the name of this struct so I can call the list something other than descriptorInfoList 34 struct DescriptorInfo { 35 VkDescriptorType type; 36 VkShaderStageFlags stageFlags; 37 38 // Only one of the below properties should be set 39 vector<VkDescriptorBufferInfo>* bufferDataList; 40 VkDescriptorImageInfo* imageData; 41 }; 42 43 template<class VertexType> 44 44 class GraphicsPipeline_Vulkan : public GraphicsPipeline { 45 45 public: 46 46 string vertShaderFile, fragShaderFile; 47 48 // TODO: Move this outside this classs, since it is no longer used here 49 StorageBufferSet storageBufferSet; 50 51 // Both of these are only used for managing the SSBO, so move them out as well 52 size_t objectCapacity; 53 size_t numObjects; 47 54 48 55 GraphicsPipeline_Vulkan(); … … 64 71 void addAttribute(VkFormat format, size_t offset); 65 72 66 void addStorageDescriptor(VkShaderStageFlags stageFlags);67 68 73 // TODO: I might be able to use a single VkDescriptorBufferInfo here and reuse it when creating the descriptor sets 69 74 void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, … … 71 76 void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData); 72 77 78 void updateDescriptorInfo(uint32_t index, vector<VkDescriptorBufferInfo>* bufferData); 79 // TODO: Maybe make an analogous one for updating image info 80 73 81 void createPipeline(string vertShaderFile, string fragShaderFile); 74 82 void createDescriptorSetLayout(); … … 78 86 void createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage); 79 87 80 bool addObject(const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType& ssbo, 81 VkCommandPool commandPool, VkQueue graphicsQueue); 82 83 void updateObject(size_t objIndex, SSBOType& ssbo); 88 void addObject(const vector<VertexType>& vertices, vector<uint16_t> indices, VkCommandPool commandPool, 89 VkQueue graphicsQueue); 84 90 85 91 void updateObjectVertices(size_t objIndex, const vector<VertexType>& vertices, VkCommandPool commandPool, … … 117 123 VkDeviceMemory indexBufferMemory; 118 124 119 size_t numObjects;120 size_t objectCapacity;121 122 StorageBufferSet storageBufferSet;123 124 125 VkShaderModule createShaderModule(const vector<char>& code); 125 126 vector<char> readFile(const string& filename); … … 127 128 void resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue); 128 129 void resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue); 129 void resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue);130 130 }; 131 131 132 132 /*** PUBLIC METHODS ***/ 133 133 134 template<class VertexType , class SSBOType>135 GraphicsPipeline_Vulkan<VertexType , SSBOType>::GraphicsPipeline_Vulkan() {134 template<class VertexType> 135 GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan() { 136 136 } 137 137 … … 139 139 // TODO: See if it would be feasible to move code in the createPipeline method 140 140 // into the constructor. That way, I can also put relevant cleanup code into the destructor 141 template<class VertexType , class SSBOType>142 GraphicsPipeline_Vulkan<VertexType , SSBOType>::GraphicsPipeline_Vulkan(141 template<class VertexType> 142 GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan( 143 143 VkPrimitiveTopology topology, VkPhysicalDevice physicalDevice, VkDevice device, 144 144 VkRenderPass renderPass, Viewport viewport, vector<VkImage>& swapChainImages, … … 173 173 this->numObjects = 0; 174 174 this->objectCapacity = objectCapacity; 175 176 // Hacky way to allow an SSBO to be optional177 // Specifying void* as the SSBOType will skip allocating the related buffers178 if (!is_same_v<SSBOType, void*>) {179 VkDeviceSize bufferSize = objectCapacity * sizeof(SSBOType);180 cout << "NUM SWAP CHAIN IMAGES: " << swapChainImages.size() << endl;181 182 storageBufferSet.buffers.resize(swapChainImages.size());183 storageBufferSet.memory.resize(swapChainImages.size());184 storageBufferSet.infoSet.resize(swapChainImages.size());185 186 for (size_t i = 0; i < swapChainImages.size(); i++) {187 VulkanUtils::createBuffer(this->device, this->physicalDevice, bufferSize,188 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,189 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,190 storageBufferSet.buffers[i], storageBufferSet.memory[i]);191 192 storageBufferSet.infoSet[i].buffer = storageBufferSet.buffers[i];193 storageBufferSet.infoSet[i].offset = 0; // This is the offset from the start of the buffer, so always 0 for now194 storageBufferSet.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE195 }196 }197 175 } 198 176 199 177 // TODO: Move as much cleanup as I can into the destructor 200 template<class VertexType , class SSBOType>201 GraphicsPipeline_Vulkan<VertexType , SSBOType>::~GraphicsPipeline_Vulkan() {202 } 203 204 template<class VertexType , class SSBOType>205 size_t GraphicsPipeline_Vulkan<VertexType , SSBOType>::getNumVertices() {178 template<class VertexType> 179 GraphicsPipeline_Vulkan<VertexType>::~GraphicsPipeline_Vulkan() { 180 } 181 182 template<class VertexType> 183 size_t GraphicsPipeline_Vulkan<VertexType>::getNumVertices() { 206 184 return numVertices; 207 185 } 208 186 209 template<class VertexType , class SSBOType>210 void GraphicsPipeline_Vulkan<VertexType , SSBOType>::updateRenderPass(VkRenderPass renderPass) {187 template<class VertexType> 188 void GraphicsPipeline_Vulkan<VertexType>::updateRenderPass(VkRenderPass renderPass) { 211 189 this->renderPass = renderPass; 212 190 } 213 191 214 template<class VertexType , class SSBOType>215 void GraphicsPipeline_Vulkan<VertexType , SSBOType>::addAttribute(VkFormat format, size_t offset) {192 template<class VertexType> 193 void GraphicsPipeline_Vulkan<VertexType>::addAttribute(VkFormat format, size_t offset) { 216 194 VkVertexInputAttributeDescription attributeDesc = {}; 217 195 … … 224 202 } 225 203 226 // TODO: The SSBOType check isn't really needed since I call this function in VulkanGame explicitly 227 template<class VertexType, class SSBOType> 228 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addStorageDescriptor(VkShaderStageFlags stageFlags) { 229 if (!is_same_v<SSBOType, void*>) { 230 addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 231 stageFlags, &storageBufferSet.infoSet); 232 } 233 } 234 235 template<class VertexType, class SSBOType> 236 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::addDescriptorInfo(VkDescriptorType type, 204 template<class VertexType> 205 void GraphicsPipeline_Vulkan<VertexType>::addDescriptorInfo(VkDescriptorType type, 237 206 VkShaderStageFlags stageFlags, vector<VkDescriptorBufferInfo>* bufferData) { 238 207 this->descriptorInfoList.push_back({ type, stageFlags, bufferData, nullptr }); 239 208 } 240 209 241 template<class VertexType , class SSBOType>242 void GraphicsPipeline_Vulkan<VertexType , SSBOType>::addDescriptorInfo(VkDescriptorType type,210 template<class VertexType> 211 void GraphicsPipeline_Vulkan<VertexType>::addDescriptorInfo(VkDescriptorType type, 243 212 VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData) { 244 213 this->descriptorInfoList.push_back({ type, stageFlags, nullptr, imageData }); 245 214 } 246 215 247 template<class VertexType, class SSBOType> 248 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createPipeline(string vertShaderFile, string fragShaderFile) { 216 template<class VertexType> 217 void GraphicsPipeline_Vulkan<VertexType>::updateDescriptorInfo(uint32_t index, 218 vector<VkDescriptorBufferInfo>* bufferData) { 219 this->descriptorInfoList[index].bufferDataList = bufferData; 220 } 221 222 template<class VertexType> 223 void GraphicsPipeline_Vulkan<VertexType>::createPipeline(string vertShaderFile, string fragShaderFile) { 249 224 this->vertShaderFile = vertShaderFile; 250 225 this->fragShaderFile = fragShaderFile; … … 386 361 } 387 362 388 template<class VertexType , class SSBOType>389 void GraphicsPipeline_Vulkan<VertexType , SSBOType>::createDescriptorSetLayout() {363 template<class VertexType> 364 void GraphicsPipeline_Vulkan<VertexType>::createDescriptorSetLayout() { 390 365 vector<VkDescriptorSetLayoutBinding> bindings(this->descriptorInfoList.size()); 391 366 … … 408 383 } 409 384 410 template<class VertexType , class SSBOType>411 void GraphicsPipeline_Vulkan<VertexType , SSBOType>::createDescriptorPool(vector<VkImage>& swapChainImages) {385 template<class VertexType> 386 void GraphicsPipeline_Vulkan<VertexType>::createDescriptorPool(vector<VkImage>& swapChainImages) { 412 387 vector<VkDescriptorPoolSize> poolSizes(this->descriptorInfoList.size()); 413 388 … … 429 404 430 405 // TODO: Since I only need the size of the swapChainImages array, I should just pass that in instead of the whole array 431 template<class VertexType , class SSBOType>432 void GraphicsPipeline_Vulkan<VertexType , SSBOType>::createDescriptorSets(vector<VkImage>& swapChainImages) {406 template<class VertexType> 407 void GraphicsPipeline_Vulkan<VertexType>::createDescriptorSets(vector<VkImage>& swapChainImages) { 433 408 vector<VkDescriptorSetLayout> layouts(swapChainImages.size(), this->descriptorSetLayout); 434 409 … … 476 451 } 477 452 478 template<class VertexType, class SSBOType> 479 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::createRenderCommands(VkCommandBuffer& commandBuffer, 480 uint32_t currentImage) { 481 453 template<class VertexType> 454 void GraphicsPipeline_Vulkan<VertexType>::createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage) { 482 455 vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); 483 456 … … 494 467 } 495 468 496 template<class VertexType, class SSBOType> 497 bool GraphicsPipeline_Vulkan<VertexType, SSBOType>::addObject( 498 const vector<VertexType>& vertices, vector<uint16_t> indices, 499 SSBOType& ssbo, VkCommandPool commandPool, VkQueue graphicsQueue) { 500 469 template<class VertexType> 470 void GraphicsPipeline_Vulkan<VertexType>::addObject(const vector<VertexType>& vertices, vector<uint16_t> indices, 471 VkCommandPool commandPool, VkQueue graphicsQueue) { 501 472 // TODO: When resizing the vertex or index buffer, take deleted objects into account. 502 473 // Remove their data from the buffer and determine the new size of the bufer based on # of remining objects … … 522 493 this->indexBuffer, this->numIndices, graphicsQueue); 523 494 this->numIndices += indices.size(); 524 525 bool resizedStorageBuffer = false;526 527 if (!is_same_v<SSBOType, void*>) {528 if (this->numObjects == this->objectCapacity) {529 resizeStorageBufferSet(storageBufferSet, commandPool, graphicsQueue);530 cleanup();531 532 // Assume the SSBO is always the 2nd binding533 this->descriptorInfoList[1].bufferDataList = &storageBufferSet.infoSet;534 resizedStorageBuffer = true;535 536 cout << "SSBO resized, New object capacity: " << this->objectCapacity << endl;537 538 // TODO: I'll need to correctly update the descriptor set array instead of appending to it539 // Then, I'll have to call createDescriptorSets() and finally createCommandBuffers() (from vulkan-game)540 // This isn't too bad actually, since I have to call createCommandBuffers() every time I add a newobject541 // anyway. So, in this function, I'll just have to call createDescriptorSets()542 }543 544 updateObject(this->numObjects, ssbo);545 }546 547 this->numObjects++;548 549 return resizedStorageBuffer;550 }551 552 // TODO: Allow a swapchain index to be passed in instead of updating all of them553 // Actually, since I'm in the process of replacing SSBOs with dynamic UBOs, I can ignore that for this function554 template<class VertexType, class SSBOType>555 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::updateObject(size_t objIndex, SSBOType& ssbo) {556 if (!is_same_v<SSBOType, void*>) {557 for (size_t i = 0; i < storageBufferSet.memory.size(); i++) {558 VulkanUtils::copyDataToMemory(this->device, ssbo, storageBufferSet.memory[i], objIndex * sizeof(SSBOType));559 }560 }561 495 } 562 496 563 497 // Should only be used if the number of vertices has not changed 564 template<class VertexType , class SSBOType>565 void GraphicsPipeline_Vulkan<VertexType , SSBOType>::updateObjectVertices(size_t objIndex,498 template<class VertexType> 499 void GraphicsPipeline_Vulkan<VertexType>::updateObjectVertices(size_t objIndex, 566 500 const vector<VertexType>& vertices, VkCommandPool commandPool, VkQueue graphicsQueue) { 567 501 VulkanUtils::copyDataToBuffer(this->device, this->physicalDevice, commandPool, vertices, … … 569 503 } 570 504 571 template<class VertexType , class SSBOType>572 void GraphicsPipeline_Vulkan<VertexType , SSBOType>::cleanup() {505 template<class VertexType> 506 void GraphicsPipeline_Vulkan<VertexType>::cleanup() { 573 507 vkDestroyPipeline(device, pipeline, nullptr); 574 508 vkDestroyDescriptorPool(device, descriptorPool, nullptr); … … 579 513 } 580 514 581 template<class VertexType , class SSBOType>582 void GraphicsPipeline_Vulkan<VertexType , SSBOType>::cleanupBuffers() {515 template<class VertexType> 516 void GraphicsPipeline_Vulkan<VertexType>::cleanupBuffers() { 583 517 vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); 584 518 … … 587 521 vkDestroyBuffer(device, indexBuffer, nullptr); 588 522 vkFreeMemory(device, indexBufferMemory, nullptr); 589 590 if (!is_same_v<SSBOType, void*>) {591 for (size_t i = 0; i < storageBufferSet.buffers.size(); i++) {592 vkDestroyBuffer(device, storageBufferSet.buffers[i], nullptr);593 vkFreeMemory(device, storageBufferSet.memory[i], nullptr);594 }595 }596 523 } 597 524 598 525 /*** PRIVATE METHODS ***/ 599 526 600 template<class VertexType , class SSBOType>601 VkShaderModule GraphicsPipeline_Vulkan<VertexType , SSBOType>::createShaderModule(const vector<char>& code) {527 template<class VertexType> 528 VkShaderModule GraphicsPipeline_Vulkan<VertexType>::createShaderModule(const vector<char>& code) { 602 529 VkShaderModuleCreateInfo createInfo = {}; 603 530 createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; … … 613 540 } 614 541 615 template<class VertexType , class SSBOType>616 vector<char> GraphicsPipeline_Vulkan<VertexType , SSBOType>::readFile(const string& filename) {542 template<class VertexType> 543 vector<char> GraphicsPipeline_Vulkan<VertexType>::readFile(const string& filename) { 617 544 ifstream file(filename, ios::ate | ios::binary); 618 545 … … 632 559 } 633 560 634 template<class VertexType, class SSBOType> 635 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeVertexBuffer(VkCommandPool commandPool, 636 VkQueue graphicsQueue) { 561 template<class VertexType> 562 void GraphicsPipeline_Vulkan<VertexType>::resizeVertexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) { 637 563 VkBuffer newVertexBuffer; 638 564 VkDeviceMemory newVertexBufferMemory; … … 652 578 } 653 579 654 template<class VertexType, class SSBOType> 655 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeIndexBuffer(VkCommandPool commandPool, 656 VkQueue graphicsQueue) { 580 template<class VertexType> 581 void GraphicsPipeline_Vulkan<VertexType>::resizeIndexBuffer(VkCommandPool commandPool, VkQueue graphicsQueue) { 657 582 VkBuffer newIndexBuffer; 658 583 VkDeviceMemory newIndexBufferMemory; … … 672 597 } 673 598 674 template<class VertexType, class SSBOType>675 void GraphicsPipeline_Vulkan<VertexType, SSBOType>::resizeStorageBufferSet(StorageBufferSet& set,676 VkCommandPool commandPool, VkQueue graphicsQueue) {677 this->objectCapacity *= 2;678 VkDeviceSize bufferSize = objectCapacity * sizeof(SSBOType);679 680 for (size_t i = 0; i < set.buffers.size(); i++) {681 VkBuffer newStorageBuffer;682 VkDeviceMemory newStorageBufferMemory;683 684 VulkanUtils::createBuffer(this->device, this->physicalDevice, bufferSize,685 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,686 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,687 newStorageBuffer, newStorageBufferMemory);688 689 VulkanUtils::copyBuffer(this->device, commandPool, set.buffers[i], newStorageBuffer,690 0, 0, this->numObjects * sizeof(SSBOType), graphicsQueue);691 692 vkDestroyBuffer(this->device, set.buffers[i], nullptr);693 vkFreeMemory(this->device, set.memory[i], nullptr);694 695 set.buffers[i] = newStorageBuffer;696 set.memory[i] = newStorageBufferMemory;697 698 set.infoSet[i].buffer = set.buffers[i];699 set.infoSet[i].offset = 0; // This is the offset from the start of the buffer, so always 0 for now700 set.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE701 }702 }703 704 599 #endif // _GRAPHICS_PIPELINE_VULKAN_H -
sdl-game.cpp
r756162f r9d21aac 103 103 modelPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex)); 104 104 105 createBufferSet( uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline,sizeof(UBO_VP_mats),105 createBufferSet(sizeof(UBO_VP_mats), 106 106 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 107 uniformBuffer InfoList_modelPipeline);107 uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline); 108 108 109 109 modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 110 110 VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_modelPipeline); 111 modelPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT); 111 modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 112 VK_SHADER_STAGE_VERTEX_BIT, &modelPipeline.storageBufferSet.infoSet); 112 113 modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 113 114 VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor); … … 256 257 257 258 void VulkanGame::initGraphicsPipelines() { 258 modelPipeline = GraphicsPipeline_Vulkan<ModelVertex , SSBO_ModelObject>(259 modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>( 259 260 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass, 260 261 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 16, 24, 10); 262 263 createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_ModelObject), 264 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 265 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 266 modelPipeline.storageBufferSet.buffers, modelPipeline.storageBufferSet.memory, 267 modelPipeline.storageBufferSet.infoSet); 261 268 } 262 269 … … 468 475 modelPipeline.cleanupBuffers(); 469 476 477 for (size_t i = 0; i < modelPipeline.storageBufferSet.buffers.size(); i++) { 478 vkDestroyBuffer(device, modelPipeline.storageBufferSet.buffers[i], nullptr); 479 vkFreeMemory(device, modelPipeline.storageBufferSet.memory[i], nullptr); 480 } 481 470 482 // END UNREVIEWED SECTION 471 483 … … 1083 1095 } 1084 1096 1085 void VulkanGame::createBufferSet( vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory,1086 VkDeviceSize bufferSize, VkBufferUsageFlags flags, VkMemoryPropertyFlags properties,1097 void VulkanGame::createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, VkMemoryPropertyFlags properties, 1098 vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, 1087 1099 vector<VkDescriptorBufferInfo>& bufferInfoList) { 1088 1100 buffers.resize(swapChainImageCount); … … 1230 1242 // instead of recreated every time 1231 1243 1232 createBufferSet( uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline,sizeof(UBO_VP_mats),1244 createBufferSet(sizeof(UBO_VP_mats), 1233 1245 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 1234 uniformBuffer InfoList_modelPipeline);1246 uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline); 1235 1247 1236 1248 modelPipeline.updateRenderPass(renderPass); -
sdl-game.hpp
r756162f r9d21aac 207 207 // the same pipeline, but use different textures, the approach I took when initially creating GraphicsPipeline_Vulkan 208 208 // wouldn't work since the whole pipeline couldn't have a common set of descriptors for the textures 209 GraphicsPipeline_Vulkan<ModelVertex , SSBO_ModelObject> modelPipeline;209 GraphicsPipeline_Vulkan<ModelVertex> modelPipeline; 210 210 211 211 // TODO: Maybe make the ubo objects part of the pipeline class since there's only one ubo … … 276 276 void cleanupImGuiOverlay(); 277 277 278 void createBufferSet(vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, VkDeviceSize bufferSize, 279 VkBufferUsageFlags flags, VkMemoryPropertyFlags properties, 278 // TODO: Maybe move these to a different class, possibly VulkanBuffer or some new related class 279 280 void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, VkMemoryPropertyFlags properties, 281 vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, 280 282 vector<VkDescriptorBufferInfo>& bufferInfoList); 283 284 // TODO: See if it makes sense to rename this to resizeBufferSet() and use it to resize other types of buffers as well 285 // TODO: Remove the need for templating, which is only there so a GraphicsPupeline_Vulkan can be passed in 286 template<class VertexType, class SSBOType> 287 void resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue, 288 GraphicsPipeline_Vulkan<VertexType>& pipeline); 289 290 template<class SSBOType> 291 void updateStorageBuffer(StorageBufferSet& storageBufferSet, size_t objIndex, SSBOType& ssbo); 281 292 282 293 // TODO: Since addObject() returns a reference to the new object now, … … 284 295 template<class VertexType, class SSBOType> 285 296 SceneObject<VertexType, SSBOType>& addObject(vector<SceneObject<VertexType, SSBOType>>& objects, 286 GraphicsPipeline_Vulkan<VertexType , SSBOType>& pipeline,297 GraphicsPipeline_Vulkan<VertexType>& pipeline, 287 298 const vector<VertexType>& vertices, vector<uint16_t> indices, 288 299 SSBOType ssbo, bool pipelinesCreated); … … 298 309 299 310 template<class VertexType, class SSBOType> 300 void updateObject(vector<SceneObject<VertexType, SSBOType>>& objects, GraphicsPipeline_Vulkan<VertexType,301 SSBOType>& pipeline, size_t index);311 void updateObject(vector<SceneObject<VertexType, SSBOType>>& objects, 312 GraphicsPipeline_Vulkan<VertexType>& pipeline, size_t index); 302 313 303 314 void renderFrame(ImDrawData* draw_data); … … 320 331 }; 321 332 333 template<class VertexType, class SSBOType> 334 void VulkanGame::resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue, 335 GraphicsPipeline_Vulkan<VertexType>& pipeline) { 336 pipeline.objectCapacity *= 2; 337 VkDeviceSize bufferSize = pipeline.objectCapacity * sizeof(SSBOType); 338 339 for (size_t i = 0; i < set.buffers.size(); i++) { 340 VkBuffer newStorageBuffer; 341 VkDeviceMemory newStorageBufferMemory; 342 343 VulkanUtils::createBuffer(device, physicalDevice, bufferSize, 344 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 345 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 346 newStorageBuffer, newStorageBufferMemory); 347 348 VulkanUtils::copyBuffer(device, commandPool, set.buffers[i], newStorageBuffer, 349 0, 0, pipeline.numObjects * sizeof(SSBOType), graphicsQueue); 350 351 vkDestroyBuffer(device, set.buffers[i], nullptr); 352 vkFreeMemory(device, set.memory[i], nullptr); 353 354 set.buffers[i] = newStorageBuffer; 355 set.memory[i] = newStorageBufferMemory; 356 357 set.infoSet[i].buffer = set.buffers[i]; 358 set.infoSet[i].offset = 0; // This is the offset from the start of the buffer, so always 0 for now 359 set.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE 360 } 361 } 362 363 // TODO: See if it makes sense to pass in the current swapchain index instead of updating all of them 364 template<class SSBOType> 365 void VulkanGame::updateStorageBuffer(StorageBufferSet& storageBufferSet, size_t objIndex, SSBOType& ssbo) { 366 for (size_t i = 0; i < storageBufferSet.memory.size(); i++) { 367 VulkanUtils::copyDataToMemory(device, ssbo, storageBufferSet.memory[i], objIndex * sizeof(SSBOType)); 368 } 369 } 370 322 371 // TODO: Right now, it's basically necessary to pass the identity matrix in for ssbo.model 323 372 // and to change the model matrix later by setting model_transform and then calling updateObject() 324 // Figure out a better way to allow the model matrix to be set during object ingcreation373 // Figure out a better way to allow the model matrix to be set during object creation 325 374 326 375 // TODO: Maybe return a reference to the object from this method if I decide that updating it … … 329 378 // to account for scaling 330 379 template<class VertexType, class SSBOType> 331 SceneObject<VertexType, SSBOType>& VulkanGame::addObject( 332 vector<SceneObject<VertexType, SSBOType>>& objects, 333 GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, 334 const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo, 335 bool pipelinesCreated) { 380 SceneObject<VertexType, SSBOType>& VulkanGame::addObject(vector<SceneObject<VertexType, SSBOType>>& objects, 381 GraphicsPipeline_Vulkan<VertexType>& pipeline, 382 const vector<VertexType>& vertices, vector<uint16_t> indices, 383 SSBOType ssbo, bool pipelinesCreated) { 336 384 // TODO: Use the model field of ssbo to set the object's model_base 337 385 // currently, the passed in model is useless since it gets overridden in updateObject() anyway … … 353 401 } 354 402 355 bool storageBufferResized = pipeline.addObject(obj.vertices, obj.indices, obj.ssbo, 356 resourceCommandPool, graphicsQueue); 403 pipeline.addObject(obj.vertices, obj.indices, resourceCommandPool, graphicsQueue); 404 405 bool resizeStorageBuffer = pipeline.numObjects == pipeline.objectCapacity; 406 407 if (resizeStorageBuffer) { 408 resizeStorageBufferSet<VertexType, SSBOType>(pipeline.storageBufferSet, resourceCommandPool, graphicsQueue, pipeline); 409 pipeline.cleanup(); 410 411 // Assume the SSBO is always the 2nd binding 412 pipeline.updateDescriptorInfo(1, &pipeline.storageBufferSet.infoSet); 413 } 414 415 pipeline.numObjects++; 416 417 updateStorageBuffer(pipeline.storageBufferSet, pipeline.numObjects - 1, obj.ssbo); 418 419 // TODO: Figure out why I am destroying and recreating the ubos when the swap chain is recreated, 420 // but am reusing the same ssbos. Maybe I don't need to recreate the ubos. 357 421 358 422 if (pipelinesCreated) { … … 367 431 // Refactor the logic to check for any resized SSBOs after all objects for the frame 368 432 // are created and then recreate each of the corresponding pipelines only once per frame 369 if (storageBufferResized) { 433 434 // TODO: Also, verify if I actually need to recreate all of these, or maybe just the descriptor sets, for instance 435 436 if (resizeStorageBuffer) { 370 437 pipeline.createPipeline(pipeline.vertShaderFile, pipeline.fragShaderFile); 371 438 pipeline.createDescriptorPool(swapChainImages); … … 457 524 // TODO: Just pass in the single object instead of a list of all of them 458 525 template<class VertexType, class SSBOType> 459 void VulkanGame::updateObject(vector<SceneObject<VertexType, SSBOType>>& objects, GraphicsPipeline_Vulkan<VertexType,460 SSBOType>& pipeline, size_t index) {526 void VulkanGame::updateObject(vector<SceneObject<VertexType, SSBOType>>& objects, 527 GraphicsPipeline_Vulkan<VertexType>& pipeline, size_t index) { 461 528 SceneObject<VertexType, SSBOType>& obj = objects[index]; 462 529 … … 464 531 obj.center = vec3(obj.ssbo.model * vec4(0.0f, 0.0f, 0.0f, 1.0f)); 465 532 466 pipeline.updateObject(index, obj.ssbo);533 updateStorageBuffer(pipeline.storageBufferSet, index, obj.ssbo); 467 534 468 535 obj.modified = false; -
vulkan-game.cpp
r756162f r9d21aac 119 119 modelPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex)); 120 120 121 createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 121 createBufferSet(sizeof(UBO_VP_mats), 122 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 122 123 uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline); 123 124 124 125 modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 125 126 VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_modelPipeline); 126 modelPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT); 127 modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 128 VK_SHADER_STAGE_VERTEX_BIT, &modelPipeline.storageBufferSet.infoSet); 127 129 modelPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 128 130 VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor); … … 180 182 shipPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex)); 181 183 182 createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 184 createBufferSet(sizeof(UBO_VP_mats), 185 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 183 186 uniformBuffers_shipPipeline, uniformBuffersMemory_shipPipeline, uniformBufferInfoList_shipPipeline); 184 187 185 188 shipPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 186 189 VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_shipPipeline); 187 shipPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT); 190 shipPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 191 VK_SHADER_STAGE_VERTEX_BIT, &shipPipeline.storageBufferSet.infoSet); 188 192 189 193 // TODO: With the normals, indexing basically becomes pointless since no vertices will have exactly … … 438 442 asteroidPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex)); 439 443 440 createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 444 createBufferSet(sizeof(UBO_VP_mats), 445 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 441 446 uniformBuffers_asteroidPipeline, uniformBuffersMemory_asteroidPipeline, uniformBufferInfoList_asteroidPipeline); 442 447 443 448 asteroidPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 444 449 VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_asteroidPipeline); 445 asteroidPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT); 450 asteroidPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 451 VK_SHADER_STAGE_VERTEX_BIT, &asteroidPipeline.storageBufferSet.infoSet); 446 452 447 453 asteroidPipeline.createDescriptorSetLayout(); … … 454 460 laserPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&LaserVertex::objIndex)); 455 461 456 createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 462 createBufferSet(sizeof(UBO_VP_mats), 463 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 457 464 uniformBuffers_laserPipeline, uniformBuffersMemory_laserPipeline, uniformBufferInfoList_laserPipeline); 458 465 459 466 laserPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 460 467 VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_laserPipeline); 461 laserPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); 468 laserPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 469 VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, &laserPipeline.storageBufferSet.infoSet); 462 470 laserPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 463 471 VK_SHADER_STAGE_FRAGMENT_BIT, &laserTextureImageDescriptor); … … 472 480 explosionPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ExplosionVertex::objIndex)); 473 481 474 createBufferSet(sizeof(UBO_Explosion), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 482 createBufferSet(sizeof(UBO_Explosion), 483 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 475 484 uniformBuffers_explosionPipeline, uniformBuffersMemory_explosionPipeline, uniformBufferInfoList_explosionPipeline); 476 485 477 486 explosionPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 478 487 VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList_explosionPipeline); 479 explosionPipeline.addStorageDescriptor(VK_SHADER_STAGE_VERTEX_BIT); 488 explosionPipeline.addDescriptorInfo(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 489 VK_SHADER_STAGE_VERTEX_BIT, &explosionPipeline.storageBufferSet.infoSet); 480 490 481 491 explosionPipeline.createDescriptorSetLayout(); … … 582 592 583 593 void VulkanGame::initGraphicsPipelines() { 584 modelPipeline = GraphicsPipeline_Vulkan<ModelVertex , SSBO_ModelObject>(594 modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>( 585 595 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass, 586 596 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 24, 24, 10); 587 597 588 shipPipeline = GraphicsPipeline_Vulkan<ModelVertex, SSBO_ModelObject>( 598 createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_ModelObject), 599 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 600 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 601 modelPipeline.storageBufferSet.buffers, modelPipeline.storageBufferSet.memory, 602 modelPipeline.storageBufferSet.infoSet); 603 604 shipPipeline = GraphicsPipeline_Vulkan<ModelVertex>( 589 605 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass, 590 606 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 138, 138, 10); 591 607 592 asteroidPipeline = GraphicsPipeline_Vulkan<ModelVertex, SSBO_Asteroid>( 608 createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_ModelObject), 609 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 610 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 611 shipPipeline.storageBufferSet.buffers, shipPipeline.storageBufferSet.memory, 612 shipPipeline.storageBufferSet.infoSet); 613 614 asteroidPipeline = GraphicsPipeline_Vulkan<ModelVertex>( 593 615 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass, 594 616 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 24, 36, 10); 595 617 596 laserPipeline = GraphicsPipeline_Vulkan<LaserVertex, SSBO_Laser>( 618 createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_Asteroid), 619 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 620 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 621 asteroidPipeline.storageBufferSet.buffers, asteroidPipeline.storageBufferSet.memory, 622 asteroidPipeline.storageBufferSet.infoSet); 623 624 laserPipeline = GraphicsPipeline_Vulkan<LaserVertex>( 597 625 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass, 598 626 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 8, 18, 2); 599 627 600 explosionPipeline = GraphicsPipeline_Vulkan<ExplosionVertex, SSBO_Explosion>( 628 createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_Laser), 629 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 630 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 631 laserPipeline.storageBufferSet.buffers, laserPipeline.storageBufferSet.memory, 632 laserPipeline.storageBufferSet.infoSet); 633 634 explosionPipeline = GraphicsPipeline_Vulkan<ExplosionVertex>( 601 635 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, physicalDevice, device, renderPass, 602 636 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 603 637 swapChainImages, EXPLOSION_PARTICLE_COUNT, EXPLOSION_PARTICLE_COUNT, 2); 638 639 createBufferSet(modelPipeline.objectCapacity * sizeof(SSBO_Explosion), 640 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 641 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 642 explosionPipeline.storageBufferSet.buffers, explosionPipeline.storageBufferSet.memory, 643 explosionPipeline.storageBufferSet.infoSet); 604 644 } 605 645 … … 1091 1131 explosionPipeline.cleanupBuffers(); 1092 1132 1133 for (size_t i = 0; i < modelPipeline.storageBufferSet.buffers.size(); i++) { 1134 vkDestroyBuffer(device, modelPipeline.storageBufferSet.buffers[i], nullptr); 1135 vkFreeMemory(device, modelPipeline.storageBufferSet.memory[i], nullptr); 1136 } 1137 1138 for (size_t i = 0; i < shipPipeline.storageBufferSet.buffers.size(); i++) { 1139 vkDestroyBuffer(device, shipPipeline.storageBufferSet.buffers[i], nullptr); 1140 vkFreeMemory(device, shipPipeline.storageBufferSet.memory[i], nullptr); 1141 } 1142 1143 for (size_t i = 0; i < asteroidPipeline.storageBufferSet.buffers.size(); i++) { 1144 vkDestroyBuffer(device, asteroidPipeline.storageBufferSet.buffers[i], nullptr); 1145 vkFreeMemory(device, asteroidPipeline.storageBufferSet.memory[i], nullptr); 1146 } 1147 1148 for (size_t i = 0; i < laserPipeline.storageBufferSet.buffers.size(); i++) { 1149 vkDestroyBuffer(device, laserPipeline.storageBufferSet.buffers[i], nullptr); 1150 vkFreeMemory(device, laserPipeline.storageBufferSet.memory[i], nullptr); 1151 } 1152 1153 for (size_t i = 0; i < explosionPipeline.storageBufferSet.buffers.size(); i++) { 1154 vkDestroyBuffer(device, explosionPipeline.storageBufferSet.buffers[i], nullptr); 1155 vkFreeMemory(device, explosionPipeline.storageBufferSet.memory[i], nullptr); 1156 } 1157 1093 1158 // END UNREVIEWED SECTION 1094 1159 … … 1810 1875 } 1811 1876 1812 void VulkanGame::createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, 1813 vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, vector<VkDescriptorBufferInfo>& bufferInfoList) { 1877 void VulkanGame::createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, VkMemoryPropertyFlags properties, 1878 vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, 1879 vector<VkDescriptorBufferInfo>& bufferInfoList) { 1814 1880 buffers.resize(swapChainImageCount); 1815 1881 buffersMemory.resize(swapChainImageCount); … … 1817 1883 1818 1884 for (size_t i = 0; i < swapChainImageCount; i++) { 1819 VulkanUtils::createBuffer(device, physicalDevice, bufferSize, flags, 1820 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 1821 buffers[i], buffersMemory[i]); 1885 VulkanUtils::createBuffer(device, physicalDevice, bufferSize, flags, properties, buffers[i], buffersMemory[i]); 1822 1886 1823 1887 bufferInfoList[i].buffer = buffers[i]; … … 2093 2157 // instead of recreated every time 2094 2158 2095 createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 2159 createBufferSet(sizeof(UBO_VP_mats), 2160 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 2096 2161 uniformBuffers_modelPipeline, uniformBuffersMemory_modelPipeline, uniformBufferInfoList_modelPipeline); 2097 2162 … … 2101 2166 modelPipeline.createDescriptorSets(swapChainImages); 2102 2167 2103 createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 2168 createBufferSet(sizeof(UBO_VP_mats), 2169 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 2104 2170 uniformBuffers_shipPipeline, uniformBuffersMemory_shipPipeline, uniformBufferInfoList_shipPipeline); 2105 2171 … … 2109 2175 shipPipeline.createDescriptorSets(swapChainImages); 2110 2176 2111 createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 2177 createBufferSet(sizeof(UBO_VP_mats), 2178 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 2112 2179 uniformBuffers_asteroidPipeline, uniformBuffersMemory_asteroidPipeline, uniformBufferInfoList_asteroidPipeline); 2113 2180 … … 2117 2184 asteroidPipeline.createDescriptorSets(swapChainImages); 2118 2185 2119 createBufferSet(sizeof(UBO_VP_mats), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 2186 createBufferSet(sizeof(UBO_VP_mats), 2187 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 2120 2188 uniformBuffers_laserPipeline, uniformBuffersMemory_laserPipeline, uniformBufferInfoList_laserPipeline); 2121 2189 … … 2125 2193 laserPipeline.createDescriptorSets(swapChainImages); 2126 2194 2127 createBufferSet(sizeof(UBO_Explosion), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 2195 createBufferSet(sizeof(UBO_Explosion), 2196 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 2128 2197 uniformBuffers_explosionPipeline, uniformBuffersMemory_explosionPipeline, uniformBufferInfoList_explosionPipeline); 2129 2198 -
vulkan-game.hpp
r756162f r9d21aac 142 142 template<class VertexType, class SSBOType> 143 143 struct EffectOverTime : public BaseEffectOverTime { 144 GraphicsPipeline_Vulkan<VertexType , SSBOType>& pipeline;144 GraphicsPipeline_Vulkan<VertexType>& pipeline; 145 145 vector<SceneObject<VertexType, SSBOType>>& objects; 146 146 unsigned int objectIndex; … … 150 150 float changePerSecond; 151 151 152 EffectOverTime(GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, 153 vector<SceneObject<VertexType, SSBOType>>& objects, unsigned int objectIndex, 154 size_t effectedFieldOffset, float startTime, float changePerSecond) : 155 pipeline(pipeline), 156 objects(objects), 157 objectIndex(objectIndex), 158 effectedFieldOffset(effectedFieldOffset), 159 startTime(startTime), 160 changePerSecond(changePerSecond) { 152 EffectOverTime(GraphicsPipeline_Vulkan<VertexType>& pipeline, vector<SceneObject<VertexType, SSBOType>>& objects, 153 unsigned int objectIndex, size_t effectedFieldOffset, float startTime, float changePerSecond) 154 : pipeline(pipeline) 155 , objects(objects) 156 , objectIndex(objectIndex) 157 , effectedFieldOffset(effectedFieldOffset) 158 , startTime(startTime) 159 , changePerSecond(changePerSecond) { 161 160 size_t ssboOffset = offset_of(&SceneObject<VertexType, SSBOType>::ssbo); 162 161 … … 301 300 // the same pipeline, but use different textures, the approach I took when initially creating GraphicsPipeline_Vulkan 302 301 // wouldn't work since the whole pipeline couldn't have a common set of descriptors for the textures 303 GraphicsPipeline_Vulkan<ModelVertex , SSBO_ModelObject> modelPipeline;304 GraphicsPipeline_Vulkan<ModelVertex , SSBO_ModelObject> shipPipeline;305 GraphicsPipeline_Vulkan<ModelVertex , SSBO_Asteroid> asteroidPipeline;306 GraphicsPipeline_Vulkan<LaserVertex , SSBO_Laser> laserPipeline;307 GraphicsPipeline_Vulkan<ExplosionVertex , SSBO_Explosion> explosionPipeline;302 GraphicsPipeline_Vulkan<ModelVertex> modelPipeline; 303 GraphicsPipeline_Vulkan<ModelVertex> shipPipeline; 304 GraphicsPipeline_Vulkan<ModelVertex> asteroidPipeline; 305 GraphicsPipeline_Vulkan<LaserVertex> laserPipeline; 306 GraphicsPipeline_Vulkan<ExplosionVertex> explosionPipeline; 308 307 309 308 // TODO: Maybe make the ubo objects part of the pipeline class since there's only one ubo … … 420 419 void cleanupImGuiOverlay(); 421 420 422 void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, 423 vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, 424 vector<VkDescriptorBufferInfo>& bufferInfoList); 421 // TODO: Maybe move these to a different class, possibly VulkanBuffer or some new related class 422 423 void createBufferSet(VkDeviceSize bufferSize, VkBufferUsageFlags flags, VkMemoryPropertyFlags properties, 424 vector<VkBuffer>& buffers, vector<VkDeviceMemory>& buffersMemory, 425 vector<VkDescriptorBufferInfo>& bufferInfoList); 426 427 // TODO: See if it makes sense to rename this to resizeBufferSet() and use it to resize other types of buffers as well 428 // TODO: Remove the need for templating, which is only there so a GraphicsPupeline_Vulkan can be passed in 429 template<class VertexType, class SSBOType> 430 void resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue, 431 GraphicsPipeline_Vulkan<VertexType>& pipeline); 432 433 template<class SSBOType> 434 void updateStorageBuffer(StorageBufferSet& storageBufferSet, size_t objIndex, SSBOType& ssbo); 425 435 426 436 // TODO: Since addObject() returns a reference to the new object now, 427 437 // stop using objects.back() to access the object that was just created 428 438 template<class VertexType, class SSBOType> 429 SceneObject<VertexType, SSBOType>& addObject( 430 vector<SceneObject<VertexType, SSBOType>>& objects, 431 GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, 432 const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo, 433 bool pipelinesCreated); 439 SceneObject<VertexType, SSBOType>& addObject(vector<SceneObject<VertexType, SSBOType>>& objects, 440 GraphicsPipeline_Vulkan<VertexType>& pipeline, 441 const vector<VertexType>& vertices, vector<uint16_t> indices, 442 SSBOType ssbo, bool pipelinesCreated); 434 443 435 444 template<class VertexType> … … 444 453 template<class VertexType, class SSBOType> 445 454 void updateObject(vector<SceneObject<VertexType, SSBOType>>& objects, 446 GraphicsPipeline_Vulkan<VertexType , SSBOType>& pipeline, size_t index);455 GraphicsPipeline_Vulkan<VertexType>& pipeline, size_t index); 447 456 448 457 template<class VertexType, class SSBOType> 449 void updateObjectVertices(GraphicsPipeline_Vulkan<VertexType , SSBOType>& pipeline,458 void updateObjectVertices(GraphicsPipeline_Vulkan<VertexType>& pipeline, 450 459 SceneObject<VertexType, SSBOType>& obj, size_t index); 451 460 … … 485 494 // End of specialized no-op functions 486 495 496 template<class VertexType, class SSBOType> 497 void VulkanGame::resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue, 498 GraphicsPipeline_Vulkan<VertexType>& pipeline) { 499 pipeline.objectCapacity *= 2; 500 VkDeviceSize bufferSize = pipeline.objectCapacity * sizeof(SSBOType); 501 502 for (size_t i = 0; i < set.buffers.size(); i++) { 503 VkBuffer newStorageBuffer; 504 VkDeviceMemory newStorageBufferMemory; 505 506 VulkanUtils::createBuffer(device, physicalDevice, bufferSize, 507 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 508 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 509 newStorageBuffer, newStorageBufferMemory); 510 511 VulkanUtils::copyBuffer(device, commandPool, set.buffers[i], newStorageBuffer, 512 0, 0, pipeline.numObjects * sizeof(SSBOType), graphicsQueue); 513 514 vkDestroyBuffer(device, set.buffers[i], nullptr); 515 vkFreeMemory(device, set.memory[i], nullptr); 516 517 set.buffers[i] = newStorageBuffer; 518 set.memory[i] = newStorageBufferMemory; 519 520 set.infoSet[i].buffer = set.buffers[i]; 521 set.infoSet[i].offset = 0; // This is the offset from the start of the buffer, so always 0 for now 522 set.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE 523 } 524 } 525 526 // TODO: See if it makes sense to pass in the current swapchain index instead of updating all of them 527 template<class SSBOType> 528 void VulkanGame::updateStorageBuffer(StorageBufferSet& storageBufferSet, size_t objIndex, SSBOType& ssbo) { 529 for (size_t i = 0; i < storageBufferSet.memory.size(); i++) { 530 VulkanUtils::copyDataToMemory(device, ssbo, storageBufferSet.memory[i], objIndex * sizeof(SSBOType)); 531 } 532 } 533 487 534 // TODO: Right now, it's basically necessary to pass the identity matrix in for ssbo.model 488 535 // and to change the model matrix later by setting model_transform and then calling updateObject() 489 // Figure out a better way to allow the model matrix to be set during object ingcreation536 // Figure out a better way to allow the model matrix to be set during object creation 490 537 491 538 // TODO: Maybe return a reference to the object from this method if I decide that updating it … … 494 541 // to account for scaling 495 542 template<class VertexType, class SSBOType> 496 SceneObject<VertexType, SSBOType>& VulkanGame::addObject( 497 vector<SceneObject<VertexType, SSBOType>>& objects, 498 GraphicsPipeline_Vulkan<VertexType, SSBOType>& pipeline, 499 const vector<VertexType>& vertices, vector<uint16_t> indices, SSBOType ssbo, 500 bool pipelinesCreated) { 543 SceneObject<VertexType, SSBOType>& VulkanGame::addObject(vector<SceneObject<VertexType, SSBOType>>& objects, 544 GraphicsPipeline_Vulkan<VertexType>& pipeline, 545 const vector<VertexType>& vertices, vector<uint16_t> indices, 546 SSBOType ssbo, bool pipelinesCreated) { 501 547 // TODO: Use the model field of ssbo to set the object's model_base 502 548 // currently, the passed in model is useless since it gets overridden in updateObject() anyway … … 518 564 } 519 565 520 bool storageBufferResized = pipeline.addObject(obj.vertices, obj.indices, obj.ssbo, 521 resourceCommandPool, graphicsQueue); 566 pipeline.addObject(obj.vertices, obj.indices, resourceCommandPool, graphicsQueue); 567 568 bool resizeStorageBuffer = pipeline.numObjects == pipeline.objectCapacity; 569 570 if (resizeStorageBuffer) { 571 resizeStorageBufferSet<VertexType, SSBOType>(pipeline.storageBufferSet, resourceCommandPool, graphicsQueue, pipeline); 572 pipeline.cleanup(); 573 574 // Assume the SSBO is always the 2nd binding 575 pipeline.updateDescriptorInfo(1, &pipeline.storageBufferSet.infoSet); 576 } 577 578 pipeline.numObjects++; 579 580 updateStorageBuffer(pipeline.storageBufferSet, pipeline.numObjects - 1, obj.ssbo); 581 582 // TODO: Figure out why I am destroying and recreating the ubos when the swap chain is recreated, 583 // but am reusing the same ssbos. Maybe I don't need to recreate the ubos. 522 584 523 585 if (pipelinesCreated) { … … 532 594 // Refactor the logic to check for any resized SSBOs after all objects for the frame 533 595 // are created and then recreate each of the corresponding pipelines only once per frame 534 if (storageBufferResized) { 596 597 // TODO: Also, verify if I actually need to recreate all of these, or maybe just the descriptor sets, for instance 598 599 if (resizeStorageBuffer) { 535 600 pipeline.createPipeline(pipeline.vertShaderFile, pipeline.fragShaderFile); 536 601 pipeline.createDescriptorPool(swapChainImages); … … 628 693 template<class VertexType, class SSBOType> 629 694 void VulkanGame::updateObject(vector<SceneObject<VertexType, SSBOType>>& objects, 630 GraphicsPipeline_Vulkan<VertexType , SSBOType>& pipeline, size_t index) {695 GraphicsPipeline_Vulkan<VertexType>& pipeline, size_t index) { 631 696 SceneObject<VertexType, SSBOType>& obj = objects[index]; 632 697 … … 634 699 obj.center = vec3(obj.ssbo.model * vec4(0.0f, 0.0f, 0.0f, 1.0f)); 635 700 636 pipeline.updateObject(index, obj.ssbo);701 updateStorageBuffer(pipeline.storageBufferSet, index, obj.ssbo); 637 702 638 703 obj.modified = false; … … 640 705 641 706 template<class VertexType, class SSBOType> 642 void VulkanGame::updateObjectVertices(GraphicsPipeline_Vulkan<VertexType , SSBOType>& pipeline,707 void VulkanGame::updateObjectVertices(GraphicsPipeline_Vulkan<VertexType>& pipeline, 643 708 SceneObject<VertexType, SSBOType>& obj, size_t index) { 644 709 pipeline.updateObjectVertices(index, obj.vertices, resourceCommandPool, graphicsQueue);
Note:
See TracChangeset
for help on using the changeset viewer.