Changeset b794178 in opengl-game
- Timestamp:
- Oct 17, 2019, 9:30:18 PM (5 years ago)
- Branches:
- feature/imgui-sdl, master, points-test
- Children:
- e83b155
- Parents:
- 771b33a
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
graphics-pipeline_vulkan.cpp
r771b33a rb794178 3 3 #include <fstream> 4 4 #include <stdexcept> 5 6 GraphicsPipeline_Vulkan::GraphicsPipeline_Vulkan(VkDevice device, Viewport viewport, int vertexSize) { 5 #include <iostream> 6 7 using namespace std; 8 9 // TODO: Remove any instances of cout and instead throw exceptions 10 11 GraphicsPipeline_Vulkan::GraphicsPipeline_Vulkan(VkDevice device, VkRenderPass renderPass, Viewport viewport, 12 int vertexSize) { 7 13 this->device = device; 14 this->renderPass = renderPass; 8 15 this->viewport = viewport; 9 16 … … 25 32 26 33 this->attributeDescriptions.push_back(attributeDesc); 34 } 35 36 void GraphicsPipeline_Vulkan::addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, vector<VkDescriptorBufferInfo>* bufferData) { 37 this->descriptorInfoList.push_back({ type, stageFlags, bufferData, nullptr }); 38 } 39 40 void GraphicsPipeline_Vulkan::addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData) { 41 this->descriptorInfoList.push_back({ type, stageFlags, nullptr, imageData }); 27 42 } 28 43 … … 131 146 pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 132 147 pipelineLayoutInfo.setLayoutCount = 1; 133 134 vkDestroyShaderModule(device, vertShaderModule, nullptr); 135 vkDestroyShaderModule(device, fragShaderModule, nullptr); 148 pipelineLayoutInfo.pSetLayouts = &this->descriptorSetLayout; 149 pipelineLayoutInfo.pushConstantRangeCount = 0; 150 151 if (vkCreatePipelineLayout(this->device, &pipelineLayoutInfo, nullptr, &this->pipelineLayout) != VK_SUCCESS) { 152 throw runtime_error("failed to create pipeline layout!"); 153 } 154 155 VkGraphicsPipelineCreateInfo pipelineInfo = {}; 156 pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 157 pipelineInfo.stageCount = 2; 158 pipelineInfo.pStages = shaderStages; 159 pipelineInfo.pVertexInputState = &vertexInputInfo; 160 pipelineInfo.pInputAssemblyState = &inputAssembly; 161 pipelineInfo.pViewportState = &viewportState; 162 pipelineInfo.pRasterizationState = &rasterizer; 163 pipelineInfo.pMultisampleState = &multisampling; 164 pipelineInfo.pDepthStencilState = &depthStencil; 165 pipelineInfo.pColorBlendState = &colorBlending; 166 pipelineInfo.pDynamicState = nullptr; 167 pipelineInfo.layout = this->pipelineLayout; 168 pipelineInfo.renderPass = this->renderPass; 169 pipelineInfo.subpass = 0; 170 pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; 171 pipelineInfo.basePipelineIndex = -1; 172 173 if (vkCreateGraphicsPipelines(this->device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &this->pipeline) != VK_SUCCESS) { 174 throw runtime_error("failed to create graphics pipeline!"); 175 } 176 177 vkDestroyShaderModule(this->device, vertShaderModule, nullptr); 178 vkDestroyShaderModule(this->device, fragShaderModule, nullptr); 179 } 180 181 void GraphicsPipeline_Vulkan::createDescriptorSetLayout() { 182 vector<VkDescriptorSetLayoutBinding> bindings(this->descriptorInfoList.size()); 183 184 for (size_t i = 0; i < bindings.size(); i++) { 185 bindings[i].binding = i; 186 bindings[i].descriptorCount = 1; 187 bindings[i].descriptorType = this->descriptorInfoList[i].type; 188 bindings[i].stageFlags = this->descriptorInfoList[i].stageFlags; 189 bindings[i].pImmutableSamplers = nullptr; 190 } 191 192 VkDescriptorSetLayoutCreateInfo layoutInfo = {}; 193 layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 194 layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size()); 195 layoutInfo.pBindings = bindings.data(); 196 197 if (vkCreateDescriptorSetLayout(this->device, &layoutInfo, nullptr, &this->descriptorSetLayout) != VK_SUCCESS) { 198 throw runtime_error("failed to create descriptor set layout!"); 199 } 200 } 201 202 void GraphicsPipeline_Vulkan::createDescriptorPool(vector<VkImage>& swapChainImages) { 203 vector<VkDescriptorPoolSize> poolSizes(this->descriptorInfoList.size()); 204 205 for (size_t i = 0; i < poolSizes.size(); i++) { 206 poolSizes[i].type = this->descriptorInfoList[i].type; 207 poolSizes[i].descriptorCount = static_cast<uint32_t>(swapChainImages.size()); 208 } 209 210 VkDescriptorPoolCreateInfo poolInfo = {}; 211 poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 212 poolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size()); 213 poolInfo.pPoolSizes = poolSizes.data(); 214 poolInfo.maxSets = static_cast<uint32_t>(swapChainImages.size()); 215 216 if (vkCreateDescriptorPool(this->device, &poolInfo, nullptr, &this->descriptorPool) != VK_SUCCESS) { 217 throw runtime_error("failed to create descriptor pool!"); 218 } 219 } 220 221 void GraphicsPipeline_Vulkan::createDescriptorSets(vector<VkImage>& swapChainImages) { 222 vector<VkDescriptorSetLayout> layouts(swapChainImages.size(), this->descriptorSetLayout); 223 224 VkDescriptorSetAllocateInfo allocInfo = {}; 225 allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 226 allocInfo.descriptorPool = this->descriptorPool; 227 allocInfo.descriptorSetCount = static_cast<uint32_t>(swapChainImages.size()); 228 allocInfo.pSetLayouts = layouts.data(); 229 230 this->descriptorSets.resize(swapChainImages.size()); 231 if (vkAllocateDescriptorSets(device, &allocInfo, this->descriptorSets.data()) != VK_SUCCESS) { 232 throw runtime_error("failed to allocate descriptor sets!"); 233 } 234 235 for (size_t i = 0; i < swapChainImages.size(); i++) { 236 vector<VkWriteDescriptorSet> descriptorWrites(this->descriptorInfoList.size()); 237 238 for (size_t j = 0; j < descriptorWrites.size(); j++) { 239 descriptorWrites[j].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 240 descriptorWrites[j].dstSet = this->descriptorSets[i]; 241 descriptorWrites[j].dstBinding = j; 242 descriptorWrites[j].dstArrayElement = 0; 243 descriptorWrites[j].descriptorType = this->descriptorInfoList[j].type; 244 descriptorWrites[j].descriptorCount = 1; 245 descriptorWrites[j].pBufferInfo = nullptr; 246 descriptorWrites[j].pImageInfo = nullptr; 247 descriptorWrites[j].pTexelBufferView = nullptr; 248 249 switch (descriptorWrites[j].descriptorType) { 250 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 251 descriptorWrites[j].pBufferInfo = &(*this->descriptorInfoList[j].bufferDataList)[i]; 252 break; 253 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 254 descriptorWrites[j].pImageInfo = this->descriptorInfoList[j].imageData; 255 break; 256 default: 257 cout << "Unknown descriptor type: " << descriptorWrites[j].descriptorType << endl; 258 } 259 } 260 261 vkUpdateDescriptorSets(this->device, static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr); 262 } 136 263 } 137 264 … … 143 270 144 271 VkShaderModule shaderModule; 145 if (vkCreateShaderModule( device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {272 if (vkCreateShaderModule(this->device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) { 146 273 throw runtime_error("failed to create shader module!"); 147 274 } … … 167 294 return buffer; 168 295 } 296 297 void GraphicsPipeline_Vulkan::cleanup() { 298 vkDestroyPipeline(this->device, this->pipeline, nullptr); 299 vkDestroyDescriptorPool(this->device, this->descriptorPool, nullptr); 300 vkDestroyPipelineLayout(this->device, this->pipelineLayout, nullptr); 301 } 302 303 void GraphicsPipeline_Vulkan::cleanupBuffers() { 304 vkDestroyDescriptorSetLayout(this->device, this->descriptorSetLayout, nullptr); 305 } -
graphics-pipeline_vulkan.hpp
r771b33a rb794178 8 8 #include <vulkan/vulkan.h> 9 9 10 // TODO: Maybe change the name of this struct so I can call the list something other than descriptorInfoList 11 struct DescriptorInfo { 12 VkDescriptorType type; 13 VkShaderStageFlags stageFlags; 14 15 // Only one of the below properties should be set 16 vector<VkDescriptorBufferInfo>* bufferDataList; 17 VkDescriptorImageInfo* imageData; 18 }; 19 10 20 class GraphicsPipeline_Vulkan : public GraphicsPipeline { 11 21 public: 12 GraphicsPipeline_Vulkan(VkDevice device, V iewport viewport, int vertexSize);22 GraphicsPipeline_Vulkan(VkDevice device, VkRenderPass renderPass, Viewport viewport, int vertexSize); 13 23 ~GraphicsPipeline_Vulkan(); 14 24 25 // Maybe I should rename these to addVertexAttribute (addVaryingAttribute) and addUniformAttribute 26 15 27 void addAttribute(VkFormat format, size_t offset); 28 29 void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, vector<VkDescriptorBufferInfo>* bufferData); 30 void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData); 31 16 32 void createPipeline(string vertShaderFile, string fragShaderFile); 33 void createDescriptorSetLayout(); 34 void createDescriptorPool(vector<VkImage>& swapChainImages); 35 void createDescriptorSets(vector<VkImage>& swapChainImages); 36 37 void cleanup(); 38 void cleanupBuffers(); 17 39 18 40 private: 19 VkDevice device;20 VkVertexInputBindingDescription bindingDescription;21 vector<VkVertexInputAttributeDescription> attributeDescriptions;22 23 41 VkShaderModule createShaderModule(const vector<char>& code); 24 42 vector<char> readFile(const string& filename); 43 44 VkDevice device; 45 VkRenderPass renderPass; 46 47 VkPipeline pipeline; 48 VkPipelineLayout pipelineLayout; 49 50 VkVertexInputBindingDescription bindingDescription; 51 52 vector<VkVertexInputAttributeDescription> attributeDescriptions; 53 vector<DescriptorInfo> descriptorInfoList; 54 55 VkDescriptorSetLayout descriptorSetLayout; 56 VkDescriptorPool descriptorPool; 57 vector<VkDescriptorSet> descriptorSets; 25 58 }; 26 59 -
vulkan-game.cpp
r771b33a rb794178 9 9 10 10 #include "utils.hpp" 11 #include "vulkan-utils.hpp"12 11 13 12 using namespace std; 13 14 struct UniformBufferObject { 15 alignas(16) mat4 model; 16 alignas(16) mat4 view; 17 alignas(16) mat4 proj; 18 }; 14 19 15 20 VulkanGame::VulkanGame() { … … 84 89 cout << gui->getError() << endl; 85 90 return RTWO_ERROR; 91 } 92 93 SDL_VERSION(&sdlVersion); 94 95 // In SDL 2.0.10 (currently, the latest), SDL_TEXTUREACCESS_TARGET is required to get a transparent overlay working 96 // However, the latest SDL version available through homebrew on Mac is 2.0.9, which requires SDL_TEXTUREACCESS_STREAMING 97 // I tried building sdl 2.0.10 (and sdl_image and sdl_ttf) from source on Mac, but had some issues, so this is easier 98 // until the homebrew recipe is updated 99 if (sdlVersion.major == 2 && sdlVersion.minor == 0 && sdlVersion.patch == 9) { 100 uiOverlay = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 101 gui->getWindowWidth(), gui->getWindowHeight()); 102 } else { 103 uiOverlay = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 104 gui->getWindowWidth(), gui->getWindowHeight()); 105 } 106 107 if (uiOverlay == nullptr) { 108 cout << "Unable to create blank texture! SDL Error: " << SDL_GetError() << endl; 109 } 110 if (SDL_SetTextureBlendMode(uiOverlay, SDL_BLENDMODE_BLEND) != 0) { 111 cout << "Unable to set texture blend mode! SDL Error: " << SDL_GetError() << endl; 86 112 } 87 113 … … 107 133 createCommandPool(); 108 134 109 graphicsPipelines.push_back(GraphicsPipeline_Vulkan(device, viewport, sizeof(Vertex))); 135 createVulkanResources(); 136 137 graphicsPipelines.push_back(GraphicsPipeline_Vulkan(device, renderPass, viewport, sizeof(Vertex))); 110 138 111 139 graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&Vertex::pos)); … … 113 141 graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32_SFLOAT, offset_of(&Vertex::texCoord)); 114 142 143 graphicsPipelines.back().addDescriptorInfo(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 144 VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList); 145 graphicsPipelines.back().addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 146 VK_SHADER_STAGE_FRAGMENT_BIT, &floorTextureImageDescriptor); 147 148 graphicsPipelines.back().createDescriptorSetLayout(); 115 149 graphicsPipelines.back().createPipeline("shaders/scene-vert.spv", "shaders/scene-frag.spv"); 116 117 graphicsPipelines.push_back(GraphicsPipeline_Vulkan(device, viewport, sizeof(OverlayVertex))); 150 graphicsPipelines.back().createDescriptorPool(swapChainImages); 151 graphicsPipelines.back().createDescriptorSets(swapChainImages); 152 153 graphicsPipelines.push_back(GraphicsPipeline_Vulkan(device, renderPass, viewport, sizeof(OverlayVertex))); 118 154 119 155 graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&OverlayVertex::pos)); 120 156 graphicsPipelines.back().addAttribute(VK_FORMAT_R32G32_SFLOAT, offset_of(&OverlayVertex::texCoord)); 121 157 158 graphicsPipelines.back().addDescriptorInfo(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 159 VK_SHADER_STAGE_FRAGMENT_BIT, &sdlOverlayImageDescriptor); 160 161 graphicsPipelines.back().createDescriptorSetLayout(); 122 162 graphicsPipelines.back().createPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv"); 163 graphicsPipelines.back().createDescriptorPool(swapChainImages); 164 graphicsPipelines.back().createDescriptorSets(swapChainImages); 123 165 124 166 cout << "Created " << graphicsPipelines.size() << " graphics pipelines" << endl; … … 189 231 cleanupSwapChain(); 190 232 233 for (GraphicsPipeline_Vulkan pipeline : graphicsPipelines) { 234 pipeline.cleanupBuffers(); 235 } 236 191 237 vkDestroyCommandPool(device, commandPool, nullptr); 192 238 vkDestroyDevice(device, nullptr); … … 198 244 199 245 vkDestroyInstance(instance, nullptr); 246 247 // TODO: Check if any of these functions accept null parameters 248 // If they do, I don't need to check for that 249 250 if (uiOverlay != nullptr) { 251 SDL_DestroyTexture(uiOverlay); 252 uiOverlay = nullptr; 253 } 200 254 201 255 SDL_DestroyRenderer(renderer); … … 343 397 QueueFamilyIndices indices = VulkanUtils::findQueueFamilies(physicalDevice, surface); 344 398 345 vector<VkDeviceQueueCreateInfo> queueCreateInfo s;399 vector<VkDeviceQueueCreateInfo> queueCreateInfoList; 346 400 set<uint32_t> uniqueQueueFamilies = { indices.graphicsFamily.value(), indices.presentFamily.value() }; 347 401 … … 354 408 queueCreateInfo.pQueuePriorities = &queuePriority; 355 409 356 queueCreateInfo s.push_back(queueCreateInfo);410 queueCreateInfoList.push_back(queueCreateInfo); 357 411 } 358 412 … … 362 416 VkDeviceCreateInfo createInfo = {}; 363 417 createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 364 createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfo s.size());365 createInfo.pQueueCreateInfos = queueCreateInfo s.data();418 createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfoList.size()); 419 createInfo.pQueueCreateInfos = queueCreateInfoList.data(); 366 420 367 421 createInfo.pEnabledFeatures = &deviceFeatures; … … 529 583 } 530 584 585 void VulkanGame::createVulkanResources() { 586 createTextureSampler(); 587 createUniformBuffers(); 588 589 // TODO: Make sure that Vulkan complains about these images not being destroyed and then destroy them 590 591 VulkanUtils::createVulkanImageFromFile(device, physicalDevice, commandPool, "textures/texture.jpg", 592 floorTextureImage, graphicsQueue); 593 VulkanUtils::createVulkanImageFromSDLTexture(device, physicalDevice, uiOverlay, sdlOverlayImage); 594 595 floorTextureImageDescriptor = {}; 596 floorTextureImageDescriptor.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 597 floorTextureImageDescriptor.imageView = floorTextureImage.imageView; 598 floorTextureImageDescriptor.sampler = textureSampler; 599 600 sdlOverlayImageDescriptor = {}; 601 sdlOverlayImageDescriptor.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 602 sdlOverlayImageDescriptor.imageView = sdlOverlayImage.imageView; 603 sdlOverlayImageDescriptor.sampler = textureSampler; 604 } 605 606 void VulkanGame::createTextureSampler() { 607 VkSamplerCreateInfo samplerInfo = {}; 608 samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 609 samplerInfo.magFilter = VK_FILTER_LINEAR; 610 samplerInfo.minFilter = VK_FILTER_LINEAR; 611 612 samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; 613 samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; 614 samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; 615 616 samplerInfo.anisotropyEnable = VK_TRUE; 617 samplerInfo.maxAnisotropy = 16; 618 samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; 619 samplerInfo.unnormalizedCoordinates = VK_FALSE; 620 samplerInfo.compareEnable = VK_FALSE; 621 samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; 622 samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; 623 samplerInfo.mipLodBias = 0.0f; 624 samplerInfo.minLod = 0.0f; 625 samplerInfo.maxLod = 0.0f; 626 627 if (vkCreateSampler(device, &samplerInfo, nullptr, &textureSampler) != VK_SUCCESS) { 628 throw runtime_error("failed to create texture sampler!"); 629 } 630 } 631 632 void VulkanGame::createUniformBuffers() { 633 VkDeviceSize bufferSize = sizeof(UniformBufferObject); 634 635 uniformBuffers.resize(swapChainImages.size()); 636 uniformBuffersMemory.resize(swapChainImages.size()); 637 uniformBufferInfoList.resize(swapChainImages.size()); 638 639 for (size_t i = 0; i < swapChainImages.size(); i++) { 640 VulkanUtils::createBuffer(device, physicalDevice, bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 641 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 642 uniformBuffers[i], uniformBuffersMemory[i]); 643 644 uniformBufferInfoList[i].buffer = uniformBuffers[i]; 645 uniformBufferInfoList[i].offset = 0; 646 uniformBufferInfoList[i].range = sizeof(UniformBufferObject); 647 } 648 } 649 531 650 void VulkanGame::cleanupSwapChain() { 651 for (GraphicsPipeline_Vulkan pipeline : graphicsPipelines) { 652 pipeline.cleanup(); 653 } 654 532 655 vkDestroyRenderPass(device, renderPass, nullptr); 533 656 534 for ( autoimageView : swapChainImageViews) {657 for (VkImageView imageView : swapChainImageViews) { 535 658 vkDestroyImageView(device, imageView, nullptr); 536 659 } -
vulkan-game.hpp
r771b33a rb794178 6 6 #include "game-gui-sdl.hpp" 7 7 #include "graphics-pipeline_vulkan.hpp" 8 9 #include "vulkan-utils.hpp" 8 10 9 11 #ifdef NDEBUG … … 40 42 41 43 SDL_version sdlVersion; 42 SDL_Window* window; 43 SDL_Renderer* renderer; 44 SDL_Window* window = nullptr; 45 SDL_Renderer* renderer = nullptr; 46 47 SDL_Texture* uiOverlay = nullptr; 44 48 45 49 VkInstance instance; … … 59 63 VkRenderPass renderPass; 60 64 VkCommandPool commandPool; 65 66 // TODO: Create these (and wrap them inside a VulkanImage) 67 VkImage depthImage; 68 VkDeviceMemory depthImageMemory; 69 VkImageView depthImageView; 70 71 VkSampler textureSampler; 72 73 vector<VkDescriptorBufferInfo> uniformBufferInfoList; 74 75 // These are currently to store the MVP matrix 76 // I should figure out if it makes sense to use them for other uniforms in the future 77 // If not, I should rename them to better indicate their purpose. 78 // I should also decide if I can use these for all shaders, or if I need a separapte set of buffers for each one 79 vector<VkBuffer> uniformBuffers; 80 vector<VkDeviceMemory> uniformBuffersMemory; 81 82 VulkanImage floorTextureImage; 83 VkDescriptorImageInfo floorTextureImageDescriptor; 84 85 VulkanImage sdlOverlayImage; 86 VkDescriptorImageInfo sdlOverlayImageDescriptor; 61 87 62 88 bool framebufferResized = false; … … 83 109 VkFormat findDepthFormat(); 84 110 void createCommandPool(); 111 void createVulkanResources(); 112 void createTextureSampler(); 113 void createUniformBuffers(); 85 114 86 115 void cleanupSwapChain(); -
vulkan-ref.cpp
r771b33a rb794178 80 80 }; 81 81 82 /*** START OF REFACTORED CODE ***/ 82 83 struct DescriptorInfo { 83 84 VkDescriptorType type; … … 87 88 VkDescriptorImageInfo* imageData; 88 89 }; 90 /*** END OF REFACTORED CODE ***/ 89 91 90 92 struct GraphicsPipelineInfo { 93 /*** START OF REFACTORED CODE ***/ 91 94 VkPipelineLayout pipelineLayout; 92 95 VkPipeline pipeline; … … 100 103 VkDescriptorSetLayout descriptorSetLayout; 101 104 vector<VkDescriptorSet> descriptorSets; 105 /*** END OF REFACTORED CODE ***/ 102 106 103 107 size_t numVertices; // Currently unused … … 153 157 SDL_Window* window = nullptr; 154 158 SDL_Renderer* gRenderer = nullptr; 155 /*** END OF REFACTORED CODE ***/156 159 SDL_Texture* uiOverlay = nullptr; 160 /*** END OF REFACTORED CODE ***/ 157 161 158 162 TTF_Font* gFont = nullptr; … … 176 180 /*** END OF REFACTORED CODE ***/ 177 181 // (This was taken out of vulkan-game for now and replaced with Viewport) 178 // It will definitely be needed when creating render passes and I could use it in a few other places 182 // It will definitely be needed when creating command buffers and I could use it in a few other places 183 // TODO: Check above ^ 179 184 VkExtent2D swapChainExtent; 180 185 /*** START OF REFACTORED CODE ***/ … … 190 195 vector<VkCommandBuffer> commandBuffers; 191 196 197 /*** START OF REFACTORED CODE ***/ 192 198 // The images and the sampler are used to store data for specific attributes. I probably 193 199 // want to keep them separate from the GraphicsPipelineInfo objects and start passing … … 197 203 VkDeviceMemory depthImageMemory; 198 204 VkImageView depthImageView; 205 /*** END OF REFACTORED CODE ***/ 199 206 200 207 VkImage textureImage; … … 202 209 VkImageView textureImageView; 203 210 204 VkImage overlayImage;205 VkDeviceMemory overlayImageMemory;206 VkImageView overlayImageView;207 208 211 VkImage sdlOverlayImage; 209 212 VkDeviceMemory sdlOverlayImageMemory; 210 213 VkImageView sdlOverlayImageView; 211 214 215 /*** START OF REFACTORED CODE ***/ 212 216 VkSampler textureSampler; 213 217 214 218 // These are currently to store the MVP matrix 215 219 // I should figure out if it makes sense to use them for other uniforms in the future 216 // If not, I should rename them to better indicate their pu prose.220 // If not, I should rename them to better indicate their purpose. 217 221 // I should also decide if I can use these for all shaders, or if I need a separapte set of buffers for each one 218 222 vector<VkBuffer> uniformBuffers; 219 223 vector<VkDeviceMemory> uniformBuffersMemory; 224 /*** END OF REFACTORED CODE ***/ 220 225 221 226 VkDescriptorImageInfo sceneImageInfo; 222 227 VkDescriptorImageInfo overlayImageInfo; 223 228 229 /*** START OF REFACTORED CODE ***/ 224 230 vector<VkDescriptorBufferInfo> uniformBufferInfoList; 231 /*** END OF REFACTORED CODE ***/ 225 232 226 233 GraphicsPipelineInfo scenePipeline; … … 257 264 return RTWO_ERROR; 258 265 } 259 /*** END OF REFACTORED CODE ***/260 266 261 267 SDL_VERSION(&sdlVersion); … … 277 283 cout << "Unable to set texture blend mode! SDL Error: " << SDL_GetError() << endl; 278 284 } 285 /*** END OF REFACTORED CODE ***/ 279 286 280 287 gFont = TTF_OpenFont("fonts/lazy.ttf", 28); … … 334 341 /*** END OF REFACTORED CODE ***/ 335 342 336 // THIS SECTION IS WHERE TEXTURES ARE CREATED, MAYBE SPLIT IT OFF INTO A SEPARATE FUNCTION337 // MAY WANT TO CREATE A STRUCT TO HOLD SIMILAR VARIABLES< LIKE THOSE FOR A TEXTURE338 339 343 createImageResources("textures/texture.jpg", textureImage, textureImageMemory, textureImageView); 344 /*** START OF REFACTORED CODE ***/ 340 345 createImageResourcesFromSDLTexture(uiOverlay, sdlOverlayImage, sdlOverlayImageMemory, sdlOverlayImageView); 341 346 createTextureSampler(); … … 350 355 overlayImageInfo.imageView = sdlOverlayImageView; 351 356 overlayImageInfo.sampler = textureSampler; 357 /*** END OF REFACTORED CODE ***/ 352 358 353 359 // SHADER-SPECIFIC STUFF STARTS HERE … … 377 383 addAttributeDescription(scenePipeline, VK_FORMAT_R32G32B32_SFLOAT, offset_of(&Vertex::color)); 378 384 addAttributeDescription(scenePipeline, VK_FORMAT_R32G32_SFLOAT, offset_of(&Vertex::texCoord)); 379 /*** END OF REFACTORED CODE ***/380 385 381 386 addDescriptorInfo(scenePipeline, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, &uniformBufferInfoList, nullptr); … … 383 388 384 389 createDescriptorSetLayout(scenePipeline); 390 /*** END OF REFACTORED CODE ***/ 385 391 386 392 numPlanes = 2; … … 403 409 addAttributeDescription(overlayPipeline, VK_FORMAT_R32G32B32_SFLOAT, offset_of(&OverlayVertex::pos)); 404 410 addAttributeDescription(overlayPipeline, VK_FORMAT_R32G32_SFLOAT, offset_of(&OverlayVertex::texCoord)); 405 /*** END OF REFACTORED CODE ***/406 411 407 412 addDescriptorInfo(overlayPipeline, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr, &overlayImageInfo); 408 413 409 414 createDescriptorSetLayout(overlayPipeline); 415 /*** END OF REFACTORED CODE ***/ 410 416 411 417 createBufferResources(); … … 847 853 } 848 854 855 /*** START OF REFACTORED CODE ***/ 849 856 void addDescriptorInfo(GraphicsPipelineInfo& info, VkDescriptorType type, VkShaderStageFlags stageFlags, vector<VkDescriptorBufferInfo>* bufferData, VkDescriptorImageInfo* imageData) { 850 857 info.descriptorInfoList.push_back({ type, stageFlags, bufferData, imageData }); … … 873 880 874 881 void createGraphicsPipeline(string vertShaderFile, string fragShaderFile, GraphicsPipelineInfo& info) { 875 /*** START OF REFACTORED CODE ***/876 882 vector<char> vertShaderCode = readFile(vertShaderFile); 877 883 vector<char> fragShaderCode = readFile(fragShaderFile); … … 977 983 pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 978 984 pipelineLayoutInfo.setLayoutCount = 1; 979 /*** END OF REFACTORED CODE ***/980 985 pipelineLayoutInfo.pSetLayouts = &info.descriptorSetLayout; 981 986 pipelineLayoutInfo.pushConstantRangeCount = 0; … … 1007 1012 } 1008 1013 1009 /*** START OF REFACTORED CODE ***/1010 1014 vkDestroyShaderModule(device, vertShaderModule, nullptr); 1011 1015 vkDestroyShaderModule(device, fragShaderModule, nullptr); 1012 /*** END OF REFACTORED CODE ***/ 1013 } 1016 } 1017 /*** END OF REFACTORED CODE ***/ 1014 1018 1015 1019 VkShaderModule createShaderModule(const vector<char>& code) { … … 1134 1138 throw runtime_error("failed to find supported format!"); 1135 1139 } 1136 /*** END OF REFACTORED CODE ***/1137 1140 1138 1141 bool hasStencilComponent(VkFormat format) { … … 1191 1194 view = createImageView(image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT); 1192 1195 } 1196 /*** END OF REFACTORED CODE ***/ 1193 1197 1194 1198 void populateImageFromSDLTexture(SDL_Texture* texture, VkImage& image) { … … 1386 1390 return imageView; 1387 1391 } 1388 /*** END OF REFACTORED CODE ***/1389 1392 1390 1393 void createTextureSampler() { … … 1413 1416 } 1414 1417 } 1418 /*** END OF REFACTORED CODE ***/ 1415 1419 1416 1420 void createVertexBuffer(GraphicsPipelineInfo& info, const void* vertexData, int vertexSize) { … … 1462 1466 } 1463 1467 1468 /*** START OF REFACTORED CODE ***/ 1464 1469 void createUniformBuffers() { 1465 1470 VkDeviceSize bufferSize = sizeof(UniformBufferObject); … … 1505 1510 vkBindBufferMemory(device, buffer, bufferMemory, 0); 1506 1511 } 1512 /*** END OF REFACTORED CODE ***/ 1507 1513 1508 1514 void copyDataToBuffer(const void* srcData, VkBuffer dst, VkDeviceSize dstOffset, VkDeviceSize dataSize) { … … 1567 1573 } 1568 1574 1575 /*** START OF REFACTORED CODE ***/ 1569 1576 uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) { 1570 1577 VkPhysicalDeviceMemoryProperties memProperties; … … 1642 1649 } 1643 1650 } 1651 /*** END OF REFACTORED CODE ***/ 1644 1652 1645 1653 void createCommandBuffers() { … … 1948 1956 1949 1957 void createBufferResources() { 1958 // TODO: The three functions below will be called in vulkan-game following the 1959 // pipeline creation (createDescriptorSets()), and before createCommandBuffers() 1950 1960 createDepthResources(); 1951 1961 createFramebuffers(); 1952 1962 createUniformBuffers(); 1953 1963 1964 /*** START OF REFACTORED CODE ***/ 1954 1965 createGraphicsPipeline("shaders/scene-vert.spv", "shaders/scene-frag.spv", scenePipeline); 1955 1966 createDescriptorPool(scenePipeline); 1967 /*** END OF REFACTORED CODE ***/ 1956 1968 createDescriptorSets(scenePipeline); 1957 1969 1970 /*** START OF REFACTORED CODE ***/ 1958 1971 createGraphicsPipeline("shaders/overlay-vert.spv", "shaders/overlay-frag.spv", overlayPipeline); 1959 1972 createDescriptorPool(overlayPipeline); 1973 /*** END OF REFACTORED CODE ***/ 1960 1974 createDescriptorSets(overlayPipeline); 1961 1975 … … 1963 1977 } 1964 1978 1965 /*** START OF REFACTORED CODE ***/1966 1979 void cleanup() { 1980 /*** START OF REFACTORED CODE ***/ 1967 1981 cleanupSwapChain(); 1968 1982 /*** END OF REFACTORED CODE ***/ … … 1974 1988 vkFreeMemory(device, textureImageMemory, nullptr); 1975 1989 1976 vkDestroyImageView(device, overlayImageView, nullptr);1977 vkDestroyImage(device, overlayImage, nullptr);1978 vkFreeMemory(device, overlayImageMemory, nullptr);1979 1980 1990 vkDestroyImageView(device, sdlOverlayImageView, nullptr); 1981 1991 vkDestroyImage(device, sdlOverlayImage, nullptr); 1982 1992 vkFreeMemory(device, sdlOverlayImageMemory, nullptr); 1983 1993 1994 /*** START OF REFACTORED CODE ***/ 1984 1995 cleanupPipelineBuffers(scenePipeline); 1985 1996 cleanupPipelineBuffers(overlayPipeline); 1997 /*** END OF REFACTORED CODE ***/ 1986 1998 1987 1999 for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { … … 2001 2013 2002 2014 vkDestroyInstance(instance, nullptr); 2003 /*** END OF REFACTORED CODE ***/2004 2015 2005 2016 // TODO: Check if any of these functions accept null parameters … … 2010 2021 uiOverlay = nullptr; 2011 2022 } 2023 /*** END OF REFACTORED CODE ***/ 2012 2024 2013 2025 TTF_CloseFont(gFont); … … 2045 2057 vkFreeCommandBuffers(device, commandPool, static_cast<uint32_t>(commandBuffers.size()), commandBuffers.data()); 2046 2058 2059 /*** START OF REFACTORED CODE ***/ 2047 2060 cleanupPipeline(scenePipeline); 2048 2061 cleanupPipeline(overlayPipeline); 2049 2062 2050 /*** START OF REFACTORED CODE ***/2051 2063 vkDestroyRenderPass(device, renderPass, nullptr); 2052 2064 … … 2062 2074 vkFreeMemory(device, uniformBuffersMemory[i], nullptr); 2063 2075 } 2064 /*** START OF REFACTORED CODE ***/ 2065 } 2066 /*** END OF REFACTORED CODE ***/ 2067 2076 } 2077 2078 /*** START OF REFACTORED CODE ***/ 2068 2079 void cleanupPipeline(GraphicsPipelineInfo& pipeline) { 2069 2080 vkDestroyPipeline(device, pipeline.pipeline, nullptr); … … 2071 2082 vkDestroyPipelineLayout(device, pipeline.pipelineLayout, nullptr); 2072 2083 } 2084 /*** END OF REFACTORED CODE ***/ 2073 2085 2074 2086 void cleanupPipelineBuffers(GraphicsPipelineInfo& pipeline) { 2087 /*** START OF REFACTORED CODE ***/ 2075 2088 vkDestroyDescriptorSetLayout(device, pipeline.descriptorSetLayout, nullptr); 2089 /*** END OF REFACTORED CODE ***/ 2076 2090 2077 2091 vkDestroyBuffer(device, pipeline.vertexBuffer, nullptr); -
vulkan-utils.cpp
r771b33a rb794178 4 4 #include <set> 5 5 #include <stdexcept> 6 #include <string> 6 7 #define STB_IMAGE_IMPLEMENTATION 8 #include "stb_image.h" // TODO: Probably switch to SDL_image 9 10 // TODO: Remove all instances of auto 7 11 8 12 bool VulkanUtils::checkValidationLayerSupport(const vector<const char*> &validationLayers) { … … 210 214 throw runtime_error("failed to find supported format!"); 211 215 } 216 217 void VulkanUtils::createBuffer(VkDevice device, VkPhysicalDevice physicalDevice, VkDeviceSize size, VkBufferUsageFlags usage, 218 VkMemoryPropertyFlags properties, VkBuffer& buffer, VkDeviceMemory& bufferMemory) { 219 VkBufferCreateInfo bufferInfo = {}; 220 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 221 bufferInfo.size = size; 222 bufferInfo.usage = usage; 223 bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 224 225 if (vkCreateBuffer(device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) { 226 throw runtime_error("failed to create buffer!"); 227 } 228 229 VkMemoryRequirements memRequirements; 230 vkGetBufferMemoryRequirements(device, buffer, &memRequirements); 231 232 VkMemoryAllocateInfo allocInfo = {}; 233 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 234 allocInfo.allocationSize = memRequirements.size; 235 allocInfo.memoryTypeIndex = findMemoryType(physicalDevice, memRequirements.memoryTypeBits, properties); 236 237 if (vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) { 238 throw runtime_error("failed to allocate buffer memory!"); 239 } 240 241 vkBindBufferMemory(device, buffer, bufferMemory, 0); 242 } 243 244 uint32_t VulkanUtils::findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter, VkMemoryPropertyFlags properties) { 245 VkPhysicalDeviceMemoryProperties memProperties; 246 vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties); 247 248 for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) { 249 if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) { 250 return i; 251 } 252 } 253 254 throw runtime_error("failed to find suitable memory type!"); 255 } 256 257 void VulkanUtils::createVulkanImageFromFile(VkDevice device, VkPhysicalDevice physicalDevice, 258 VkCommandPool commandPool, string filename, VulkanImage& image, VkQueue graphicsQueue) { 259 int texWidth, texHeight, texChannels; 260 261 stbi_uc* pixels = stbi_load(filename.c_str(), &texWidth, &texHeight, &texChannels, STBI_rgb_alpha); 262 VkDeviceSize imageSize = texWidth * texHeight * 4; 263 264 if (!pixels) { 265 throw runtime_error("failed to load texture image!"); 266 } 267 268 VkBuffer stagingBuffer; 269 VkDeviceMemory stagingBufferMemory; 270 271 createBuffer(device, physicalDevice, imageSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 272 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, 273 stagingBuffer, stagingBufferMemory); 274 275 void* data; 276 277 vkMapMemory(device, stagingBufferMemory, 0, imageSize, 0, &data); 278 memcpy(data, pixels, static_cast<size_t>(imageSize)); 279 vkUnmapMemory(device, stagingBufferMemory); 280 281 stbi_image_free(pixels); 282 283 createImage(device, physicalDevice, texWidth, texHeight, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, 284 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, image); 285 286 transitionImageLayout(device, commandPool, image.image, VK_FORMAT_R8G8B8A8_UNORM, 287 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, graphicsQueue); 288 copyBufferToImage(device, commandPool, stagingBuffer, image.image, 289 static_cast<uint32_t>(texWidth), static_cast<uint32_t>(texHeight), graphicsQueue); 290 transitionImageLayout(device, commandPool, image.image, VK_FORMAT_R8G8B8A8_UNORM, 291 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, graphicsQueue); 292 293 vkDestroyBuffer(device, stagingBuffer, nullptr); 294 vkFreeMemory(device, stagingBufferMemory, nullptr); 295 296 image.imageView = createImageView(device, image.image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT); 297 } 298 299 void VulkanUtils::createVulkanImageFromSDLTexture(VkDevice device, VkPhysicalDevice physicalDevice, 300 SDL_Texture* texture, VulkanImage& image) { 301 int a, w, h; 302 303 // I only need this here for the width and height, which are constants, so just use those instead 304 SDL_QueryTexture(texture, nullptr, &a, &w, &h); 305 306 createImage(device, physicalDevice, w, h, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_TILING_OPTIMAL, 307 VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, image); 308 309 image.imageView = createImageView(device, image.image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT); 310 } 311 312 void VulkanUtils::createImage(VkDevice device, VkPhysicalDevice physicalDevice, uint32_t width, uint32_t height, 313 VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, 314 VulkanImage& image) { 315 VkImageCreateInfo imageInfo = {}; 316 imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 317 imageInfo.imageType = VK_IMAGE_TYPE_2D; 318 imageInfo.extent.width = width; 319 imageInfo.extent.height = height; 320 imageInfo.extent.depth = 1; 321 imageInfo.mipLevels = 1; 322 imageInfo.arrayLayers = 1; 323 imageInfo.format = format; 324 imageInfo.tiling = tiling; 325 imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 326 imageInfo.usage = usage; 327 imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; 328 imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 329 330 if (vkCreateImage(device, &imageInfo, nullptr, &image.image) != VK_SUCCESS) { 331 throw runtime_error("failed to create image!"); 332 } 333 334 VkMemoryRequirements memRequirements; 335 vkGetImageMemoryRequirements(device, image.image, &memRequirements); 336 337 VkMemoryAllocateInfo allocInfo = {}; 338 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; 339 allocInfo.allocationSize = memRequirements.size; 340 allocInfo.memoryTypeIndex = findMemoryType(physicalDevice, memRequirements.memoryTypeBits, properties); 341 342 if (vkAllocateMemory(device, &allocInfo, nullptr, &image.imageMemory) != VK_SUCCESS) { 343 throw runtime_error("failed to allocate image memory!"); 344 } 345 346 vkBindImageMemory(device, image.image, image.imageMemory, 0); 347 } 348 349 void VulkanUtils::transitionImageLayout(VkDevice device, VkCommandPool commandPool, VkImage image, 350 VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout, VkQueue graphicsQueue) { 351 VkCommandBuffer commandBuffer = beginSingleTimeCommands(device, commandPool); 352 353 VkImageMemoryBarrier barrier = {}; 354 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 355 barrier.oldLayout = oldLayout; 356 barrier.newLayout = newLayout; 357 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 358 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 359 barrier.image = image; 360 361 if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { 362 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 363 364 if (hasStencilComponent(format)) { 365 barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; 366 } 367 } else { 368 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 369 } 370 371 barrier.subresourceRange.baseMipLevel = 0; 372 barrier.subresourceRange.levelCount = 1; 373 barrier.subresourceRange.baseArrayLayer = 0; 374 barrier.subresourceRange.layerCount = 1; 375 376 VkPipelineStageFlags sourceStage; 377 VkPipelineStageFlags destinationStage; 378 379 if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { 380 barrier.srcAccessMask = 0; 381 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 382 383 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 384 destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; 385 } else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { 386 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 387 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; 388 389 sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; 390 destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; 391 } else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) { 392 barrier.srcAccessMask = 0; 393 barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 394 395 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 396 destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; 397 } else { 398 throw invalid_argument("unsupported layout transition!"); 399 } 400 401 vkCmdPipelineBarrier( 402 commandBuffer, 403 sourceStage, destinationStage, 404 0, 405 0, nullptr, 406 0, nullptr, 407 1, &barrier 408 ); 409 410 endSingleTimeCommands(device, commandPool, commandBuffer, graphicsQueue); 411 } 412 413 VkCommandBuffer VulkanUtils::beginSingleTimeCommands(VkDevice device, VkCommandPool commandPool) { 414 VkCommandBufferAllocateInfo allocInfo = {}; 415 allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 416 allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 417 allocInfo.commandPool = commandPool; 418 allocInfo.commandBufferCount = 1; 419 420 VkCommandBuffer commandBuffer; 421 vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer); 422 423 VkCommandBufferBeginInfo beginInfo = {}; 424 beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 425 beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 426 427 vkBeginCommandBuffer(commandBuffer, &beginInfo); 428 429 return commandBuffer; 430 } 431 432 void VulkanUtils::endSingleTimeCommands(VkDevice device, VkCommandPool commandPool, 433 VkCommandBuffer commandBuffer, VkQueue graphicsQueue) { 434 vkEndCommandBuffer(commandBuffer); 435 436 VkSubmitInfo submitInfo = {}; 437 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 438 submitInfo.commandBufferCount = 1; 439 submitInfo.pCommandBuffers = &commandBuffer; 440 441 vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE); 442 vkQueueWaitIdle(graphicsQueue); 443 444 vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer); 445 } 446 447 void VulkanUtils::copyBufferToImage(VkDevice device, VkCommandPool commandPool, VkBuffer buffer, 448 VkImage image, uint32_t width, uint32_t height, VkQueue graphicsQueue) { 449 VkCommandBuffer commandBuffer = beginSingleTimeCommands(device, commandPool); 450 451 VkBufferImageCopy region = {}; 452 region.bufferOffset = 0; 453 region.bufferRowLength = 0; 454 region.bufferImageHeight = 0; 455 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 456 region.imageSubresource.mipLevel = 0; 457 region.imageSubresource.baseArrayLayer = 0; 458 region.imageSubresource.layerCount = 1; 459 region.imageOffset = { 0, 0, 0 }; 460 region.imageExtent = { width, height, 1 }; 461 462 vkCmdCopyBufferToImage( 463 commandBuffer, 464 buffer, 465 image, 466 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 467 1, 468 ®ion 469 ); 470 471 endSingleTimeCommands(device, commandPool, commandBuffer, graphicsQueue); 472 } 473 474 bool VulkanUtils::hasStencilComponent(VkFormat format) { 475 return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT; 476 } -
vulkan-utils.hpp
r771b33a rb794178 3 3 4 4 #include <optional> 5 #include <string> 5 6 #include <vector> 6 7 7 8 #include <vulkan/vulkan.h> 9 10 #include <SDL2/SDL.h> 11 #include <SDL2/SDL_image.h> 12 #include <SDL2/SDL_vulkan.h> 8 13 9 14 using namespace std; … … 24 29 }; 25 30 31 struct VulkanImage { 32 VkImage image; 33 VkDeviceMemory imageMemory; 34 VkImageView imageView; 35 }; 36 26 37 class VulkanUtils { 27 38 public: … … 38 49 39 50 static QueueFamilyIndices findQueueFamilies(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface); 40 static bool checkDeviceExtensionSupport(VkPhysicalDevice physicalDevice, const vector<const char*>& deviceExtensions); 41 static SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface); 51 static bool checkDeviceExtensionSupport(VkPhysicalDevice physicalDevice, 52 const vector<const char*>& deviceExtensions); 53 static SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice physicalDevice, 54 VkSurfaceKHR surface); 42 55 static VkSurfaceFormatKHR chooseSwapSurfaceFormat(const vector<VkSurfaceFormatKHR>& availableFormats); 43 56 static VkPresentModeKHR chooseSwapPresentMode(const vector<VkPresentModeKHR>& availablePresentModes); 44 57 static VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, int width, int height); 45 static VkImageView createImageView(VkDevice device, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags); 58 static VkImageView createImageView(VkDevice device, VkImage image, VkFormat format, 59 VkImageAspectFlags aspectFlags); 46 60 static VkFormat findSupportedFormat(VkPhysicalDevice physicalDevice, const vector<VkFormat>& candidates, 47 61 VkImageTiling tiling, VkFormatFeatureFlags features); 62 static void createBuffer(VkDevice device, VkPhysicalDevice physicalDevice, VkDeviceSize size, 63 VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer& buffer, 64 VkDeviceMemory& bufferMemory); 65 static uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter, 66 VkMemoryPropertyFlags properties); 67 68 static void createVulkanImageFromFile(VkDevice device, VkPhysicalDevice physicalDevice, 69 VkCommandPool commandPool, string filename, VulkanImage& image, VkQueue graphicsQueue); 70 static void createVulkanImageFromSDLTexture(VkDevice device, VkPhysicalDevice physicalDevice, 71 SDL_Texture* texture, VulkanImage& image); 72 static void createImage(VkDevice device, VkPhysicalDevice physicalDevice, uint32_t width, uint32_t height, 73 VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, 74 VulkanImage& image); 75 76 static void transitionImageLayout(VkDevice device, VkCommandPool commandPool, VkImage image, 77 VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout, VkQueue graphicsQueue); 78 static VkCommandBuffer beginSingleTimeCommands(VkDevice device, VkCommandPool commandPool); 79 static void endSingleTimeCommands(VkDevice device, VkCommandPool commandPool, 80 VkCommandBuffer commandBuffer, VkQueue graphicsQueue); 81 static void copyBufferToImage(VkDevice device, VkCommandPool commandPool, VkBuffer buffer, VkImage image, 82 uint32_t width, uint32_t height, VkQueue graphicsQueue); 83 84 static bool hasStencilComponent(VkFormat format); 48 85 }; 49 86
Note:
See TracChangeset
for help on using the changeset viewer.