Graphics/ForwardFramePipeline: Reuse light UBO

This commit is contained in:
Jérôme Leclercq 2022-02-02 13:47:29 +01:00
parent 8a3a8547dc
commit 109127459b
2 changed files with 23 additions and 6 deletions

View File

@ -88,6 +88,11 @@ namespace Nz
UploadPool::Allocation* allocation = nullptr; UploadPool::Allocation* allocation = nullptr;
}; };
struct LightUboPool
{
std::vector<std::shared_ptr<RenderBuffer>> lightUboBuffers;
};
struct MaterialData struct MaterialData
{ {
std::size_t usedCount = 0; std::size_t usedCount = 0;
@ -139,6 +144,7 @@ namespace Nz
std::size_t m_depthPassIndex; std::size_t m_depthPassIndex;
std::size_t m_forwardPassIndex; std::size_t m_forwardPassIndex;
std::shared_ptr<LightUboPool> m_lightUboPool;
std::unordered_map<AbstractViewer*, ViewerData> m_viewers; std::unordered_map<AbstractViewer*, ViewerData> m_viewers;
std::unordered_map<Light*, LightData> m_lights; std::unordered_map<Light*, LightData> m_lights;
std::unordered_map<MaterialPass*, MaterialData> m_materials; std::unordered_map<MaterialPass*, MaterialData> m_materials;

View File

@ -38,6 +38,8 @@ namespace Nz
m_elementRenderers.resize(BasicRenderElementCount); m_elementRenderers.resize(BasicRenderElementCount);
m_elementRenderers[UnderlyingCast(BasicRenderElement::SpriteChain)] = std::make_unique<SpriteChainRenderer>(*Graphics::Instance()->GetRenderDevice()); m_elementRenderers[UnderlyingCast(BasicRenderElement::SpriteChain)] = std::make_unique<SpriteChainRenderer>(*Graphics::Instance()->GetRenderDevice());
m_elementRenderers[UnderlyingCast(BasicRenderElement::Submesh)] = std::make_unique<SubmeshRenderer>(); m_elementRenderers[UnderlyingCast(BasicRenderElement::Submesh)] = std::make_unique<SubmeshRenderer>();
m_lightUboPool = std::make_shared<LightUboPool>();
} }
void ForwardFramePipeline::InvalidateViewer(AbstractViewer* viewerInstance) void ForwardFramePipeline::InvalidateViewer(AbstractViewer* viewerInstance)
@ -302,9 +304,12 @@ namespace Nz
for (auto& lightDataUbo : m_lightDataBuffers) for (auto& lightDataUbo : m_lightDataBuffers)
{ {
lightDataUbo.allocation = nullptr; renderFrame.PushReleaseCallback([pool = m_lightUboPool, lightUbo = std::move(lightDataUbo.renderBuffer)]()
lightDataUbo.offset = 0; {
pool->lightUboBuffers.push_back(std::move(lightUbo));
});
} }
m_lightDataBuffers.clear();
for (const auto& renderableData : m_visibleRenderables) for (const auto& renderableData : m_visibleRenderables)
{ {
@ -353,9 +358,17 @@ namespace Nz
if (!targetLightData) if (!targetLightData)
{ {
// Allocate a new light UBO // Make a new light UBO
auto& lightUboData = m_lightDataBuffers.emplace_back(); auto& lightUboData = m_lightDataBuffers.emplace_back();
lightUboData.renderBuffer = graphics->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform, 256 * lightUboAlignedSize, BufferUsage::DeviceLocal | BufferUsage::Dynamic | BufferUsage::Write);
// Reuse from pool if possible
if (!m_lightUboPool->lightUboBuffers.empty())
{
lightUboData.renderBuffer = m_lightUboPool->lightUboBuffers.back();
m_lightUboPool->lightUboBuffers.pop_back();
}
else
lightUboData.renderBuffer = graphics->GetRenderDevice()->InstantiateBuffer(BufferType::Uniform, 256 * lightUboAlignedSize, BufferUsage::DeviceLocal | BufferUsage::Dynamic | BufferUsage::Write);
targetLightData = &lightUboData; targetLightData = &lightUboData;
} }
@ -405,8 +418,6 @@ namespace Nz
{ {
builder.BeginDebugRegion("Light UBO Update", Color::Yellow); builder.BeginDebugRegion("Light UBO Update", Color::Yellow);
{ {
builder.PreTransferBarrier();
for (auto& lightUboData : m_lightDataBuffers) for (auto& lightUboData : m_lightDataBuffers)
{ {
if (!lightUboData.allocation) if (!lightUboData.allocation)