Graphics/RenderQueue: Remake it with a naive implementation

The idea is to improve it in the future, after profiling
This commit is contained in:
Jérôme Leclercq
2021-07-28 13:11:03 +02:00
parent 335b48056f
commit 3de0edec6f
8 changed files with 48 additions and 228 deletions

View File

@@ -325,29 +325,7 @@ namespace Nz
builder.BindShaderBinding(Graphics::ViewerBindingSet, viewer->GetViewerInstance().GetShaderBinding());
auto it = m_depthPrepassRenderQueue.begin();
while (it != m_depthPrepassRenderQueue.end())
{
const RenderElement* element = *it;
UInt8 elementType = element->GetElementType();
m_temporaryElementList.push_back(element);
++it;
while (it != m_depthPrepassRenderQueue.end() && (*it)->GetElementType() == elementType)
{
m_temporaryElementList.push_back(*it);
++it;
}
if (elementType >= m_elementRenderers.size() || !m_elementRenderers[elementType])
continue;
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
elementRenderer.Render(builder, m_temporaryElementList.data(), m_temporaryElementList.size());
m_temporaryElementList.clear();
}
ProcessRenderQueue(builder, m_depthPrepassRenderQueue);
});
FramePass& forwardPass = frameGraph.AddPass("Forward pass");
@@ -375,29 +353,7 @@ namespace Nz
builder.BindShaderBinding(Graphics::ViewerBindingSet, viewer->GetViewerInstance().GetShaderBinding());
auto it = m_forwardRenderQueue.begin();
while (it != m_forwardRenderQueue.end())
{
const RenderElement* element = *it;
UInt8 elementType = element->GetElementType();
m_temporaryElementList.push_back(element);
++it;
while (it != m_forwardRenderQueue.end() && (*it)->GetElementType() == elementType)
{
m_temporaryElementList.push_back(*it);
++it;
}
if (elementType >= m_elementRenderers.size() || !m_elementRenderers[elementType])
continue;
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
elementRenderer.Render(builder, m_temporaryElementList.data(), m_temporaryElementList.size());
m_temporaryElementList.clear();
}
ProcessRenderQueue(builder, m_forwardRenderQueue);
});
}
@@ -425,6 +381,31 @@ namespace Nz
it->second.usedCount++;
}
void ForwardFramePipeline::ProcessRenderQueue(CommandBufferBuilder& builder, const RenderQueue<RenderElement*>& renderQueue)
{
auto it = renderQueue.begin();
auto itEnd = renderQueue.end();
while (it != itEnd)
{
const RenderElement* element = *it;
UInt8 elementType = element->GetElementType();
const Pointer<const RenderElement>* first = it;
++it;
while (it != itEnd && (*it)->GetElementType() == elementType)
++it;
std::size_t count = it - first;
if (elementType >= m_elementRenderers.size() || !m_elementRenderers[elementType])
continue;
ElementRenderer& elementRenderer = *m_elementRenderers[elementType];
elementRenderer.Render(builder, first, count);
}
}
void ForwardFramePipeline::UnregisterMaterialPass(MaterialPass* material)
{
auto it = m_materials.find(material);

View File

@@ -1,32 +0,0 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/RenderQueue.hpp>
#include <algorithm>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
void RenderQueueInternal::Sort()
{
std::sort(m_orderedRenderQueue.begin(), m_orderedRenderQueue.end(), [](const RenderDataPair& lhs, const RenderDataPair& rhs)
{
/*
Original code:
if (lhs.first == rhs.first)
return lhs.second < rhs.second;
else
return lhs.first < rhs.first;
Clang seems to the the only one to prevent branching with the original code (using cmov)
Rewriting the code with bit ops seems to prevent branching with Clang/GCC/MSVC
*/
bool equal = lhs.first == rhs.first;
bool compareFirst = lhs.first < rhs.first;
bool compareSecond = lhs.second < rhs.second;
return (equal & compareSecond) | (!equal & compareFirst);
});
}
}

View File

@@ -10,7 +10,7 @@
namespace Nz
{
void SubmeshRenderer::Render(CommandBufferBuilder& commandBuffer, const RenderElement** elements, std::size_t elementCount)
void SubmeshRenderer::Render(CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t elementCount)
{
const AbstractBuffer* currentIndexBuffer = nullptr;
const AbstractBuffer* currentVertexBuffer = nullptr;