Merge branch 'master' into automatic-file-fix
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include <Nazara/Graphics/SpriteChainRenderer.hpp>
|
||||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <Nazara/Graphics/RenderSpriteChain.hpp>
|
||||
#include <Nazara/Graphics/ViewerInstance.hpp>
|
||||
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
|
||||
#include <Nazara/Renderer/RenderFrame.hpp>
|
||||
#include <Nazara/Renderer/UploadPool.hpp>
|
||||
@@ -52,7 +53,7 @@ namespace Nz
|
||||
return std::make_unique<SpriteChainRendererData>();
|
||||
}
|
||||
|
||||
void SpriteChainRenderer::Prepare(ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||
void SpriteChainRenderer::Prepare(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, RenderFrame& currentFrame, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||
{
|
||||
Graphics* graphics = Graphics::Instance();
|
||||
|
||||
@@ -65,10 +66,9 @@ namespace Nz
|
||||
const VertexDeclaration* currentVertexDeclaration = nullptr;
|
||||
AbstractBuffer* currentVertexBuffer = nullptr;
|
||||
const RenderPipeline* currentPipeline = nullptr;
|
||||
const ShaderBinding* currentDrawDataBinding = nullptr;
|
||||
const ShaderBinding* currentInstanceBinding = nullptr;
|
||||
const ShaderBinding* currentMaterialBinding = nullptr;
|
||||
const ShaderBinding* currentShaderBinding = nullptr;
|
||||
const Texture* currentTextureOverlay = nullptr;
|
||||
const WorldInstance* currentWorldInstance = nullptr;
|
||||
|
||||
auto FlushDrawCall = [&]()
|
||||
{
|
||||
@@ -79,7 +79,7 @@ namespace Nz
|
||||
{
|
||||
FlushDrawCall();
|
||||
|
||||
currentDrawDataBinding = nullptr;
|
||||
currentShaderBinding = nullptr;
|
||||
};
|
||||
|
||||
auto Flush = [&]()
|
||||
@@ -122,24 +122,18 @@ namespace Nz
|
||||
currentVertexDeclaration = vertexDeclaration;
|
||||
}
|
||||
|
||||
if (currentPipeline != spriteChain.GetRenderPipeline())
|
||||
if (currentPipeline != &spriteChain.GetRenderPipeline())
|
||||
{
|
||||
FlushDrawCall();
|
||||
currentPipeline = spriteChain.GetRenderPipeline();
|
||||
currentPipeline = &spriteChain.GetRenderPipeline();
|
||||
}
|
||||
|
||||
if (currentMaterialBinding != &spriteChain.GetMaterialBinding())
|
||||
{
|
||||
FlushDrawCall();
|
||||
currentMaterialBinding = &spriteChain.GetMaterialBinding();
|
||||
}
|
||||
|
||||
if (currentInstanceBinding != &spriteChain.GetInstanceBinding())
|
||||
if (currentWorldInstance != &spriteChain.GetWorldInstance())
|
||||
{
|
||||
// TODO: Flushing draw calls on instance binding means we can have e.g. 1000 sprites rendered using a draw call for each one
|
||||
// which is far from being efficient, using some bindless could help (or at least instancing?)
|
||||
FlushDrawCall();
|
||||
currentInstanceBinding = &spriteChain.GetInstanceBinding();
|
||||
FlushDrawData();
|
||||
currentWorldInstance = &spriteChain.GetWorldInstance();
|
||||
}
|
||||
|
||||
if (currentTextureOverlay != spriteChain.GetTextureOverlay())
|
||||
@@ -177,19 +171,52 @@ namespace Nz
|
||||
data.vertexBuffers.emplace_back(std::move(vertexBuffer));
|
||||
}
|
||||
|
||||
if (!currentDrawDataBinding)
|
||||
if (!currentShaderBinding)
|
||||
{
|
||||
ShaderBindingPtr drawDataBinding = Graphics::Instance()->GetReferencePipelineLayout()->AllocateShaderBinding(Graphics::DrawDataBindingSet);
|
||||
drawDataBinding->Update({
|
||||
{
|
||||
0,
|
||||
ShaderBinding::TextureBinding {
|
||||
currentTextureOverlay, defaultSampler.get()
|
||||
}
|
||||
}
|
||||
});
|
||||
m_bindingCache.clear();
|
||||
|
||||
currentDrawDataBinding = drawDataBinding.get();
|
||||
const MaterialPass& materialPass = spriteChain.GetMaterialPass();
|
||||
materialPass.FillShaderBinding(m_bindingCache);
|
||||
|
||||
// Predefined shader bindings
|
||||
const auto& matSettings = materialPass.GetSettings();
|
||||
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::InstanceDataUbo); bindingIndex != MaterialSettings::InvalidIndex)
|
||||
{
|
||||
const auto& instanceBuffer = currentWorldInstance->GetInstanceBuffer();
|
||||
|
||||
auto& bindingEntry = m_bindingCache.emplace_back();
|
||||
bindingEntry.bindingIndex = bindingIndex;
|
||||
bindingEntry.content = ShaderBinding::UniformBufferBinding{
|
||||
instanceBuffer.get(),
|
||||
0, instanceBuffer->GetSize()
|
||||
};
|
||||
}
|
||||
|
||||
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::ViewerDataUbo); bindingIndex != MaterialSettings::InvalidIndex)
|
||||
{
|
||||
const auto& viewerBuffer = viewerInstance.GetViewerBuffer();
|
||||
|
||||
auto& bindingEntry = m_bindingCache.emplace_back();
|
||||
bindingEntry.bindingIndex = bindingIndex;
|
||||
bindingEntry.content = ShaderBinding::UniformBufferBinding{
|
||||
viewerBuffer.get(),
|
||||
0, viewerBuffer->GetSize()
|
||||
};
|
||||
}
|
||||
|
||||
if (std::size_t bindingIndex = matSettings->GetPredefinedBinding(PredefinedShaderBinding::OverlayTexture); bindingIndex != MaterialSettings::InvalidIndex)
|
||||
{
|
||||
auto& bindingEntry = m_bindingCache.emplace_back();
|
||||
bindingEntry.bindingIndex = bindingIndex;
|
||||
bindingEntry.content = ShaderBinding::TextureBinding{
|
||||
currentTextureOverlay, defaultSampler.get()
|
||||
};
|
||||
}
|
||||
|
||||
ShaderBindingPtr drawDataBinding = currentPipeline->GetPipelineInfo().pipelineLayout->AllocateShaderBinding(0);
|
||||
drawDataBinding->Update(m_bindingCache.data(), m_bindingCache.size());
|
||||
|
||||
currentShaderBinding = drawDataBinding.get();
|
||||
|
||||
data.shaderBindings.emplace_back(std::move(drawDataBinding));
|
||||
}
|
||||
@@ -199,9 +226,7 @@ namespace Nz
|
||||
data.drawCalls.push_back(SpriteChainRendererData::DrawCall{
|
||||
currentVertexBuffer,
|
||||
currentPipeline,
|
||||
currentDrawDataBinding,
|
||||
currentInstanceBinding,
|
||||
currentMaterialBinding,
|
||||
currentShaderBinding,
|
||||
6 * firstQuadIndex,
|
||||
0,
|
||||
});
|
||||
@@ -255,7 +280,7 @@ namespace Nz
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteChainRenderer::Render(ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t /*elementCount*/)
|
||||
void SpriteChainRenderer::Render(const ViewerInstance& viewerInstance, ElementRendererData& rendererData, CommandBufferBuilder& commandBuffer, const Pointer<const RenderElement>* elements, std::size_t /*elementCount*/)
|
||||
{
|
||||
auto& data = static_cast<SpriteChainRendererData&>(rendererData);
|
||||
|
||||
@@ -263,9 +288,9 @@ namespace Nz
|
||||
|
||||
const AbstractBuffer* currentVertexBuffer = nullptr;
|
||||
const RenderPipeline* currentPipeline = nullptr;
|
||||
const ShaderBinding* currentDrawDataBinding = nullptr;
|
||||
const ShaderBinding* currentInstanceBinding = nullptr;
|
||||
const ShaderBinding* currentMaterialBinding = nullptr;
|
||||
const ShaderBinding* currentShaderBinding = nullptr;
|
||||
const ViewerInstance* currentViewerInstance = nullptr;
|
||||
const WorldInstance* currentWorldInstance = nullptr;
|
||||
|
||||
const RenderSpriteChain* firstSpriteChain = static_cast<const RenderSpriteChain*>(elements[0]);
|
||||
auto it = data.drawCallPerElement.find(firstSpriteChain);
|
||||
@@ -289,22 +314,10 @@ namespace Nz
|
||||
currentPipeline = drawCall.renderPipeline;
|
||||
}
|
||||
|
||||
if (currentDrawDataBinding != drawCall.drawDataBinding)
|
||||
if (currentShaderBinding != drawCall.shaderBinding)
|
||||
{
|
||||
commandBuffer.BindShaderBinding(Graphics::DrawDataBindingSet, *drawCall.drawDataBinding);
|
||||
currentDrawDataBinding = drawCall.drawDataBinding;
|
||||
}
|
||||
|
||||
if (currentMaterialBinding != drawCall.materialBinding)
|
||||
{
|
||||
commandBuffer.BindShaderBinding(Graphics::MaterialBindingSet, *drawCall.materialBinding);
|
||||
currentMaterialBinding = drawCall.materialBinding;
|
||||
}
|
||||
|
||||
if (currentInstanceBinding != drawCall.instanceBinding)
|
||||
{
|
||||
commandBuffer.BindShaderBinding(Graphics::WorldBindingSet, *drawCall.instanceBinding);
|
||||
currentInstanceBinding = drawCall.instanceBinding;
|
||||
commandBuffer.BindShaderBinding(0, *drawCall.shaderBinding);
|
||||
currentShaderBinding = drawCall.shaderBinding;
|
||||
}
|
||||
|
||||
commandBuffer.DrawIndexed(drawCall.quadCount * 6, 1U, drawCall.firstIndex);
|
||||
|
||||
Reference in New Issue
Block a user