From ecc11f07db8db80889a4d2d744de6abf340dee5f Mon Sep 17 00:00:00 2001 From: Thraix Date: Fri, 11 Oct 2024 20:06:22 +0200 Subject: [PATCH] Improve vulkan resource freeing and some minor improvements to the Renderer, now taking in an AssetRef as parameter. --- CopiumEngine/CopiumEngine.vcxproj | 2 +- CopiumEngine/CopiumEngine.vcxproj.filters | 6 ++-- CopiumEngine/src/copium/buffer/Buffer.cpp | 8 +++-- .../src/copium/buffer/CommandBuffer.cpp | 5 ++- .../src/copium/buffer/Framebuffer.cpp | 12 ++++--- .../src/copium/buffer/UniformBuffer.cpp | 6 +++- CopiumEngine/src/copium/core/Device.cpp | 23 ++++++++++++++ CopiumEngine/src/copium/core/Device.h | 31 ++++++++++++------- CopiumEngine/src/copium/core/SwapChain.cpp | 2 +- CopiumEngine/src/copium/core/Vulkan.cpp | 9 ++++++ CopiumEngine/src/copium/core/Vulkan.h | 2 ++ .../src/copium/pipeline/DescriptorPool.cpp | 11 +++++-- CopiumEngine/src/copium/pipeline/Pipeline.cpp | 19 ++++++++---- CopiumEngine/src/copium/pipeline/Shader.cpp | 8 +++-- CopiumEngine/src/copium/renderer/Renderer.cpp | 4 +-- CopiumEngine/src/copium/renderer/Renderer.h | 2 +- .../src/copium/sampler/ColorAttachment.cpp | 17 ++++++---- .../src/copium/sampler/DepthAttachment.cpp | 11 +++++-- CopiumEngine/src/copium/sampler/Font.cpp | 11 +++++-- CopiumEngine/src/copium/sampler/Sampler.cpp | 5 ++- CopiumEngine/src/copium/sampler/Texture2D.cpp | 15 ++++----- 21 files changed, 151 insertions(+), 58 deletions(-) diff --git a/CopiumEngine/CopiumEngine.vcxproj b/CopiumEngine/CopiumEngine.vcxproj index ddb9bb3..c1f7479 100644 --- a/CopiumEngine/CopiumEngine.vcxproj +++ b/CopiumEngine/CopiumEngine.vcxproj @@ -202,7 +202,6 @@ - @@ -287,6 +286,7 @@ + diff --git a/CopiumEngine/CopiumEngine.vcxproj.filters b/CopiumEngine/CopiumEngine.vcxproj.filters index 8da5e80..13a1c0e 100644 --- a/CopiumEngine/CopiumEngine.vcxproj.filters +++ b/CopiumEngine/CopiumEngine.vcxproj.filters @@ -216,9 +216,6 @@ Source Files - - Header Files - Source Files @@ -479,5 +476,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/CopiumEngine/src/copium/buffer/Buffer.cpp b/CopiumEngine/src/copium/buffer/Buffer.cpp index 0929f2f..7c118f8 100644 --- a/CopiumEngine/src/copium/buffer/Buffer.cpp +++ b/CopiumEngine/src/copium/buffer/Buffer.cpp @@ -30,8 +30,12 @@ namespace Copium Buffer::~Buffer() { - vkFreeMemory(Vulkan::GetDevice(), memory, nullptr); - vkDestroyBuffer(Vulkan::GetDevice(), handle, nullptr); + VkDeviceMemory memoryCpy = memory; + VkBuffer handleCpy = handle; + Vulkan::GetDevice().QueueIdleCommand([memoryCpy, handleCpy]() { + vkFreeMemory(Vulkan::GetDevice(), memoryCpy, nullptr); + vkDestroyBuffer(Vulkan::GetDevice(), handleCpy, nullptr); + }); } void Buffer::Update(void* indexData, int index) diff --git a/CopiumEngine/src/copium/buffer/CommandBuffer.cpp b/CopiumEngine/src/copium/buffer/CommandBuffer.cpp index 49417ab..2f7b7e1 100644 --- a/CopiumEngine/src/copium/buffer/CommandBuffer.cpp +++ b/CopiumEngine/src/copium/buffer/CommandBuffer.cpp @@ -29,7 +29,10 @@ namespace Copium CommandBuffer::~CommandBuffer() { - vkFreeCommandBuffers(Vulkan::GetDevice(), Vulkan::GetDevice().GetCommandPool(), commandBuffers.size(), commandBuffers.data()); + std::vector commandBuffersCpy = commandBuffers; + Vulkan::GetDevice().QueueIdleCommand([commandBuffersCpy]() { + vkFreeCommandBuffers(Vulkan::GetDevice(), Vulkan::GetDevice().GetCommandPool(), commandBuffersCpy.size(), commandBuffersCpy.data()); + }); } // TODO: Test as constexpr function to see if it avoids the switch case diff --git a/CopiumEngine/src/copium/buffer/Framebuffer.cpp b/CopiumEngine/src/copium/buffer/Framebuffer.cpp index 7095ed7..fdbae99 100644 --- a/CopiumEngine/src/copium/buffer/Framebuffer.cpp +++ b/CopiumEngine/src/copium/buffer/Framebuffer.cpp @@ -30,14 +30,18 @@ namespace Copium Framebuffer::~Framebuffer() { - for (auto& framebuffer : framebuffers) - vkDestroyFramebuffer(Vulkan::GetDevice(), framebuffer, nullptr); - vkDestroyRenderPass(Vulkan::GetDevice(), renderPass, nullptr); + std::vector framebuffersCpy = framebuffers; + VkRenderPass renderPassCpy = renderPass; + Vulkan::GetDevice().QueueIdleCommand([framebuffersCpy, renderPassCpy]() { + for (auto& framebuffer : framebuffersCpy) + vkDestroyFramebuffer(Vulkan::GetDevice(), framebuffer, nullptr); + vkDestroyRenderPass(Vulkan::GetDevice(), renderPassCpy, nullptr); + }); } void Framebuffer::Resize(uint32_t width, uint32_t height) { - vkDeviceWaitIdle(Vulkan::GetDevice()); + Vulkan::GetDevice().WaitIdle(); this->width = width; this->height = height; for (auto&& framebuffer : framebuffers) diff --git a/CopiumEngine/src/copium/buffer/UniformBuffer.cpp b/CopiumEngine/src/copium/buffer/UniformBuffer.cpp index 2c00b54..c3c47db 100644 --- a/CopiumEngine/src/copium/buffer/UniformBuffer.cpp +++ b/CopiumEngine/src/copium/buffer/UniformBuffer.cpp @@ -23,7 +23,11 @@ namespace Copium { CP_ASSERT(binding.GetUniformType(str) == UniformType::Mat3, "Uniform type missmatch = %s", str.c_str()); uint32_t offset = binding.GetUniformOffset(str); - memcpy(buffer.data() + offset, &data, sizeof(glm::mat3)); + // memcpy(buffer.data() + offset, &data[0], sizeof(glm::vec3)); + // memcpy(buffer.data() + offset + 16, &data[1], sizeof(glm::vec3)); + // memcpy(buffer.data() + offset + 32, &data[2], sizeof(glm::vec3)); + glm::mat4x3 mat43{data}; + memcpy(buffer.data() + offset, &mat43, sizeof(glm::mat4x3)); } void UniformBuffer::Set(const std::string& str, const glm::mat4& data) diff --git a/CopiumEngine/src/copium/core/Device.cpp b/CopiumEngine/src/copium/core/Device.cpp index 0d82f59..b872529 100644 --- a/CopiumEngine/src/copium/core/Device.cpp +++ b/CopiumEngine/src/copium/core/Device.cpp @@ -65,6 +65,29 @@ namespace Copium CP_ABORT("Failed to find suitable memory type"); } + void Device::WaitIdle() + { + vkDeviceWaitIdle(device); + while (!idleCommands.empty()) + { + idleCommands.front()(); + idleCommands.pop(); + } + } + + void Device::WaitIdleIfCommandQueued() + { + if (!idleCommands.empty()) + { + WaitIdle(); + } + } + + void Device::QueueIdleCommand(std::function idleCommand) + { + idleCommands.emplace(idleCommand); + } + void Device::SelectPhysicalDevice() { uint32_t deviceCount; diff --git a/CopiumEngine/src/copium/core/Device.h b/CopiumEngine/src/copium/core/Device.h index 7c0a5ab..baab080 100644 --- a/CopiumEngine/src/copium/core/Device.h +++ b/CopiumEngine/src/copium/core/Device.h @@ -4,6 +4,8 @@ #include "copium/util/Common.h" #include +#include +#include namespace Copium { @@ -11,18 +13,6 @@ namespace Copium class Device { CP_DELETE_COPY_AND_MOVE_CTOR(Device); - private: - VkPhysicalDevice physicalDevice; - VkDevice device; - VkCommandPool commandPool; - - // TODO: Move to SwapChain? - uint32_t graphicsQueueIndex; - uint32_t presentQueueIndex; - VkQueue graphicsQueue; - VkQueue presentQueue; - // TODO end - public: Device(); ~Device(); @@ -35,6 +25,23 @@ namespace Copium VkPhysicalDevice GetPhysicalDevice() const; operator VkDevice() const; uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties); + void WaitIdle(); + void WaitIdleIfCommandQueued(); + void QueueIdleCommand(std::function idleCommand); + + private: + VkPhysicalDevice physicalDevice; + VkDevice device; + VkCommandPool commandPool; + + // TODO: Move to SwapChain? + uint32_t graphicsQueueIndex; + uint32_t presentQueueIndex; + VkQueue graphicsQueue; + VkQueue presentQueue; + std::queue> idleCommands; + // TODO end + private: void SelectPhysicalDevice(); diff --git a/CopiumEngine/src/copium/core/SwapChain.cpp b/CopiumEngine/src/copium/core/SwapChain.cpp index f71166d..63b9053 100644 --- a/CopiumEngine/src/copium/core/SwapChain.cpp +++ b/CopiumEngine/src/copium/core/SwapChain.cpp @@ -179,7 +179,7 @@ namespace Copium glfwWaitEvents(); } - vkDeviceWaitIdle(Vulkan::GetDevice()); + Vulkan::GetDevice().WaitIdle(); Destroy(); diff --git a/CopiumEngine/src/copium/core/Vulkan.cpp b/CopiumEngine/src/copium/core/Vulkan.cpp index 1dd02c8..dff51b3 100644 --- a/CopiumEngine/src/copium/core/Vulkan.cpp +++ b/CopiumEngine/src/copium/core/Vulkan.cpp @@ -16,6 +16,7 @@ namespace Copium std::unique_ptr Vulkan::swapChain; std::unique_ptr Vulkan::imGuiInstance; AssetHandle Vulkan::emptyTexture2D; + AssetHandle Vulkan::whiteTexture2D; void Vulkan::Initialize() { @@ -39,16 +40,19 @@ namespace Copium // By looking at where the executable is, since that should always be in the bin folder (it currently isn't though) AssetManager::RegisterAssetDir("assets/"); emptyTexture2D = AssetHandle{"empty_texture2d", std::make_unique(std::vector{255, 0, 255, 255}, 1, 1, SamplerCreator{})}; + whiteTexture2D = AssetHandle{"white_texture2d", std::make_unique(std::vector{255, 255, 255, 255}, 1, 1, SamplerCreator{})}; CP_INFO("Initialized AssetManager in %f seconds", timer.Elapsed()); } void Vulkan::Destroy() { emptyTexture2D.UnloadAsset(); + whiteTexture2D.UnloadAsset(); AssetManager::UnregisterAssetDir("assets/"); AssetManager::Cleanup(); imGuiInstance.reset(); swapChain.reset(); + device->WaitIdle(); device.reset(); window.reset(); instance.reset(); @@ -79,6 +83,11 @@ namespace Copium return *imGuiInstance; } + AssetHandle Vulkan::GetWhiteTexture2D() + { + return whiteTexture2D; + } + AssetHandle Vulkan::GetEmptyTexture2D() { return emptyTexture2D; diff --git a/CopiumEngine/src/copium/core/Vulkan.h b/CopiumEngine/src/copium/core/Vulkan.h index 87c5e2c..a6288a5 100644 --- a/CopiumEngine/src/copium/core/Vulkan.h +++ b/CopiumEngine/src/copium/core/Vulkan.h @@ -24,6 +24,7 @@ namespace Copium static std::unique_ptr imGuiInstance; static AssetHandle emptyTexture2D; + static AssetHandle whiteTexture2D; public: static void Initialize(); static void Destroy(); @@ -33,6 +34,7 @@ namespace Copium static SwapChain& GetSwapChain(); static ImGuiInstance& GetImGuiInstance(); static bool Valid(); + static AssetHandle GetWhiteTexture2D(); static AssetHandle GetEmptyTexture2D(); }; } \ No newline at end of file diff --git a/CopiumEngine/src/copium/pipeline/DescriptorPool.cpp b/CopiumEngine/src/copium/pipeline/DescriptorPool.cpp index 4a6fec7..8ca9b57 100644 --- a/CopiumEngine/src/copium/pipeline/DescriptorPool.cpp +++ b/CopiumEngine/src/copium/pipeline/DescriptorPool.cpp @@ -25,7 +25,10 @@ namespace Copium DescriptorPool::~DescriptorPool() { - vkDestroyDescriptorPool(Vulkan::GetDevice(), descriptorPool, nullptr); + VkDescriptorPool descriptorPoolCpy = descriptorPool; + Vulkan::GetDevice().QueueIdleCommand([descriptorPoolCpy]() { + vkDestroyDescriptorPool(Vulkan::GetDevice(), descriptorPoolCpy, nullptr); + }); } std::vector DescriptorPool::AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout) @@ -45,7 +48,11 @@ namespace Copium void DescriptorPool::FreeDescriptorSets(const std::vector& descriptorSets) { - vkFreeDescriptorSets(Vulkan::GetDevice(), descriptorPool, descriptorSets.size(), descriptorSets.data()); + VkDescriptorPool descriptorPoolCpy = descriptorPool; + std::vector descriptorSetsCpy = descriptorSets; + Vulkan::GetDevice().QueueIdleCommand([descriptorPoolCpy, descriptorSetsCpy]() { + vkFreeDescriptorSets(Vulkan::GetDevice(), descriptorPoolCpy, descriptorSetsCpy.size(), descriptorSetsCpy.data()); + }); } DescriptorPool::operator VkDescriptorPool() const diff --git a/CopiumEngine/src/copium/pipeline/Pipeline.cpp b/CopiumEngine/src/copium/pipeline/Pipeline.cpp index f2cd628..32e47bd 100644 --- a/CopiumEngine/src/copium/pipeline/Pipeline.cpp +++ b/CopiumEngine/src/copium/pipeline/Pipeline.cpp @@ -44,11 +44,13 @@ namespace Copium { creator.SetVertexDescriptor(Vertex::GetDescriptor()); creator.SetBlending(metaFileClass.GetValue("alpha-blending", "false") == "true" ? true : false); + creator.SetDepthTest(metaFileClass.GetValue("depth-test", "true") == "true" ? true : false); } else if (type == "LineRenderer") { creator.SetVertexDescriptor(LineVertex::GetDescriptor()); creator.SetPrimitiveTopology(VK_PRIMITIVE_TOPOLOGY_LINE_LIST); + creator.SetDepthTest(metaFileClass.GetValue("depth-test", "false") == "true" ? true : false); } InitializeDescriptorSetLayout(creator); InitializePipeline(creator); @@ -63,12 +65,17 @@ namespace Copium Pipeline::~Pipeline() { - vkDestroyPipeline(Vulkan::GetDevice(), graphicsPipeline, nullptr); - vkDestroyPipelineLayout(Vulkan::GetDevice(), pipelineLayout, nullptr); - for (auto&& descriptorSetLayout : descriptorSetLayouts) - { - vkDestroyDescriptorSetLayout(Vulkan::GetDevice(), descriptorSetLayout, nullptr); - } + VkPipeline graphicsPipelineCpy = graphicsPipeline; + VkPipelineLayout pipelineLayoutCpy = pipelineLayout; + std::vector descriptorSetLayoutsCpy = descriptorSetLayouts; + Vulkan::GetDevice().QueueIdleCommand([graphicsPipelineCpy, pipelineLayoutCpy, descriptorSetLayoutsCpy]() { + vkDestroyPipeline(Vulkan::GetDevice(), graphicsPipelineCpy, nullptr); + vkDestroyPipelineLayout(Vulkan::GetDevice(), pipelineLayoutCpy, nullptr); + for (auto&& descriptorSetLayout : descriptorSetLayoutsCpy) + { + vkDestroyDescriptorSetLayout(Vulkan::GetDevice(), descriptorSetLayout, nullptr); + } + }); } void Pipeline::Bind(const CommandBuffer& commandBuffer) diff --git a/CopiumEngine/src/copium/pipeline/Shader.cpp b/CopiumEngine/src/copium/pipeline/Shader.cpp index 86cfa9f..447947a 100644 --- a/CopiumEngine/src/copium/pipeline/Shader.cpp +++ b/CopiumEngine/src/copium/pipeline/Shader.cpp @@ -46,8 +46,12 @@ namespace Copium Shader::~Shader() { - vkDestroyShaderModule(Vulkan::GetDevice(), vertShaderModule, nullptr); - vkDestroyShaderModule(Vulkan::GetDevice(), fragShaderModule, nullptr); + VkShaderModule vertShaderModuleCpy = vertShaderModule; + VkShaderModule fragShaderModuleCpy = fragShaderModule; + Vulkan::GetDevice().QueueIdleCommand([vertShaderModuleCpy, fragShaderModuleCpy]() { + vkDestroyShaderModule(Vulkan::GetDevice(), vertShaderModuleCpy, nullptr); + vkDestroyShaderModule(Vulkan::GetDevice(), fragShaderModuleCpy, nullptr); + }); } const std::vector Shader::GetShaderStages() const diff --git a/CopiumEngine/src/copium/renderer/Renderer.cpp b/CopiumEngine/src/copium/renderer/Renderer.cpp index 1fd6c93..dbda03b 100644 --- a/CopiumEngine/src/copium/renderer/Renderer.cpp +++ b/CopiumEngine/src/copium/renderer/Renderer.cpp @@ -12,10 +12,10 @@ namespace Copium static constexpr int MAX_NUM_INDICES = 6 * MAX_NUM_QUADS; static constexpr int MAX_NUM_TEXTURES = 32; - Renderer::Renderer() + Renderer::Renderer(const AssetRef& pipeline) : descriptorPool{}, ibo{MAX_NUM_INDICES}, - pipeline{"renderer.meta"}, // TODO: should be a runtime renderer pipeline or passed in constructor + pipeline{pipeline}, samplers{MAX_NUM_TEXTURES, &Vulkan::GetEmptyTexture2D().GetAsset()} { InitializeIndexBuffer(); diff --git a/CopiumEngine/src/copium/renderer/Renderer.h b/CopiumEngine/src/copium/renderer/Renderer.h index bdbc327..0c0d798 100644 --- a/CopiumEngine/src/copium/renderer/Renderer.h +++ b/CopiumEngine/src/copium/renderer/Renderer.h @@ -33,7 +33,7 @@ namespace Copium int textureCount; void* mappedVertexBuffer; public: - Renderer(); + Renderer(const AssetRef& pipeline); ~Renderer(); void Quad(const glm::vec2& from, const glm::vec2& to, const glm::vec3& color = glm::vec3{1, 1, 1}); diff --git a/CopiumEngine/src/copium/sampler/ColorAttachment.cpp b/CopiumEngine/src/copium/sampler/ColorAttachment.cpp index 914b24f..00163ed 100644 --- a/CopiumEngine/src/copium/sampler/ColorAttachment.cpp +++ b/CopiumEngine/src/copium/sampler/ColorAttachment.cpp @@ -39,12 +39,17 @@ namespace Copium ColorAttachment::~ColorAttachment() { - for (auto&& image : images) - vkDestroyImage(Vulkan::GetDevice(), image, nullptr); - for (auto&& imageMemory : imageMemories) - vkFreeMemory(Vulkan::GetDevice(), imageMemory, nullptr); - for (auto&& imageView : imageViews) - vkDestroyImageView(Vulkan::GetDevice(), imageView, nullptr); + std::vector imagesCpy = images; + std::vector imageMemoriesCpy = imageMemories; + std::vector imageViewsCpy = imageViews; + Vulkan::GetDevice().QueueIdleCommand([imagesCpy, imageMemoriesCpy, imageViewsCpy]() { + for (auto&& image : imagesCpy) + vkDestroyImage(Vulkan::GetDevice(), image, nullptr); + for (auto&& imageMemory : imageMemoriesCpy) + vkFreeMemory(Vulkan::GetDevice(), imageMemory, nullptr); + for (auto&& imageView : imageViewsCpy) + vkDestroyImageView(Vulkan::GetDevice(), imageView, nullptr); + }); } void ColorAttachment::Resize(int width, int height) diff --git a/CopiumEngine/src/copium/sampler/DepthAttachment.cpp b/CopiumEngine/src/copium/sampler/DepthAttachment.cpp index 5e6d169..ff3ad7e 100644 --- a/CopiumEngine/src/copium/sampler/DepthAttachment.cpp +++ b/CopiumEngine/src/copium/sampler/DepthAttachment.cpp @@ -13,9 +13,14 @@ namespace Copium DepthAttachment::~DepthAttachment() { - vkDestroyImage(Vulkan::GetDevice(), image, nullptr); - vkFreeMemory(Vulkan::GetDevice(), imageMemory, nullptr); - vkDestroyImageView(Vulkan::GetDevice(), imageView, nullptr); + VkImage imageCpy = image; + VkDeviceMemory imageMemoryCpy = imageMemory; + VkImageView imageViewCpy = imageView; + Vulkan::GetDevice().QueueIdleCommand([imageCpy, imageMemoryCpy, imageViewCpy]() { + vkDestroyImage(Vulkan::GetDevice(), imageCpy, nullptr); + vkFreeMemory(Vulkan::GetDevice(), imageMemoryCpy, nullptr); + vkDestroyImageView(Vulkan::GetDevice(), imageViewCpy, nullptr); + }); } diff --git a/CopiumEngine/src/copium/sampler/Font.cpp b/CopiumEngine/src/copium/sampler/Font.cpp index 94e1834..ba2a49e 100644 --- a/CopiumEngine/src/copium/sampler/Font.cpp +++ b/CopiumEngine/src/copium/sampler/Font.cpp @@ -75,9 +75,14 @@ namespace Copium Font::~Font() { - vkDestroyImage(Vulkan::GetDevice(), image, nullptr); - vkFreeMemory(Vulkan::GetDevice(), imageMemory, nullptr); - vkDestroyImageView(Vulkan::GetDevice(), imageView, nullptr); + VkImage imageCpy = image; + VkDeviceMemory imageMemoryCpy = imageMemory; + VkImageView imageViewCpy = imageView; + Vulkan::GetDevice().QueueIdleCommand([imageCpy, imageMemoryCpy, imageViewCpy]() { + vkDestroyImage(Vulkan::GetDevice(), imageCpy, nullptr); + vkFreeMemory(Vulkan::GetDevice(), imageMemoryCpy, nullptr); + vkDestroyImageView(Vulkan::GetDevice(), imageViewCpy, nullptr); + }); } VkDescriptorImageInfo Font::GetDescriptorImageInfo(int index) const diff --git a/CopiumEngine/src/copium/sampler/Sampler.cpp b/CopiumEngine/src/copium/sampler/Sampler.cpp index 1e454c3..0c01d5a 100644 --- a/CopiumEngine/src/copium/sampler/Sampler.cpp +++ b/CopiumEngine/src/copium/sampler/Sampler.cpp @@ -11,7 +11,10 @@ namespace Copium Sampler::~Sampler() { - vkDestroySampler(Vulkan::GetDevice(), sampler, nullptr); + VkSampler samplerCpy = sampler; + Vulkan::GetDevice().QueueIdleCommand([samplerCpy]() { + vkDestroySampler(Vulkan::GetDevice(), samplerCpy, nullptr); + }); } void Sampler::InitializeSampler(const SamplerCreator& samplerCreator) diff --git a/CopiumEngine/src/copium/sampler/Texture2D.cpp b/CopiumEngine/src/copium/sampler/Texture2D.cpp index 8604965..87af066 100644 --- a/CopiumEngine/src/copium/sampler/Texture2D.cpp +++ b/CopiumEngine/src/copium/sampler/Texture2D.cpp @@ -27,13 +27,14 @@ namespace Copium Texture2D::~Texture2D() { - // TODO: Do we want to queue the deletion and have it wait for idle once every frame instead? - // Something like: - // Vulkan::GetDevice().QueueIdleCommand([]() { Texture2D::Destroy(image, imageMemory, imageView); }); - vkDeviceWaitIdle(Vulkan::GetDevice()); - vkDestroyImage(Vulkan::GetDevice(), image, nullptr); - vkFreeMemory(Vulkan::GetDevice(), imageMemory, nullptr); - vkDestroyImageView(Vulkan::GetDevice(), imageView, nullptr); + VkImage imageCpy = image; + VkDeviceMemory imageMemoryCpy = imageMemory; + VkImageView imageViewCpy = imageView; + Vulkan::GetDevice().QueueIdleCommand([imageCpy, imageMemoryCpy, imageViewCpy]() { + vkDestroyImage(Vulkan::GetDevice(), imageCpy, nullptr); + vkFreeMemory(Vulkan::GetDevice(), imageMemoryCpy, nullptr); + vkDestroyImageView(Vulkan::GetDevice(), imageViewCpy, nullptr); + }); } VkDescriptorImageInfo Texture2D::GetDescriptorImageInfo(int index) const