Graphics: Add data-driven pipeline passes

Fix compilation
This commit is contained in:
SirLynix
2023-11-02 16:19:41 +01:00
committed by Jérôme Leclercq
parent 4995364418
commit 8fb6ea728d
41 changed files with 876 additions and 264 deletions

View File

@@ -8,32 +8,31 @@
#define NAZARA_GRAPHICS_CAMERA_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/PipelineViewer.hpp>
#include <Nazara/Graphics/ViewerInstance.hpp>
#include <Nazara/Math/Rect.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
#include <memory>
#include <vector>
namespace Nz
{
class NAZARA_GRAPHICS_API Camera : public AbstractViewer
class PipelinePassList;
class NAZARA_GRAPHICS_API Camera : public PipelineViewer
{
public:
inline Camera(const RenderTarget* renderTarget, ProjectionType projectionType = ProjectionType::Perspective);
inline Camera(const RenderTarget* renderTarget, std::shared_ptr<PipelinePassList> pipelinePasses, ProjectionType projectionType = ProjectionType::Perspective);
Camera(const RenderTarget* renderTarget, ProjectionType projectionType = ProjectionType::Perspective);
inline Camera(const Camera& camera);
inline Camera(Camera&& camera) noexcept;
~Camera() = default;
inline void DisableFramePipelinePasses(FramePipelineExtraPassFlags framePipelineExtraPassFlags);
inline void EnableFramePipelinePasses(FramePipelineExtraPassFlags framePipelineExtraPassFlags);
std::vector<std::unique_ptr<FramePipelinePass>> BuildPasses(FramePipelinePass::PassData& passData) const override;
inline float GetAspectRatio() const;
const Color& GetClearColor() const override;
inline DegreeAnglef GetFOV() const;
inline FramePipelineExtraPassFlags GetFramePipelineExtraPassFlags() const;
inline ProjectionType GetProjectionType() const;
UInt32 GetRenderMask() const override;
inline Int32 GetRenderOrder() const;
@@ -46,9 +45,10 @@ namespace Nz
inline float GetZFar() const;
inline float GetZNear() const;
std::size_t RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph) const override;
inline void UpdateClearColor(Color color);
inline void UpdateFOV(DegreeAnglef fov);
inline void UpdateFramePipelinePasses(FramePipelineExtraPassFlags framePipelineExtraFlags);
inline void UpdateProjectionType(ProjectionType projectionType);
inline void UpdateRenderMask(UInt32 renderMask);
inline void UpdateRenderOrder(Int32 renderOrder);
@@ -70,10 +70,10 @@ namespace Nz
NazaraSlot(RenderTarget, OnRenderTargetRelease, m_onRenderTargetRelease);
NazaraSlot(RenderTarget, OnRenderTargetSizeChange, m_onRenderTargetSizeChange);
std::shared_ptr<PipelinePassList> m_framePipelinePasses;
const RenderTarget* m_renderTarget;
Color m_clearColor;
DegreeAnglef m_fov;
FramePipelineExtraPassFlags m_framePipelineExtraPassFlags;
Int32 m_renderOrder;
ProjectionType m_projectionType;
Rectf m_targetRegion;

View File

@@ -7,11 +7,11 @@
namespace Nz
{
inline Camera::Camera(const RenderTarget* renderTarget, ProjectionType projectionType) :
inline Camera::Camera(const RenderTarget* renderTarget, std::shared_ptr<PipelinePassList> pipelinePasses, ProjectionType projectionType) :
m_framePipelinePasses(std::move(pipelinePasses)),
m_renderTarget(nullptr),
m_clearColor(Color::Black()),
m_fov(90.f),
m_framePipelineExtraPassFlags(FramePipelineExtraPass::DebugDraw),
m_renderOrder(0),
m_projectionType(projectionType),
m_targetRegion(0.f, 0.f, 1.f, 1.f),
@@ -21,17 +21,14 @@ namespace Nz
m_zFar((projectionType == ProjectionType::Perspective) ? 1000.f : 1.f),
m_zNear((projectionType == ProjectionType::Perspective) ? 1.f : -1.f)
{
if (projectionType == ProjectionType::Perspective)
m_framePipelineExtraPassFlags |= FramePipelineExtraPass::DepthPrepass;
UpdateTarget(renderTarget);
}
inline Camera::Camera(const Camera& camera) :
m_framePipelinePasses(camera.m_framePipelinePasses),
m_renderTarget(nullptr),
m_clearColor(camera.m_clearColor),
m_fov(camera.m_fov),
m_framePipelineExtraPassFlags(camera.m_framePipelineExtraPassFlags),
m_renderOrder(camera.m_renderOrder),
m_projectionType(camera.m_projectionType),
m_targetRegion(camera.m_targetRegion),
@@ -46,10 +43,10 @@ namespace Nz
}
inline Camera::Camera(Camera&& camera) noexcept :
m_framePipelinePasses(std::move(camera.m_framePipelinePasses)),
m_renderTarget(nullptr),
m_clearColor(camera.m_clearColor),
m_fov(camera.m_fov),
m_framePipelineExtraPassFlags(camera.m_framePipelineExtraPassFlags),
m_renderOrder(camera.m_renderOrder),
m_projectionType(camera.m_projectionType),
m_targetRegion(camera.m_targetRegion),
@@ -63,16 +60,6 @@ namespace Nz
UpdateTarget(camera.m_renderTarget);
}
inline void Camera::DisableFramePipelinePasses(FramePipelineExtraPassFlags framePipelineExtraPassFlags)
{
m_framePipelineExtraPassFlags &= ~framePipelineExtraPassFlags;
}
inline void Camera::EnableFramePipelinePasses(FramePipelineExtraPassFlags framePipelineExtraPassFlags)
{
m_framePipelineExtraPassFlags |= framePipelineExtraPassFlags;
}
inline float Camera::GetAspectRatio() const
{
return m_aspectRatio;
@@ -83,11 +70,6 @@ namespace Nz
return m_fov;
}
inline FramePipelineExtraPassFlags Camera::GetFramePipelineExtraPassFlags() const
{
return m_framePipelineExtraPassFlags;
}
inline ProjectionType Camera::GetProjectionType() const
{
return m_projectionType;
@@ -129,11 +111,6 @@ namespace Nz
UpdateProjectionMatrix();
}
inline void Camera::UpdateFramePipelinePasses(FramePipelineExtraPassFlags framePipelineExtraFlags)
{
m_framePipelineExtraPassFlags = framePipelineExtraFlags;
}
inline void Camera::UpdateZFar(float zFar)
{
m_zFar = zFar;
@@ -150,7 +127,7 @@ namespace Nz
inline Camera& Camera::operator=(const Camera& camera)
{
m_framePipelineExtraPassFlags = camera.m_framePipelineExtraPassFlags;
m_framePipelinePasses = camera.m_framePipelinePasses;
m_fov = camera.m_fov;
m_projectionType = camera.m_projectionType;
m_targetRegion = camera.m_targetRegion;
@@ -167,7 +144,7 @@ namespace Nz
inline Camera& Camera::operator=(Camera&& camera) noexcept
{
m_framePipelineExtraPassFlags = camera.m_framePipelineExtraPassFlags;
m_framePipelinePasses = std::move(camera.m_framePipelinePasses);
m_fov = camera.m_fov;
m_projectionType = camera.m_projectionType;
m_targetRegion = camera.m_targetRegion;
@@ -281,4 +258,3 @@ namespace Nz
}
#include <Nazara/Graphics/DebugOff.hpp>
#include "Camera.hpp"

View File

@@ -10,6 +10,7 @@
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/FramePipelinePass.hpp>
#include <string>
namespace Nz
{
@@ -17,24 +18,26 @@ namespace Nz
class FrameGraph;
class FramePass;
class FramePipeline;
class ParameterList;
class RenderFrame;
class NAZARA_GRAPHICS_API DebugDrawPipelinePass : public FramePipelinePass
{
public:
DebugDrawPipelinePass(FramePipeline& owner, AbstractViewer* viewer);
DebugDrawPipelinePass(PassData& passData, std::string passName, const ParameterList& parameters = {});
DebugDrawPipelinePass(const DebugDrawPipelinePass&) = delete;
DebugDrawPipelinePass(DebugDrawPipelinePass&&) = delete;
~DebugDrawPipelinePass() = default;
void Prepare(RenderFrame& renderFrame);
void Prepare(FrameData& frameData) override;
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t inputColorBufferIndex, std::size_t outputColorBufferIndex);
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs) override;
DebugDrawPipelinePass& operator=(const DebugDrawPipelinePass&) = delete;
DebugDrawPipelinePass& operator=(DebugDrawPipelinePass&&) = delete;
private:
std::string m_passName;
AbstractViewer* m_viewer;
FramePipeline& m_pipeline;
};

View File

@@ -6,6 +6,13 @@
namespace Nz
{
inline DebugDrawPipelinePass::DebugDrawPipelinePass(PassData& passData, std::string passName, const ParameterList& /*parameters*/) :
FramePipelinePass({}),
m_passName(std::move(passName)),
m_viewer(passData.viewer),
m_pipeline(passData.pipeline)
{
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -30,24 +30,28 @@ namespace Nz
class NAZARA_GRAPHICS_API DepthPipelinePass : public FramePipelinePass
{
public:
DepthPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer, std::size_t passIndex, std::string passName);
inline DepthPipelinePass(PassData& passData, std::string passName, const ParameterList& parameters);
inline DepthPipelinePass(PassData& passData, std::string passName, std::size_t materialPassIndex);
DepthPipelinePass(const DepthPipelinePass&) = delete;
DepthPipelinePass(DepthPipelinePass&&) = delete;
~DepthPipelinePass() = default;
inline void InvalidateCommandBuffers();
inline void InvalidateElements();
void InvalidateElements() override;
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, std::size_t visibilityHash);
void Prepare(FrameData& frameData) override;
void RegisterMaterialInstance(const MaterialInstance& materialInstance);
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t outputAttachment);
void RegisterMaterialInstance(const MaterialInstance& materialInstance) override;
void UnregisterMaterialInstance(const MaterialInstance& materialInstance);
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs) override;
void UnregisterMaterialInstance(const MaterialInstance& materialInstance) override;
DepthPipelinePass& operator=(const DepthPipelinePass&) = delete;
DepthPipelinePass& operator=(DepthPipelinePass&&) = delete;
static std::size_t GetMaterialPassIndex(const ParameterList& parameters);
private:
struct MaterialPassEntry
{

View File

@@ -6,6 +6,24 @@
namespace Nz
{
inline DepthPipelinePass::DepthPipelinePass(PassData& passData, std::string passName, const ParameterList& parameters) :
DepthPipelinePass(passData, std::move(passName), GetMaterialPassIndex(parameters))
{
}
inline DepthPipelinePass::DepthPipelinePass(PassData& passData, std::string passName, std::size_t materialPassIndex) :
FramePipelinePass(FramePipelineNotification::ElementInvalidation | FramePipelineNotification::MaterialInstanceRegistration),
m_passIndex(materialPassIndex),
m_lastVisibilityHash(0),
m_passName(std::move(passName)),
m_viewer(passData.viewer),
m_elementRegistry(passData.elementRegistry),
m_pipeline(passData.pipeline),
m_rebuildCommandBuffer(false),
m_rebuildElements(false)
{
}
inline void DepthPipelinePass::InvalidateCommandBuffers()
{
m_rebuildCommandBuffer = true;

View File

@@ -41,25 +41,22 @@ namespace Nz
Volume
};
enum class FramePipelineExtraPass
enum class FramePipelineNotification
{
DebugDraw,
DepthPrepass,
GammaCorrection,
ElementInvalidation,
MaterialInstanceRegistration,
Max = GammaCorrection
Max = MaterialInstanceRegistration
};
template<>
struct EnumAsFlags<FramePipelineExtraPass>
struct EnumAsFlags<FramePipelineNotification>
{
static constexpr FramePipelineExtraPass max = FramePipelineExtraPass::Max;
static constexpr FramePipelineNotification max = FramePipelineNotification::Max;
};
using FramePipelineExtraPassFlags = Flags<FramePipelineExtraPass>;
using FramePipelineNotificationFlags = Flags<FramePipelineNotification>;
constexpr FramePipelineExtraPassFlags FramePipelineAllExtraPasses = FramePipelineExtraPass::DebugDraw | FramePipelineExtraPass::DepthPrepass | FramePipelineExtraPass::GammaCorrection;
enum class MaterialPropertyType
{
Bool,

View File

@@ -55,7 +55,7 @@ namespace Nz
std::size_t RegisterLight(const Light* light, UInt32 renderMask) override;
std::size_t RegisterRenderable(std::size_t worldInstanceIndex, std::size_t skeletonInstanceIndex, const InstancedRenderable* instancedRenderable, UInt32 renderMask, const Recti& scissorBox) override;
std::size_t RegisterSkeleton(SkeletonInstancePtr skeletonInstance) override;
std::size_t RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder, FramePipelineExtraPassFlags passFlags) override;
std::size_t RegisterViewer(PipelineViewer* viewerInstance, Int32 renderOrder) override;
std::size_t RegisterWorldInstance(WorldInstancePtr worldInstance) override;
const Light* RetrieveLight(std::size_t lightIndex) const override;
@@ -140,14 +140,8 @@ namespace Nz
};
std::size_t finalColorAttachment;
std::size_t forwardColorAttachment;
std::size_t debugColorAttachment;
std::size_t depthStencilAttachment;
std::unique_ptr<DepthPipelinePass> depthPrepass;
std::unique_ptr<ForwardPipelinePass> forwardPass;
std::unique_ptr<DebugDrawPipelinePass> debugDrawPass;
std::unique_ptr<PostProcessPipelinePass> gammaCorrectionPass;
AbstractViewer* viewer;
std::vector<std::unique_ptr<FramePipelinePass>> passes;
PipelineViewer* viewer;
Int32 renderOrder = 0;
RenderQueueRegistry forwardRegistry;
RenderQueue<RenderElement*> forwardRenderQueue;

View File

@@ -34,20 +34,21 @@ namespace Nz
class NAZARA_GRAPHICS_API ForwardPipelinePass : public FramePipelinePass, TransferInterface
{
public:
ForwardPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer);
ForwardPipelinePass(PassData& passData, std::string passName, const ParameterList& parameters = {});
ForwardPipelinePass(const ForwardPipelinePass&) = delete;
ForwardPipelinePass(ForwardPipelinePass&&) = delete;
~ForwardPipelinePass() = default;
inline void InvalidateCommandBuffers();
inline void InvalidateElements();
void InvalidateElements() override;
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, const Bitset<UInt64>& visibleLights, std::size_t visibilityHash);
void Prepare(FrameData& frameData) override;
void RegisterMaterialInstance(const MaterialInstance& material);
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t colorBufferIndex, std::size_t depthBufferIndex, bool hasDepthPrepass);
void RegisterMaterialInstance(const MaterialInstance& material) override;
void UnregisterMaterialInstance(const MaterialInstance& material);
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs) override;
void UnregisterMaterialInstance(const MaterialInstance& material) override;
ForwardPipelinePass& operator=(const ForwardPipelinePass&) = delete;
ForwardPipelinePass& operator=(ForwardPipelinePass&&) = delete;
@@ -79,6 +80,7 @@ namespace Nz
std::size_t m_forwardPassIndex;
std::size_t m_lastVisibilityHash;
std::shared_ptr<RenderBuffer> m_lightDataBuffer;
std::string m_passName;
std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData;
std::vector<RenderElementOwner> m_renderElements;
std::unordered_map<const MaterialInstance*, MaterialPassEntry> m_materialInstances;

View File

@@ -20,11 +20,11 @@
namespace Nz
{
class AbstractViewer;
class InstancedRenderable;
class Light;
class LightShadowData;
class MaterialInstance;
class PipelineViewer;
class RenderFrame;
class NAZARA_GRAPHICS_API FramePipeline
@@ -47,7 +47,7 @@ namespace Nz
virtual std::size_t RegisterLight(const Light* light, UInt32 renderMask) = 0;
virtual std::size_t RegisterRenderable(std::size_t worldInstanceIndex, std::size_t skeletonInstanceIndex, const InstancedRenderable* instancedRenderable, UInt32 renderMask, const Recti& scissorBox) = 0;
virtual std::size_t RegisterSkeleton(SkeletonInstancePtr skeletonInstance) = 0;
virtual std::size_t RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder, FramePipelineExtraPassFlags passFlags) = 0;
virtual std::size_t RegisterViewer(PipelineViewer* viewerInstance, Int32 renderOrder) = 0;
virtual std::size_t RegisterWorldInstance(WorldInstancePtr worldInstance) = 0;
virtual const Light* RetrieveLight(std::size_t lightIndex) const = 0;

View File

@@ -9,25 +9,80 @@
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Math/Frustum.hpp>
#include <Nazara/Math/Rect.hpp>
#include <NazaraUtils/Bitset.hpp>
#include <limits>
namespace Nz
{
class AbstractViewer;
class ElementRendererRegistry;
class FrameGraph;
class FramePass;
class FramePipeline;
class InstancedRenderable;
class MaterialInstance;
class RenderFrame;
class SkeletonInstance;
class WorldInstance;
class NAZARA_GRAPHICS_API FramePipelinePass
{
public:
FramePipelinePass() = default;
struct FrameData;
struct PassData;
struct PassInputOuputs;
struct VisibleRenderable;
inline FramePipelinePass(FramePipelineNotificationFlags notificationFlags);
FramePipelinePass(const FramePipelinePass&) = delete;
FramePipelinePass(FramePipelinePass&&) = delete;
virtual ~FramePipelinePass();
virtual void InvalidateElements();
virtual void Prepare(FrameData& frameData) = 0;
virtual void RegisterMaterialInstance(const MaterialInstance& materialInstance);
virtual FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs) = 0;
inline bool ShouldNotify(FramePipelineNotification notification) const;
virtual void UnregisterMaterialInstance(const MaterialInstance& materialInstance);
FramePipelinePass& operator=(const FramePipelinePass&) = delete;
FramePipelinePass& operator=(FramePipelinePass&&) = delete;
struct FrameData
{
const Bitset<UInt64>* visibleLights;
const Frustumf& frustum;
RenderFrame& renderFrame;
const std::vector<VisibleRenderable>& visibleRenderables;
std::size_t visibilityHash;
};
struct PassData
{
AbstractViewer* viewer;
ElementRendererRegistry& elementRegistry;
FramePipeline& pipeline;
};
struct PassInputOuputs
{
// TODO: Add Nz::View / Nz::Span
const std::size_t* inputAttachments;
const std::size_t* outputAttachments;
std::size_t depthStencilInput = InvalidAttachmentIndex;
std::size_t depthStencilOutput = InvalidAttachmentIndex;
std::size_t inputCount = 0;
std::size_t outputCount = 0;
};
struct VisibleRenderable
{
const InstancedRenderable* instancedRenderable;
@@ -35,6 +90,11 @@ namespace Nz
const WorldInstance* worldInstance;
Recti scissorBox;
};
static constexpr std::size_t InvalidAttachmentIndex = std::numeric_limits<std::size_t>::max();
private:
FramePipelineNotificationFlags m_notificationFlags;
};
}

View File

@@ -6,6 +6,15 @@
namespace Nz
{
inline FramePipelinePass::FramePipelinePass(FramePipelineNotificationFlags notificationFlags) :
m_notificationFlags(notificationFlags)
{
}
inline bool FramePipelinePass::ShouldNotify(FramePipelineNotification notification) const
{
return m_notificationFlags.Test(notification);
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -0,0 +1,52 @@
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_FRAMEPIPELINEPASSREGISTRY_HPP
#define NAZARA_GRAPHICS_FRAMEPIPELINEPASSREGISTRY_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Graphics/FramePipelinePass.hpp>
#include <NazaraUtils/Algorithm.hpp>
#include <functional>
#include <list>
#include <string>
#include <unordered_map>
#include <vector>
namespace Nz
{
class ParameterList;
class FramePipelinePassRegistry
{
public:
using Factory = std::function<std::unique_ptr<FramePipelinePass>(FramePipelinePass::PassData& passData, std::string passName, const ParameterList& parameters)>;
FramePipelinePassRegistry() = default;
FramePipelinePassRegistry(const FramePipelinePassRegistry&) = default;
FramePipelinePassRegistry(FramePipelinePassRegistry&&) = default;
~FramePipelinePassRegistry() = default;
inline std::unique_ptr<FramePipelinePass> BuildPass(std::size_t passIndex, FramePipelinePass::PassData& passData, std::string passName, const ParameterList& parameters) const;
inline std::size_t GetPassIndex(std::string_view passName) const;
template<typename T> std::size_t RegisterPass(std::string passName);
inline std::size_t RegisterPass(std::string passName, Factory factory);
FramePipelinePassRegistry& operator=(const FramePipelinePassRegistry&) = default;
FramePipelinePassRegistry& operator=(FramePipelinePassRegistry&&) = default;
private:
std::list<std::string> m_passNames; //< in order to allow std::string_view as a key in C++17 (keep std::string stable as well because of SSO)
std::unordered_map<std::string_view, std::size_t> m_passIndex;
std::vector<Factory> m_passFactories;
};
}
#include <Nazara/Graphics/FramePipelinePassRegistry.inl>
#endif // NAZARA_GRAPHICS_FRAMEPIPELINEPASSREGISTRY_HPP

View File

@@ -0,0 +1,49 @@
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <cassert>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline std::unique_ptr<FramePipelinePass> FramePipelinePassRegistry::BuildPass(std::size_t passIndex, FramePipelinePass::PassData& passData, std::string passName, const ParameterList& parameters) const
{
assert(passIndex < m_passFactories.size());
return m_passFactories[passIndex](passData, passName, parameters);
}
inline std::size_t FramePipelinePassRegistry::GetPassIndex(std::string_view passName) const
{
auto it = m_passIndex.find(passName);
if (it == m_passIndex.end())
throw std::runtime_error("pass " + std::string(passName) + " must be registered before being used");
return it->second;
}
template<typename T>
std::size_t FramePipelinePassRegistry::RegisterPass(std::string passName)
{
return RegisterPass(std::move(passName), [](FramePipelinePass::PassData& passData, std::string passName, const ParameterList& parameters) -> std::unique_ptr<FramePipelinePass>
{
return std::make_unique<T>(passData, std::move(passName), parameters);
});
}
inline std::size_t FramePipelinePassRegistry::RegisterPass(std::string passName, Factory factory)
{
if (m_passIndex.find(passName) != m_passIndex.end())
throw std::runtime_error("pass " + passName + " is already registered");
m_passNames.push_back(std::move(passName));
std::size_t passIndex = m_passIndex.size();
m_passIndex.emplace(m_passNames.back(), passIndex);
m_passFactories.emplace_back(std::move(factory));
return passIndex;
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -9,9 +9,11 @@
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/FramePipelinePassRegistry.hpp>
#include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/MaterialInstance.hpp>
#include <Nazara/Graphics/MaterialPassRegistry.hpp>
#include <Nazara/Graphics/PipelinePassList.hpp>
#include <Nazara/Graphics/TextureSamplerCache.hpp>
#include <Nazara/Renderer/RenderDevice.hpp>
#include <Nazara/Renderer/RenderPassCache.hpp>
@@ -43,7 +45,10 @@ namespace Nz
inline const std::shared_ptr<RenderPipeline>& GetBlitPipeline(bool transparent) const;
inline const std::shared_ptr<RenderPipelineLayout>& GetBlitPipelineLayout() const;
inline const DefaultMaterials& GetDefaultMaterials() const;
inline const std::shared_ptr<PipelinePassList>& GetDefaultPipelinePasses() const;
inline const DefaultTextures& GetDefaultTextures() const;
inline FramePipelinePassRegistry& GetFramePipelinePassRegistry();
inline const FramePipelinePassRegistry& GetFramePipelinePassRegistry() const;
inline MaterialPassRegistry& GetMaterialPassRegistry();
inline const MaterialPassRegistry& GetMaterialPassRegistry() const;
inline MaterialInstanceLoader& GetMaterialInstanceLoader();
@@ -88,21 +93,25 @@ namespace Nz
private:
void BuildBlitPipeline();
void BuildDefaultMaterials();
void BuildDefaultPipelinePasses();
void BuildDefaultTextures();
template<std::size_t N> void RegisterEmbedShaderModule(const UInt8(&content)[N]);
void RegisterMaterialPasses();
void RegisterPipelinePasses();
void RegisterShaderModules();
void SelectDepthStencilFormats();
std::optional<RenderPassCache> m_renderPassCache;
std::optional<TextureSamplerCache> m_samplerCache;
std::shared_ptr<nzsl::FilesystemModuleResolver> m_shaderModuleResolver;
std::shared_ptr<PipelinePassList> m_defaultPipelinePasses;
std::shared_ptr<RenderDevice> m_renderDevice;
std::shared_ptr<RenderPipeline> m_blitPipeline;
std::shared_ptr<RenderPipeline> m_blitPipelineTransparent;
std::shared_ptr<RenderPipelineLayout> m_blitPipelineLayout;
DefaultMaterials m_defaultMaterials;
DefaultTextures m_defaultTextures;
FramePipelinePassRegistry m_pipelinePassRegistry;
MaterialInstanceLoader m_materialInstanceLoader;
MaterialLoader m_materialLoader;
MaterialPassRegistry m_materialPassRegistry;

View File

@@ -21,11 +21,26 @@ namespace Nz
return m_defaultMaterials;
}
inline const std::shared_ptr<PipelinePassList>& Graphics::GetDefaultPipelinePasses() const
{
return m_defaultPipelinePasses;
}
inline auto Graphics::GetDefaultTextures() const -> const DefaultTextures&
{
return m_defaultTextures;
}
inline FramePipelinePassRegistry& Graphics::GetFramePipelinePassRegistry()
{
return m_pipelinePassRegistry;
}
inline const FramePipelinePassRegistry& Graphics::GetFramePipelinePassRegistry() const
{
return m_pipelinePassRegistry;
}
inline MaterialPassRegistry& Graphics::GetMaterialPassRegistry()
{
return m_materialPassRegistry;

View File

@@ -30,7 +30,7 @@ namespace Nz
inline bool IsPerViewer() const;
virtual void PrepareRendering(RenderFrame& renderFrame, const AbstractViewer* viewer) = 0;
virtual void PrepareRendering(RenderFrame& renderFrame, [[maybe_unused]] const AbstractViewer* viewer) = 0;
virtual void RegisterMaterialInstance(const MaterialInstance& matInstance) = 0;
virtual void RegisterPassInputs(FramePass& pass, const AbstractViewer* viewer) = 0;

View File

@@ -0,0 +1,72 @@
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_PIPELINEPASSLIST_HPP
#define NAZARA_GRAPHICS_PIPELINEPASSLIST_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Core/ParameterList.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/FramePassAttachment.hpp>
#include <Nazara/Graphics/FramePipelinePass.hpp>
#include <NazaraUtils/FixedVector.hpp>
#include <array>
#include <limits>
#include <string>
namespace Nz
{
class FrameGraph;
class NAZARA_GRAPHICS_API PipelinePassList
{
public:
PipelinePassList() = default;
PipelinePassList(const PipelinePassList&) = delete;
PipelinePassList(PipelinePassList&&) = delete;
~PipelinePassList() = default;
inline std::size_t AddAttachment(FramePassAttachment attachment);
inline std::size_t AddPass(std::string name, std::size_t implIndex, ParameterList parameterList = {});
std::vector<std::unique_ptr<FramePipelinePass>> BuildPasses(FramePipelinePass::PassData& passData) const;
std::size_t RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph) const;
inline void SetFinalOutput(std::size_t attachmentIndex);
inline void SetPassInput(std::size_t passIndex, std::size_t inputIndex, std::size_t attachmentIndex);
inline void SetPassOutput(std::size_t passIndex, std::size_t outputIndex, std::size_t attachmentIndex);
inline void SetPassDepthStencilInput(std::size_t passIndex, std::size_t attachmentIndex);
inline void SetPassDepthStencilOutput(std::size_t passIndex, std::size_t attachmentIndex);
PipelinePassList& operator=(const PipelinePassList&) = delete;
PipelinePassList& operator=(PipelinePassList&&) = delete;
static constexpr std::size_t MaxPassAttachment = 8;
private:
static constexpr std::size_t NoAttachment = std::numeric_limits<std::size_t>::max();
struct Pass
{
FixedVector<std::size_t /*attachmentIndex*/, MaxPassAttachment> inputs;
FixedVector<std::size_t /*attachmentIndex*/, MaxPassAttachment> outputs;
std::size_t depthStencilInput = NoAttachment;
std::size_t depthStencilOutput = NoAttachment;
std::size_t implIndex;
std::string name;
ParameterList parameterList;
};
std::size_t m_finalOutputAttachment;
std::vector<FramePassAttachment> m_attachments;
std::vector<Pass> m_passes;
};
}
#include <Nazara/Graphics/PipelinePassList.inl>
#endif // NAZARA_GRAPHICS_PIPELINEPASSLIST_HPP

View File

@@ -0,0 +1,73 @@
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <cassert>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline std::size_t PipelinePassList::AddAttachment(FramePassAttachment attachment)
{
std::size_t index = m_attachments.size();
m_attachments.emplace_back(std::move(attachment));
return index;
}
inline std::size_t PipelinePassList::AddPass(std::string name, std::size_t implIndex, ParameterList parameterList)
{
std::size_t index = m_passes.size();
auto& pass = m_passes.emplace_back();
pass.name = std::move(name);
pass.implIndex = implIndex;
pass.parameterList = std::move(parameterList);
return index;
}
inline void PipelinePassList::SetFinalOutput(std::size_t attachmentIndex)
{
m_finalOutputAttachment = attachmentIndex;
}
inline void PipelinePassList::SetPassInput(std::size_t passIndex, std::size_t inputIndex, std::size_t attachmentIndex)
{
assert(passIndex < m_passes.size());
auto& pass = m_passes[passIndex];
assert(inputIndex < MaxPassAttachment);
if (inputIndex >= pass.inputs.size())
pass.inputs.resize(inputIndex + 1, NoAttachment);
pass.inputs[inputIndex] = attachmentIndex;
}
inline void PipelinePassList::SetPassOutput(std::size_t passIndex, std::size_t outputIndex, std::size_t attachmentIndex)
{
assert(passIndex < m_passes.size());
auto& pass = m_passes[passIndex];
assert(outputIndex < MaxPassAttachment);
if (outputIndex >= pass.outputs.size())
pass.outputs.resize(outputIndex + 1, NoAttachment);
pass.outputs[outputIndex] = attachmentIndex;
}
inline void PipelinePassList::SetPassDepthStencilInput(std::size_t passIndex, std::size_t attachmentIndex)
{
assert(passIndex < m_passes.size());
auto& pass = m_passes[passIndex];
pass.depthStencilInput = attachmentIndex;
}
inline void PipelinePassList::SetPassDepthStencilOutput(std::size_t passIndex, std::size_t attachmentIndex)
{
assert(passIndex < m_passes.size());
auto& pass = m_passes[passIndex];
pass.depthStencilOutput = attachmentIndex;
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_PIPELINEVIEWER_HPP
#define NAZARA_GRAPHICS_PIPELINEVIEWER_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Graphics/FramePipelinePass.hpp>
#include <vector>
namespace Nz
{
class NAZARA_GRAPHICS_API PipelineViewer : public AbstractViewer
{
public:
PipelineViewer() = default;
PipelineViewer(const PipelineViewer&) = delete;
PipelineViewer(PipelineViewer&&) = delete;
~PipelineViewer() = default;
virtual std::vector<std::unique_ptr<FramePipelinePass>> BuildPasses(FramePipelinePass::PassData& passData) const = 0;
virtual std::size_t RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph) const = 0;
PipelineViewer& operator=(const PipelineViewer&) = delete;
PipelineViewer& operator=(PipelineViewer&&) = delete;
};
}
#include <Nazara/Graphics/PipelineViewer.inl>
#endif // NAZARA_GRAPHICS_PIPELINEVIEWER_HPP

View File

@@ -0,0 +1,11 @@
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// 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/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -17,6 +17,7 @@ namespace Nz
class FrameGraph;
class FramePass;
class FramePipeline;
class ParameterList;
class RenderFrame;
class RenderPipeline;
class ShaderBinding;
@@ -24,18 +25,21 @@ namespace Nz
class NAZARA_GRAPHICS_API PostProcessPipelinePass : public FramePipelinePass
{
public:
PostProcessPipelinePass(FramePipeline& owner, std::string passName, std::string shaderName);
PostProcessPipelinePass(PassData& passData, std::string passName, const ParameterList& parameters);
PostProcessPipelinePass(PassData& passData, std::string passName, std::string shaderName);
PostProcessPipelinePass(const PostProcessPipelinePass&) = delete;
PostProcessPipelinePass(PostProcessPipelinePass&&) = delete;
~PostProcessPipelinePass() = default;
void Prepare(RenderFrame& renderFrame);
void Prepare(FrameData& frameData) override;
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t inputColorBufferIndex, std::size_t outputColorBufferIndex);
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs) override;
PostProcessPipelinePass& operator=(const PostProcessPipelinePass&) = delete;
PostProcessPipelinePass& operator=(PostProcessPipelinePass&&) = delete;
static std::string GetShaderName(const ParameterList& parameters);
private:
void BuildPipeline();

View File

@@ -6,6 +6,10 @@
namespace Nz
{
inline PostProcessPipelinePass::PostProcessPipelinePass(PassData& passData, std::string passName, const ParameterList& parameters) :
PostProcessPipelinePass(passData, std::move(passName), GetShaderName(parameters))
{
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -28,7 +28,7 @@ namespace Nz
inline const ViewerInstance& GetViewerInstance() const;
void PrepareRendering(RenderFrame& renderFrame, const AbstractViewer* viewer) override;
void PrepareRendering(RenderFrame& renderFrame, [[maybe_unused]] const AbstractViewer* viewer) override;
void RegisterMaterialInstance(const MaterialInstance& matInstance) override;
void RegisterPassInputs(FramePass& pass, const AbstractViewer* viewer) override;