From 40ecdda3cdd574229cbb6589d62526b48699fcb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Sat, 17 Jul 2021 20:56:36 +0200 Subject: [PATCH] VulkanRenderer: Handle VulkanRenderPass destruction --- .../Nazara/VulkanRenderer/VulkanRenderPass.hpp | 5 ++++- .../VulkanRenderer/VulkanRenderPipeline.hpp | 14 +++++++++++++- src/Nazara/VulkanRenderer/VulkanRenderPass.cpp | 7 ++++++- .../VulkanRenderer/VulkanRenderPipeline.cpp | 15 ++++++++++----- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/include/Nazara/VulkanRenderer/VulkanRenderPass.hpp b/include/Nazara/VulkanRenderer/VulkanRenderPass.hpp index 7b66c1bcb..1973c5f47 100644 --- a/include/Nazara/VulkanRenderer/VulkanRenderPass.hpp +++ b/include/Nazara/VulkanRenderer/VulkanRenderPass.hpp @@ -8,6 +8,7 @@ #define NAZARA_VULKANRENDERER_VULKANRENDERPASS_HPP #include +#include #include #include #include @@ -21,7 +22,7 @@ namespace Nz VulkanRenderPass(Vk::Device& device, std::vector attachments, std::vector subpassDescriptions, std::vector subpassDependencies); VulkanRenderPass(const VulkanRenderPass&) = delete; VulkanRenderPass(VulkanRenderPass&&) noexcept = default; - ~VulkanRenderPass() = default; + ~VulkanRenderPass(); inline Vk::RenderPass& GetRenderPass(); inline const Vk::RenderPass& GetRenderPass() const; @@ -29,6 +30,8 @@ namespace Nz VulkanRenderPass& operator=(const VulkanRenderPass&) = delete; VulkanRenderPass& operator=(VulkanRenderPass&&) noexcept = default; + NazaraSignal(OnRenderPassRelease, const VulkanRenderPass* /*renderPass*/); + private: Vk::RenderPass m_renderPass; }; diff --git a/include/Nazara/VulkanRenderer/VulkanRenderPipeline.hpp b/include/Nazara/VulkanRenderer/VulkanRenderPipeline.hpp index f73a5bf03..ed746db63 100644 --- a/include/Nazara/VulkanRenderer/VulkanRenderPipeline.hpp +++ b/include/Nazara/VulkanRenderer/VulkanRenderPipeline.hpp @@ -27,12 +27,17 @@ namespace Nz struct CreateInfo; VulkanRenderPipeline(VulkanDevice& device, RenderPipelineInfo pipelineInfo); + VulkanRenderPipeline(const VulkanRenderPipeline&) = delete; + VulkanRenderPipeline(VulkanRenderPipeline&&) = delete; ~VulkanRenderPipeline() = default; VkPipeline Get(const VulkanRenderPass& renderPass, std::size_t subpassIndex) const; inline const RenderPipelineInfo& GetPipelineInfo() const override; + VulkanRenderPipeline& operator=(const VulkanRenderPipeline&) = delete; + VulkanRenderPipeline& operator=(VulkanRenderPipeline&&) = delete; + static std::vector BuildColorBlendAttachmentStateList(const RenderPipelineInfo& pipelineInfo); static VkPipelineColorBlendStateCreateInfo BuildColorBlendInfo(const RenderPipelineInfo& pipelineInfo, const std::vector& attachmentState); static VkPipelineDepthStencilStateCreateInfo BuildDepthStencilInfo(const RenderPipelineInfo& pipelineInfo); @@ -81,7 +86,14 @@ namespace Nz inline std::size_t operator()(const std::pair& renderPass) const; }; - mutable std::unordered_map, Vk::Pipeline, PipelineHasher> m_pipelines; + struct PipelineData + { + NazaraSlot(VulkanRenderPass, OnRenderPassRelease, onRenderPassRelease); + + Vk::Pipeline pipeline; + }; + + mutable std::unordered_map, PipelineData, PipelineHasher> m_pipelines; MovablePtr m_device; mutable CreateInfo m_pipelineCreateInfo; RenderPipelineInfo m_pipelineInfo; diff --git a/src/Nazara/VulkanRenderer/VulkanRenderPass.cpp b/src/Nazara/VulkanRenderer/VulkanRenderPass.cpp index 88da30cef..45e121efd 100644 --- a/src/Nazara/VulkanRenderer/VulkanRenderPass.cpp +++ b/src/Nazara/VulkanRenderer/VulkanRenderPass.cpp @@ -10,7 +10,7 @@ namespace Nz { - inline VulkanRenderPass::VulkanRenderPass(Vk::Device& device, std::vector attachments, std::vector subpassDescriptions, std::vector subpassDependencies) : + VulkanRenderPass::VulkanRenderPass(Vk::Device& device, std::vector attachments, std::vector subpassDescriptions, std::vector subpassDependencies) : RenderPass(std::move(attachments), std::move(subpassDescriptions), std::move(subpassDependencies)) { std::size_t totalAttachmentReference = 0; @@ -128,4 +128,9 @@ namespace Nz if (!m_renderPass.Create(device, renderPassInfo)) throw std::runtime_error("failed to instantiate Vulkan render pass: " + TranslateVulkanError(m_renderPass.GetLastErrorCode())); } + + VulkanRenderPass::~VulkanRenderPass() + { + OnRenderPassRelease(this); + } } diff --git a/src/Nazara/VulkanRenderer/VulkanRenderPipeline.cpp b/src/Nazara/VulkanRenderer/VulkanRenderPipeline.cpp index 5afc9e537..0f538ffac 100644 --- a/src/Nazara/VulkanRenderer/VulkanRenderPipeline.cpp +++ b/src/Nazara/VulkanRenderer/VulkanRenderPipeline.cpp @@ -35,19 +35,24 @@ namespace Nz std::pair key = { renderPassHandle, colorAttachmentCount }; if (auto it = m_pipelines.find(key); it != m_pipelines.end()) - return it->second; + return it->second.pipeline; UpdateCreateInfo(colorAttachmentCount); VkGraphicsPipelineCreateInfo pipelineCreateInfo = m_pipelineCreateInfo.pipelineInfo; pipelineCreateInfo.renderPass = renderPassHandle; - Vk::Pipeline newPipeline; - if (!newPipeline.CreateGraphics(*m_device, pipelineCreateInfo)) + PipelineData pipelineData; + pipelineData.onRenderPassRelease.Connect(renderPass.OnRenderPassRelease, [this, key](const VulkanRenderPass*) + { + m_pipelines.erase(key); + }); + + if (!pipelineData.pipeline.CreateGraphics(*m_device, pipelineCreateInfo)) return VK_NULL_HANDLE; - auto it = m_pipelines.emplace(key, std::move(newPipeline)).first; - return it->second; + auto it = m_pipelines.emplace(key, std::move(pipelineData)).first; + return it->second.pipeline; } std::vector VulkanRenderPipeline::BuildColorBlendAttachmentStateList(const RenderPipelineInfo& pipelineInfo)