Graphics: Add MaterialPassRegistry

This commit is contained in:
Jérôme Leclercq
2021-07-29 20:16:06 +02:00
parent 5b1123b971
commit 9a311da2c8
20 changed files with 181 additions and 52 deletions

View File

@@ -27,6 +27,10 @@ namespace Nz
m_rebuildDepthPrepass(false),
m_rebuildForwardPass(false)
{
auto& passRegistry = Graphics::Instance()->GetMaterialPassRegistry();
m_depthPassIndex = passRegistry.GetPassIndex("DepthPass");
m_forwardPassIndex = passRegistry.GetPassIndex("ForwardPass");
m_elementRenderers.resize(1);
m_elementRenderers[UnderlyingCast(BasicRenderElement::Submesh)] = std::make_unique<SubmeshRenderer>();
}
@@ -46,6 +50,9 @@ namespace Nz
m_removedWorldInstances.erase(worldInstance);
auto& renderableMap = m_renderables[worldInstance];
if (renderableMap.empty())
InvalidateWorldInstance(worldInstance.get());
if (auto it = renderableMap.find(instancedRenderable); it == renderableMap.end())
{
auto& renderableData = renderableMap.emplace(instancedRenderable, RenderableData{}).first->second;
@@ -53,20 +60,20 @@ namespace Nz
{
if (newMaterial)
{
if (MaterialPass* pass = newMaterial->GetPass("DepthPass"))
if (MaterialPass* pass = newMaterial->GetPass(m_depthPassIndex))
RegisterMaterialPass(pass);
if (MaterialPass* pass = newMaterial->GetPass("ForwardPass"))
if (MaterialPass* pass = newMaterial->GetPass(m_forwardPassIndex))
RegisterMaterialPass(pass);
}
const auto& prevMaterial = instancedRenderable->GetMaterial(materialIndex);
if (prevMaterial)
{
if (MaterialPass* pass = prevMaterial->GetPass("DepthPass"))
if (MaterialPass* pass = prevMaterial->GetPass(m_depthPassIndex))
UnregisterMaterialPass(pass);
if (MaterialPass* pass = prevMaterial->GetPass("ForwardPass"))
if (MaterialPass* pass = prevMaterial->GetPass(m_forwardPassIndex))
UnregisterMaterialPass(pass);
}
@@ -79,10 +86,10 @@ namespace Nz
{
if (Material* mat = instancedRenderable->GetMaterial(i).get())
{
if (MaterialPass* pass = mat->GetPass("DepthPass"))
if (MaterialPass* pass = mat->GetPass(m_depthPassIndex))
RegisterMaterialPass(pass);
if (MaterialPass* pass = mat->GetPass("ForwardPass"))
if (MaterialPass* pass = mat->GetPass(m_forwardPassIndex))
RegisterMaterialPass(pass);
}
}
@@ -95,6 +102,7 @@ namespace Nz
void ForwardFramePipeline::RegisterViewer(AbstractViewer* viewerInstance)
{
m_viewers.emplace(viewerInstance, ViewerData{});
m_invalidatedViewerInstances.insert(viewerInstance);
}
void ForwardFramePipeline::Render(RenderFrame& renderFrame)
@@ -151,7 +159,7 @@ namespace Nz
for (const auto& [worldInstance, renderables] : m_renderables)
{
for (const auto& [renderable, renderableData] : renderables)
renderable->BuildElement("DepthPass", *worldInstance, m_depthPrepassRenderElements);
renderable->BuildElement(m_depthPassIndex, *worldInstance, m_depthPrepassRenderElements);
}
}
@@ -162,7 +170,7 @@ namespace Nz
for (const auto& [worldInstance, renderables] : m_renderables)
{
for (const auto& [renderable, renderableData] : renderables)
renderable->BuildElement("ForwardPass", *worldInstance, m_forwardRenderElements);
renderable->BuildElement(m_forwardPassIndex, *worldInstance, m_forwardRenderElements);
}
}
@@ -280,10 +288,10 @@ namespace Nz
std::size_t matCount = instancedRenderable->GetMaterialCount();
for (std::size_t i = 0; i < matCount; ++i)
{
if (MaterialPass* pass = instancedRenderable->GetMaterial(i)->GetPass("DepthPass"))
if (MaterialPass* pass = instancedRenderable->GetMaterial(i)->GetPass(m_depthPassIndex))
UnregisterMaterialPass(pass);
if (MaterialPass* pass = instancedRenderable->GetMaterial(i)->GetPass("ForwardPass"))
if (MaterialPass* pass = instancedRenderable->GetMaterial(i)->GetPass(m_forwardPassIndex))
UnregisterMaterialPass(pass);
}
@@ -395,6 +403,9 @@ namespace Nz
void ForwardFramePipeline::ProcessRenderQueue(CommandBufferBuilder& builder, const RenderQueue<RenderElement*>& renderQueue)
{
if (renderQueue.empty())
return;
auto it = renderQueue.begin();
auto itEnd = renderQueue.end();
while (it != itEnd)

View File

@@ -90,9 +90,10 @@ namespace Nz
for (const auto& output : framePass.GetOutputs())
bakedPass.outputTextureIndices.push_back(Retrieve(m_pending.attachmentToTextures, output.attachmentId));
if (std::size_t attachmentId = framePass.GetDepthStencilOutput(); attachmentId != FramePass::InvalidAttachmentId)
std::size_t attachmentId;
if (attachmentId = framePass.GetDepthStencilOutput(); attachmentId != FramePass::InvalidAttachmentId)
bakedPass.outputTextureIndices.push_back(Retrieve(m_pending.attachmentToTextures, attachmentId));
else if (std::size_t attachmentId = framePass.GetDepthStencilInput(); attachmentId != FramePass::InvalidAttachmentId)
else if (attachmentId = framePass.GetDepthStencilInput(); attachmentId != FramePass::InvalidAttachmentId)
bakedPass.outputTextureIndices.push_back(Retrieve(m_pending.attachmentToTextures, attachmentId)); //< FIXME?
}
}
@@ -292,7 +293,6 @@ namespace Nz
std::size_t dsInputAttachment = framePass.GetDepthStencilInput();
std::size_t dsOutputAttachement = framePass.GetDepthStencilOutput();
bool depthRead = false;
if (dsInputAttachment != FramePass::InvalidAttachmentId && dsOutputAttachement != FramePass::InvalidAttachmentId)
{

View File

@@ -73,6 +73,7 @@ namespace Nz
BuildFullscreenVertexBuffer();
BuildBlitPipeline();
RegisterMaterialPasses();
SelectDepthStencilFormats();
}
@@ -165,6 +166,12 @@ namespace Nz
throw std::runtime_error("failed to fill fullscreen vertex buffer");
}
void Graphics::RegisterMaterialPasses()
{
m_materialPassRegistry.RegisterPass("DepthPass");
m_materialPassRegistry.RegisterPass("ForwardPass");
}
void Graphics::SelectDepthStencilFormats()
{
for (PixelFormat depthStencilCandidate : { PixelFormat::Depth24Stencil8, PixelFormat::Depth32FStencil8, PixelFormat::Depth16Stencil8 })

View File

@@ -10,22 +10,4 @@ namespace Nz
Material::Material()
{
}
void Material::AddPass(std::string name, std::shared_ptr<MaterialPass> pass)
{
if (HasPass(name))
return;
m_passes.emplace(std::move(name), std::move(pass));
}
bool Material::HasPass(const std::string& name) const
{
return m_passes.find(name) != m_passes.end();
}
void Material::RemovePass(const std::string& name)
{
m_passes.erase(name);
}
}

View File

@@ -29,6 +29,7 @@ namespace Nz
MaterialPass::MaterialPass(std::shared_ptr<const MaterialSettings> settings) :
m_settings(std::move(settings)),
m_enabledOptions(0),
m_forceCommandBufferRegeneration(false),
m_pipelineUpdated(false),
m_shaderBindingUpdated(false)
{
@@ -66,11 +67,8 @@ namespace Nz
bool MaterialPass::Update(RenderFrame& renderFrame, CommandBufferBuilder& builder)
{
bool shouldRegenerateCommandBuffer = false;
if (!m_shaderBindingUpdated)
{
shouldRegenerateCommandBuffer = true;
renderFrame.PushForRelease(std::move(m_shaderBinding));
m_shaderBinding.reset();
@@ -92,6 +90,9 @@ namespace Nz
}
}
bool shouldRegenerateCommandBuffer = m_forceCommandBufferRegeneration;
m_forceCommandBufferRegeneration = false;
return shouldRegenerateCommandBuffer;
}

View File

@@ -30,13 +30,13 @@ namespace Nz
}
}
void Model::BuildElement(const std::string& pass, WorldInstance& worldInstance, std::vector<std::unique_ptr<RenderElement>>& elements) const
void Model::BuildElement(std::size_t passIndex, WorldInstance& worldInstance, std::vector<std::unique_ptr<RenderElement>>& elements) const
{
for (std::size_t i = 0; i < m_submeshes.size(); ++i)
{
const auto& submeshData = m_submeshes[i];
MaterialPass* materialPass = submeshData.material->GetPass(pass);
MaterialPass* materialPass = submeshData.material->GetPass(passIndex);
if (!materialPass)
continue;