diff --git a/include/Nazara/Renderer/RenderResources.hpp b/include/Nazara/Renderer/RenderResources.hpp index b1791d2aa..851ffaf6d 100644 --- a/include/Nazara/Renderer/RenderResources.hpp +++ b/include/Nazara/Renderer/RenderResources.hpp @@ -26,6 +26,8 @@ namespace Nz { public: class Releasable; + class ReleasableCallback; + template class ReleasableData; template class ReleasableLambda; virtual ~RenderResources(); @@ -50,10 +52,14 @@ namespace Nz RenderResources(RenderResources&&) = delete; private: + template T* Allocate(); + inline void* Allocate(std::size_t size, std::size_t alignment); + static constexpr std::size_t BlockSize = 4 * 1024 * 1024; using Block = std::vector; + std::vector m_callbackQueue; std::vector m_releaseQueue; std::vector m_releaseMemoryPool; RenderDevice& m_renderDevice; @@ -63,12 +69,32 @@ namespace Nz { public: virtual ~Releasable(); + }; + class RenderResources::ReleasableCallback : public Releasable + { + public: virtual void Release() = 0; }; template - class RenderResources::ReleasableLambda : public Releasable + class RenderResources::ReleasableData : public Releasable + { + public: + ReleasableData(T&& data); + ReleasableData(const ReleasableData&) = delete; + ReleasableData(ReleasableData&&) = delete; + ~ReleasableData() = default; + + ReleasableData& operator=(const ReleasableData&) = delete; + ReleasableData& operator=(ReleasableData&&) = delete; + + private: + T m_data; + }; + + template + class RenderResources::ReleasableLambda final : public ReleasableCallback { public: template ReleasableLambda(U&& lambda); diff --git a/include/Nazara/Renderer/RenderResources.inl b/include/Nazara/Renderer/RenderResources.inl index 892dd9503..13a0698c2 100644 --- a/include/Nazara/Renderer/RenderResources.inl +++ b/include/Nazara/Renderer/RenderResources.inl @@ -15,11 +15,14 @@ namespace Nz inline void RenderResources::FlushReleaseQueue() { + for (ReleasableCallback* callback : m_callbackQueue) + callback->Release(); + + m_callbackQueue.clear(); + for (Releasable* releasable : m_releaseQueue) - { - releasable->Release(); PlacementDestroy(releasable); - } + m_releaseQueue.clear(); for (auto& memoryblock : m_releaseMemoryPool) @@ -36,7 +39,12 @@ namespace Nz { static_assert(std::is_rvalue_reference_v); - return PushReleaseCallback([v = std::move(value)] {}); + using ReleaseData = ReleasableData>>; + + ReleaseData* releasable = Allocate(); + PlacementNew(releasable, std::forward(value)); + + m_releaseQueue.push_back(releasable); } template @@ -44,9 +52,21 @@ namespace Nz { using ReleaseFunctor = ReleasableLambda>>; - constexpr std::size_t functorSize = sizeof(ReleaseFunctor); - constexpr std::size_t functorAlignment = alignof(ReleaseFunctor); + ReleaseFunctor* releasable = Allocate(); + PlacementNew(releasable, std::forward(callback)); + m_releaseQueue.push_back(releasable); + m_callbackQueue.push_back(releasable); + } + + template + T* RenderResources::Allocate() + { + return static_cast(Allocate(sizeof(T), alignof(T))); + } + + void* RenderResources::Allocate(std::size_t size, std::size_t alignment) + { // Try to minimize lost space struct { @@ -59,8 +79,8 @@ namespace Nz { std::size_t freeOffset = block.size(); - UInt64 alignedOffset = Align(freeOffset, functorAlignment); - if (alignedOffset + functorSize > block.capacity()) + UInt64 alignedOffset = Align(freeOffset, alignment); + if (alignedOffset + size > block.capacity()) continue; //< Not enough space UInt64 lostSpace = alignedOffset - freeOffset; @@ -85,12 +105,16 @@ namespace Nz } Block& targetBlock = *bestBlock.block; - targetBlock.resize(bestBlock.alignedOffset + functorSize); + targetBlock.resize(bestBlock.alignedOffset + size); - ReleaseFunctor* releasable = reinterpret_cast(&targetBlock[bestBlock.alignedOffset]); - PlacementNew(releasable, std::forward(callback)); + return &targetBlock[bestBlock.alignedOffset]; + } - m_releaseQueue.push_back(releasable); + + template + RenderResources::ReleasableData::ReleasableData(T&& data) : + m_data(std::move(data)) + { } template @@ -108,3 +132,4 @@ namespace Nz } #include +#include "RenderResources.hpp"