FCT
载入中...
搜索中...
未找到
RenderGraph.h
浏览该文件的文档.
1//
2// Created by Administrator on 2025/8/10.
3//
4
5#ifndef RENDERGRAPH_H
6#define RENDERGRAPH_H
7
9#include "./ResourceManager.h"
10#include "../RHI/ImageAspect.h"
11#include "../RHI/ImageLayout.h"
13#include "../RHI/AccessFlags.h"
14
15#include "../ThirdParty.h"
16#include "./Format.h"
17#include "../Base/TokenGraph.h"
18#include "../Base/UnionFind.h"
20#include "./ShaderStage.h"
21#include "./ClearTypes.h"
22#include "Vec.h"
23#include "../Base/Graph.h"
24#include "./SizeNode.h"
25#include "CommandBufferGraph.h"
26#include "../Base/UnionFind.h"
28#include "./FlowControl.h"
29#include "./Device.h"
30
31namespace FCT
32{
33 class TextureEdge;
34 class Context;
35 class Window;
36 namespace RHI
37 {
38 class CommandBuffer;
39 }
40}
47namespace FCT
48{
56 {
57 protected:
58 std::string m_name;
59 public:
60 RenderGraphNode() = default;
61 RenderGraphNode(const std::string& name) : m_name(name) {}
62 };
63
64 class Edge
65 {
66 public:
67
68 };
69
70 class TargetEdge : public Edge
71 {
72 public:
73 std::string fromPass;
74 std::string toImage;
75 uint32_t order;
76 };
77
78 class DepthStencilEdge : public Edge
79 {
80 public:
81 std::string fromPass;
82 std::string toImage;
83 uint32_t order;
84 };
85
87 {
88 public:
91 virtual RenderGraphImageNode& operator|=(const Texture& other) = 0;
92 virtual RenderGraphImageNode& operator|=(const Target& other) = 0;
93 virtual RenderGraphImageNode& operator|=(const DepthStencil& other) = 0;
94
96 m_textureOutgoingEdges.push_back(edge);
97 }
98
100 edge->order = m_targetOrderCounter++;
101 m_targetIncomingEdges.push_back(edge);
102 }
103
106 m_depthStencilIncomingEdges.push_back(edge);
107 }
108
111 std::remove(m_textureOutgoingEdges.begin(), m_textureOutgoingEdges.end(), edge),
113 );
114 }
115
118 std::remove(m_targetIncomingEdges.begin(), m_targetIncomingEdges.end(), edge),
120 );
121 }
122
129
130 const std::vector<TextureEdge*>& getTextureOutgoingEdges() const {
132 }
133
134 const std::vector<TargetEdge*>& getTargetIncomingEdges() const {
136 }
137
138 const std::vector<DepthStencilEdge*>& getDepthStencilIncomingEdges() const {
140 }
141 virtual Image* getImage() const = 0;
142 virtual void fillDefaultData() = 0;
143 private:
144 std::vector<TextureEdge*> m_textureOutgoingEdges;
145 std::vector<TargetEdge*> m_targetIncomingEdges;
146 std::vector<DepthStencilEdge*> m_depthStencilIncomingEdges;
149 };
150}
152namespace FCT
153{
154 class RenderGraphPassNode;
155 class TextureEdge : public Edge
156 {
157 public:
159 std::string fromImage;
160 std::string toPass;
167 };
168
170 {
171 public:
173
174 RenderGraphPassNode(std::string name) : RenderGraphNode(name)
175 {
176
177 }
178
180 m_textureIncomingEdges.push_back(edge);
181 }
182
184 m_targetOutgoingEdges.push_back(edge);
185 }
186
188 m_depthStencilOutgoingEdges.push_back(edge);
189 }
190
191 const std::vector<TextureEdge*>& getTextureIncomingEdges() const {
193 }
194
195 const std::vector<TargetEdge*>& getTargetOutgoingEdges() const {
197 }
198
199 const std::vector<DepthStencilEdge*>& getDepthStencilOutgoingEdges() const {
201 }
204 std::remove(m_textureIncomingEdges.begin(), m_textureIncomingEdges.end(), edge),
206 );
207 }
208
211 std::remove(m_targetOutgoingEdges.begin(), m_targetOutgoingEdges.end(), edge),
213 );
214 }
215
222
223 void applyPassDesc(const PassDesc& desc) {
224 m_clearInfo = desc.clear;
225 }
227 return m_clearInfo;
228 }
229 private:
230 std::vector<TextureEdge*> m_textureIncomingEdges;
231 std::vector<TargetEdge*> m_targetOutgoingEdges;
232 std::vector<DepthStencilEdge*> m_depthStencilOutgoingEdges;
234 };
236 {
237 std::string passName;
239 };
240
242 {
243 constexpr const char* RenderGraphSubmit = "RenderGraphSubmit";
244 constexpr const char* CheckRecompiledSync = "RenderGraphCheckRecompiled";
245 }
246 class RenderGraph : private IEventSystem<EventSystemConfig::TriggerOnly>{
264 private:
265 bool m_needRecompiled = false;
270 private:
277 void initForSubmit();
279 private:
280 std::unordered_map<std::string, std::vector<std::string>> m_passGroupOrders;
281 std::vector<std::string> m_passGroupExecutionOrder;
282 public:
283 private:
284 std::unordered_map<std::string, std::vector<BarrierInfo>> m_passGroupBarriers;
285 std::map<std::string, std::set<std::string>> m_passGroupDependencies;
286 std::unordered_map<std::string, std::unique_ptr<RenderGraphImageNode>> m_imageNodes;
287 std::unordered_map<std::string,RenderGraphPassNode> m_passNodes;
289 std::unordered_set<std::unique_ptr<Edge>> m_edges;
290 std::unordered_map<std::string, Image*> m_allocatedImages;
291 std::unordered_map<std::string, RHI::Pass*> m_allocatedPasses;
292 std::vector<PassDesc> m_originalPasses;
293 std::vector<std::string> m_topologicalSortPasses;
294 std::unordered_map<std::string, RHI::PassGroup*> m_allocatedPassGroups; // 存储创建的PassGroup
295 void cleanUpCompile();
297 private:
299 public:
300 RenderGraph(PipeHub& pipeHub, Device* device, FlowControl* flowControl, CommandBufferGraph* commandBufferGraph,
301 ResourceManager* resourceManager);
302 ~RenderGraph();
303 void recompile();
304 std::vector<PassDesc> getOriginalPasses() const
305 {
306 return m_originalPasses;
307 }
309 {
310 m_originalPasses.clear();
311 }
312 private:
313 RenderGraphImageNode* getOrCreateImageNode(const std::string& name, const Texture& texture);
314 RenderGraphImageNode* getOrCreateImageNode(const std::string& name, const Target& target);
315 RenderGraphImageNode* getOrCreateImageNode(const std::string& name, const DepthStencil& depthStencil);
316 void createTextureEdge(const std::string& passName, const std::string& textureName, const Texture& texture);
317 void createTargetEdge(const std::string& passName, const std::string& targetName, const Target& target);
318 void createDepthStencilEdge(const std::string& passName, const std::string& depthStencilName, const DepthStencil& depthStencil);
319 void removeTextureEdge(TextureEdge* edgeToRemove);
320 void simulatePassGroupExecution(const std::string& groupLeader,
321 const std::vector<std::string>& groupMembers,
322 std::unordered_map<Image*, ImageState>& imageStates);
324 std::vector<BarrierInfo> checkBarriersBeforePassGroup(const std::string& groupLeader,
325 const std::vector<std::string>& groupMembers,
326 const std::unordered_map<Image*, ImageState>& imageStates);
327
328 void executeBarriers(RHI::CommandBuffer* cmdBuffer, const std::vector<BarrierInfo>& barriers);
329 void removeTargetEdge(TargetEdge* edgeToRemove);
330 void removeDepthStencilEdge(DepthStencilEdge* edgeToRemove);
331 void addPass(const PassDesc& desc);
332 void cleanUp();
350 void resolveTextureSizes();
351 void cullPasses();
352 void cullPass(const std::string& passName);
353 void cullSinglePass(const std::string& passName);
354 void cullUnusedImageNode(const std::string& imageName);
364 void groupPasses();
365 void clearResources();
366
367 void allocateResources();
376 void createRHIPasses();
377 void analyzePassGroupDependencies(const std::string& groupLeader, const std::vector<std::string>& groupMembers,
378 std::map<std::string, std::set<std::string>>& dependencies) const;
379 std::vector<std::string> topologicalSortPasses() const;
380 std::map<std::string, std::set<std::string>> buildPassDependencyGraph() const;
381 std::vector<std::string> topologicalSort(const std::map<std::string, std::set<std::string>>& dependencies) const;
395 void createPassGroups();
396 public:
397 template<typename Func>
398 SubscribeId subscribe(std::string passName,Func&& func)
399 {
401 {
402 if (env.passName == passName)
403 {
404 func(env);
405 }
406 });
407 return subId;
408 }
413 template<typename... Args>
414 void addPass(std::string name,Args&&... args)
415 {
416 PassDesc desc(name);
417 desc.processArgs(std::forward<Args>(args)...);
418 m_originalPasses.push_back(desc);
419 //addPass(desc);
420 }
421 void addPassDesc(const PassDesc& desc)
422 {
423 m_originalPasses.push_back(desc);
424 }
426 {
427 for (auto pass : m_originalPasses)
428 {
429 addPass(pass);
430 }
431 }
446 void pushPipe();
448 RHI::Pass* getPass(const std::string& name) const;
449 Image* getImage(const std::string& name) const;
450 std::vector<TextureEdge*> getTextureEdges(const std::string& passName) const;
451 private:
452 void submitPassGroup(RHI::CommandBuffer* cmdBuffer,
453 const std::string& groupLeader);
454
455 };
456
457} // FCT
458
459#endif //RENDERGRAPH_H
void unsubscribe(SubscribeId subscribeId)
SubscribeId subscribe(Func &&func)
void simulateExecutionAndAnalyzeBarriers()
void simulatePassGroupExecution(const std::string &groupLeader, const std::vector< std::string > &groupMembers, std::unordered_map< Image *, ImageState > &imageStates)
std::unordered_set< std::unique_ptr< Edge > > m_edges
void createTextureEdge(const std::string &passName, const std::string &textureName, const Texture &texture)
std::vector< PassDesc > getOriginalPasses() const
std::unordered_map< std::string, Image * > m_allocatedImages
void unsubscribe(SubscribeId subscribeId)
void addPassDesc(const PassDesc &desc)
void analyzePassGroupBarriers()
void cullSinglePass(const std::string &passName)
std::map< std::string, std::set< std::string > > buildPassDependencyGraph() const
std::map< std::string, std::set< std::string > > m_passGroupDependencies
std::unordered_map< std::string, std::unique_ptr< RenderGraphImageNode > > m_imageNodes
SubscribeId subscribe(std::string passName, Func &&func)
void addPass(std::string name, Args &&... args)
FlowControl * m_flowControl
std::vector< TextureEdge * > getTextureEdges(const std::string &passName) const
RenderGraphImageNode * getOrCreateImageNode(const std::string &name, const Texture &texture)
std::vector< PassDesc > m_originalPasses
void addPass(const PassDesc &desc)
void submitPassGroup(RHI::CommandBuffer *cmdBuffer, const std::string &groupLeader)
RHI::Pass * getPass(const std::string &name) const
void executeBarriers(RHI::CommandBuffer *cmdBuffer, const std::vector< BarrierInfo > &barriers)
CommandBufferGraph * m_commandBufferGraph
void cullUnusedImageNode(const std::string &imageName)
Image * getImage(const std::string &name) const
std::unordered_map< std::string, RHI::PassGroup * > m_allocatedPassGroups
std::unordered_map< std::string, RenderGraphPassNode > m_passNodes
std::vector< std::string > topologicalSortPasses() const
ResourceManager * m_resourceManager
std::vector< std::string > m_passGroupExecutionOrder
UnionFind< std::string, char > m_passesUnions
std::unordered_map< std::string, std::vector< BarrierInfo > > m_passGroupBarriers
std::vector< std::string > m_topologicalSortPasses
void removeTextureEdge(TextureEdge *edgeToRemove)
RenderGraph(PipeHub &pipeHub, Device *device, FlowControl *flowControl, CommandBufferGraph *commandBufferGraph, ResourceManager *resourceManager)
void removeTargetEdge(TargetEdge *edgeToRemove)
void executeAllPassGroups(RHI::CommandBuffer *cmdBuffer)
PipelineStage convertShaderStageToPipelineStage(ShaderStage stage) const
std::vector< std::string > topologicalSort(const std::map< std::string, std::set< std::string > > &dependencies) const
std::vector< BarrierInfo > checkBarriersBeforePassGroup(const std::string &groupLeader, const std::vector< std::string > &groupMembers, const std::unordered_map< Image *, ImageState > &imageStates)
std::unordered_map< std::string, RHI::Pass * > m_allocatedPasses
void createDepthStencilEdge(const std::string &passName, const std::string &depthStencilName, const DepthStencil &depthStencil)
void analyzePassGroupDependencies(const std::string &groupLeader, const std::vector< std::string > &groupMembers, std::map< std::string, std::set< std::string > > &dependencies) const
void removeDepthStencilEdge(DepthStencilEdge *edgeToRemove)
void createTargetEdge(const std::string &passName, const std::string &targetName, const Target &target)
void cullPass(const std::string &passName)
std::unordered_map< std::string, std::vector< std::string > > m_passGroupOrders
CommandBufferToken m_commandBufferToken
RenderGraphImageNode(const std::string &name)
std::vector< TargetEdge * > m_targetIncomingEdges
void addOutgoingEdge(TextureEdge *edge)
virtual Image * getImage() const =0
void removeOutgoingEdge(TextureEdge *edge)
void removeIncomingEdge(TargetEdge *edge)
virtual RenderGraphImageNode & operator|=(const DepthStencil &other)=0
const std::vector< TargetEdge * > & getTargetIncomingEdges() const
std::vector< DepthStencilEdge * > m_depthStencilIncomingEdges
void removeIncomingEdge(DepthStencilEdge *edge)
const std::vector< DepthStencilEdge * > & getDepthStencilIncomingEdges() const
std::vector< TextureEdge * > m_textureOutgoingEdges
virtual RenderGraphImageNode & operator|=(const Texture &other)=0
void addIncomingEdge(TargetEdge *edge)
const std::vector< TextureEdge * > & getTextureOutgoingEdges() const
void addIncomingEdge(DepthStencilEdge *edge)
virtual void fillDefaultData()=0
virtual RenderGraphImageNode & operator|=(const Target &other)=0
RenderGraphNode()=default
RenderGraphNode(const std::string &name)
void addOutgoingEdge(DepthStencilEdge *edge)
void removeOutgoingEdge(DepthStencilEdge *edge)
std::vector< TargetEdge * > m_targetOutgoingEdges
const std::vector< DepthStencilEdge * > & getDepthStencilOutgoingEdges() const
std::vector< TextureEdge * > m_textureIncomingEdges
RenderGraphPassNode(std::string name)
void removeIncomingEdge(TextureEdge *edge)
void addOutgoingEdge(TargetEdge *edge)
std::vector< DepthStencilEdge * > m_depthStencilOutgoingEdges
const std::vector< TextureEdge * > & getTextureIncomingEdges() const
const std::vector< TargetEdge * > & getTargetOutgoingEdges() const
void applyPassDesc(const PassDesc &desc)
void removeOutgoingEdge(TargetEdge *edge)
void addIncomingEdge(TextureEdge *edge)
const EnablePassClear & getClearInfo() const
constexpr const char * CheckRecompiledSync
constexpr const char * RenderGraphSubmit
std::size_t SubscribeId
CommandBufferNodes::CommandBuffer * CommandBufferToken
void processArgs(const EnablePassClear &other, Rest &&... rest)
RHI::CommandBuffer * cmdBuf
SizeNode() noexcept