From e637ccf84be322fdfd3dee6e60aa873a26b9c82f Mon Sep 17 00:00:00 2001 From: Tobias Frisch <tfrisch@uni-koblenz.de> Date: Tue, 1 Jun 2021 17:27:22 +0200 Subject: [PATCH] [#62] Added magic to free resources if unused and out of scope! Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de> --- include/vkcv/BufferManager.hpp | 16 ++++----- include/vkcv/Core.hpp | 11 +++--- include/vkcv/Handles.hpp | 32 +++++++++++++---- include/vkcv/Image.hpp | 5 +-- src/vkcv/BufferManager.cpp | 8 ++--- src/vkcv/Core.cpp | 28 ++++++++------- src/vkcv/DescriptorManager.cpp | 26 ++++++++++---- src/vkcv/DescriptorManager.hpp | 5 +-- src/vkcv/Handles.cpp | 66 +++++++++++++++++++++++++++++++--- src/vkcv/Image.cpp | 14 +++----- src/vkcv/ImageManager.cpp | 46 ++++++++++++++++++++---- src/vkcv/ImageManager.hpp | 25 ++++++++----- src/vkcv/PassManager.cpp | 27 +++++++++----- src/vkcv/PassManager.hpp | 4 ++- src/vkcv/PipelineManager.cpp | 63 ++++++++++++++++++++++---------- src/vkcv/PipelineManager.hpp | 12 +++++-- src/vkcv/SamplerManager.cpp | 8 ++--- src/vkcv/SamplerManager.hpp | 4 +-- 18 files changed, 288 insertions(+), 112 deletions(-) diff --git a/include/vkcv/BufferManager.hpp b/include/vkcv/BufferManager.hpp index 322873b3..a390a2ff 100644 --- a/include/vkcv/BufferManager.hpp +++ b/include/vkcv/BufferManager.hpp @@ -44,6 +44,14 @@ namespace vkcv void init(); + /** + * Destroys and deallocates buffer represented by a given + * buffer handle id. + * + * @param id Buffer handle id + */ + void destroyBufferById(uint64_t id); + public: ~BufferManager() noexcept; @@ -123,14 +131,6 @@ namespace vkcv * @param handle Buffer handle */ void unmapBuffer(const BufferHandle& handle); - - /** - * Destroys and deallocates buffer represented by a given - * buffer handle. - * - * @param handle Buffer handle - */ - void destroyBuffer(const BufferHandle& handle); }; diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index cf75b8e7..ea9b5c77 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -21,6 +21,7 @@ #include "vkcv/DescriptorConfig.hpp" #include "Sampler.hpp" #include "DescriptorWrites.hpp" +#include "Event.hpp" namespace vkcv { @@ -43,8 +44,8 @@ namespace vkcv std::vector<vk::Semaphore> signalSemaphores; }; - typedef std::function<void(const vk::CommandBuffer& cmdBuffer)> RecordCommandFunction; - typedef std::function<void(void)> FinishCommandFunction; + typedef typename event_function<const vk::CommandBuffer&>::type RecordCommandFunction; + typedef typename event_function<>::type FinishCommandFunction; class Core final { @@ -80,6 +81,8 @@ namespace vkcv SyncResources m_SyncResources; uint32_t m_currentSwapchainImageIndex; std::vector<vk::Framebuffer> m_TemporaryFramebuffers; + + ImageHandle m_DepthImage; /** * recreates the swapchain @@ -229,8 +232,8 @@ namespace vkcv void renderMesh( const PassHandle renderpassHandle, const PipelineHandle pipelineHandle, - const int width, - const int height, + const uint32_t width, + const uint32_t height, const size_t pushConstantSize, const void* pushConstantData, const std::vector<VertexBufferBinding> &vertexBufferBindings, diff --git a/include/vkcv/Handles.hpp b/include/vkcv/Handles.hpp index 58f795f0..86cd5555 100644 --- a/include/vkcv/Handles.hpp +++ b/include/vkcv/Handles.hpp @@ -7,31 +7,51 @@ #include <iostream> +#include "Event.hpp" + namespace vkcv { + typedef typename event_function<uint64_t>::type HandleDestroyFunction; + class Handle { friend std::ostream& operator << (std::ostream& out, const Handle& handle); private: uint64_t m_id; + uint64_t* m_rc; + + HandleDestroyFunction m_destroy; protected: Handle(); - explicit Handle(uint64_t id); + explicit Handle(uint64_t id, const HandleDestroyFunction& destroy = nullptr); + /** + * Returns the actual handle id of a handle. + * + * @return Handle id + */ [[nodiscard]] uint64_t getId() const; + + /** + * Returns the reference counter of a handle + * + * @return Reference counter + */ + [[nodiscard]] + uint64_t getRC() const; public: - virtual ~Handle() = default; + virtual ~Handle(); - Handle(const Handle& other) = default; - Handle(Handle&& other) = default; + Handle(const Handle& other); + Handle(Handle&& other) noexcept; - Handle& operator=(const Handle& other) = default; - Handle& operator=(Handle&& other) = default; + Handle& operator=(const Handle& other); + Handle& operator=(Handle&& other) noexcept; explicit operator bool() const; bool operator!() const; diff --git a/include/vkcv/Image.hpp b/include/vkcv/Image.hpp index d56fac9c..d76bd121 100644 --- a/include/vkcv/Image.hpp +++ b/include/vkcv/Image.hpp @@ -39,12 +39,9 @@ namespace vkcv { ImageManager* const m_manager; const ImageHandle m_handle; const vk::Format m_format; - const uint32_t m_width; - const uint32_t m_height; - const uint32_t m_depth; vk::ImageLayout m_layout; - Image(ImageManager* manager, const ImageHandle& handle, vk::Format format, uint32_t width, uint32_t height, uint32_t depth); + Image(ImageManager* manager, const ImageHandle& handle, vk::Format format); static Image create(ImageManager* manager, vk::Format format, uint32_t width, uint32_t height, uint32_t depth); diff --git a/src/vkcv/BufferManager.cpp b/src/vkcv/BufferManager.cpp index ab34a3df..ef874606 100644 --- a/src/vkcv/BufferManager.cpp +++ b/src/vkcv/BufferManager.cpp @@ -23,7 +23,7 @@ namespace vkcv { BufferManager::~BufferManager() noexcept { for (uint64_t id = 0; id < m_buffers.size(); id++) { - destroyBuffer(BufferHandle(id)); + destroyBufferById(id); } } @@ -119,7 +119,7 @@ namespace vkcv { const uint64_t id = m_buffers.size(); m_buffers.push_back({ buffer, memory, size, nullptr, mappable }); - return BufferHandle{ id }; + return BufferHandle(id, [&](uint64_t id) { destroyBufferById(id); }); } struct StagingStepInfo { @@ -315,9 +315,7 @@ namespace vkcv { buffer.m_mapped = nullptr; } - void BufferManager::destroyBuffer(const BufferHandle& handle) { - const uint64_t id = handle.getId(); - + void BufferManager::destroyBufferById(uint64_t id) { if (id >= m_buffers.size()) { return; } diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index 0b0d3a24..720b89c2 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -176,8 +176,8 @@ namespace vkcv void Core::renderMesh( const PassHandle renderpassHandle, const PipelineHandle pipelineHandle, - const int width, - const int height, + const uint32_t width, + const uint32_t height, const size_t pushConstantSize, const void *pushConstantData, const std::vector<VertexBufferBinding>& vertexBufferBindings, @@ -194,12 +194,18 @@ namespace vkcv const vk::RenderPass renderpass = m_PassManager->getVkPass(renderpassHandle); const PassConfig passConfig = m_PassManager->getPassConfig(renderpassHandle); - ImageHandle depthImage; + const bool checkForDepthImage = ( + (!m_DepthImage) || + (width != m_ImageManager->getImageWidth(m_DepthImage)) || + (height != m_ImageManager->getImageHeight(m_DepthImage)) + ); - for (const auto& attachment : passConfig.attachments) { - if (attachment.layout_final == AttachmentLayout::DEPTH_STENCIL_ATTACHMENT) { - depthImage = m_ImageManager->createImage(width, height, 1, attachment.format); - break; + if (checkForDepthImage) { + for (const auto &attachment : passConfig.attachments) { + if (attachment.layout_final == AttachmentLayout::DEPTH_STENCIL_ATTACHMENT) { + m_DepthImage = m_ImageManager->createImage(width, height, 1, attachment.format); + break; + } } } @@ -212,8 +218,8 @@ namespace vkcv std::vector<vk::ImageView> attachments; attachments.push_back(imageView); - if (depthImage) { - attachments.push_back(m_ImageManager->getVulkanImageView(depthImage)); + if (m_DepthImage) { + attachments.push_back(m_ImageManager->getVulkanImageView(m_DepthImage)); } const vk::Framebuffer framebuffer = createFramebuffer( @@ -273,9 +279,7 @@ namespace vkcv cmdBuffer.pushConstants(pipelineLayout, vk::ShaderStageFlagBits::eAll, 0, pushConstantSize, pushConstantData); cmdBuffer.drawIndexed(indexCount, 1, 0, 0, {}); cmdBuffer.endRenderPass(); - }, [&]() { - m_ImageManager->destroyImage(depthImage); - }); + }, nullptr); } void Core::endFrame() { diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index cf689b44..5f1be539 100644 --- a/src/vkcv/DescriptorManager.cpp +++ b/src/vkcv/DescriptorManager.cpp @@ -8,7 +8,7 @@ namespace vkcv descriptorSetLayouts{std::move(layouts)} {} DescriptorManager::DescriptorManager(vk::Device device) noexcept: - m_Device{ device }, m_NextResourceDescriptionID{ 0 } + m_Device{ device } { /** * Allocate a set size for the initial pool, namely 1000 units of each descriptor type below. @@ -32,11 +32,10 @@ namespace vkcv DescriptorManager::~DescriptorManager() noexcept { - for(const auto &resource : m_ResourceDescriptions) - { - for(const auto &layout : resource.descriptorSetLayouts) - m_Device.destroyDescriptorSetLayout(layout); + for (uint64_t id = 0; id < m_ResourceDescriptions.size(); id++) { + destroyResourceDescriptionById(id); } + m_Device.destroy(m_Pool); } @@ -82,8 +81,9 @@ namespace vkcv return ResourcesHandle(); }; + const uint64_t id = m_ResourceDescriptions.size(); m_ResourceDescriptions.emplace_back(vk_sets, vk_setLayouts); - return ResourcesHandle(m_NextResourceDescriptionID++); + return ResourcesHandle(id, [&](uint64_t id) { destroyResourceDescriptionById(id); }); } struct WriteDescriptorSetInfo { @@ -270,5 +270,19 @@ namespace vkcv return vk::ShaderStageFlagBits::eAll; } } + + void DescriptorManager::destroyResourceDescriptionById(uint64_t id) { + if (id >= m_ResourceDescriptions.size()) { + return; + } + + auto& resourceDescription = m_ResourceDescriptions[id]; + + for(const auto &layout : resourceDescription.descriptorSetLayouts) { + m_Device.destroyDescriptorSetLayout(layout); + } + + resourceDescription.descriptorSetLayouts.clear(); + } } \ No newline at end of file diff --git a/src/vkcv/DescriptorManager.hpp b/src/vkcv/DescriptorManager.hpp index 937fb278..8063277d 100644 --- a/src/vkcv/DescriptorManager.hpp +++ b/src/vkcv/DescriptorManager.hpp @@ -58,8 +58,6 @@ namespace vkcv * Contains all the resource descriptions that were requested by the user in calls of createResourceDescription. */ std::vector<ResourceDescription> m_ResourceDescriptions; - // Counter for the vector above - uint64_t m_NextResourceDescriptionID; /** * Converts the flags of the descriptor types from VulkanCV (vkcv) to Vulkan (vk). @@ -73,5 +71,8 @@ namespace vkcv * @return vk flag of the ShaderStage */ static vk::ShaderStageFlagBits convertShaderStageFlag(ShaderStage stage); + + void destroyResourceDescriptionById(uint64_t id); + }; } \ No newline at end of file diff --git a/src/vkcv/Handles.cpp b/src/vkcv/Handles.cpp index bd465d4e..4a00121f 100644 --- a/src/vkcv/Handles.cpp +++ b/src/vkcv/Handles.cpp @@ -3,17 +3,75 @@ namespace vkcv { Handle::Handle() : - m_id(UINT64_MAX) + m_id(UINT64_MAX), m_rc(nullptr), m_destroy(nullptr) {} - Handle::Handle(uint64_t id) : - m_id(id) + Handle::Handle(uint64_t id, const HandleDestroyFunction& destroy) : + m_id(id), m_rc(new uint64_t(1)), m_destroy(destroy) {} + Handle::~Handle() { + if ((m_rc) && (--(*m_rc) == 0)) { + if (m_destroy) { + m_destroy(m_id); + } + + delete m_rc; + } + } + + Handle::Handle(const Handle &other) : + m_id(other.m_id), + m_rc(other.m_rc), + m_destroy(other.m_destroy) + { + if (m_rc) { + ++(*m_rc); + } + } + + Handle::Handle(Handle &&other) noexcept : + m_id(other.m_id), + m_rc(other.m_rc), + m_destroy(other.m_destroy) + { + other.m_rc = nullptr; + } + + Handle &Handle::operator=(const Handle &other) { + if (&other == this) { + return *this; + } + + m_id = other.m_id; + m_rc = other.m_rc; + m_destroy = other.m_destroy; + + if (m_rc) { + ++(*m_rc); + } + + return *this; + } + + Handle &Handle::operator=(Handle &&other) noexcept { + m_id = other.m_id; + m_rc = other.m_rc; + m_destroy = other.m_destroy; + + other.m_rc = nullptr; + + return *this; + } + uint64_t Handle::getId() const { return m_id; } + uint64_t Handle::getRC() const { + return m_rc? *m_rc : 0; + } + Handle::operator bool() const { return (m_id < UINT64_MAX); } @@ -24,7 +82,7 @@ namespace vkcv { std::ostream& operator << (std::ostream& out, const Handle& handle) { if (handle) { - return out << "[Handle: " << handle.getId() << "]"; + return out << "[Handle: " << handle.getId() << ":" << handle.getRC() << "]"; } else { return out << "[Handle: none]"; } diff --git a/src/vkcv/Image.cpp b/src/vkcv/Image.cpp index 7104f784..9ce5c25a 100644 --- a/src/vkcv/Image.cpp +++ b/src/vkcv/Image.cpp @@ -10,7 +10,7 @@ namespace vkcv{ Image Image::create(ImageManager* manager, vk::Format format, uint32_t width, uint32_t height, uint32_t depth) { - return Image(manager, manager->createImage(width, height, depth, format), format, width, height, depth); + return Image(manager, manager->createImage(width, height, depth, format), format); } vk::Format Image::getFormat() const { @@ -18,15 +18,15 @@ namespace vkcv{ } uint32_t Image::getWidth() const { - return m_width; + return m_manager->getImageWidth(m_handle); } uint32_t Image::getHeight() const { - return m_height; + return m_manager->getImageHeight(m_handle); } uint32_t Image::getDepth() const { - return m_depth; + return m_manager->getImageDepth(m_handle); } vk::ImageLayout Image::getLayout() const { @@ -47,14 +47,10 @@ namespace vkcv{ m_manager->fillImage(m_handle, data, size); } - Image::Image(ImageManager* manager, const ImageHandle& handle, - vk::Format format, uint32_t width, uint32_t height, uint32_t depth) : + Image::Image(ImageManager* manager, const ImageHandle& handle, vk::Format format) : m_manager(manager), m_handle(handle), m_format(format), - m_width(width), - m_height(height), - m_depth(depth), m_layout(vk::ImageLayout::eUndefined) { } diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp index 3896d6bc..d3eb9cc5 100644 --- a/src/vkcv/ImageManager.cpp +++ b/src/vkcv/ImageManager.cpp @@ -43,7 +43,7 @@ namespace vkcv { ImageManager::~ImageManager() noexcept { for (uint64_t id = 0; id < m_images.size(); id++) { - destroyImage(ImageHandle(id)); + destroyImageById(id); } } @@ -167,7 +167,7 @@ namespace vkcv { const uint64_t id = m_images.size(); m_images.push_back({ image, memory, view, width, height, depth, format, arrayLayers, mipLevels }); - return ImageHandle(id); + return ImageHandle(id, [&](uint64_t id) { destroyImageById(id); }); } vk::Image ImageManager::getVulkanImage(const ImageHandle &handle) const { @@ -359,16 +359,48 @@ namespace vkcv { vk::ImageLayout::eTransferDstOptimal, vk::ImageLayout::eShaderReadOnlyOptimal ); - - m_bufferManager.destroyBuffer(bufferHandle); } ); } - - void ImageManager::destroyImage(const ImageHandle& handle) - { + + uint32_t ImageManager::getImageWidth(const ImageHandle &handle) const { + const uint64_t id = handle.getId(); + + if (id >= m_images.size()) { + return 0; + } + + auto& image = m_images[id]; + + return image.m_width; + } + + uint32_t ImageManager::getImageHeight(const ImageHandle &handle) const { + const uint64_t id = handle.getId(); + + if (id >= m_images.size()) { + return 0; + } + + auto& image = m_images[id]; + + return image.m_height; + } + + uint32_t ImageManager::getImageDepth(const ImageHandle &handle) const { const uint64_t id = handle.getId(); + if (id >= m_images.size()) { + return 0; + } + + auto& image = m_images[id]; + + return image.m_depth; + } + + void ImageManager::destroyImageById(uint64_t id) + { if (id >= m_images.size()) { return; } diff --git a/src/vkcv/ImageManager.hpp b/src/vkcv/ImageManager.hpp index 7dc6746f..4b6e5208 100644 --- a/src/vkcv/ImageManager.hpp +++ b/src/vkcv/ImageManager.hpp @@ -36,6 +36,14 @@ namespace vkcv { ImageManager(BufferManager& bufferManager) noexcept; + /** + * Destroys and deallocates image represented by a given + * image handle id. + * + * @param id Image handle id + */ + void destroyImageById(uint64_t id); + public: ~ImageManager() noexcept; ImageManager(ImageManager&& other) = delete; @@ -57,14 +65,15 @@ namespace vkcv { void switchImageLayout(const ImageHandle& handle, vk::ImageLayout oldLayout, vk::ImageLayout newLayout); void fillImage(const ImageHandle& handle, void* data, size_t size); - - /** - * Destroys and deallocates image represented by a given - * buffer handle. - * - * @param handle Image handle - */ - void destroyImage(const ImageHandle& handle); + + [[nodiscard]] + uint32_t getImageWidth(const ImageHandle& handle) const; + + [[nodiscard]] + uint32_t getImageHeight(const ImageHandle& handle) const; + + [[nodiscard]] + uint32_t getImageDepth(const ImageHandle& handle) const; }; } \ No newline at end of file diff --git a/src/vkcv/PassManager.cpp b/src/vkcv/PassManager.cpp index 26e5f290..8b59495a 100644 --- a/src/vkcv/PassManager.cpp +++ b/src/vkcv/PassManager.cpp @@ -49,17 +49,14 @@ namespace vkcv PassManager::PassManager(vk::Device device) noexcept : m_Device{device}, - m_Passes{}, - m_NextPassId(0) + m_Passes{} {} PassManager::~PassManager() noexcept { - for(const auto &pass : m_Passes) - m_Device.destroy(pass.m_Handle); - - m_Passes.clear(); - m_NextPassId = 0; + for (uint64_t id = 0; id < m_Passes.size(); id++) { + destroyPassById(id); + } } PassHandle PassManager::createPass(const PassConfig &config) @@ -130,8 +127,9 @@ namespace vkcv vk::RenderPass renderPass = m_Device.createRenderPass(passInfo); + const uint64_t id = m_Passes.size(); m_Passes.push_back({ renderPass, config }); - return PassHandle(m_NextPassId++); + return PassHandle(id, [&](uint64_t id) { destroyPassById(id); }); } vk::RenderPass PassManager::getVkPass(const PassHandle &handle) const @@ -160,4 +158,17 @@ namespace vkcv return pass.m_Config; } + void PassManager::destroyPassById(uint64_t id) { + if (id >= m_Passes.size()) { + return; + } + + auto& pass = m_Passes[id]; + + if (pass.m_Handle) { + m_Device.destroy(pass.m_Handle); + pass.m_Handle = nullptr; + } + } + } diff --git a/src/vkcv/PassManager.hpp b/src/vkcv/PassManager.hpp index bfc20fe2..661a8b27 100644 --- a/src/vkcv/PassManager.hpp +++ b/src/vkcv/PassManager.hpp @@ -17,7 +17,9 @@ namespace vkcv vk::Device m_Device; std::vector<Pass> m_Passes; - uint64_t m_NextPassId; + + void destroyPassById(uint64_t id); + public: PassManager() = delete; // no default ctor explicit PassManager(vk::Device device) noexcept; // ctor diff --git a/src/vkcv/PipelineManager.cpp b/src/vkcv/PipelineManager.cpp index 1b0d665e..1b866c05 100644 --- a/src/vkcv/PipelineManager.cpp +++ b/src/vkcv/PipelineManager.cpp @@ -5,22 +5,14 @@ namespace vkcv PipelineManager::PipelineManager(vk::Device device) noexcept : m_Device{device}, - m_Pipelines{}, - m_PipelineLayouts{}, - m_NextPipelineId{0} + m_Pipelines{} {} PipelineManager::~PipelineManager() noexcept { - for(const auto &pipeline: m_Pipelines) - m_Device.destroy(pipeline); - - for(const auto &layout : m_PipelineLayouts) - m_Device.destroy(layout); - - m_Pipelines.clear(); - m_PipelineLayouts.clear(); - m_NextPipelineId = 0; + for (uint64_t id = 0; id < m_Pipelines.size(); id++) { + destroyPipelineById(id); + } } // currently assuming default 32 bit formats, no lower precision or normalized variants supported @@ -252,19 +244,54 @@ namespace vkcv m_Device.destroy(vertexModule); m_Device.destroy(fragmentModule); - - m_Pipelines.push_back(vkPipeline); - m_PipelineLayouts.push_back(vkPipelineLayout); - return PipelineHandle(m_NextPipelineId++); + + const uint64_t id = m_Pipelines.size(); + m_Pipelines.push_back({ vkPipeline, vkPipelineLayout }); + return PipelineHandle(id, [&](uint64_t id) { destroyPipelineById(id); }); } vk::Pipeline PipelineManager::getVkPipeline(const PipelineHandle &handle) const { - return m_Pipelines.at(handle.getId()); + const uint64_t id = handle.getId(); + + if (id >= m_Pipelines.size()) { + return nullptr; + } + + auto& pipeline = m_Pipelines[id]; + + return pipeline.m_handle; } vk::PipelineLayout PipelineManager::getVkPipelineLayout(const PipelineHandle &handle) const { - return m_PipelineLayouts.at(handle.getId()); + const uint64_t id = handle.getId(); + + if (id >= m_Pipelines.size()) { + return nullptr; + } + + auto& pipeline = m_Pipelines[id]; + + return pipeline.m_layout; + } + + void PipelineManager::destroyPipelineById(uint64_t id) { + if (id >= m_Pipelines.size()) { + return; + } + + auto& pipeline = m_Pipelines[id]; + + if (pipeline.m_handle) { + m_Device.destroy(pipeline.m_handle); + pipeline.m_handle = nullptr; + } + + if (pipeline.m_layout) { + m_Device.destroy(pipeline.m_layout); + pipeline.m_layout = nullptr; + } } + } \ No newline at end of file diff --git a/src/vkcv/PipelineManager.hpp b/src/vkcv/PipelineManager.hpp index 896d0df1..950df0be 100644 --- a/src/vkcv/PipelineManager.hpp +++ b/src/vkcv/PipelineManager.hpp @@ -11,10 +11,16 @@ namespace vkcv class PipelineManager { private: + struct Pipeline { + vk::Pipeline m_handle; + vk::PipelineLayout m_layout; + }; + vk::Device m_Device; - std::vector<vk::Pipeline> m_Pipelines; - std::vector<vk::PipelineLayout> m_PipelineLayouts; - uint64_t m_NextPipelineId; + std::vector<Pipeline> m_Pipelines; + + void destroyPipelineById(uint64_t id); + public: PipelineManager() = delete; // no default ctor explicit PipelineManager(vk::Device device) noexcept; // ctor diff --git a/src/vkcv/SamplerManager.cpp b/src/vkcv/SamplerManager.cpp index 7935bbc1..eb44356f 100644 --- a/src/vkcv/SamplerManager.cpp +++ b/src/vkcv/SamplerManager.cpp @@ -10,7 +10,7 @@ namespace vkcv { SamplerManager::~SamplerManager() { for (uint64_t id = 0; id < m_samplers.size(); id++) { - destroySampler(SamplerHandle(id)); + destroySamplerById(id); } } @@ -96,7 +96,7 @@ namespace vkcv { const uint64_t id = m_samplers.size(); m_samplers.push_back(sampler); - return SamplerHandle(id); + return SamplerHandle(id, [&](uint64_t id) { destroySamplerById(id); }); } vk::Sampler SamplerManager::getVulkanSampler(const SamplerHandle &handle) const { @@ -109,9 +109,7 @@ namespace vkcv { return m_samplers[id]; } - void SamplerManager::destroySampler(const SamplerHandle &handle) { - const uint64_t id = handle.getId(); - + void SamplerManager::destroySamplerById(uint64_t id) { if (id >= m_samplers.size()) { return; } diff --git a/src/vkcv/SamplerManager.hpp b/src/vkcv/SamplerManager.hpp index 41f58b2f..511176d4 100644 --- a/src/vkcv/SamplerManager.hpp +++ b/src/vkcv/SamplerManager.hpp @@ -18,6 +18,8 @@ namespace vkcv { explicit SamplerManager(const vk::Device& device) noexcept; + void destroySamplerById(uint64_t id); + public: ~SamplerManager(); @@ -34,8 +36,6 @@ namespace vkcv { [[nodiscard]] vk::Sampler getVulkanSampler(const SamplerHandle& handle) const; - - void destroySampler(const SamplerHandle& handle); }; -- GitLab