update framegraph
This commit is contained in:
parent
4c0291d271
commit
f89424979e
@ -7,15 +7,15 @@ namespace api {
|
||||
class TextureBuilder;
|
||||
class RenderPassBuilder;
|
||||
public:
|
||||
lemon::ListGraph mGraph;
|
||||
pmr::vector<RenderPassNode*> mPasses{FramePool()};
|
||||
lemon::ListGraph mGraph;
|
||||
pmr::vector<FrameGraphNodePtr> mNodes{FramePool()};
|
||||
public:
|
||||
template<typename T>
|
||||
RenderPassNode* AddRenderPass() { return AddRenderPass(&T::Setup, &T::Execute); }
|
||||
FrameGraphNodePtr AddRenderPass() { return AddRenderPass(&T::Setup, &T::Execute); }
|
||||
using RenderPassSetupFunction = std::function<void(FrameGraph&, RenderPassBuilder&)>;
|
||||
RenderPassNode* AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor);
|
||||
FrameGraphNodePtr AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor);
|
||||
using TextureSetupFunction = std::function<void(FrameGraph&, class TextureBuilder&)>;
|
||||
FrameResourceEdge* CreateTexture(const TextureSetupFunction& setup);
|
||||
FrameGraphEdgePtr CreateTexture(const TextureSetupFunction& setup);
|
||||
|
||||
void Compile();
|
||||
void Execute();
|
||||
|
||||
@ -3,22 +3,23 @@
|
||||
namespace api {
|
||||
struct FrameGraph::RenderPassBuilder {
|
||||
FrameGraph& graph;
|
||||
RenderPassNode& node;
|
||||
FrameResourceEdge* edge;
|
||||
FrameGraphNodePtr& node;
|
||||
FrameResource* resource;
|
||||
public:
|
||||
RenderPassBuilder(FrameGraph* graph, RenderPassNode* node) noexcept: graph(*graph) , node(*node) {};
|
||||
RenderPassBuilder(FrameGraph* graph, FrameGraphNodePtr& node) noexcept
|
||||
: graph(*graph) , node(node) {};
|
||||
FrameGraph::RenderPassBuilder& Name(pmr::Name name);
|
||||
FrameGraph::RenderPassBuilder& Pass(RenderPass* pass);
|
||||
FrameGraph::RenderPassBuilder& Read(TextureDesc desc);
|
||||
FrameGraph::RenderPassBuilder& Write(TextureDesc desc);
|
||||
FrameGraph::RenderPassBuilder& Attach(AttachmentDesc desc);
|
||||
FrameGraph::RenderPassBuilder& Read(FrameResourceEdge* edge);
|
||||
FrameGraph::RenderPassBuilder& Read(const FrameGraphEdgePtr& edge);
|
||||
};
|
||||
struct FrameGraph::TextureBuilder {
|
||||
FrameGraph& graph;
|
||||
FrameResourceEdge& edge;
|
||||
FrameGraphEdgePtr& edge;
|
||||
public:
|
||||
TextureBuilder(FrameGraph* graph, FrameResourceEdge* edge)noexcept : graph(*graph), edge(*edge) {};
|
||||
TextureBuilder(FrameGraph* graph, FrameGraphEdgePtr& edge)noexcept : graph(*graph), edge(edge) {};
|
||||
FrameGraph::TextureBuilder& Name(pmr::Name name);
|
||||
FrameGraph::TextureBuilder& Import(RscHandle<Texture> handle);
|
||||
};
|
||||
|
||||
@ -13,40 +13,78 @@ namespace api {
|
||||
using RenderPassExecuteFunction = std::function<void(FrameGraph&, RenderPassContext&)>;
|
||||
using RenderPassNodeExecuteFn = std::variant<RenderPassExecuteFunction, ComputePassExecuteFunction, CopyPassExecuteFunction>;
|
||||
class RenderPass;
|
||||
class FrameResourceEdge;
|
||||
enum class ERenderPassNodeType : uint8_t {
|
||||
Render,
|
||||
Present,
|
||||
Compute,
|
||||
Copy
|
||||
};
|
||||
struct RenderPassNode {
|
||||
class RenderPassNode;
|
||||
struct FrameGraphNodePtr {
|
||||
enum NodeType : uint8_t {
|
||||
Render,
|
||||
Present,
|
||||
Compute,
|
||||
Copy
|
||||
};
|
||||
using GraphNodeRef = lemon::ListGraphBase::Node;
|
||||
GraphNodeRef ref;
|
||||
Name name;
|
||||
ERenderPassNodeType type{ ERenderPassNodeType::Render};
|
||||
RenderPass* pass;
|
||||
RenderPassNodeExecuteFn executor;
|
||||
pmr::vector<FrameResourceEdge*> edges{ FramePool() };//read -> write, 顺序固定
|
||||
RenderPassNode(GraphNodeRef ref) : ref(ref) {}
|
||||
FrameResourceEdge* GetInput(int i);
|
||||
FrameResourceEdge* GetOutput(int i);
|
||||
FrameResourceEdge* FindInput(Name name);
|
||||
FrameResourceEdge* FindOutput(Name name);
|
||||
NodeType type{ NodeType::Render };
|
||||
RenderPassNode* node;
|
||||
FrameGraphNodePtr() : node(nullptr){};
|
||||
FrameGraphNodePtr(GraphNodeRef ref, const RenderPassNodeExecuteFn& executor, NodeType type = NodeType::Render);
|
||||
operator bool() const {
|
||||
return node;
|
||||
}
|
||||
RenderPassNode* operator ->()const {
|
||||
return node;
|
||||
}
|
||||
};
|
||||
struct FrameTextureResource {
|
||||
TextureDesc texture;
|
||||
AttachmentDesc attach;
|
||||
};
|
||||
struct FrameResourceEdge {
|
||||
struct FrameResource {
|
||||
using Resource = std::variant<FrameTextureResource, void*>;
|
||||
Name name;
|
||||
Resource resource;
|
||||
RenderPassNode* source;
|
||||
pmr::vector<RenderPassNode*> targets{ FramePool() };
|
||||
FrameGraphNodePtr source;
|
||||
pmr::vector<FrameGraphNodePtr> targets{ FramePool() };
|
||||
template<typename T>
|
||||
T CastTo() {
|
||||
return std::get<T>(resource);
|
||||
}
|
||||
};
|
||||
struct FrameGraphEdgePtr {
|
||||
enum EdgeType : uint8_t {
|
||||
Import,
|
||||
Input,
|
||||
Output
|
||||
};
|
||||
EdgeType type{ EdgeType::Import };
|
||||
FrameResource* resource;
|
||||
FrameGraphEdgePtr() : resource(nullptr) {};
|
||||
FrameGraphEdgePtr(FrameResource* resource, EdgeType type = EdgeType::Import)
|
||||
: resource(resource), type(type) {}
|
||||
FrameGraphEdgePtr(EdgeType type) : type(type){
|
||||
resource = new (FramePool()) FrameResource();
|
||||
}
|
||||
bool IsImport() const { return type == EdgeType::Import; }
|
||||
operator bool() const{
|
||||
return resource;
|
||||
}
|
||||
FrameResource* operator ->()const {
|
||||
return resource;
|
||||
}
|
||||
};
|
||||
struct RenderPassNode {
|
||||
Name name;
|
||||
RenderPass* pass;
|
||||
RenderPassNodeExecuteFn executor;
|
||||
pmr::vector<FrameGraphEdgePtr> edges{ FramePool() };//read -> write, 顺序固定
|
||||
FrameGraphEdgePtr GetInput(int i);
|
||||
FrameGraphEdgePtr GetOutput(int i);
|
||||
FrameGraphEdgePtr FindInput(Name name);
|
||||
FrameGraphEdgePtr FindOutput(Name name);
|
||||
};
|
||||
inline FrameGraphNodePtr::FrameGraphNodePtr(GraphNodeRef ref, const RenderPassNodeExecuteFn& executor, NodeType type)
|
||||
: ref(ref), type(type)
|
||||
{
|
||||
node = new (FramePool()) RenderPassNode();
|
||||
node->executor = executor;
|
||||
}
|
||||
}
|
||||
@ -1,46 +1,47 @@
|
||||
#include "render/graph/frame_graph.h"
|
||||
#include "render/graph/frame_graph_builder.h"
|
||||
namespace api {
|
||||
RenderPassNode* FrameGraph::AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor)
|
||||
FrameGraphNodePtr FrameGraph::AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor)
|
||||
{
|
||||
RenderPassNode* node = new(FramePool()) RenderPassNode(mGraph.addNode());
|
||||
RenderPassBuilder builder{this, node};
|
||||
FrameGraphNodePtr node_ptr{ mGraph.addNode(), executor };
|
||||
RenderPassBuilder builder{ this, node_ptr };
|
||||
setup(*this, builder);
|
||||
node->executor = executor;
|
||||
mPasses.push_back(node);
|
||||
return node;
|
||||
mNodes.push_back(node_ptr);
|
||||
return node_ptr;
|
||||
}
|
||||
FrameResourceEdge* FrameGraph::CreateTexture(const TextureSetupFunction& setup)
|
||||
FrameGraphEdgePtr FrameGraph::CreateTexture(const TextureSetupFunction& setup)
|
||||
{
|
||||
FrameResourceEdge* edge = new(FramePool()) FrameResourceEdge();
|
||||
FrameGraphEdgePtr edge{ FrameGraphEdgePtr::Import };
|
||||
TextureBuilder builder(this, edge);
|
||||
setup(*this, builder);
|
||||
return edge;
|
||||
}
|
||||
void FrameGraph::Compile()
|
||||
{
|
||||
auto end = std::remove_if(mPasses.begin(), mPasses.end(), [this](RenderPassNode* pass) {
|
||||
auto end = std::remove_if(mNodes.begin(), mNodes.end(), [this](FrameGraphNodePtr& node) {
|
||||
int degree = 0;
|
||||
for (lemon::ListGraph::IncEdgeIt e(mGraph, pass->ref); e != lemon::INVALID; ++e) {
|
||||
for (lemon::ListGraph::IncEdgeIt e(mGraph, node.ref); e != lemon::INVALID; ++e) {
|
||||
++degree;
|
||||
}
|
||||
return degree;
|
||||
return !degree;
|
||||
});
|
||||
mPasses.erase(end, mPasses.end());
|
||||
mNodes.erase(end, mNodes.end());
|
||||
}
|
||||
void FrameGraph::Execute()
|
||||
{
|
||||
for (auto pass : mPasses) {
|
||||
switch (pass->type) {
|
||||
case ERenderPassNodeType::Render:
|
||||
ExecuteRenderPass(pass);
|
||||
for (auto node : mNodes) {
|
||||
switch (node.type) {
|
||||
case FrameGraphNodePtr::Render:
|
||||
ExecuteRenderPass(node.node);
|
||||
break;
|
||||
case ERenderPassNodeType::Present:
|
||||
ExecuteComputePass(pass);
|
||||
case FrameGraphNodePtr::Present:
|
||||
ExecuteComputePass(node.node);
|
||||
break;
|
||||
case ERenderPassNodeType::Compute:
|
||||
ExecuteRenderPass(pass);
|
||||
case FrameGraphNodePtr::Compute:
|
||||
ExecuteRenderPass(node.node);
|
||||
break;
|
||||
case ERenderPassNodeType::Copy:
|
||||
ExecuteCopyPass(pass);
|
||||
case FrameGraphNodePtr::Copy:
|
||||
ExecuteCopyPass(node.node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -48,7 +49,7 @@ namespace api {
|
||||
void FrameGraph::Clear()
|
||||
{
|
||||
mGraph.clear();
|
||||
mPasses.clear();
|
||||
mNodes.clear();
|
||||
}
|
||||
void FrameGraph::ExecuteRenderPass(RenderPassNode* node)
|
||||
{
|
||||
@ -70,39 +71,39 @@ namespace api {
|
||||
CopyPassContext context{};
|
||||
std::get<CopyPassExecuteFunction>(node->executor)(*this, context);
|
||||
}
|
||||
FrameResourceEdge* RenderPassNode::GetInput(int i)
|
||||
FrameGraphEdgePtr RenderPassNode::GetInput(int i)
|
||||
{
|
||||
int count = 0;
|
||||
for (auto edge : edges) {
|
||||
if (edge->source == this && count++ == i) {
|
||||
if (edge.type != FrameGraphEdgePtr::Output && count++ == i) {
|
||||
return edge;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
FrameResourceEdge* RenderPassNode::GetOutput(int i)
|
||||
FrameGraphEdgePtr RenderPassNode::GetOutput(int i)
|
||||
{
|
||||
int count = 0;
|
||||
for (auto edge : edges) {
|
||||
if (edge->source && edge->source != this && count++ == i) {
|
||||
if (edge.type == FrameGraphEdgePtr::Output && count++ == i) {
|
||||
return edge;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
FrameResourceEdge* RenderPassNode::FindInput(Name name)
|
||||
FrameGraphEdgePtr RenderPassNode::FindInput(Name name)
|
||||
{
|
||||
for (auto edge : edges) {
|
||||
if (edge->name == name && edge->source == this) {
|
||||
if (edge.resource->name == name && edge.type != FrameGraphEdgePtr::Output) {
|
||||
return edge;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
FrameResourceEdge* RenderPassNode::FindOutput(Name name)
|
||||
FrameGraphEdgePtr RenderPassNode::FindOutput(Name name)
|
||||
{
|
||||
for (auto edge : edges) {
|
||||
if (edge->name == name && edge->source && edge->source != this) {
|
||||
if (edge.resource->name == name && edge.type == FrameGraphEdgePtr::Output) {
|
||||
return edge;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,56 +3,61 @@
|
||||
namespace api {
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Name(pmr::Name name)
|
||||
{
|
||||
node.name = name;
|
||||
node->name = name;
|
||||
return *this;
|
||||
}
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Pass(RenderPass* pass)
|
||||
{
|
||||
node.pass = pass;
|
||||
node->pass = pass;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Read(TextureDesc desc)
|
||||
{
|
||||
edge = new(FramePool()) FrameResourceEdge();
|
||||
edge->source = &node;
|
||||
edge->resource = FrameTextureResource{desc};
|
||||
node.edges.push_back(edge);
|
||||
FrameGraphEdgePtr edge{ FrameGraphEdgePtr::Input };
|
||||
resource = edge.resource;
|
||||
resource->source = node;
|
||||
resource->resource = FrameTextureResource{desc};
|
||||
node->edges.push_back(edge);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Write(TextureDesc desc)
|
||||
{
|
||||
edge = new(FramePool()) FrameResourceEdge();
|
||||
edge->source = &node;
|
||||
edge->resource = FrameTextureResource{ desc };
|
||||
node.edges.push_back(edge);
|
||||
FrameGraphEdgePtr edge{ FrameGraphEdgePtr::Output };
|
||||
resource = edge.resource;
|
||||
resource->source = node;
|
||||
resource->resource = FrameTextureResource{ desc };
|
||||
node->edges.push_back(edge);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Attach(AttachmentDesc desc)
|
||||
{
|
||||
if (edge) {
|
||||
auto& resource = std::get<FrameTextureResource>(edge->resource);
|
||||
resource.attach = desc;
|
||||
if (resource) {
|
||||
auto& text_resource = std::get<FrameTextureResource>(resource->resource);
|
||||
text_resource.attach = desc;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Read(FrameResourceEdge* edge)
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Read(const FrameGraphEdgePtr& edge)
|
||||
{
|
||||
edge->targets.emplace_back(&node);
|
||||
if (!edge) { return *this; }
|
||||
node->edges.emplace_back(edge.resource, edge.IsImport() ? FrameGraphEdgePtr::Import : FrameGraphEdgePtr::Input);
|
||||
edge->targets.emplace_back(node);
|
||||
if(edge->source)
|
||||
graph.mGraph.addEdge(edge->source->ref, node.ref);
|
||||
graph.mGraph.addEdge(edge->source.ref, node.ref);
|
||||
return *this;
|
||||
}
|
||||
FrameGraph::TextureBuilder& FrameGraph::TextureBuilder::Name(pmr::Name name)
|
||||
{
|
||||
edge.name = name;
|
||||
edge->name = name;
|
||||
return *this;
|
||||
}
|
||||
FrameGraph::TextureBuilder& FrameGraph::TextureBuilder::Import(RscHandle<Texture> handle)
|
||||
{
|
||||
edge.type = FrameGraphEdgePtr::Import;
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
@ -4,20 +4,21 @@ namespace api {
|
||||
void DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder)
|
||||
{
|
||||
auto edge = graph.CreateTexture(
|
||||
[=](auto&, auto) {
|
||||
|
||||
[=](FrameGraph& graph, FrameGraph::TextureBuilder& builder) {
|
||||
builder.Name("import")
|
||||
.Import({});
|
||||
});
|
||||
builder.Name("DemoPass")
|
||||
.Read(TextureDesc::Make())
|
||||
.Read(edge)
|
||||
.Write(TextureDesc::Make())
|
||||
.Attach(AttachmentDesc::Make());
|
||||
auto parent_pass = &builder.node;
|
||||
auto parent_node = builder.node;
|
||||
graph.AddRenderPass(
|
||||
[=](FrameGraph& graph, FrameGraph::RenderPassBuilder& builder) {
|
||||
builder.Name("DemoPassSub")
|
||||
.Read(edge)
|
||||
.Read(parent_pass->GetOutput(0));
|
||||
.Read(parent_node->GetOutput(0));
|
||||
},
|
||||
[](FrameGraph& graph, RenderPassContext& context) {
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user