Graphics/ForwardFramePipeline: Handle material invalidation correctly

This commit is contained in:
Jérôme Leclercq 2021-10-26 20:24:43 +02:00
parent 66bbf63e87
commit 4067116eb8
4 changed files with 40 additions and 35 deletions

View File

@ -87,6 +87,7 @@ namespace Nz
RenderQueue<RenderElement*> depthPrepassRenderQueue; RenderQueue<RenderElement*> depthPrepassRenderQueue;
RenderQueue<RenderElement*> forwardRenderQueue; RenderQueue<RenderElement*> forwardRenderQueue;
ShaderBindingPtr blitShaderBinding; ShaderBindingPtr blitShaderBinding;
bool prepare = true;
bool rebuildDepthPrepass = true; bool rebuildDepthPrepass = true;
bool rebuildForwardPass = true; bool rebuildForwardPass = true;
}; };

View File

@ -110,6 +110,7 @@ namespace Nz
NazaraSignal(OnMaterialRelease, const MaterialPass* /*material*/); NazaraSignal(OnMaterialRelease, const MaterialPass* /*material*/);
private: private:
inline void InvalidateCommandBuffer();
inline void InvalidatePipeline(); inline void InvalidatePipeline();
inline void InvalidateTextureSampler(std::size_t textureIndex); inline void InvalidateTextureSampler(std::size_t textureIndex);
inline void InvalidateUniformData(std::size_t uniformBufferIndex); inline void InvalidateUniformData(std::size_t uniformBufferIndex);

View File

@ -608,7 +608,8 @@ namespace Nz
if (m_textures[textureIndex].texture != texture) if (m_textures[textureIndex].texture != texture)
{ {
m_textures[textureIndex].texture = std::move(texture); m_textures[textureIndex].texture = std::move(texture);
OnMaterialInvalidated(this);
InvalidateCommandBuffer();
} }
} }
@ -618,6 +619,7 @@ namespace Nz
if (m_textures[textureIndex].samplerInfo != samplerInfo) if (m_textures[textureIndex].samplerInfo != samplerInfo)
{ {
m_textures[textureIndex].samplerInfo = std::move(samplerInfo); m_textures[textureIndex].samplerInfo = std::move(samplerInfo);
InvalidateTextureSampler(textureIndex); InvalidateTextureSampler(textureIndex);
} }
} }
@ -630,10 +632,16 @@ namespace Nz
m_uniformBuffers[bufferIndex].buffer = std::move(uniformBuffer); m_uniformBuffers[bufferIndex].buffer = std::move(uniformBuffer);
m_uniformBuffers[bufferIndex].dataInvalidated = true; m_uniformBuffers[bufferIndex].dataInvalidated = true;
OnMaterialInvalidated(this); InvalidateCommandBuffer();
} }
} }
inline void MaterialPass::InvalidateCommandBuffer()
{
m_forceCommandBufferRegeneration = true;
OnMaterialInvalidated(this);
}
inline void MaterialPass::InvalidatePipeline() inline void MaterialPass::InvalidatePipeline()
{ {
m_forceCommandBufferRegeneration = true; m_forceCommandBufferRegeneration = true;
@ -647,7 +655,7 @@ namespace Nz
assert(textureIndex < m_textures.size()); assert(textureIndex < m_textures.size());
m_textures[textureIndex].sampler.reset(); m_textures[textureIndex].sampler.reset();
OnMaterialInvalidated(this); InvalidateCommandBuffer();
} }
inline void MaterialPass::InvalidateUniformData(std::size_t uniformBufferIndex) inline void MaterialPass::InvalidateUniformData(std::size_t uniformBufferIndex)

View File

@ -155,6 +155,7 @@ namespace Nz
{ {
viewerData.rebuildDepthPrepass = true; viewerData.rebuildDepthPrepass = true;
viewerData.rebuildForwardPass = true; viewerData.rebuildForwardPass = true;
viewerData.prepare = true;
} }
} }
} }
@ -171,7 +172,6 @@ namespace Nz
}; };
// Render queues handling // Render queues handling
bool prepare = false;
for (auto&& [viewer, data] : m_viewers) for (auto&& [viewer, data] : m_viewers)
{ {
auto& viewerData = data; auto& viewerData = data;
@ -213,7 +213,7 @@ namespace Nz
{ {
viewerData.rebuildDepthPrepass = true; viewerData.rebuildDepthPrepass = true;
viewerData.rebuildForwardPass = true; viewerData.rebuildForwardPass = true;
prepare = true; viewerData.prepare = true;
viewerData.visibilityHash = visibilityHash; viewerData.visibilityHash = visibilityHash;
} }
@ -262,48 +262,42 @@ namespace Nz
}); });
} }
if (prepare) for (auto&& [viewer, viewerData] : m_viewers)
{ {
if (!viewerData.prepare)
continue;
for (std::size_t i = 0; i < m_elementRenderers.size(); ++i) for (std::size_t i = 0; i < m_elementRenderers.size(); ++i)
{ {
auto& elementRendererPtr = m_elementRenderers[i]; auto& elementRendererPtr = m_elementRenderers[i];
for (auto&& [_, viewerData] : m_viewers) if (i >= viewerData.elementRendererData.size() || !viewerData.elementRendererData[i])
{ {
if (i >= viewerData.elementRendererData.size() || !viewerData.elementRendererData[i]) if (i >= viewerData.elementRendererData.size())
{ viewerData.elementRendererData.resize(i + 1);
if (i >= viewerData.elementRendererData.size())
viewerData.elementRendererData.resize(i + 1);
viewerData.elementRendererData[i] = elementRendererPtr->InstanciateData(); viewerData.elementRendererData[i] = elementRendererPtr->InstanciateData();
}
if (elementRendererPtr)
elementRendererPtr->Reset(*viewerData.elementRendererData[i], renderFrame);
} }
if (elementRendererPtr)
elementRendererPtr->Reset(*viewerData.elementRendererData[i], renderFrame);
} }
for (auto&& [viewer, viewerData] : m_viewers) auto& rendererData = viewerData.elementRendererData;
const auto& viewerInstance = viewer->GetViewerInstance();
ProcessRenderQueue(viewerData.depthPrepassRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
{ {
auto& rendererData = viewerData.elementRendererData; ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
elementRenderer.Prepare(viewerInstance, *rendererData[elementType], renderFrame, elements, elementCount);
});
const auto& viewerInstance = viewer->GetViewerInstance(); ProcessRenderQueue(viewerData.forwardRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
{
ProcessRenderQueue(viewerData.depthPrepassRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount) ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
{ elementRenderer.Prepare(viewerInstance, *rendererData[elementType], renderFrame, elements, elementCount);
ElementRenderer& elementRenderer = *m_elementRenderers[elementType]; });
elementRenderer.Prepare(viewerInstance, *rendererData[elementType], renderFrame, elements, elementCount);
});
ProcessRenderQueue(viewerData.forwardRenderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
{
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
elementRenderer.Prepare(viewerInstance, *rendererData[elementType], renderFrame, elements, elementCount);
});
viewerData.rebuildForwardPass = true;
viewerData.rebuildDepthPrepass = true;
}
} }
if (m_bakedFrameGraph.Resize(renderFrame)) if (m_bakedFrameGraph.Resize(renderFrame))
@ -335,6 +329,7 @@ namespace Nz
{ {
viewerData.rebuildForwardPass = false; viewerData.rebuildForwardPass = false;
viewerData.rebuildDepthPrepass = false; viewerData.rebuildDepthPrepass = false;
viewerData.prepare = false;
const RenderTarget& renderTarget = viewer->GetRenderTarget(); const RenderTarget& renderTarget = viewer->GetRenderTarget();
Recti renderRegion(0, 0, frameSize.x, frameSize.y); Recti renderRegion(0, 0, frameSize.x, frameSize.y);