Changeset a3cefaa in opengl-game
- Timestamp:
- May 17, 2021, 4:06:33 PM (3 years ago)
- Branches:
- feature/imgui-sdl
- Children:
- 1abebc1
- Parents:
- 996dd3e
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
VulkanGame.vcxproj
r996dd3e ra3cefaa 181 181 <ClInclude Include="StackWalker.h" /> 182 182 <ClInclude Include="utils.hpp" /> 183 <ClInclude Include="vulkan-buffer.hpp" /> 183 184 <ClInclude Include="vulkan-game.hpp" /> 184 185 <ClInclude Include="vulkan-utils.hpp" /> -
VulkanGame.vcxproj.filters
r996dd3e ra3cefaa 86 86 <Filter>gui\imgui</Filter> 87 87 </ClInclude> 88 <ClInclude Include="vulkan-buffer.hpp" /> 88 89 </ItemGroup> 89 90 <ItemGroup> -
graphics-pipeline_vulkan.hpp
r996dd3e ra3cefaa 36 36 public: 37 37 string vertShaderFile, fragShaderFile; 38 39 // Both of these are only used for managing the SSBO, so move them out as well40 size_t objectCapacity;41 size_t numObjects;42 38 43 39 GraphicsPipeline_Vulkan(); … … 48 44 GraphicsPipeline_Vulkan(VkPrimitiveTopology topology, VkPhysicalDevice physicalDevice, VkDevice device, 49 45 VkRenderPass renderPass, Viewport viewport, vector<VkImage>& swapChainImages, 50 size_t vertexCapacity, size_t indexCapacity , size_t objectCapacity);46 size_t vertexCapacity, size_t indexCapacity); 51 47 ~GraphicsPipeline_Vulkan(); 52 48 … … 64 60 void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData); 65 61 66 void updateDescriptorInfo(uint32_t index, vector<VkDescriptorBufferInfo>* bufferData); 62 void updateDescriptorInfo(uint32_t index, vector<VkDescriptorBufferInfo>* bufferData, 63 vector<VkImage>& swapChainImages); 67 64 // TODO: Maybe make an analogous one for updating image info 68 65 … … 128 125 // into the constructor. That way, I can also put relevant cleanup code into the destructor 129 126 template<class VertexType> 130 GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan( 131 VkPrimitiveTopology topology, VkPhysicalDevice physicalDevice, VkDevice device, 132 VkRenderPass renderPass, Viewport viewport, vector<VkImage>& swapChainImages, 133 size_t vertexCapacity, size_t indexCapacity, size_t objectCapacity) { 134 this->topology = topology; 135 this->physicalDevice = physicalDevice; 136 this->device = device; 137 this->renderPass = renderPass; 127 GraphicsPipeline_Vulkan<VertexType>::GraphicsPipeline_Vulkan(VkPrimitiveTopology topology, 128 VkPhysicalDevice physicalDevice, VkDevice device, 129 VkRenderPass renderPass, Viewport viewport, 130 vector<VkImage>& swapChainImages, size_t vertexCapacity, 131 size_t indexCapacity) 132 : topology(topology) 133 , physicalDevice(physicalDevice) 134 , device(device) 135 , renderPass(renderPass) { 136 // This is a member of the base GraphicsPipeline class 137 // It currently is not used for the OpenGL pipeline. Either figure out why (since OpenGL certainly has the concept of 138 // viewports) and use it there too and add viewport the the base class constructor, or create a second base class 139 // constructor which takes the viewport 138 140 this->viewport = viewport; 139 141 … … 158 160 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, 159 161 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBuffer, indexBufferMemory); 160 161 this->numObjects = 0;162 this->objectCapacity = objectCapacity;163 162 } 164 163 … … 204 203 template<class VertexType> 205 204 void GraphicsPipeline_Vulkan<VertexType>::updateDescriptorInfo(uint32_t index, 206 vector<VkDescriptorBufferInfo>* bufferData) { 205 vector<VkDescriptorBufferInfo>* bufferData, 206 vector<VkImage>& swapChainImages) { 207 207 this->descriptorInfoList[index].bufferDataList = bufferData; 208 209 // TODO: This code was mostly copied from createDescriptorSets. I should make some common function they both use 210 // for updating descriptor sets 211 for (size_t i = 0; i < swapChainImages.size(); i++) { 212 VkWriteDescriptorSet descriptorWrite = {}; 213 214 descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 215 descriptorWrite.dstSet = this->descriptorSets[i]; 216 descriptorWrite.dstBinding = index; 217 descriptorWrite.dstArrayElement = 0; 218 descriptorWrite.descriptorType = this->descriptorInfoList[index].type; 219 descriptorWrite.descriptorCount = 1; 220 descriptorWrite.pBufferInfo = nullptr; 221 descriptorWrite.pImageInfo = nullptr; 222 descriptorWrite.pTexelBufferView = nullptr; 223 224 // This method is only intended for updated descriptor sets of type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 225 // but I'm leaving that in here for completeness 226 switch (descriptorWrite.descriptorType) { 227 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 228 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 229 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 230 descriptorWrite.pBufferInfo = &(*this->descriptorInfoList[index].bufferDataList)[i]; 231 break; 232 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 233 descriptorWrite.pImageInfo = this->descriptorInfoList[index].imageData; 234 break; 235 default: 236 throw runtime_error("Unknown descriptor type: " + to_string(descriptorWrite.descriptorType)); 237 } 238 239 if (bufferData->size() != swapChainImages.size()) { 240 cout << "ALERT ALERT ALERT: SIZE MISMATCH!!!!!!!" << endl; 241 } 242 243 vkUpdateDescriptorSets(this->device, 1, &descriptorWrite, 0, nullptr); 244 } 208 245 } 209 246 -
sdl-game.cpp
r996dd3e ra3cefaa 70 70 , gui(nullptr) 71 71 , window(nullptr) 72 , objects_modelPipeline() 72 73 , score(0) 73 74 , fps(0.0f) { … … 87 88 88 89 initVulkan(); 90 91 VkPhysicalDeviceProperties deviceProperties; 92 vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties); 93 94 objects_modelPipeline = VulkanBuffer<SSBO_ModelObject>(10, deviceProperties.limits.minUniformBufferOffsetAlignment); 89 95 90 96 initImGuiOverlay(); … … 131 137 }, { 132 138 mat4(1.0f) 133 }, storageBuffers_modelPipeline , false);134 135 updateStorageBuffer(storageBuffers_modelPipeline, modelPipeline.numObjects - 1, texturedSquare->ssbo);139 }, storageBuffers_modelPipeline); 140 141 objects_modelPipeline.numObjects++; 136 142 137 143 texturedSquare->model_base = … … 152 158 }, { 153 159 mat4(1.0f) 154 }, storageBuffers_modelPipeline , false);155 156 updateStorageBuffer(storageBuffers_modelPipeline, modelPipeline.numObjects - 1, texturedSquare->ssbo);160 }, storageBuffers_modelPipeline); 161 162 objects_modelPipeline.numObjects++; 157 163 158 164 texturedSquare->model_base = … … 263 269 modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>( 264 270 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass, 265 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 16, 24 , 10);266 267 createBufferSet( modelPipeline.objectCapacity * sizeof(SSBO_ModelObject),271 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 16, 24); 272 273 createBufferSet(objects_modelPipeline.capacity * sizeof(SSBO_ModelObject), 268 274 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 269 275 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, … … 376 382 }, { 377 383 mat4(1.0f) 378 }, storageBuffers_modelPipeline , true);379 380 updateStorageBuffer(storageBuffers_modelPipeline, modelPipeline.numObjects - 1, texturedSquare.ssbo);384 }, storageBuffers_modelPipeline); 385 386 objects_modelPipeline.numObjects++; 381 387 382 388 texturedSquare.model_base = … … 446 452 447 453 void VulkanGame::updateScene() { 448 // TODO: These two for loops could probably be combined into one 449 454 // Rotate the textured squares 450 455 for (SceneObject<ModelVertex, SSBO_ModelObject>& model : this->modelObjects) { 451 456 model.model_transform = … … 455 460 } 456 461 457 // TODO: Instead, update entire sections (up to 64k) of the dynamic ubo if some objects there have changed 458 // Also, update the objects modelMat and center in the loop above instead of here 462 // TODO: Probably move the resizing to the VulkanBuffer class 463 if (objects_modelPipeline.numObjects > objects_modelPipeline.capacity) { 464 resizeStorageBufferSet(storageBuffers_modelPipeline, objects_modelPipeline, modelPipeline, resourceCommandPool, 465 graphicsQueue); 466 } 467 459 468 for (size_t i = 0; i < modelObjects.size(); i++) { 460 469 if (modelObjects[i].modified) { 461 // TODO: Think about changing the SSBO-related code to also use a contiguous array462 // to store the data on the cpu side instead of storing it per-object463 // Then, I could also copy it to the GPU in one go464 // Also, double-check if the alignment restrictions also hold for SSBOs465 466 470 updateObject(modelObjects, modelPipeline, i); 467 471 updateStorageBuffer(storageBuffers_modelPipeline, i, modelObjects[i].ssbo); … … 845 849 return VulkanUtils::findSupportedFormat( 846 850 physicalDevice, 847 { VK_FORMAT_D32_SFLOAT , VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT },851 { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT }, 848 852 VK_IMAGE_TILING_OPTIMAL, 849 853 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT -
sdl-game.hpp
r996dd3e ra3cefaa 21 21 #include "consts.hpp" 22 22 #include "vulkan-utils.hpp" 23 #include "vulkan-buffer.hpp" 23 24 #include "graphics-pipeline_vulkan.hpp" 24 25 #include "game-gui-sdl.hpp" … … 77 78 // Also, probably better to make this a vector of structs where each struct 78 79 // has a VkBuffer, VkDeviceMemory, and VkDescriptorBufferInfo 80 // TODO: Maybe change the structure here since VkDescriptorBufferInfo already stores a reference to the VkBuffer 79 81 struct StorageBufferSet { 80 82 vector<VkBuffer> buffers; … … 219 221 220 222 StorageBufferSet storageBuffers_modelPipeline; 223 VulkanBuffer<SSBO_ModelObject> objects_modelPipeline; 221 224 222 225 // TODO: Maybe make the ubo objects part of the pipeline class since there's only one ubo … … 296 299 // TODO: Remove the need for templating, which is only there so a GraphicsPupeline_Vulkan can be passed in 297 300 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); 300 304 301 305 template<class SSBOType> … … 308 312 GraphicsPipeline_Vulkan<VertexType>& pipeline, 309 313 const vector<VertexType>& vertices, vector<uint16_t> indices, 310 SSBOType ssbo, StorageBufferSet& storageBuffers, 311 bool pipelinesCreated); 314 SSBOType ssbo, StorageBufferSet& storageBuffers); 312 315 313 316 template<class VertexType> … … 344 347 345 348 template<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); 349 void 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); 350 359 351 360 for (size_t i = 0; i < set.buffers.size(); i++) { … … 359 368 360 369 VulkanUtils::copyBuffer(device, commandPool, set.buffers[i], newStorageBuffer, 361 0, 0, pipeline.numObjects * sizeof(SSBOType), graphicsQueue);370 0, 0, numObjects * sizeof(SSBOType), graphicsQueue); 362 371 363 372 vkDestroyBuffer(device, set.buffers[i], nullptr); … … 371 380 set.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE 372 381 } 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); 373 386 } 374 387 … … 384 397 // and to change the model matrix later by setting model_transform and then calling updateObject() 385 398 // 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 it388 // 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 asteroids390 // to account for scaling391 399 template<class VertexType, class SSBOType> 392 400 SceneObject<VertexType, SSBOType>& VulkanGame::addObject(vector<SceneObject<VertexType, SSBOType>>& objects, 393 401 GraphicsPipeline_Vulkan<VertexType>& pipeline, 394 402 const vector<VertexType>& vertices, vector<uint16_t> indices, 395 SSBOType ssbo, StorageBufferSet& storageBuffers, 396 bool pipelinesCreated) { 403 SSBOType ssbo, StorageBufferSet& storageBuffers) { 397 404 // TODO: Use the model field of ssbo to set the object's model_base 398 405 // currently, the passed in model is useless since it gets overridden in updateObject() anyway … … 415 422 416 423 pipeline.addObject(obj.vertices, obj.indices, resourceCommandPool, graphicsQueue); 417 418 // TODO: Probably move the resizing to the VulkanBuffer class419 // First, try moving this out of addObject420 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 binding427 // TODO: Figure out a way to make this more flexible428 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 pipeline438 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 least445 // one SSBO is resized.446 // Refactor the logic to check for any resized SSBOs after all objects for the frame447 // are created and then recreate each of the corresponding pipelines only once per frame448 449 // TODO: Also, verify if I actually need to recreate all of these, or maybe just the descriptor sets, for instance450 451 if (resizeStorageBuffer) {452 pipeline.createPipeline(pipeline.vertShaderFile, pipeline.fragShaderFile);453 pipeline.createDescriptorPool(swapChainImages);454 pipeline.createDescriptorSets(swapChainImages);455 }456 457 createCommandBuffers();458 }459 424 460 425 return obj; -
vulkan-game.cpp
r996dd3e ra3cefaa 77 77 , gui(nullptr) 78 78 , window(nullptr) 79 , objects_modelPipeline() 80 , objects_shipPipeline() 81 , objects_asteroidPipeline() 82 , objects_laserPipeline() 83 , objects_explosionPipeline() 79 84 , score(0) 80 85 , fps(0.0f) { … … 102 107 initVulkan(); 103 108 109 VkPhysicalDeviceProperties deviceProperties; 110 vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties); 111 112 objects_modelPipeline = VulkanBuffer<SSBO_ModelObject>(10, deviceProperties.limits.minUniformBufferOffsetAlignment); 113 objects_shipPipeline = VulkanBuffer<SSBO_ModelObject>(10, deviceProperties.limits.minUniformBufferOffsetAlignment); 114 objects_asteroidPipeline = VulkanBuffer<SSBO_Asteroid>(10, deviceProperties.limits.minUniformBufferOffsetAlignment); 115 objects_laserPipeline = VulkanBuffer<SSBO_Laser>(2, deviceProperties.limits.minUniformBufferOffsetAlignment); 116 objects_explosionPipeline = VulkanBuffer<SSBO_Explosion>(2, deviceProperties.limits.minUniformBufferOffsetAlignment); 117 104 118 initImGuiOverlay(); 105 119 … … 131 145 132 146 SceneObject<ModelVertex, SSBO_ModelObject>* texturedSquare = nullptr; 147 148 // TODO: Ideally, avoid having to make the squares as modified upon creation 133 149 134 150 texturedSquare = &addObject(modelObjects, modelPipeline, … … 145 161 }, { 146 162 mat4(1.0f) 147 }, storageBuffers_modelPipeline , false);148 149 updateStorageBuffer(storageBuffers_modelPipeline, modelPipeline.numObjects - 1, texturedSquare->ssbo);163 }, storageBuffers_modelPipeline); 164 165 objects_modelPipeline.numObjects++; 150 166 151 167 texturedSquare->model_base = … … 166 182 }, { 167 183 mat4(1.0f) 168 }, storageBuffers_modelPipeline , false);169 170 updateStorageBuffer(storageBuffers_modelPipeline, modelPipeline.numObjects - 1, texturedSquare->ssbo);184 }, storageBuffers_modelPipeline); 185 186 objects_modelPipeline.numObjects++; 171 187 172 188 texturedSquare->model_base = … … 428 444 }, { 429 445 mat4(1.0f) 430 }, storageBuffers_shipPipeline , false);431 432 updateStorageBuffer(storageBuffers_shipPipeline, shipPipeline.numObjects - 1, ship.ssbo);446 }, storageBuffers_shipPipeline); 447 448 objects_shipPipeline.numObjects++; 433 449 434 450 ship.model_base = … … 600 616 modelPipeline = GraphicsPipeline_Vulkan<ModelVertex>( 601 617 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass, 602 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 24, 24 , 10);603 604 createBufferSet( modelPipeline.objectCapacity * sizeof(SSBO_ModelObject),618 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 24, 24); 619 620 createBufferSet(objects_modelPipeline.capacity * sizeof(SSBO_ModelObject), 605 621 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 606 622 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, … … 610 626 shipPipeline = GraphicsPipeline_Vulkan<ModelVertex>( 611 627 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass, 612 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 138, 138 , 10);613 614 createBufferSet( modelPipeline.objectCapacity * sizeof(SSBO_ModelObject),628 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 138, 138); 629 630 createBufferSet(objects_shipPipeline.capacity * sizeof(SSBO_ModelObject), 615 631 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 616 632 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, … … 620 636 asteroidPipeline = GraphicsPipeline_Vulkan<ModelVertex>( 621 637 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass, 622 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 24, 36 , 10);623 624 createBufferSet( modelPipeline.objectCapacity * sizeof(SSBO_Asteroid),638 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 24, 36); 639 640 createBufferSet(objects_asteroidPipeline.capacity * sizeof(SSBO_Asteroid), 625 641 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 626 642 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, … … 630 646 laserPipeline = GraphicsPipeline_Vulkan<LaserVertex>( 631 647 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, physicalDevice, device, renderPass, 632 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 8, 18 , 2);633 634 createBufferSet( modelPipeline.objectCapacity * sizeof(SSBO_Laser),648 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, swapChainImages, 8, 18); 649 650 createBufferSet(objects_laserPipeline.capacity * sizeof(SSBO_Laser), 635 651 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 636 652 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, … … 641 657 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, physicalDevice, device, renderPass, 642 658 { 0, 0, (int)swapChainExtent.width, (int)swapChainExtent.height }, 643 swapChainImages, EXPLOSION_PARTICLE_COUNT, EXPLOSION_PARTICLE_COUNT , 2);644 645 createBufferSet( modelPipeline.objectCapacity * sizeof(SSBO_Explosion),659 swapChainImages, EXPLOSION_PARTICLE_COUNT, EXPLOSION_PARTICLE_COUNT); 660 661 createBufferSet(objects_explosionPipeline.capacity * sizeof(SSBO_Explosion), 646 662 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 647 663 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, … … 768 784 }, { 769 785 mat4(1.0f) 770 }, storageBuffers_modelPipeline , true);771 772 updateStorageBuffer(storageBuffers_modelPipeline, modelPipeline.numObjects - 1, texturedSquare.ssbo);786 }, storageBuffers_modelPipeline); 787 788 objects_modelPipeline.numObjects++; 773 789 774 790 texturedSquare.model_base = … … 929 945 // where it will run just once per frame 930 946 void VulkanGame::updateScene() { 947 // Rotate the textured squares 931 948 for (SceneObject<ModelVertex, SSBO_ModelObject>& model : this->modelObjects) { 932 949 model.model_transform = … … 1050 1067 10.0f, 1051 1068 false 1052 }, storageBuffers_asteroidPipeline , true);1053 1054 updateStorageBuffer(storageBuffers_asteroidPipeline, asteroidPipeline.numObjects - 1, asteroid.ssbo);1069 }, storageBuffers_asteroidPipeline); 1070 1071 objects_asteroidPipeline.numObjects++; 1055 1072 1056 1073 // This accounts for the scaling in model_base. … … 1077 1094 } 1078 1095 1096 // TODO: Probably move the resizing to the VulkanBuffer class 1097 if (objects_modelPipeline.numObjects > objects_modelPipeline.capacity) { 1098 resizeStorageBufferSet(storageBuffers_modelPipeline, objects_modelPipeline, modelPipeline, resourceCommandPool, 1099 graphicsQueue); 1100 } 1101 1102 for (size_t i = 0; i < modelObjects.size(); i++) { 1103 if (modelObjects[i].modified) { 1104 updateObject(modelObjects, modelPipeline, i); 1105 updateStorageBuffer(storageBuffers_modelPipeline, i, modelObjects[i].ssbo); 1106 } 1107 } 1108 1109 // TODO: Probably move the resizing to the VulkanBuffer class 1110 if (objects_shipPipeline.numObjects > objects_shipPipeline.capacity) { 1111 resizeStorageBufferSet(storageBuffers_shipPipeline, objects_shipPipeline, shipPipeline, resourceCommandPool, 1112 graphicsQueue); 1113 } 1114 1079 1115 for (size_t i = 0; i < shipObjects.size(); i++) { 1080 1116 if (shipObjects[i].modified) { … … 1084 1120 } 1085 1121 1086 for (size_t i = 0; i < modelObjects.size(); i++) { 1087 if (modelObjects[i].modified) { 1088 updateObject(modelObjects, modelPipeline, i); 1089 updateStorageBuffer(storageBuffers_modelPipeline, i, modelObjects[i].ssbo); 1090 } 1122 // TODO: Probably move the resizing to the VulkanBuffer class 1123 if (objects_asteroidPipeline.numObjects > objects_asteroidPipeline.capacity) { 1124 resizeStorageBufferSet(storageBuffers_asteroidPipeline, objects_asteroidPipeline, asteroidPipeline, 1125 resourceCommandPool, graphicsQueue); 1091 1126 } 1092 1127 … … 1098 1133 } 1099 1134 1135 // TODO: Probably move the resizing to the VulkanBuffer class 1136 if (objects_laserPipeline.numObjects > objects_laserPipeline.capacity) { 1137 resizeStorageBufferSet(storageBuffers_laserPipeline, objects_laserPipeline, laserPipeline, resourceCommandPool, 1138 graphicsQueue); 1139 } 1140 1100 1141 for (size_t i = 0; i < laserObjects.size(); i++) { 1101 1142 if (laserObjects[i].modified) { … … 1103 1144 updateStorageBuffer(storageBuffers_laserPipeline, i, laserObjects[i].ssbo); 1104 1145 } 1146 } 1147 1148 // TODO: Probably move the resizing to the VulkanBuffer class 1149 if (objects_explosionPipeline.numObjects > objects_explosionPipeline.capacity) { 1150 resizeStorageBufferSet(storageBuffers_explosionPipeline, objects_explosionPipeline, explosionPipeline, 1151 resourceCommandPool, graphicsQueue); 1105 1152 } 1106 1153 … … 1525 1572 return VulkanUtils::findSupportedFormat( 1526 1573 physicalDevice, 1527 { VK_FORMAT_D32_SFLOAT , VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT },1574 { VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D24_UNORM_S8_UINT }, 1528 1575 VK_IMAGE_TILING_OPTIMAL, 1529 1576 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT … … 1929 1976 color, 1930 1977 false 1931 }, storageBuffers_laserPipeline , true);1932 1933 updateStorageBuffer(storageBuffers_laserPipeline, laserPipeline.numObjects - 1, laser.ssbo);1978 }, storageBuffers_laserPipeline); 1979 1980 objects_laserPipeline.numObjects++; 1934 1981 1935 1982 float xAxisRotation = asin(ray.y / length); … … 2141 2188 duration, 2142 2189 false 2143 }, storageBuffers_explosionPipeline , true);2144 2145 updateStorageBuffer(storageBuffers_explosionPipeline, explosionPipeline.numObjects - 1, explosion.ssbo);2190 }, storageBuffers_explosionPipeline); 2191 2192 objects_explosionPipeline.numObjects++; 2146 2193 2147 2194 explosion.model_base = model_mat; -
vulkan-game.hpp
r996dd3e ra3cefaa 22 22 23 23 #include "consts.hpp" 24 #include "utils.hpp" 25 #include "vulkan-utils.hpp" 26 #include "vulkan-buffer.hpp" 24 27 #include "graphics-pipeline_vulkan.hpp" 25 28 #include "game-gui-sdl.hpp" 26 #include "utils.hpp"27 #include "vulkan-utils.hpp"28 29 29 30 using namespace glm; … … 101 102 // Also, probably better to make this a vector of structs where each struct 102 103 // has a VkBuffer, VkDeviceMemory, and VkDescriptorBufferInfo 104 // TODO: Maybe change the structure here since VkDescriptorBufferInfo already stores a reference to the VkBuffer 103 105 struct StorageBufferSet { 104 106 vector<VkBuffer> buffers; … … 316 318 317 319 StorageBufferSet storageBuffers_modelPipeline; 320 VulkanBuffer<SSBO_ModelObject> objects_modelPipeline; 321 318 322 StorageBufferSet storageBuffers_shipPipeline; 323 VulkanBuffer<SSBO_ModelObject> objects_shipPipeline; 324 319 325 StorageBufferSet storageBuffers_asteroidPipeline; 326 VulkanBuffer<SSBO_Asteroid> objects_asteroidPipeline; 327 320 328 StorageBufferSet storageBuffers_laserPipeline; 329 VulkanBuffer<SSBO_Laser> objects_laserPipeline; 330 321 331 StorageBufferSet storageBuffers_explosionPipeline; 332 VulkanBuffer<SSBO_Explosion> objects_explosionPipeline; 322 333 323 334 // TODO: Maybe make the ubo objects part of the pipeline class since there's only one ubo … … 443 454 // TODO: Remove the need for templating, which is only there so a GraphicsPupeline_Vulkan can be passed in 444 455 template<class VertexType, class SSBOType> 445 void resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue, 446 GraphicsPipeline_Vulkan<VertexType>& pipeline); 456 void resizeStorageBufferSet(StorageBufferSet& set, VulkanBuffer<SSBOType>& buffer, 457 GraphicsPipeline_Vulkan<VertexType>& pipeline, 458 VkCommandPool commandPool, VkQueue graphicsQueue); 447 459 448 460 template<class SSBOType> … … 455 467 GraphicsPipeline_Vulkan<VertexType>& pipeline, 456 468 const vector<VertexType>& vertices, vector<uint16_t> indices, 457 SSBOType ssbo, StorageBufferSet& storageBuffers, 458 bool pipelinesCreated); 469 SSBOType ssbo, StorageBufferSet& storageBuffers); 459 470 460 471 template<class VertexType> … … 511 522 512 523 template<class VertexType, class SSBOType> 513 void VulkanGame::resizeStorageBufferSet(StorageBufferSet& set, VkCommandPool commandPool, VkQueue graphicsQueue, 514 GraphicsPipeline_Vulkan<VertexType>& pipeline) { 515 pipeline.objectCapacity *= 2; 516 VkDeviceSize bufferSize = pipeline.objectCapacity * sizeof(SSBOType); 524 void VulkanGame::resizeStorageBufferSet(StorageBufferSet& set, VulkanBuffer<SSBOType>& buffer, 525 GraphicsPipeline_Vulkan<VertexType>& pipeline, 526 VkCommandPool commandPool, VkQueue graphicsQueue) { 527 size_t numObjects = buffer.numObjects < buffer.capacity ? buffer.numObjects : buffer.capacity; 528 529 do { 530 buffer.capacity *= 2; 531 } while (buffer.capacity < buffer.numObjects); 532 533 VkDeviceSize bufferSize = buffer.capacity * sizeof(SSBOType); 517 534 518 535 for (size_t i = 0; i < set.buffers.size(); i++) { … … 526 543 527 544 VulkanUtils::copyBuffer(device, commandPool, set.buffers[i], newStorageBuffer, 528 0, 0, pipeline.numObjects * sizeof(SSBOType), graphicsQueue);545 0, 0, numObjects * sizeof(SSBOType), graphicsQueue); 529 546 530 547 vkDestroyBuffer(device, set.buffers[i], nullptr); … … 538 555 set.infoSet[i].range = bufferSize; // Size of the update starting from offset, or VK_WHOLE_SIZE 539 556 } 557 558 // Assume the SSBO is always the 2nd binding 559 // TODO: Figure out a way to make this more flexible 560 pipeline.updateDescriptorInfo(1, &set.infoSet, swapChainImages); 540 561 } 541 562 … … 551 572 // and to change the model matrix later by setting model_transform and then calling updateObject() 552 573 // Figure out a better way to allow the model matrix to be set during object creation 553 554 // TODO: Maybe return a reference to the object from this method if I decide that updating it555 // immediately after creation is a good idea (such as setting model_base)556 // Currently, model_base is set like this in a few places and the radius is set for asteroids557 // to account for scaling558 574 template<class VertexType, class SSBOType> 559 575 SceneObject<VertexType, SSBOType>& VulkanGame::addObject(vector<SceneObject<VertexType, SSBOType>>& objects, 560 576 GraphicsPipeline_Vulkan<VertexType>& pipeline, 561 577 const vector<VertexType>& vertices, vector<uint16_t> indices, 562 SSBOType ssbo, StorageBufferSet& storageBuffers, 563 bool pipelinesCreated) { 578 SSBOType ssbo, StorageBufferSet& storageBuffers) { 564 579 // TODO: Use the model field of ssbo to set the object's model_base 565 580 // currently, the passed in model is useless since it gets overridden in updateObject() anyway … … 582 597 583 598 pipeline.addObject(obj.vertices, obj.indices, resourceCommandPool, graphicsQueue); 584 585 // TODO: Probably move the resizing to the VulkanBuffer class586 // First, try moving this out of addObject587 bool resizeStorageBuffer = pipeline.numObjects == pipeline.objectCapacity;588 589 if (resizeStorageBuffer) {590 resizeStorageBufferSet<VertexType, SSBOType>(storageBuffers, resourceCommandPool, graphicsQueue, pipeline);591 pipeline.cleanup();592 593 // Assume the SSBO is always the 2nd binding594 // TODO: Figure out a way to make this more flexible595 pipeline.updateDescriptorInfo(1, &storageBuffers.infoSet);596 }597 598 pipeline.numObjects++;599 600 // TODO: Figure out why I am destroying and recreating the ubos when the swap chain is recreated,601 // but am reusing the same ssbos. Maybe I don't need to recreate the ubos.602 603 if (pipelinesCreated) {604 // TODO: See if I can avoid doing this when recreating the pipeline605 vkDeviceWaitIdle(device);606 607 for (uint32_t i = 0; i < swapChainImageCount; i++) {608 vkFreeCommandBuffers(device, commandPools[i], 1, &commandBuffers[i]);609 }610 611 // TODO: The pipeline recreation only has to be done once per frame where at least612 // one SSBO is resized.613 // Refactor the logic to check for any resized SSBOs after all objects for the frame614 // are created and then recreate each of the corresponding pipelines only once per frame615 616 // TODO: Also, verify if I actually need to recreate all of these, or maybe just the descriptor sets, for instance617 618 if (resizeStorageBuffer) {619 pipeline.createPipeline(pipeline.vertShaderFile, pipeline.fragShaderFile);620 pipeline.createDescriptorPool(swapChainImages);621 pipeline.createDescriptorSets(swapChainImages);622 }623 624 createCommandBuffers();625 }626 599 627 600 return obj;
Note:
See TracChangeset
for help on using the changeset viewer.