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

View File

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