Add FrameGraph (WIP)
This commit is contained in:
98
include/Nazara/Graphics/BakedFrameGraph.hpp
Normal file
98
include/Nazara/Graphics/BakedFrameGraph.hpp
Normal file
@@ -0,0 +1,98 @@
|
||||
// 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_BAKEDFRAMEGRAPH_HPP
|
||||
#define NAZARA_BAKEDFRAMEGRAPH_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/FramePass.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Renderer/CommandPool.hpp>
|
||||
#include <Nazara/Renderer/Framebuffer.hpp>
|
||||
#include <Nazara/Renderer/RenderPass.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class RenderFrame;
|
||||
|
||||
class NAZARA_GRAPHICS_API BakedFrameGraph
|
||||
{
|
||||
friend class FrameGraph;
|
||||
|
||||
public:
|
||||
BakedFrameGraph(const BakedFrameGraph&) = delete;
|
||||
BakedFrameGraph(BakedFrameGraph&&) noexcept = default;
|
||||
~BakedFrameGraph() = default;
|
||||
|
||||
void Execute(RenderFrame& renderFrame);
|
||||
|
||||
const std::shared_ptr<Texture>& GetAttachmentTexture(std::size_t attachmentIndex) const;
|
||||
const std::shared_ptr<RenderPass>& GetRenderPass(std::size_t passIndex) const;
|
||||
|
||||
void Resize(unsigned int width, unsigned int height);
|
||||
|
||||
BakedFrameGraph& operator=(const BakedFrameGraph&) = delete;
|
||||
BakedFrameGraph& operator=(BakedFrameGraph&&) noexcept = default;
|
||||
|
||||
private:
|
||||
struct PassData;
|
||||
struct TextureData;
|
||||
using AttachmentIdToTextureId = std::unordered_map<std::size_t /*attachmentId*/, std::size_t /*textureId*/>;
|
||||
using PassIdToPhysicalPassIndex = std::unordered_map<std::size_t /*passId*/, std::size_t /*physicalPassId*/>;
|
||||
|
||||
BakedFrameGraph(std::vector<PassData> passes, std::vector<TextureData> textures, AttachmentIdToTextureId attachmentIdToTextureMapping, PassIdToPhysicalPassIndex passIdToPhysicalPassMapping);
|
||||
|
||||
struct TextureTransition
|
||||
{
|
||||
std::size_t textureId;
|
||||
MemoryAccessFlags dstAccessMask;
|
||||
MemoryAccessFlags srcAccessMask;
|
||||
PipelineStageFlags dstStageMask;
|
||||
PipelineStageFlags srcStageMask;
|
||||
TextureLayout newLayout;
|
||||
TextureLayout oldLayout;
|
||||
};
|
||||
|
||||
struct SubpassData
|
||||
{
|
||||
FramePass::CommandCallback commandCallback;
|
||||
};
|
||||
|
||||
struct PassData
|
||||
{
|
||||
CommandBufferPtr commandBuffer;
|
||||
std::shared_ptr<Framebuffer> framebuffer;
|
||||
std::shared_ptr<RenderPass> renderPass;
|
||||
std::vector<std::size_t> outputTextureIndices;
|
||||
std::vector<SubpassData> subpasses;
|
||||
std::vector<TextureTransition> transitions;
|
||||
FramePass::ExecutionCallback executionCallback;
|
||||
Recti renderRect;
|
||||
};
|
||||
|
||||
struct TextureData
|
||||
{
|
||||
std::shared_ptr<Texture> texture;
|
||||
PixelFormat format;
|
||||
TextureUsageFlags usage;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
};
|
||||
|
||||
std::shared_ptr<CommandPool> m_commandPool;
|
||||
std::vector<PassData> m_passes;
|
||||
std::vector<TextureData> m_textures;
|
||||
AttachmentIdToTextureId m_attachmentToTextureMapping;
|
||||
PassIdToPhysicalPassIndex m_passIdToPhysicalPassMapping;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/BakedFrameGraph.inl>
|
||||
|
||||
#endif
|
||||
12
include/Nazara/Graphics/BakedFrameGraph.inl
Normal file
12
include/Nazara/Graphics/BakedFrameGraph.inl
Normal file
@@ -0,0 +1,12 @@
|
||||
// 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/BakedFrameGraph.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
120
include/Nazara/Graphics/FrameGraph.hpp
Normal file
120
include/Nazara/Graphics/FrameGraph.hpp
Normal file
@@ -0,0 +1,120 @@
|
||||
// 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_FRAMEGRAPH_HPP
|
||||
#define NAZARA_FRAMEGRAPH_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/BakedFrameGraph.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/FramePass.hpp>
|
||||
#include <Nazara/Graphics/FramePassAttachment.hpp>
|
||||
#include <Nazara/Renderer/Enums.hpp>
|
||||
#include <Nazara/Renderer/RenderPass.hpp>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API FrameGraph
|
||||
{
|
||||
public:
|
||||
FrameGraph() = default;
|
||||
FrameGraph(const FrameGraph&) = delete;
|
||||
FrameGraph(FrameGraph&&) noexcept = default;
|
||||
~FrameGraph() = default;
|
||||
|
||||
inline std::size_t AddAttachment(FramePassAttachment attachment);
|
||||
inline FramePass& AddPass(std::string name);
|
||||
|
||||
BakedFrameGraph Bake();
|
||||
|
||||
inline void SetBackbufferOutput(std::size_t backbufferOutput);
|
||||
|
||||
FrameGraph& operator=(const FrameGraph&) = delete;
|
||||
FrameGraph& operator=(FrameGraph&&) noexcept = default;
|
||||
|
||||
private:
|
||||
struct PassBarriers;
|
||||
|
||||
using BarrierList = std::vector<PassBarriers>;
|
||||
using PassList = std::vector<std::size_t /*PassIndex*/>;
|
||||
using AttachmentIdToPassMap = std::unordered_map<std::size_t /*resourceIndex*/, PassList /*passIndexes*/>;
|
||||
using AttachmentIdToTextureId = std::unordered_map<std::size_t /*attachmentId*/, std::size_t /*textureId*/>;
|
||||
using PassIdToPhysicalPassIndex = std::unordered_map<std::size_t /*passId*/, std::size_t /*physicalPassId*/>;
|
||||
using TextureTransition = BakedFrameGraph::TextureTransition;
|
||||
|
||||
struct Barrier
|
||||
{
|
||||
std::size_t textureId;
|
||||
MemoryAccessFlags access;
|
||||
PipelineStageFlags stages;
|
||||
TextureLayout layout;
|
||||
};
|
||||
|
||||
struct PassBarriers
|
||||
{
|
||||
std::vector<Barrier> invalidationBarriers;
|
||||
std::vector<Barrier> flushBarriers;
|
||||
};
|
||||
|
||||
struct PhysicalPassData
|
||||
{
|
||||
struct Subpass
|
||||
{
|
||||
std::size_t passIndex;
|
||||
};
|
||||
|
||||
std::vector<TextureTransition> textureTransitions;
|
||||
std::vector<Subpass> passes;
|
||||
};
|
||||
|
||||
struct TextureData
|
||||
{
|
||||
PixelFormat format;
|
||||
TextureUsageFlags usage;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
};
|
||||
|
||||
struct WorkData
|
||||
{
|
||||
std::size_t backbufferResourceIndex;
|
||||
std::vector<std::shared_ptr<RenderPass>> renderPasses;
|
||||
std::vector<PhysicalPassData> physicalPasses;
|
||||
std::vector<TextureData> textures;
|
||||
AttachmentIdToPassMap attachmentReadList;
|
||||
AttachmentIdToPassMap attachmentWriteList;
|
||||
AttachmentIdToTextureId attachmentToTextures;
|
||||
BarrierList barrierList;
|
||||
PassList passList;
|
||||
PassIdToPhysicalPassIndex passIdToPhysicalPassIndex;
|
||||
};
|
||||
|
||||
void AssignPhysicalPasses();
|
||||
void AssignPhysicalTextures();
|
||||
void BuildBarriers();
|
||||
void BuildPhysicalBarriers();
|
||||
void BuildPhysicalPassDependencies(std::size_t colorAttachmentCount, bool hasDepthStencilAttachment, std::vector<RenderPass::Attachment>& renderPassAttachments, std::vector<RenderPass::SubpassDescription>& subpasses, std::vector<RenderPass::SubpassDependency>& dependencies);
|
||||
void BuildPhysicalPasses();
|
||||
void BuildReadWriteList();
|
||||
void RemoveDuplicatePasses();
|
||||
void ReorderPasses();
|
||||
void TraverseGraph(std::size_t passIndex);
|
||||
|
||||
std::optional<std::size_t> m_backbufferOutput;
|
||||
std::vector<FramePass> m_framePasses;
|
||||
std::vector<FramePassAttachment> m_attachments;
|
||||
WorkData m_pending;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/FrameGraph.inl>
|
||||
|
||||
#endif
|
||||
31
include/Nazara/Graphics/FrameGraph.inl
Normal file
31
include/Nazara/Graphics/FrameGraph.inl
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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/FrameGraph.hpp>
|
||||
#include <cassert>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline std::size_t FrameGraph::AddAttachment(FramePassAttachment attachment)
|
||||
{
|
||||
std::size_t id = m_attachments.size();
|
||||
m_attachments.emplace_back(std::move(attachment));
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
inline FramePass& FrameGraph::AddPass(std::string name)
|
||||
{
|
||||
std::size_t id = m_framePasses.size();
|
||||
return m_framePasses.emplace_back(*this, id, std::move(name));
|
||||
}
|
||||
|
||||
inline void FrameGraph::SetBackbufferOutput(std::size_t backbufferOutput)
|
||||
{
|
||||
m_backbufferOutput = backbufferOutput;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
102
include/Nazara/Graphics/FramePass.hpp
Normal file
102
include/Nazara/Graphics/FramePass.hpp
Normal file
@@ -0,0 +1,102 @@
|
||||
// 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_FRAMEPASS_HPP
|
||||
#define NAZARA_FRAMEPASS_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/FramePassAttachment.hpp>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class CommandBufferBuilder;
|
||||
class FrameGraph;
|
||||
|
||||
enum class FramePassExecution
|
||||
{
|
||||
Execute,
|
||||
Skip,
|
||||
UpdateAndExecute
|
||||
};
|
||||
|
||||
class NAZARA_GRAPHICS_API FramePass
|
||||
{
|
||||
public:
|
||||
using CommandCallback = std::function<void(CommandBufferBuilder& builder)>;
|
||||
using ExecutionCallback = std::function<FramePassExecution()>;
|
||||
struct DepthStencilClear;
|
||||
struct Input;
|
||||
struct Output;
|
||||
|
||||
inline FramePass(FrameGraph& owner, std::size_t passId, std::string name);
|
||||
FramePass(const FramePass&) = delete;
|
||||
FramePass(FramePass&&) noexcept = default;
|
||||
~FramePass() = default;
|
||||
|
||||
inline std::size_t AddInput(std::size_t attachmentId);
|
||||
inline std::size_t AddOutput(std::size_t attachmentId);
|
||||
|
||||
inline const CommandCallback& GetCommandCallback() const;
|
||||
inline const std::optional<DepthStencilClear>& GetDepthStencilClear() const;
|
||||
inline std::size_t GetDepthStencilInput() const;
|
||||
inline std::size_t GetDepthStencilOutput() const;
|
||||
inline const ExecutionCallback& GetExecutionCallback() const;
|
||||
inline const std::vector<Input>& GetInputs() const;
|
||||
inline const std::vector<Output>& GetOutputs() const;
|
||||
inline std::size_t GetPassId() const;
|
||||
|
||||
inline void SetCommandCallback(CommandCallback callback);
|
||||
inline void SetClearColor(std::size_t outputIndex, const std::optional<Color>& color);
|
||||
inline void SetDepthStencilClear(float depth, UInt32 stencil);
|
||||
inline void SetExecutionCallback(CommandCallback callback);
|
||||
|
||||
inline void SetDepthStencilInput(std::size_t attachmentId);
|
||||
inline void SetDepthStencilOutput(std::size_t attachmentId);
|
||||
|
||||
FramePass& operator=(const FramePass&) = delete;
|
||||
FramePass& operator=(FramePass&&) noexcept = default;
|
||||
|
||||
static constexpr std::size_t InvalidAttachmentId = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
struct DepthStencilClear
|
||||
{
|
||||
float depth;
|
||||
UInt32 stencil;
|
||||
};
|
||||
|
||||
struct Input
|
||||
{
|
||||
std::size_t attachmentId;
|
||||
};
|
||||
|
||||
struct Output
|
||||
{
|
||||
std::size_t attachmentId;
|
||||
std::optional<Color> clearColor;
|
||||
};
|
||||
|
||||
private:
|
||||
std::optional<DepthStencilClear> m_depthStencilClear;
|
||||
std::size_t m_depthStencilInput;
|
||||
std::size_t m_depthStencilOutput;
|
||||
std::size_t m_passId;
|
||||
std::string m_name;
|
||||
std::vector<Input> m_inputs;
|
||||
std::vector<Output> m_outputs;
|
||||
FrameGraph& m_owner;
|
||||
CommandCallback m_commandCallback;
|
||||
ExecutionCallback m_executionCallback;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/FramePass.inl>
|
||||
|
||||
#endif
|
||||
116
include/Nazara/Graphics/FramePass.inl
Normal file
116
include/Nazara/Graphics/FramePass.inl
Normal file
@@ -0,0 +1,116 @@
|
||||
// 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/FramePass.hpp>
|
||||
#include <cassert>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline FramePass::FramePass(FrameGraph& owner, std::size_t passId, std::string name) :
|
||||
m_depthStencilInput(InvalidAttachmentId),
|
||||
m_depthStencilOutput(InvalidAttachmentId),
|
||||
m_passId(passId),
|
||||
m_name(std::move(name)),
|
||||
m_owner(owner)
|
||||
{
|
||||
}
|
||||
|
||||
inline std::size_t FramePass::AddInput(std::size_t attachmentId)
|
||||
{
|
||||
assert(attachmentId != InvalidAttachmentId);
|
||||
|
||||
std::size_t inputIndex = m_inputs.size();
|
||||
auto& input = m_inputs.emplace_back();
|
||||
input.attachmentId = attachmentId;
|
||||
|
||||
return inputIndex;
|
||||
}
|
||||
|
||||
inline std::size_t FramePass::AddOutput(std::size_t attachmentId)
|
||||
{
|
||||
assert(attachmentId != InvalidAttachmentId);
|
||||
|
||||
std::size_t outputIndex = m_outputs.size();
|
||||
auto& output = m_outputs.emplace_back();
|
||||
output.attachmentId = attachmentId;
|
||||
|
||||
return outputIndex;
|
||||
}
|
||||
|
||||
inline auto FramePass::GetCommandCallback() const -> const CommandCallback&
|
||||
{
|
||||
return m_commandCallback;
|
||||
}
|
||||
|
||||
inline auto FramePass::GetDepthStencilClear() const -> const std::optional<DepthStencilClear>&
|
||||
{
|
||||
return m_depthStencilClear;
|
||||
}
|
||||
|
||||
inline std::size_t FramePass::GetDepthStencilInput() const
|
||||
{
|
||||
return m_depthStencilInput;
|
||||
}
|
||||
|
||||
inline std::size_t FramePass::GetDepthStencilOutput() const
|
||||
{
|
||||
return m_depthStencilOutput;
|
||||
}
|
||||
|
||||
inline auto FramePass::GetExecutionCallback() const -> const ExecutionCallback&
|
||||
{
|
||||
return m_executionCallback;
|
||||
}
|
||||
|
||||
inline auto FramePass::GetInputs() const -> const std::vector<Input>&
|
||||
{
|
||||
return m_inputs;
|
||||
}
|
||||
|
||||
inline auto FramePass::GetOutputs() const -> const std::vector<Output>&
|
||||
{
|
||||
return m_outputs;
|
||||
}
|
||||
|
||||
inline std::size_t FramePass::GetPassId() const
|
||||
{
|
||||
return m_passId;
|
||||
}
|
||||
|
||||
inline void FramePass::SetCommandCallback(CommandCallback callback)
|
||||
{
|
||||
m_commandCallback = std::move(callback);
|
||||
}
|
||||
|
||||
inline void FramePass::SetClearColor(std::size_t outputIndex, const std::optional<Color>& color)
|
||||
{
|
||||
assert(outputIndex < m_outputs.size());
|
||||
m_outputs[outputIndex].clearColor = color;
|
||||
}
|
||||
|
||||
inline void FramePass::SetDepthStencilClear(float depth, UInt32 stencil)
|
||||
{
|
||||
auto& dsClear = m_depthStencilClear.emplace();
|
||||
dsClear.depth = depth;
|
||||
dsClear.stencil = stencil;
|
||||
}
|
||||
|
||||
inline void FramePass::SetExecutionCallback(CommandCallback callback)
|
||||
{
|
||||
m_commandCallback = std::move(callback);
|
||||
}
|
||||
|
||||
inline void FramePass::SetDepthStencilInput(std::size_t attachmentId)
|
||||
{
|
||||
m_depthStencilInput = attachmentId;
|
||||
}
|
||||
|
||||
inline void FramePass::SetDepthStencilOutput(std::size_t attachmentId)
|
||||
{
|
||||
m_depthStencilOutput = attachmentId;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
26
include/Nazara/Graphics/FramePassAttachment.hpp
Normal file
26
include/Nazara/Graphics/FramePassAttachment.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
// 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
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_FRAMEPASSATTACHMENT_HPP
|
||||
#define NAZARA_FRAMEPASSATTACHMENT_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Utility/PixelFormat.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
struct FramePassAttachment
|
||||
{
|
||||
std::string name;
|
||||
PixelFormat format;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/FramePassAttachment.inl>
|
||||
|
||||
#endif
|
||||
13
include/Nazara/Graphics/FramePassAttachment.inl
Normal file
13
include/Nazara/Graphics/FramePassAttachment.inl
Normal file
@@ -0,0 +1,13 @@
|
||||
// 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/FramePassAttachment.hpp>
|
||||
#include <cassert>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
Reference in New Issue
Block a user