Graphics: Separate pipeline state from Material into a new class, MaterialPipeline

This allows much more efficient batching, along with pipeline reusage and preparation for the Vulkan API


Former-commit-id: fd2de2f0e9612ea275ee69c5578c68e7169cd05b [formerly 53bd8a5ed5695311b7543ad717df63f93fad2da6] [formerly 171740929652ac9fe30e84983709388859cedd6b [formerly 25096a76678f1052e76f67d26b458077a0632cc3]]
Former-commit-id: 7978dbeb87af2eac9e5501a97afa83849648bf6e [formerly 81b6cce1ee81a2ca8873d3c70d468b2c71510c95]
Former-commit-id: 6663e2721c3f79d5f1e3f33c6183174378b502f4
This commit is contained in:
Lynix
2016-08-05 22:09:39 +02:00
parent 3cf4cd3d53
commit ac25df0126
31 changed files with 2249 additions and 1422 deletions

View File

@@ -0,0 +1,42 @@
// Copyright (C) 2016 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_RENDERPIPELINE_HPP
#define NAZARA_RENDERPIPELINE_HPP
#include <Nazara/Utility/Enums.hpp>
#include <Nazara/Renderer/RenderStates.hpp>
#include <Nazara/Renderer/Shader.hpp>
namespace Nz
{
struct RenderPipelineInfo : RenderStates
{
ShaderConstRef shader;
};
class RenderPipeline
{
public:
inline RenderPipeline();
inline ~RenderPipeline();
inline bool Create(const RenderPipelineInfo& pipelineInfo);
inline void Destroy();
inline const RenderPipelineInfo& GetInfo() const;
inline bool IsValid() const;
private:
RenderPipelineInfo m_pipelineInfo;
bool m_valid;
};
}
#include <Nazara/Renderer/RenderPipeline.inl>
#endif // NAZARA_RENDERPIPELINE_HPP

View File

@@ -0,0 +1,48 @@
// Copyright (C) 2016 Jérôme Leclercq
// This file is part of the "Nazara Engine - Renderer module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/RenderPipeline.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
inline RenderPipeline::RenderPipeline() :
m_valid(false)
{
}
inline RenderPipeline::~RenderPipeline()
{
}
inline bool RenderPipeline::Create(const RenderPipelineInfo& pipelineInfo)
{
NazaraAssert(pipelineInfo.shader, "Invalid shader");
m_pipelineInfo = pipelineInfo;
m_valid = true;
return true;
}
inline void RenderPipeline::Destroy()
{
m_valid = false;
}
inline const RenderPipelineInfo& RenderPipeline::GetInfo() const
{
NazaraAssert(m_valid, "Invalid pipeline info");
return m_pipelineInfo;
}
inline bool RenderPipeline::IsValid() const
{
return m_valid;
}
}
#include <Nazara/Renderer/DebugOff.hpp>

View File

@@ -7,8 +7,8 @@
#ifndef NAZARA_RENDERSTATES_HPP
#define NAZARA_RENDERSTATES_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/Utility/Enums.hpp>
#include <Nazara/Renderer/Shader.hpp>
namespace Nz
{
@@ -74,10 +74,7 @@ namespace Nz
float pointSize = 1.f;
};
struct RenderPipeline : RenderStates
{
ShaderConstRef shader;
};
inline bool operator==(const RenderStates& lhs, const RenderStates& rhs);
}
#include <Nazara/Renderer/RenderStates.inl>

View File

@@ -3,11 +3,143 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/RenderStates.hpp>
#include <cstring>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <functional>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
bool operator==(const RenderStates& lhs, const RenderStates& rhs)
{
#define NazaraRenderStateMember(field) if (lhs.##field != rhs.##field) return false
#define NazaraRenderStateBoolMember NazaraRenderStateMember
#define NazaraRenderStateFloatMember(field, maxDiff) if (!NumberEquals(lhs.##field, rhs.##field, maxDiff)) return false
NazaraRenderStateBoolMember(blending);
NazaraRenderStateBoolMember(colorWrite);
NazaraRenderStateBoolMember(depthBuffer);
NazaraRenderStateBoolMember(faceCulling);
NazaraRenderStateBoolMember(scissorTest);
NazaraRenderStateBoolMember(stencilTest);
if (lhs.depthBuffer)
NazaraRenderStateBoolMember(depthWrite);
NazaraRenderStateMember(faceFilling);
if (lhs.blending) //< Remember, at this time we know lhs.blending == rhs.blending
{
NazaraRenderStateMember(dstBlend);
NazaraRenderStateMember(srcBlend);
}
if (lhs.depthBuffer)
NazaraRenderStateMember(depthFunc);
if (lhs.faceCulling)
NazaraRenderStateMember(cullingSide);
if (lhs.stencilTest)
{
NazaraRenderStateMember(stencilCompare.back);
NazaraRenderStateMember(stencilCompare.front);
NazaraRenderStateMember(stencilCompareMask.back);
NazaraRenderStateMember(stencilCompareMask.front);
NazaraRenderStateMember(stencilDepthFail.back);
NazaraRenderStateMember(stencilDepthFail.front);
NazaraRenderStateMember(stencilFail.back);
NazaraRenderStateMember(stencilFail.front);
NazaraRenderStateMember(stencilPass.back);
NazaraRenderStateMember(stencilPass.front);
NazaraRenderStateMember(stencilReference.back);
NazaraRenderStateMember(stencilReference.front);
NazaraRenderStateMember(stencilWriteMask.back);
NazaraRenderStateMember(stencilWriteMask.front);
}
NazaraRenderStateFloatMember(lineWidth, 0.001f);
NazaraRenderStateFloatMember(pointSize, 0.001f);
#undef NazaraRenderStateMember
#undef NazaraRenderStateBoolMember
#undef NazaraRenderStateFloatMember
return true;
}
}
namespace std
{
template<>
struct hash<Nz::RenderStates>
{
size_t operator()(const Nz::RenderStates& pipelineInfo) const
{
std::size_t seed = 0;
Nz::UInt8 parameterHash = 0;
Nz::UInt8 parameterIndex = 0;
#define NazaraRenderStateMember(member) Nz::HashCombine(seed, pipelineInfo.##member)
#define NazaraRenderStateBoolMember(member) parameterHash |= ((pipelineInfo.##member) ? 1U : 0U) << (parameterIndex++)
#define NazaraRenderStateBoolMemberDep(dependency, member) parameterHash |= ((pipelineInfo.##dependency && pipelineInfo.##member) ? 1U : 0U) << (parameterIndex++)
#define NazaraRenderStateFloatMember(member, maxDiff) Nz::HashCombine(seed, std::floor(pipelineInfo.##member / maxDiff) * maxDiff)
NazaraRenderStateBoolMember(blending);
NazaraRenderStateBoolMember(colorWrite);
NazaraRenderStateBoolMember(depthBuffer);
NazaraRenderStateBoolMember(faceCulling);
NazaraRenderStateBoolMember(scissorTest);
NazaraRenderStateBoolMember(stencilTest);
NazaraRenderStateBoolMemberDep(depthBuffer, depthWrite);
NazaraRenderStateMember(faceFilling);
if (pipelineInfo.blending) //< Remember, at this time we know lhs.blending == rhs.blending
{
NazaraRenderStateMember(dstBlend);
NazaraRenderStateMember(srcBlend);
}
if (pipelineInfo.depthBuffer)
NazaraRenderStateMember(depthFunc);
if (pipelineInfo.faceCulling)
NazaraRenderStateMember(cullingSide);
if (pipelineInfo.stencilTest)
{
NazaraRenderStateMember(stencilCompare.back);
NazaraRenderStateMember(stencilCompare.front);
NazaraRenderStateMember(stencilCompareMask.back);
NazaraRenderStateMember(stencilCompareMask.front);
NazaraRenderStateMember(stencilDepthFail.back);
NazaraRenderStateMember(stencilDepthFail.front);
NazaraRenderStateMember(stencilFail.back);
NazaraRenderStateMember(stencilFail.front);
NazaraRenderStateMember(stencilPass.back);
NazaraRenderStateMember(stencilPass.front);
NazaraRenderStateMember(stencilReference.back);
NazaraRenderStateMember(stencilReference.front);
NazaraRenderStateMember(stencilWriteMask.back);
NazaraRenderStateMember(stencilWriteMask.front);
}
NazaraRenderStateFloatMember(lineWidth, 0.001f);
NazaraRenderStateFloatMember(pointSize, 0.001f);
#undef NazaraRenderStateMember
#undef NazaraRenderStateBoolMember
#undef NazaraRenderStateBoolMemberDep
#undef NazaraRenderStateFloatMember
Nz::HashCombine(seed, parameterHash);
return seed;
}
};
}
#include <Nazara/Renderer/DebugOff.hpp>