diff --git a/engine/modules/engine/render/include/render/graph/frame_graph.h b/engine/modules/engine/render/include/render/graph/frame_graph.h index a961531..989e93f 100644 --- a/engine/modules/engine/render/include/render/graph/frame_graph.h +++ b/engine/modules/engine/render/include/render/graph/frame_graph.h @@ -7,15 +7,15 @@ namespace api { class TextureBuilder; class RenderPassBuilder; public: - lemon::ListGraph mGraph; - pmr::vector mPasses{FramePool()}; + lemon::ListGraph mGraph; + pmr::vector mNodes{FramePool()}; public: template - RenderPassNode* AddRenderPass() { return AddRenderPass(&T::Setup, &T::Execute); } + FrameGraphNodePtr AddRenderPass() { return AddRenderPass(&T::Setup, &T::Execute); } using RenderPassSetupFunction = std::function; - RenderPassNode* AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor); + FrameGraphNodePtr AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor); using TextureSetupFunction = std::function; - FrameResourceEdge* CreateTexture(const TextureSetupFunction& setup); + FrameGraphEdgePtr CreateTexture(const TextureSetupFunction& setup); void Compile(); void Execute(); diff --git a/engine/modules/engine/render/include/render/graph/frame_graph_builder.h b/engine/modules/engine/render/include/render/graph/frame_graph_builder.h index 65e76bd..ec50f7d 100644 --- a/engine/modules/engine/render/include/render/graph/frame_graph_builder.h +++ b/engine/modules/engine/render/include/render/graph/frame_graph_builder.h @@ -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 handle); }; diff --git a/engine/modules/engine/render/include/render/graph/type.h b/engine/modules/engine/render/include/render/graph/type.h index 9220984..4804492 100644 --- a/engine/modules/engine/render/include/render/graph/type.h +++ b/engine/modules/engine/render/include/render/graph/type.h @@ -13,40 +13,78 @@ namespace api { using RenderPassExecuteFunction = std::function; using RenderPassNodeExecuteFn = std::variant; 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 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; Name name; Resource resource; - RenderPassNode* source; - pmr::vector targets{ FramePool() }; + FrameGraphNodePtr source; + pmr::vector targets{ FramePool() }; template T CastTo() { return std::get(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 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; + } } \ No newline at end of file diff --git a/engine/modules/engine/render/src/graph/frame_graph.cpp b/engine/modules/engine/render/src/graph/frame_graph.cpp index c83c60f..bfa7014 100644 --- a/engine/modules/engine/render/src/graph/frame_graph.cpp +++ b/engine/modules/engine/render/src/graph/frame_graph.cpp @@ -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(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; } } diff --git a/engine/modules/engine/render/src/graph/frame_graph_builder.cpp b/engine/modules/engine/render/src/graph/frame_graph_builder.cpp index beff6ef..85707f8 100644 --- a/engine/modules/engine/render/src/graph/frame_graph_builder.cpp +++ b/engine/modules/engine/render/src/graph/frame_graph_builder.cpp @@ -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(edge->resource); - resource.attach = desc; + if (resource) { + auto& text_resource = std::get(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 handle) { + edge.type = FrameGraphEdgePtr::Import; return *this; } } \ No newline at end of file diff --git a/engine/modules/engine/render/src/pass/demo_pass.cpp b/engine/modules/engine/render/src/pass/demo_pass.cpp index 9ca8364..53e1b5c 100644 --- a/engine/modules/engine/render/src/pass/demo_pass.cpp +++ b/engine/modules/engine/render/src/pass/demo_pass.cpp @@ -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) {