diff --git a/vulkan/Application.cpp b/vulkan/Application.cpp index 15bbffc..9b9b37e 100644 --- a/vulkan/Application.cpp +++ b/vulkan/Application.cpp @@ -599,12 +599,23 @@ void Application::cleanup() { vkDestroyImageView(device, imageView, nullptr); } + for (auto framebuffer : swapChainFramebuffers) + { + if (framebuffer != VK_NULL_HANDLE) + { + vkDestroyFramebuffer(device, framebuffer, nullptr); + } + } + swapChainFramebuffers.clear(); + vkDestroySwapchainKHR(device, swapChain, nullptr); vkDestroyDevice(device, nullptr); vkDestroySurfaceKHR(instance, surface, nullptr); vkDestroyInstance(instance, nullptr); + + #ifdef _WIN32 glfwDestroyWindow(window); glfwTerminate(); diff --git a/vulkan/FaceApp.cpp b/vulkan/FaceApp.cpp index 91fbdef..da05cef 100644 --- a/vulkan/FaceApp.cpp +++ b/vulkan/FaceApp.cpp @@ -454,6 +454,10 @@ void FaceApp::create_face_pipelines() pipeline_create_info.pStages = shader_stages; VK_CHECK(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, &m_graphicsPipeline)); + + // 销毁着色器模块 + vkDestroyShaderModule(device, fragShaderModule, nullptr); + vkDestroyShaderModule(device, vertShaderModule, nullptr); } @@ -713,11 +717,17 @@ void FaceApp::initVulkan() createVmaAllocator(); LoadOBJ("face_picture_3dmax.obj", obj_vertices, obj_indices); m_texs.resize(kMaxTexture); - m_texs_ex.resize(kMaxTexture); + if (kThick) + { + m_texs_ex.resize(kMaxTexture); + } for (int i = 0; i < kMaxTexture; ++i) { loadTexture("demo0.png", m_texs[i], true); - loadTexture("demo0_ex.png", m_texs_ex[i], true); + if (kThick) + { + loadTexture("demo0_ex.png", m_texs_ex[i], true); + } } loadTexture("out.png", tex_bg, true); @@ -1032,6 +1042,10 @@ void FaceApp::create_pipelines_bg() pipeline_create_info.pStages = shader_stages; VK_CHECK(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, &m_graphicsPipeline_bg)); + + // 销毁着色器模块 + vkDestroyShaderModule(device, fragShaderModule, nullptr); + vkDestroyShaderModule(device, vertShaderModule, nullptr); } void FaceApp::setup_descriptor_set_layout_bg() @@ -1101,21 +1115,141 @@ void FaceApp::setup_descriptor_set_bg() vkUpdateDescriptorSets(device, static_cast(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL); } +void FaceApp::destroyTexture(VkDevice device, Texture& texture) { + // 注意销毁顺序:先销毁依赖对象,后销毁被依赖对象 + + // 1. 销毁采样器 + if (texture.sampler != VK_NULL_HANDLE) { + vkDestroySampler(device, texture.sampler, nullptr); + texture.sampler = VK_NULL_HANDLE; + } + + // 2. 销毁图像视图 + if (texture.view != VK_NULL_HANDLE) { + vkDestroyImageView(device, texture.view, nullptr); + texture.view = VK_NULL_HANDLE; + } + + // 3. 销毁图像 + if (texture.image != VK_NULL_HANDLE) { + vkDestroyImage(device, texture.image, nullptr); + texture.image = VK_NULL_HANDLE; + } + + // 4. 释放设备内存 + if (texture.device_memory != VK_NULL_HANDLE) { + vkFreeMemory(device, texture.device_memory, nullptr); + texture.device_memory = VK_NULL_HANDLE; + } +} + +void FaceApp::cleanupResources(VkDevice device, VmaAllocator allocator) { + // 销毁图形管线 + if (m_graphicsPipeline != VK_NULL_HANDLE) { + vkDestroyPipeline(device, m_graphicsPipeline, nullptr); + m_graphicsPipeline = VK_NULL_HANDLE; + } + + // 销毁管线布局 + if (m_pipelineLayout != VK_NULL_HANDLE) { + vkDestroyPipelineLayout(device, m_pipelineLayout, nullptr); + m_pipelineLayout = VK_NULL_HANDLE; + } + + // 销毁描述符集布局 + if (m_descriptorSetLayout != VK_NULL_HANDLE) { + vkDestroyDescriptorSetLayout(device, m_descriptorSetLayout, nullptr); + m_descriptorSetLayout = VK_NULL_HANDLE; + } + + // 销毁图形管线 + if (m_graphicsPipeline_bg != VK_NULL_HANDLE) { + vkDestroyPipeline(device, m_graphicsPipeline_bg, nullptr); + m_graphicsPipeline_bg = VK_NULL_HANDLE; + } + + // 销毁管线布局 + if (m_pipelineLayout_bg != VK_NULL_HANDLE) { + vkDestroyPipelineLayout(device, m_pipelineLayout_bg, nullptr); + m_pipelineLayout_bg = VK_NULL_HANDLE; + } + + // 销毁描述符集布局 + if (m_descriptorSetLayout_bg != VK_NULL_HANDLE) { + vkDestroyDescriptorSetLayout(device, m_descriptorSetLayout_bg, nullptr); + m_descriptorSetLayout_bg = VK_NULL_HANDLE; + } + + // 销毁顶点缓冲区 + if (m_vertexBuffer != VK_NULL_HANDLE) { + vkDestroyBuffer(device, m_vertexBuffer, nullptr); + m_vertexBuffer = VK_NULL_HANDLE; + } + if (m_vertexBufferAllocation != VK_NULL_HANDLE) { + vmaFreeMemory(allocator, m_vertexBufferAllocation); + m_vertexBufferAllocation = VK_NULL_HANDLE; + } + + // 销毁暂存缓冲区 + if (m_stagingBuffer != VK_NULL_HANDLE) { + vkDestroyBuffer(device, m_stagingBuffer, nullptr); + m_stagingBuffer = VK_NULL_HANDLE; + } + if (m_stagingBufferAllocation != VK_NULL_HANDLE) { + vmaFreeMemory(allocator, m_stagingBufferAllocation); + m_stagingBufferAllocation = VK_NULL_HANDLE; + } + + // 销毁索引缓冲区 + if (m_indexBuffer != VK_NULL_HANDLE) { + vkDestroyBuffer(device, m_indexBuffer, nullptr); + m_indexBuffer = VK_NULL_HANDLE; + } + if (m_indexBufferAllocation != VK_NULL_HANDLE) { + vmaFreeMemory(allocator, m_indexBufferAllocation); + m_indexBufferAllocation = VK_NULL_HANDLE; + } + + if (descriptor_pool != VK_NULL_HANDLE) + { + vkDestroyDescriptorPool(device, descriptor_pool, nullptr); + descriptor_pool = VK_NULL_HANDLE; + } + + // 清空描述符集列表(不需要单独销毁,由描述符池管理) + m_descriptor_sets.clear(); +} void FaceApp::cleanup() { vkDeviceWaitIdle(device); + + if (uniform_buffer_mapped != nullptr) + { + vmaUnmapMemory(allocator, uniform_buffer_allocation); + uniform_buffer_mapped = nullptr; + } + + if (uniform_buffer_vs != VK_NULL_HANDLE) + { + vmaDestroyBuffer(allocator, uniform_buffer_vs, uniform_buffer_allocation); + uniform_buffer_vs = VK_NULL_HANDLE; + uniform_buffer_allocation = VK_NULL_HANDLE; // 可选,但推荐重置 + } + + cleanupResources(device, allocator); + for (int i = 0; i < this->m_texs.size(); ++i) + { + destroyTexture(device, m_texs[i]); + } + + destroyTexture(device, tex_bg); vkDestroyCommandPool(device, commandPool, nullptr); - vkDestroyPipeline(device, m_graphicsPipeline, nullptr); - vkDestroyPipelineLayout(device, m_pipelineLayout, nullptr); - //vmaUnmapMemory(allocator, m_stagingBufferAllocation); - //vmaUnmapMemory(allocator, uniform_buffer_allocation); - //vmaDestroyBuffer(allocator, uniform_buffer_vs, uniform_buffer_allocation); - //vmaDestroyBuffer(allocator, m_indexBuffer, m_indexBufferAllocation); - //vmaDestroyBuffer(allocator, m_vertexBuffer, m_vertexBufferAllocation); - //vmaDestroyBuffer(allocator, m_stagingBuffer, m_stagingBufferAllocation); - vkDestroyDescriptorSetLayout(device, m_descriptorSetLayout, nullptr); Application::cleanup(); + //if (allocator != VK_NULL_HANDLE) { + // vmaDestroyAllocator(allocator); + // allocator = VK_NULL_HANDLE; + //} } diff --git a/vulkan/FaceApp.h b/vulkan/FaceApp.h index cc84793..503ad2f 100644 --- a/vulkan/FaceApp.h +++ b/vulkan/FaceApp.h @@ -143,6 +143,9 @@ public: void SetInitArg(const char* arg); void drawFrame(long long frameTime)override; + + void destroyTexture(VkDevice device, Texture& texture); + void cleanupResources(VkDevice device, VmaAllocator allocator); }; #endif