From 26e5a41dceca232e0ea09f79495296195bbe00c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Sun, 5 Sep 2021 16:04:10 +0200 Subject: [PATCH] Graphics/SpriteChainRenderer: Reuse vertex buffers and memory --- .../Nazara/Graphics/SpriteChainRenderer.hpp | 8 ++++ src/Nazara/Graphics/SpriteChainRenderer.cpp | 37 ++++++++++++++----- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/include/Nazara/Graphics/SpriteChainRenderer.hpp b/include/Nazara/Graphics/SpriteChainRenderer.hpp index 8868ef94a..73d354f4a 100644 --- a/include/Nazara/Graphics/SpriteChainRenderer.hpp +++ b/include/Nazara/Graphics/SpriteChainRenderer.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -33,9 +34,16 @@ namespace Nz void Reset(ElementRendererData& rendererData, RenderFrame& currentFrame); private: + struct VertexBufferPool + { + std::vector> vertexBuffers; + }; + std::shared_ptr m_indexBuffer; + std::shared_ptr m_vertexBufferPool; std::size_t m_maxVertexBufferSize; std::size_t m_maxVertexCount; + std::vector> m_pendingCopies; RenderDevice& m_device; }; diff --git a/src/Nazara/Graphics/SpriteChainRenderer.cpp b/src/Nazara/Graphics/SpriteChainRenderer.cpp index 033e36ab9..3dc6c71cc 100644 --- a/src/Nazara/Graphics/SpriteChainRenderer.cpp +++ b/src/Nazara/Graphics/SpriteChainRenderer.cpp @@ -18,6 +18,8 @@ namespace Nz m_maxVertexBufferSize(maxVertexBufferSize), m_maxVertexCount(m_maxVertexBufferSize / (2 * sizeof(float))) // Treat vec2 as the minimum declaration possible { + m_vertexBufferPool = std::make_shared(); + std::size_t maxQuadCount = m_maxVertexCount / 4; std::size_t indexCount = 6 * maxQuadCount; @@ -52,8 +54,6 @@ namespace Nz { auto& data = static_cast(rendererData); - std::vector> pendingCopies; - std::size_t firstQuadIndex = 0; SpriteChainRendererData::DrawCall* currentDrawCall = nullptr; UploadPool::Allocation* currentAllocation = nullptr; @@ -76,7 +76,7 @@ namespace Nz if (currentAllocation) { - pendingCopies.emplace_back(currentAllocation, currentVertexBuffer); + m_pendingCopies.emplace_back(currentAllocation, currentVertexBuffer); firstQuadIndex = 0; currentAllocation = nullptr; @@ -130,8 +130,19 @@ namespace Nz currentAllocation = ¤tFrame.GetUploadPool().Allocate(m_maxVertexBufferSize); currentAllocationMemPtr = static_cast(currentAllocation->mappedPtr); - std::shared_ptr vertexBuffer = m_device.InstantiateBuffer(BufferType::Vertex); - vertexBuffer->Initialize(m_maxVertexBufferSize, BufferUsage::DeviceLocal); + std::shared_ptr vertexBuffer; + + // Try to reuse vertex buffers from pool if any + if (!m_vertexBufferPool->vertexBuffers.empty()) + { + vertexBuffer = std::move(m_vertexBufferPool->vertexBuffers.back()); + m_vertexBufferPool->vertexBuffers.pop_back(); + } + else + { + vertexBuffer = m_device.InstantiateBuffer(BufferType::Vertex); + vertexBuffer->Initialize(m_maxVertexBufferSize, BufferUsage::DeviceLocal); + } currentVertexBuffer = vertexBuffer.get(); @@ -183,15 +194,17 @@ namespace Nz std::size_t drawCallCount = data.drawCalls.size() - oldDrawCallCount; data.drawCallPerElement[firstSpriteChain] = SpriteChainRendererData::DrawCallIndices{ oldDrawCallCount, drawCallCount }; - if (!pendingCopies.empty()) + if (!m_pendingCopies.empty()) { currentFrame.Execute([&](CommandBufferBuilder& builder) { - for (auto&& [allocation, buffer] : pendingCopies) + for (auto&& [allocation, buffer] : m_pendingCopies) builder.CopyBuffer(*allocation, buffer); builder.PostTransferBarrier(); }, Nz::QueueType::Transfer); + + m_pendingCopies.clear(); } } @@ -248,11 +261,15 @@ namespace Nz { auto& data = static_cast(rendererData); - // TODO: Reuse vertex buffers for (auto& vertexBufferPtr : data.vertexBuffers) - currentFrame.PushForRelease(std::move(vertexBufferPtr)); + { + currentFrame.PushReleaseCallback([pool = m_vertexBufferPool, vertexBuffer = std::move(vertexBufferPtr)]() + { + pool->vertexBuffers.push_back(std::move(vertexBuffer)); + }); + } + data.vertexBuffers.clear(); data.drawCalls.clear(); - data.vertexBuffers.clear(); } }