diff --git a/engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h b/engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h index a50ec088..01078de6 100644 --- a/engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h +++ b/engine/include/XCEngine/Rendering/Passes/BuiltinObjectIdOutlinePass.h @@ -17,6 +17,7 @@ #include #include +#include #include namespace XCEngine { @@ -31,7 +32,12 @@ struct ObjectIdOutlineStyle { class BuiltinObjectIdOutlinePass { public: + BuiltinObjectIdOutlinePass(); ~BuiltinObjectIdOutlinePass() = default; + BuiltinObjectIdOutlinePass(const BuiltinObjectIdOutlinePass&) = delete; + BuiltinObjectIdOutlinePass& operator=(const BuiltinObjectIdOutlinePass&) = delete; + BuiltinObjectIdOutlinePass(BuiltinObjectIdOutlinePass&&) = delete; + BuiltinObjectIdOutlinePass& operator=(BuiltinObjectIdOutlinePass&&) = delete; static constexpr uint32_t kMaxSelectedObjectCount = 256u; @@ -55,6 +61,8 @@ private: bool EnsureInitialized(const RenderContext& renderContext); bool CreateResources(const RenderContext& renderContext); void DestroyResources(); + bool HasCreatedResources() const; + void ResetState(); RHI::RHIDevice* m_device = nullptr; RHI::RHIType m_backendType = RHI::RHIType::D3D12; @@ -64,7 +72,7 @@ private: RHI::RHIDescriptorSet* m_constantSet = nullptr; RHI::RHIDescriptorPool* m_texturePool = nullptr; RHI::RHIDescriptorSet* m_textureSet = nullptr; - Resources::ResourceHandle m_builtinObjectIdOutlineShader; + std::optional> m_builtinObjectIdOutlineShader; }; } // namespace Passes diff --git a/engine/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp b/engine/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp index 3eb5803d..f2aca993 100644 --- a/engine/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp +++ b/engine/src/Rendering/Passes/BuiltinObjectIdOutlinePass.cpp @@ -9,6 +9,7 @@ #include "Resources/BuiltinResources.h" #include +#include namespace XCEngine { namespace Rendering { @@ -85,6 +86,10 @@ RHI::GraphicsPipelineDesc CreatePipelineDesc( } // namespace +BuiltinObjectIdOutlinePass::BuiltinObjectIdOutlinePass() { + ResetState(); +} + void BuiltinObjectIdOutlinePass::Shutdown() { DestroyResources(); } @@ -181,7 +186,9 @@ bool BuiltinObjectIdOutlinePass::EnsureInitialized(const RenderContext& renderCo return true; } - DestroyResources(); + if (HasCreatedResources()) { + DestroyResources(); + } return CreateResources(renderContext); } @@ -190,21 +197,23 @@ bool BuiltinObjectIdOutlinePass::CreateResources(const RenderContext& renderCont return false; } - m_device = renderContext.device; - m_backendType = renderContext.backendType; - m_builtinObjectIdOutlineShader = Resources::ResourceManager::Get().Load( + Resources::ResourceHandle shader = Resources::ResourceManager::Get().Load( Resources::GetBuiltinObjectIdOutlineShaderPath()); - if (!m_builtinObjectIdOutlineShader.IsValid()) { + if (!shader.IsValid()) { Debug::Logger::Get().Error( Debug::LogCategory::Rendering, "BuiltinObjectIdOutlinePass failed to load builtin object-id-outline shader resource"); - DestroyResources(); + ResetState(); return false; } + m_device = renderContext.device; + m_backendType = renderContext.backendType; + m_builtinObjectIdOutlineShader.emplace(std::move(shader)); + const Resources::ShaderBackend backend = ::XCEngine::Rendering::Detail::ToShaderBackend(m_backendType); const Resources::ShaderPass* outlinePass = - FindObjectIdOutlineCompatiblePass(*m_builtinObjectIdOutlineShader.Get(), backend); + FindObjectIdOutlineCompatiblePass(*m_builtinObjectIdOutlineShader->Get(), backend); if (outlinePass == nullptr) { Debug::Logger::Get().Error( Debug::LogCategory::Rendering, @@ -276,10 +285,10 @@ bool BuiltinObjectIdOutlinePass::CreateResources(const RenderContext& renderCont m_pipelineState = m_device->CreatePipelineState( CreatePipelineDesc( - m_backendType, - m_pipelineLayout, - *m_builtinObjectIdOutlineShader.Get(), - outlinePass->name)); + m_backendType, + m_pipelineLayout, + *m_builtinObjectIdOutlineShader->Get(), + outlinePass->name)); if (m_pipelineState == nullptr || !m_pipelineState->IsValid()) { DestroyResources(); return false; @@ -288,6 +297,17 @@ bool BuiltinObjectIdOutlinePass::CreateResources(const RenderContext& renderCont return true; } +bool BuiltinObjectIdOutlinePass::HasCreatedResources() const { + return m_device != nullptr || + m_pipelineLayout != nullptr || + m_pipelineState != nullptr || + m_constantPool != nullptr || + m_constantSet != nullptr || + m_texturePool != nullptr || + m_textureSet != nullptr || + m_builtinObjectIdOutlineShader.has_value(); +} + void BuiltinObjectIdOutlinePass::DestroyResources() { if (m_pipelineState != nullptr) { m_pipelineState->Shutdown(); @@ -325,9 +345,23 @@ void BuiltinObjectIdOutlinePass::DestroyResources() { m_pipelineLayout = nullptr; } + if (m_builtinObjectIdOutlineShader.has_value()) { + m_builtinObjectIdOutlineShader.reset(); + } + + ResetState(); +} + +void BuiltinObjectIdOutlinePass::ResetState() { m_device = nullptr; m_backendType = RHI::RHIType::D3D12; - m_builtinObjectIdOutlineShader.Reset(); + m_pipelineLayout = nullptr; + m_pipelineState = nullptr; + m_constantPool = nullptr; + m_constantSet = nullptr; + m_texturePool = nullptr; + m_textureSet = nullptr; + m_builtinObjectIdOutlineShader.reset(); } } // namespace Passes