FCT
载入中...
搜索中...
未找到
RenderGraph.cpp
浏览该文件的文档.
1#include "../UI/Window.h"
2#include "./Context.h"
3#include "./Context.hpp"
4#include "../RHI/PassGroup.h"
5
6namespace FCT
7{
9 {
10 return m_window->getCurrentTarget()->targetImage();
11 }
12
14 {
15 return m_window->getCurrentTarget()->depthStencilBuffer();
16 }
17
19 {
20 m_commandBufferToken = nullptr;
21 auto& submitGraph = m_flowControl->submitTickers();
22 submitGraph[RenderGraphTickers::RenderGraphSubmit] = {[this]()
23 {
24 auto cmdGraph = m_commandBufferGraph;
25 auto cmdBuf = cmdGraph->getCommandBuffer(m_commandBufferToken);
26 cmdBuf->reset();
27 cmdBuf->begin();
29 cmdBuf->end();
30 cmdBuf->submit();
31 },{},
33 };
34 submitGraph.update();
35 }
36
38 {
39 auto cmdGraph = m_commandBufferGraph;
40
42 {
48 }
49 std::vector<CommandBufferGraph::NodeRef> windowNodes;
50
51 for (const auto& [imageName, imageNode] : m_imageNodes) {
52 Window* window = nullptr;
53
54 auto* windowTargetNode = dynamic_cast<RenderGraphWindowTargetNode*>(imageNode.get());
55 if (windowTargetNode && windowTargetNode->isValidWindowTarget()) {
56 window = windowTargetNode->getWindow();
57 }
58
59 if (!window) {
60 auto* windowDepthNode = dynamic_cast<RenderGraphWindowDepthStencilNode*>(imageNode.get());
61 if (windowDepthNode && windowDepthNode->isValidWindowDepthStencil()) {
62 window = windowDepthNode->getWindow();
63 }
64 }
65
66 if (window) {
67 bool alreadyAdded = false;
68 for (const auto& node : windowNodes) {
69 if (node.type == CommandBufferGraph::NodeRef::WindowType && node.window == window) {
70 alreadyAdded = true;
71 break;
72 }
73 }
74 if (!alreadyAdded) {
75 windowNodes.emplace_back(window);
76 }
77 }
78 }
79
80 m_commandBufferToken = cmdGraph->addBuffer(windowNodes, windowNodes);
81 }
82
83 RenderGraph::RenderGraph(PipeHub& pipeHub,Device* device, FlowControl* flowControl, CommandBufferGraph* commandBufferGraph,
84 ResourceManager* resourceManager) : pipeHub(pipeHub)
85 {
86 m_resourceDevice = device;
87 m_flowControl = flowControl;
88 m_commandBufferGraph = commandBufferGraph;
89 m_resourceManager = resourceManager;
91 auto& syncTickers = m_flowControl->syncTickers();
93 [this]()
94 {
96 {
98 compile();
99 m_needRecompiled = false;
100 }
101 },
102 {},
103 {}
104 };
105 syncTickers.update();
106 }
107
109 {
110 auto& syncTickers = m_flowControl->syncTickers();
111 syncTickers.removeNode(RenderGraphTickers::CheckRecompiledSync);
112 syncTickers.update();
113 auto& submitGraph = m_flowControl->submitTickers();
114 submitGraph.removeNode(RenderGraphTickers::RenderGraphSubmit);
115 submitGraph.update();
116 }
117
118 RenderGraphImageNode* RenderGraph::getOrCreateImageNode(const std::string& name, const Texture& texture)
119 {
120 auto it = m_imageNodes.find(name);
121 if (it != m_imageNodes.end()) {
122 *(it->second) |= texture;
123 return it->second.get();
124 } else {
125 auto node = std::make_unique<RenderGraphBufferNode>(texture);
126 RenderGraphImageNode* nodePtr = node.get();
127 m_imageNodes[name] = std::move(node);
128 return nodePtr;
129 }
130 }
131
132 RenderGraphImageNode* RenderGraph::getOrCreateImageNode(const std::string& name, const Target& target)
133 {
134 auto it = m_imageNodes.find(name);
135 if (it != m_imageNodes.end()) {
136 *(it->second) |= target;
137 return it->second.get();
138 } else {
139 if (target.isWindow) {
140 auto node = std::make_unique<RenderGraphWindowTargetNode>(target);
141 RenderGraphImageNode* nodePtr = node.get();
142 m_imageNodes[name] = std::move(node);
143 return nodePtr;
144 } else {
145 auto node = std::make_unique<RenderGraphBufferNode>(target);
146 RenderGraphImageNode* nodePtr = node.get();
147 m_imageNodes[name] = std::move(node);
148 return nodePtr;
149 }
150 }
151 }
152
154 {
155 auto it = m_imageNodes.find(name);
156 if (it != m_imageNodes.end()) {
157 *(it->second) |= depthStencil;
158 return it->second.get();
159 } else {
160 if (depthStencil.isWindow) {
161 auto node = std::make_unique<RenderGraphWindowDepthStencilNode>(depthStencil);
162 RenderGraphImageNode* nodePtr = node.get();
163 m_imageNodes[name] = std::move(node);
164 return nodePtr;
165 } else {
166 auto node = std::make_unique<RenderGraphBufferNode>(depthStencil);
167 RenderGraphImageNode* nodePtr = node.get();
168 m_imageNodes[name] = std::move(node);
169 return nodePtr;
170 }
171 }
172 }
173
174 void RenderGraph::createTextureEdge(const std::string& passName, const std::string& textureName,
175 const Texture& texture)
176 {
177 auto& pass = m_passNodes[passName];
178
179 auto edge = std::make_unique<TextureEdge>();
180 edge->size = texture.size;
181 edge->fromImage = textureName;
182 edge->toPass = passName;
183 edge->stage = getEarliestStage(texture.stages);
184
185 TextureEdge* edgePtr = edge.get();
186
187 auto imageNodeIt = m_imageNodes.find(textureName);
188 if (imageNodeIt != m_imageNodes.end()) {
189 imageNodeIt->second->addOutgoingEdge(edgePtr);
190 }
191 pass.addIncomingEdge(edgePtr);
192
193 m_edges.insert(std::move(edge));
194 }
195
196 void RenderGraph::createTargetEdge(const std::string& passName, const std::string& targetName, const Target& target)
197 {
198 auto& pass = m_passNodes[passName];
199
200 auto edge = std::make_unique<TargetEdge>();
201 edge->fromPass = passName;
202 edge->toImage = targetName;
203
204 TargetEdge* edgePtr = edge.get();
205
206 auto imageNodeIt = m_imageNodes.find(targetName);
207 if (imageNodeIt != m_imageNodes.end()) {
208 imageNodeIt->second->addIncomingEdge(edgePtr);
209 }
210 pass.addOutgoingEdge(edgePtr);
211
212 m_edges.insert(std::move(edge));
213 }
214
215 void RenderGraph::createDepthStencilEdge(const std::string& passName, const std::string& depthStencilName,
217 {
218 auto& pass = m_passNodes[passName];
219
220 auto edge = std::make_unique<DepthStencilEdge>();
221 edge->fromPass = passName;
222 edge->toImage = depthStencilName;
223
224 DepthStencilEdge* edgePtr = edge.get();
225
226 auto imageNodeIt = m_imageNodes.find(depthStencilName);
227 if (imageNodeIt != m_imageNodes.end()) {
228 imageNodeIt->second->addIncomingEdge(edgePtr);
229 }
230 pass.addOutgoingEdge(edgePtr);
231
232 m_edges.insert(std::move(edge));
233 }
235 if (!edgeToRemove) return;
236
237 auto passIt = m_passNodes.find(edgeToRemove->toPass);
238 if (passIt != m_passNodes.end()) {
239 auto& pass = passIt->second;
240 auto& incomingEdges = const_cast<std::vector<TextureEdge*>&>(pass.getTextureIncomingEdges());
241 incomingEdges.erase(
242 std::remove(incomingEdges.begin(), incomingEdges.end(), edgeToRemove),
243 incomingEdges.end()
244 );
245 }
246
247 auto imageNodeIt = m_imageNodes.find(edgeToRemove->fromImage);
248 if (imageNodeIt != m_imageNodes.end()) {
249 imageNodeIt->second->removeOutgoingEdge(edgeToRemove);
250 }
251
252 auto it = std::find_if(m_edges.begin(), m_edges.end(),
253 [edgeToRemove](const std::unique_ptr<Edge>& edge) {
254 return edge.get() == edgeToRemove;
255 });
256
257 if (it != m_edges.end()) {
258 m_edges.erase(it);
259 }
260}
261
263 if (!edgeToRemove) return;
264
265 auto passIt = m_passNodes.find(edgeToRemove->fromPass);
266 if (passIt != m_passNodes.end()) {
267 auto& pass = passIt->second;
268 auto& outgoingEdges = const_cast<std::vector<TargetEdge*>&>(pass.getTargetOutgoingEdges());
269 outgoingEdges.erase(
270 std::remove(outgoingEdges.begin(), outgoingEdges.end(), edgeToRemove),
271 outgoingEdges.end()
272 );
273 }
274
275 auto imageNodeIt = m_imageNodes.find(edgeToRemove->toImage);
276 if (imageNodeIt != m_imageNodes.end()) {
277 imageNodeIt->second->removeIncomingEdge(edgeToRemove);
278 }
279
280 auto it = std::find_if(m_edges.begin(), m_edges.end(),
281 [edgeToRemove](const std::unique_ptr<Edge>& edge) {
282 return edge.get() == edgeToRemove;
283 });
284
285 if (it != m_edges.end()) {
286 m_edges.erase(it);
287 }
288}
289
291 if (!edgeToRemove) return;
292
293 // 从 pass 的 outgoing edges 中移除
294 auto passIt = m_passNodes.find(edgeToRemove->fromPass);
295 if (passIt != m_passNodes.end()) {
296 auto& pass = passIt->second;
297 auto& outgoingEdges = const_cast<std::vector<DepthStencilEdge*>&>(pass.getDepthStencilOutgoingEdges());
298 outgoingEdges.erase(
299 std::remove(outgoingEdges.begin(), outgoingEdges.end(), edgeToRemove),
300 outgoingEdges.end()
301 );
302 }
303
304 // 从 image node 的 incoming edges 中移除
305 auto imageNodeIt = m_imageNodes.find(edgeToRemove->toImage);
306 if (imageNodeIt != m_imageNodes.end()) {
307 imageNodeIt->second->removeIncomingEdge(edgeToRemove);
308 }
309
310 // 从 m_edges 中移除并销毁
311 auto it = std::find_if(m_edges.begin(), m_edges.end(),
312 [edgeToRemove](const std::unique_ptr<Edge>& edge) {
313 return edge.get() == edgeToRemove;
314 });
315
316 if (it != m_edges.end()) {
317 m_edges.erase(it);
318 }
319}
321 {
322 m_passNodes[desc.name] = desc.name;
323 auto& pass = m_passNodes[desc.name];
324
325 pass.applyPassDesc(desc);
326
327 for (auto& texture : desc.textures)
328 {
329 getOrCreateImageNode(texture.name, texture);
330 createTextureEdge(desc.name, texture.name, texture);
331 }
332
333 std::vector<RenderGraphImageNode*> renderTargetNodes;
334
335 for (auto& target : desc.targets)
336 {
337 auto* node = getOrCreateImageNode(target.name, target);
338 renderTargetNodes.push_back(node);
339 createTargetEdge(desc.name, target.name, target);
340 }
341
342 for (auto& depthStencil : desc.depthStencils)
343 {
345 renderTargetNodes.push_back(node);
347 }
348
349 if (renderTargetNodes.size() > 1) {
350 RenderGraphImageNode* firstNode = renderTargetNodes[0];
351 for (size_t i = 1; i < renderTargetNodes.size(); ++i) {
352 firstNode->unite(renderTargetNodes[i]);
353 }
354 }
355 }
356
358 {
359 m_needRecompiled = true;
360 /*
361 *
362 cleanUpCompile();
363 compile();
364 */
365 }
366
368 {
369
370 for (auto& passName : m_topologicalSortPasses) {
371 auto& pass = m_passNodes[passName];
372 std::vector<RenderGraphImageNode*> referenceNodes;
373
374 for (auto* targetEdge : pass.getTargetOutgoingEdges()) {
375 auto imageNodeIt = m_imageNodes.find(targetEdge->toImage);
376 if (imageNodeIt != m_imageNodes.end()) {
377 referenceNodes.push_back(imageNodeIt->second.get());
378 }
379 }
380
381 for (auto* depthStencilEdge : pass.getDepthStencilOutgoingEdges()) {
382 auto imageNodeIt = m_imageNodes.find(depthStencilEdge->toImage);
383 if (imageNodeIt != m_imageNodes.end()) {
384 referenceNodes.push_back(imageNodeIt->second.get());
385 }
386 }
387
388 if (referenceNodes.empty()) {
389 continue;
390 }
391
392 RenderGraphImageNode* referenceNode = referenceNodes[0];
393
394 for (auto* textureEdge : pass.getTextureIncomingEdges()) {
395 auto imageNodeIt = m_imageNodes.find(textureEdge->fromImage);
396 if (imageNodeIt == m_imageNodes.end()) {
397 continue;
398 }
399
400 RenderGraphImageNode* textureNode = imageNodeIt->second.get();
401
402 if (textureEdge->size.type == TextureSize::Type::Undefined) {
403 if (!textureNode->isSizeDetermined()) {//
404 textureEdge->size = TextureSize(Fraction(),Fraction());
405 //textureNode->unite(referenceNode);
406 }
407 }
408 if (textureEdge->size.type == TextureSize::Type::Relative) {
409 FractionScale2D scale(textureEdge->size.relativeWidth, textureEdge->size.relativeHeight);
410 textureNode->unite(referenceNode, scale);
411 }
412 }
413 }
414 }
415
417 {
418 for (const auto& [passName, passNode] : m_passNodes) {
419 m_passesUnions.unite(passName, passName);
420 }
421
422 for (const auto& [passName, passNode] : m_passNodes) {
423 for (auto* textureEdge : passNode.getTextureIncomingEdges()) {
424 std::string imageName = textureEdge->fromImage;
425
426 auto imageIt = m_imageNodes.find(imageName);
427 if (imageIt == m_imageNodes.end()) continue;
428
429 RenderGraphImageNode* imageNode = imageIt->second.get();
430
431 RenderGraphImageNode* passRenderTarget = nullptr;
432
433 for (auto* targetEdge : passNode.getTargetOutgoingEdges()) {
434 auto targetIt = m_imageNodes.find(targetEdge->toImage);
435 if (targetIt != m_imageNodes.end()) {
436 passRenderTarget = targetIt->second.get();
437 break;
438 }
439 }
440
441 if (!passRenderTarget) {
442 for (auto* depthEdge : passNode.getDepthStencilOutgoingEdges()) {
443 auto depthIt = m_imageNodes.find(depthEdge->toImage);
444 if (depthIt != m_imageNodes.end()) {
445 passRenderTarget = depthIt->second.get();
446 break;
447 }
448 }
449 }
450
451 if (passRenderTarget && imageNode->isSameSize(passRenderTarget)) {
452 for (auto* targetEdge : imageNode->getTargetIncomingEdges()) {
453 m_passesUnions.unite(passName, targetEdge->fromPass);
454 }
455
456 for (auto* depthEdge : imageNode->getDepthStencilIncomingEdges()) {
457 m_passesUnions.unite(passName, depthEdge->fromPass);
458 }
459 }
460 }
461 }
462
463 for (const auto& [imageName, imageNode] : m_imageNodes) {
464 std::vector<std::string> targetPasses;
465 std::vector<std::string> depthStencilPasses;
466
467 for (auto* targetEdge : imageNode->getTargetIncomingEdges()) {
468 targetPasses.push_back(targetEdge->fromPass);
469 }
470
471 for (auto* depthEdge : imageNode->getDepthStencilIncomingEdges()) {
472 depthStencilPasses.push_back(depthEdge->fromPass);
473 }
474
475 for (size_t i = 1; i < targetPasses.size(); i++) {
476 m_passesUnions.unite(targetPasses[0], targetPasses[i]);
477 }
478
479 for (size_t i = 1; i < depthStencilPasses.size(); i++) {
480 m_passesUnions.unite(depthStencilPasses[0], depthStencilPasses[i]);
481 }
482
483 if (!targetPasses.empty() && !depthStencilPasses.empty()) {
484 m_passesUnions.unite(targetPasses[0], depthStencilPasses[0]);
485 }
486 }
487 }
489 {
490 for (auto& [name, image] : m_allocatedImages)
491 {
492 m_resourceManager->clearImage(name);
493 }
494 m_allocatedImages.clear();
495 }
496
498 {
499 for (auto& [name, imageNode] : m_imageNodes) {
500 imageNode->fillDefaultData();
501 }
502 auto* resourceManager = m_resourceManager;
503 if (!resourceManager) {
504 throw std::runtime_error("ResourceManager not available");
505 }
506
507 std::set<const SizeNode*> processedRoots;
508
509 for (auto& [name, imageNode] : m_imageNodes) {
510 auto* bufferNode = dynamic_cast<RenderGraphBufferNode*>(imageNode.get());
511 if (!bufferNode || !bufferNode->isFilled()) {
512 continue;
513 }
514
515 const SizeNode* root = bufferNode->getRoot();
516
517 if (root == bufferNode && processedRoots.find(root) == processedRoots.end()) {
518 processedRoots.insert(root);
519
520 uint32_t width, height;
521 bool hasFixedSize = bufferNode->getComputedSize(width, height);
522
523 if (hasFixedSize) {
524 TargetDesc targetDesc;
525 targetDesc.width = static_cast<int>(width);
526 targetDesc.height = static_cast<int>(height);
527 targetDesc.samples = bufferNode->getSamples();
528 targetDesc.format = bufferNode->getFormat();
529 targetDesc.usage = bufferNode->getUsage();
530
531 Image* allocatedImage = resourceManager->allocateTarget(name, targetDesc);
532 bufferNode->setAllocatedImage(allocatedImage); // 调用setAllocatedImage保存图像
533 m_allocatedImages[name] = allocatedImage; // 存储分配的图像
534 } else {
535 throw std::runtime_error("Root node has no fixed size: " + name);
536 }
537 }
538 }
539
540 for (auto& [name, imageNode] : m_imageNodes) {
541 auto* bufferNode = dynamic_cast<RenderGraphBufferNode*>(imageNode.get());
542 if (!bufferNode || !bufferNode->isFilled()) {
543 continue;
544 }
545
546 const SizeNode* root = bufferNode->getRoot();
547
548 if (root != bufferNode) {
549 ImageDesc imageDesc;
550 imageDesc.format = bufferNode->getFormat();
551 imageDesc.samples = bufferNode->getSamples();
552 imageDesc.usage = bufferNode->getUsage();
553
554 Image* allocatedImage = nullptr;
555
556 std::string dependencyName;
557 for (auto& [otherName, otherNode] : m_imageNodes) {
558 if (otherNode->getRoot() == root && otherNode->getRoot() == otherNode.get()) {
559 dependencyName = otherName;
560 break;
561 }
562 }
563
564 if (!dependencyName.empty()) {
565 auto* windowTargetNode = dynamic_cast<RenderGraphWindowTargetNode*>(
566 m_imageNodes[dependencyName].get());
567 auto* windowDepthNode = dynamic_cast<RenderGraphWindowDepthStencilNode*>(
568 m_imageNodes[dependencyName].get());
569
570 if (windowTargetNode && windowTargetNode->isValidWindowTarget()) {
571 allocatedImage = resourceManager->allocateImage(
572 name, windowTargetNode->getWindow(), imageDesc);
573 } else if (windowDepthNode && windowDepthNode->isValidWindowDepthStencil()) {
574 allocatedImage = resourceManager->allocateImage(
575 name, windowDepthNode->getWindow(), imageDesc);
576 } else {
577 allocatedImage = resourceManager->allocateImage(
578 name, dependencyName, imageDesc);
579 }
580
581 bufferNode->setAllocatedImage(allocatedImage);
582 m_allocatedImages[name] = allocatedImage;
583 } else {
584 throw std::runtime_error("Cannot determine dependency for image: " + name);
585 }
586 }
587 }
588 }
589
591 for (const auto& [passName, passNode] : m_passNodes) {
592 RHI::Pass* rhiPass = m_resourceDevice->createResource<RHI::Pass>();
593
594 const EnablePassClear& clearInfo = passNode.getClearInfo();
595 if (clearInfo.types) {
596 rhiPass->enableClear(clearInfo.types, clearInfo.color, clearInfo.depth, clearInfo.stencil);
597 }
598
599 const auto& targetEdges = passNode.getTargetOutgoingEdges();
600 for (size_t i = 0; i < targetEdges.size(); ++i) {
601 const auto& edge = targetEdges[i];
602 auto imageNodeIt = m_imageNodes.find(edge->toImage);
603 if (imageNodeIt != m_imageNodes.end()) {
604 Image* image = imageNodeIt->second->getImage();
605 if (image) {
606 rhiPass->bindTarget(static_cast<int>(i), image);
607 }
608 }
609 }
610
611 const auto& depthStencilEdges = passNode.getDepthStencilOutgoingEdges();
612 for (const auto& edge : depthStencilEdges) {
613 auto imageNodeIt = m_imageNodes.find(edge->toImage);
614 if (imageNodeIt != m_imageNodes.end()) {
615 Image* image = imageNodeIt->second->getImage();
616 if (image) {
617 rhiPass->depthStencil(image);
618 }
619 }
620 }
621
622 m_allocatedPasses[passName] = rhiPass;
623 }
624 }
626 const std::string& groupLeader,
627 const std::vector<std::string>& groupMembers,
628 std::map<std::string, std::set<std::string>>& dependencies
629) const {
630 if (dependencies.find(groupLeader) == dependencies.end()) {
631 dependencies[groupLeader] = std::set<std::string>();
632 }
633
634 for (const std::string& passName : groupMembers) {
635 auto passNodeIt = m_passNodes.find(passName);
636 if (passNodeIt == m_passNodes.end()) continue;
637
638 const auto& passNode = passNodeIt->second;
639
640 for (const auto* textureEdge : passNode.getTextureIncomingEdges()) {
641 auto imageNodeIt = m_imageNodes.find(textureEdge->fromImage);
642 if (imageNodeIt == m_imageNodes.end()) continue;
643
644 const auto& imageNode = imageNodeIt->second;
645
646 for (const auto* targetEdge : imageNode->getTargetIncomingEdges()) {
647 std::string producerPass = targetEdge->fromPass;
648
649 auto allGroups = m_passesUnions.getGroups();
650 for (const auto& [otherGroupLeader, otherGroupMembers] : allGroups) {
651 if (otherGroupLeader != groupLeader &&
652 std::find(otherGroupMembers.begin(), otherGroupMembers.end(), producerPass) != otherGroupMembers.end()) {
653 dependencies[groupLeader].insert(otherGroupLeader);
654 break;
655 }
656 }
657 }
658
659 for (const auto* depthEdge : imageNode->getDepthStencilIncomingEdges()) {
660 std::string producerPass = depthEdge->fromPass;
661
662 auto allGroups = m_passesUnions.getGroups();
663 for (const auto& [otherGroupLeader, otherGroupMembers] : allGroups) {
664 if (otherGroupLeader != groupLeader &&
665 std::find(otherGroupMembers.begin(), otherGroupMembers.end(), producerPass) != otherGroupMembers.end()) {
666 dependencies[groupLeader].insert(otherGroupLeader);
667 break;
668 }
669 }
670 }
671 }
672 }
673 }
674 std::vector<std::string> RenderGraph::topologicalSortPasses() const
675 {
676 auto dependencies = buildPassDependencyGraph();
677 return topologicalSort(dependencies);
678 }
679
680 std::map<std::string, std::set<std::string>> RenderGraph::buildPassDependencyGraph() const
681 {
682 std::map<std::string, std::set<std::string>> dependencies;
683
684 for (const auto& [passName, passNode] : m_passNodes) {
685 dependencies[passName] = std::set<std::string>();
686 }
687
688 for (const auto& [consumerPassName, consumerPassNode] : m_passNodes) {
689 for (const auto* textureEdge : consumerPassNode.getTextureIncomingEdges()) {
690 std::string imageName = textureEdge->fromImage;
691
692 auto imageIt = m_imageNodes.find(imageName);
693 if (imageIt != m_imageNodes.end()) {
694 const auto& imageNode = imageIt->second;
695
696 for (const auto* targetEdge : imageNode->getTargetIncomingEdges()) {
697 std::string producerPassName = targetEdge->fromPass;
698 if (producerPassName != consumerPassName) {
699 dependencies[consumerPassName].insert(producerPassName);
700 }
701 }
702
703 for (const auto* depthEdge : imageNode->getDepthStencilIncomingEdges()) {
704 std::string producerPassName = depthEdge->fromPass;
705 if (producerPassName != consumerPassName) {
706 dependencies[consumerPassName].insert(producerPassName);
707 }
708 }
709 }
710 }
711 }
712
713 return dependencies;
714 }
715
716 std::vector<std::string> RenderGraph::topologicalSort(
717 const std::map<std::string, std::set<std::string>>& dependencies
718 ) const {
719 std::vector<std::string> result;
720 std::map<std::string, int> inDegree;
721 std::queue<std::string> queue;
722
723 for (const auto& [node, deps] : dependencies) {
724 inDegree[node] = 0;
725 }
726
727 for (const auto& [node, deps] : dependencies) {
728 for (const std::string& dep : deps) {
729 if (inDegree.find(dep) != inDegree.end()) {
730 inDegree[node]++;
731 }
732 }
733 }
734
735 for (const auto& [node, degree] : inDegree) {
736 if (degree == 0) {
737 queue.push(node);
738 }
739 }
740
741 while (!queue.empty()) {
742 std::string current = queue.front();
743 queue.pop();
744 result.push_back(current);
745
746 for (const auto& [node, deps] : dependencies) {
747 if (deps.find(current) != deps.end()) {
748 inDegree[node]--;
749 if (inDegree[node] == 0) {
750 queue.push(node);
751 }
752 }
753 }
754 }
755
756 if (result.size() != dependencies.size()) {
757 throw std::runtime_error("Circular dependency detected in PassGroups");
758 }
759
760 return result;
761 }
762
764 auto passGroups = m_passesUnions.getGroups();
765 std::map<std::string, std::set<std::string>> dependencies;
766
767 for (const auto& [groupLeader, groupMembers] : passGroups) {
768 analyzePassGroupDependencies(groupLeader, groupMembers, dependencies);
769 }
770
772
774 }
775
776
778 auto passGroups = m_passesUnions.getGroups();
779
780 for (const auto& [groupLeader, groupMembers] : passGroups) {
781 RHI::PassGroup* passGroup = m_resourceDevice->createResource<RHI::PassGroup>();
782
783 std::vector<std::string> orderedPassNames;
784
785 for (const std::string& passName : groupMembers) {
786 auto passIt = m_allocatedPasses.find(passName);
787 if (passIt == m_allocatedPasses.end()) continue;
788
789 RHI::Pass* currentPass = passIt->second;
790 std::vector<RHI::PassNeighbors> predecessors;
791 std::vector<RHI::PassNeighbors> successors;
792
793 auto passNodeIt = m_passNodes.find(passName);
794 if (passNodeIt != m_passNodes.end()) {
795 const auto& passNode = passNodeIt->second;
796
797 bool outputsToWindow = false;
798 //判断 target和depth是否窗口
799 for (const auto* targetEdge : passNode.getTargetOutgoingEdges()) {
800 auto imageNodeIt = m_imageNodes.find(targetEdge->toImage);
801 if (imageNodeIt != m_imageNodes.end()) {
802 auto* windowTargetNode = dynamic_cast<RenderGraphWindowTargetNode*>(
803 imageNodeIt->second.get());
804 if (windowTargetNode && windowTargetNode->isValidWindowTarget()) {
805 outputsToWindow = true;
806 break;
807 }
808 }
809 }
810
811 if (!outputsToWindow) {
812 for (const auto* depthEdge : passNode.getDepthStencilOutgoingEdges()) {
813 auto imageNodeIt = m_imageNodes.find(depthEdge->toImage);
814 if (imageNodeIt != m_imageNodes.end()) {
815 auto* windowDepthNode = dynamic_cast<RenderGraphWindowDepthStencilNode*>(
816 imageNodeIt->second.get());
817 if (windowDepthNode && windowDepthNode->isValidWindowDepthStencil()) {
818 outputsToWindow = true;
819 break;
820 }
821 }
822 }
823 }
824
825 if (outputsToWindow) {
826 successors.emplace_back(
828 );
829 }
830
831 for (const auto* textureEdge : passNode.getTextureIncomingEdges()) {
832 auto imageNodeIt = m_imageNodes.find(textureEdge->fromImage);
833 if (imageNodeIt != m_imageNodes.end()) {
834 const auto& imageNode = imageNodeIt->second;
835
836 // 检查Target边
837 for (const auto* targetEdge : imageNode->getTargetIncomingEdges()) {
838 if (std::find(groupMembers.begin(), groupMembers.end(), targetEdge->fromPass) != groupMembers.end()) {
839 auto predecessorPassIt = m_allocatedPasses.find(targetEdge->fromPass);
840 if (predecessorPassIt != m_allocatedPasses.end()) {
841 predecessors.emplace_back(
842 predecessorPassIt->second,
845 convertShaderStageToPipelineStage(textureEdge->stage),
847 );
848 }
849 }
850 }
851
852 // 检查DepthStencil边
853 for (const auto* depthEdge : imageNode->getDepthStencilIncomingEdges()) {
854 if (std::find(groupMembers.begin(), groupMembers.end(), depthEdge->fromPass) != groupMembers.end()) {
855 auto predecessorPassIt = m_allocatedPasses.find(depthEdge->fromPass);
856 if (predecessorPassIt != m_allocatedPasses.end()) {
857 predecessors.emplace_back(
858 predecessorPassIt->second,
861 convertShaderStageToPipelineStage(textureEdge->stage),
863 );
864 }
865 }
866 }
867 }
868 }
869 }
870
871 orderedPassNames.push_back(passName);
872
873 passGroup->addPass({
874 currentPass,
875 predecessors,
876 successors
877 });
878 }
879
880 m_passGroupOrders[groupLeader] = std::move(orderedPassNames);
881
882 passGroup->create();
883
884 m_allocatedPassGroups[groupLeader] = passGroup;
885 }
886 }
888 const std::string& groupLeader) {
889 auto passGroup = m_allocatedPassGroups.at(groupLeader);
890 auto orderIt = m_passGroupOrders.find(groupLeader);
891 if (orderIt == m_passGroupOrders.end()) {
892 return;
893 }
894
895 const std::vector<std::string>& orderedPassNames = orderIt->second;
896
897 passGroup->beginSubmit(cmdBuffer);
898
899 for (size_t i = 0; i < orderedPassNames.size(); ++i) {
900 const std::string& passName = orderedPassNames[i];
901
902 PassSubmitEvent env;
903 env.passName = passName;
904 env.cmdBuf = cmdBuffer;
905 trigger(env);
906
907 if (i < orderedPassNames.size() - 1) {
908 passGroup->nextPass(cmdBuffer);
909 }
910 }
911
912 passGroup->endSubmit(cmdBuffer);
913 }
915 auto passGroups = m_passesUnions.getGroups();
916 std::unordered_map<Image*, ImageState> imageStates;
917
918 for (const auto& [imageName, imageNode] : m_imageNodes) {
919 Image* image = imageNode->getImage();
920 if (image) {
921 imageStates[image] = ImageState{};
922 }
923 }
924
925 for (const std::string& groupLeader : m_passGroupExecutionOrder) {
926 auto groupIt = passGroups.find(groupLeader);
927 if (groupIt == passGroups.end()) continue;
928
929 const auto& groupMembers = groupIt->second;
930
931 std::vector<BarrierInfo> barriers = checkBarriersBeforePassGroup(groupLeader, groupMembers, imageStates);
932
933 if (!barriers.empty()) {
934 m_passGroupBarriers[groupLeader] = std::move(barriers);
935 }
936
937 simulatePassGroupExecution(groupLeader, groupMembers, imageStates);
938 }
939 }
940
941 std::vector<RenderGraph::BarrierInfo> RenderGraph::checkBarriersBeforePassGroup(
942 const std::string& groupLeader,
943 const std::vector<std::string>& groupMembers,
944 const std::unordered_map<Image*, ImageState>& imageStates) {
945
946 std::vector<BarrierInfo> barriers;
947 std::set<Image*> processedImages;
948
949 for (const std::string& passName : groupMembers) {
950 auto passIt = m_passNodes.find(passName);
951 if (passIt == m_passNodes.end()) continue;
952
953 const auto& passNode = passIt->second;
954
955 for (const auto* textureEdge : passNode.getTextureIncomingEdges()) {
956 auto imageNodeIt = m_imageNodes.find(textureEdge->fromImage);
957 if (imageNodeIt == m_imageNodes.end()) continue;
958
959 Image* image = imageNodeIt->second->getImage();
960 if (!image || processedImages.count(image)) continue;
961
962 auto stateIt = imageStates.find(image);
963 if (stateIt == imageStates.end()) continue;
964
965 const ImageState& currentState = stateIt->second;
966
967 PipelineStage requiredStage = convertShaderStageToPipelineStage(textureEdge->stage);
968 AccessFlag requiredAccess = AccessFlag::shaderRead;
970
971 bool needsBarrier = false;
972
973 if (currentState.currentLayout != requiredLayout &&
974 currentState.currentLayout != ImageLayout::undefined) {
975 needsBarrier = true;
976 }
977
978 if (!currentState.lastWriterGroup.empty() &&
979 currentState.lastWriterGroup != groupLeader &&
981 needsBarrier = true;
982 }
983
984 if (needsBarrier) {
985 BarrierInfo barrier;
986 barrier.image = image;
987 barrier.oldLayout = currentState.currentLayout;
988 barrier.newLayout = requiredLayout;
989 barrier.srcStage = currentState.lastStage;
990 barrier.dstStage = requiredStage;
991 barrier.srcAccess = currentState.lastAccess;
992 barrier.dstAccess = requiredAccess;
993
996 barrier.aspect = ImageAspect::depth;
997 } else {
998 barrier.aspect = ImageAspect::color;
999 }
1000
1001 barriers.push_back(barrier);
1002 processedImages.insert(image);
1003 }
1004 }
1005 }
1006
1007 return barriers;
1008 }
1009
1011 const std::string& groupLeader,
1012 const std::vector<std::string>& groupMembers,
1013 std::unordered_map<Image*, ImageState>& imageStates) {
1014
1015 for (const std::string& passName : groupMembers) {
1016 auto passIt = m_passNodes.find(passName);
1017 if (passIt == m_passNodes.end()) continue;
1018
1019 const auto& passNode = passIt->second;
1020
1021 for (const auto* targetEdge : passNode.getTargetOutgoingEdges()) {
1022 auto imageNodeIt = m_imageNodes.find(targetEdge->toImage);
1023 if (imageNodeIt == m_imageNodes.end()) continue;
1024
1025 Image* image = imageNodeIt->second->getImage();
1026 if (!image) continue;
1027
1028 ImageState& state = imageStates[image];
1032 state.lastWriterGroup = groupLeader;
1033 }
1034
1035 for (const auto* depthEdge : passNode.getDepthStencilOutgoingEdges()) {
1036 auto imageNodeIt = m_imageNodes.find(depthEdge->toImage);
1037 if (imageNodeIt == m_imageNodes.end()) continue;
1038
1039 Image* image = imageNodeIt->second->getImage();
1040 if (!image) continue;
1041
1042 ImageState& state = imageStates[image];
1046 state.lastWriterGroup = groupLeader;
1047 }
1048
1049 for (const auto* textureEdge : passNode.getTextureIncomingEdges()) {
1050 auto imageNodeIt = m_imageNodes.find(textureEdge->fromImage);
1051 if (imageNodeIt == m_imageNodes.end()) continue;
1052
1053 Image* image = imageNodeIt->second->getImage();
1054 if (!image) continue;
1055
1056 ImageState& state = imageStates[image];
1059 state.lastStage = convertShaderStageToPipelineStage(textureEdge->stage);
1061 }
1062 }
1063 }
1064 }
1065
1067 {
1069 for (auto& [name, pass] : m_allocatedPasses)
1070 {
1071 pipeHub.passPipe.remove<PassInfo>(name);
1072 }
1073 m_passGroupOrders.clear();
1075 m_passGroupBarriers.clear();
1077 m_imageNodes.clear();
1078 m_passNodes.clear();
1080 m_edges.clear();
1081 clearResources();//m_allocatedImages
1082 for (auto& [name, pass] : m_allocatedPasses)
1083 {
1084 pass->release();
1085 }
1086 m_allocatedPasses.clear();
1088 for (auto& [name, passGroup] : m_allocatedPassGroups)
1089 {
1090 passGroup->release();
1091 }
1092 }
1093
1106 void RenderGraph::executeBarriers(RHI::CommandBuffer* cmdBuffer, const std::vector<BarrierInfo>& barriers) {
1107 for (const auto& barrier : barriers) {
1108 cmdBuffer->barrier(
1109 barrier.image,
1110 barrier.oldLayout,
1111 barrier.newLayout,
1112 barrier.srcStage,
1113 barrier.dstStage,
1114 barrier.srcAccess,
1115 barrier.dstAccess,
1116 barrier.aspect
1117 );
1118 }
1119 }
1121 {
1122 std::vector<std::string> passesToCull;
1123
1124 for (const auto& [passName, passNode] : m_passNodes) {
1125 bool shouldCull = false;
1126
1127 bool hasTargetOutput = !passNode.getTargetOutgoingEdges().empty();
1128 bool hasDepthStencilOutput = !passNode.getDepthStencilOutgoingEdges().empty();
1129
1130 if (!hasTargetOutput && !hasDepthStencilOutput) {
1131 shouldCull = true;
1132 } else {
1133 for (const auto* targetEdge : passNode.getTargetOutgoingEdges()) {
1134 auto imageNodeIt = m_imageNodes.find(targetEdge->toImage);
1135 if (imageNodeIt != m_imageNodes.end()) {
1136 const auto* imageNode = imageNodeIt->second.get();
1137
1138 const auto* bufferNode = dynamic_cast<const RenderGraphBufferNode*>(imageNode);
1139 if (bufferNode && !bufferNode->isSizeDetermined()) {
1140 shouldCull = true;
1141 break;
1142 }
1143 }
1144 }
1145
1146 if (!shouldCull) {
1147 for (const auto* depthEdge : passNode.getDepthStencilOutgoingEdges()) {
1148 auto imageNodeIt = m_imageNodes.find(depthEdge->toImage);
1149 if (imageNodeIt != m_imageNodes.end()) {
1150 const auto* imageNode = imageNodeIt->second.get();
1151
1152 const auto* bufferNode = dynamic_cast<const RenderGraphBufferNode*>(imageNode);
1153 if (bufferNode && !bufferNode->isSizeDetermined()) {
1154 shouldCull = true;
1155 break;
1156 }
1157 }
1158 }
1159 }
1160 }
1161
1162 if (shouldCull) {
1163 passesToCull.push_back(passName);
1164 }
1165 }
1166
1167 for (const std::string& passName : passesToCull) {
1168 cullPass(passName);
1169 }
1170 }
1171
1172void RenderGraph::cullPass(const std::string& passName)
1173 {
1174 auto passIt = m_passNodes.find(passName);
1175 if (passIt == m_passNodes.end()) {
1176 return;
1177 }
1178
1179 const auto& passNode = passIt->second;
1180 std::vector<std::string> imagesToCull;
1181
1182 std::vector<TextureEdge*> textureEdgesToRemove;
1183 std::vector<TargetEdge*> targetEdgesToRemove;
1184 std::vector<DepthStencilEdge*> depthStencilEdgesToRemove;
1185
1186 for (const auto* textureEdge : passNode.getTextureIncomingEdges()) {
1187 textureEdgesToRemove.push_back(const_cast<TextureEdge*>(textureEdge));
1188 }
1189
1190 for (const auto* targetEdge : passNode.getTargetOutgoingEdges()) {
1191 targetEdgesToRemove.push_back(const_cast<TargetEdge*>(targetEdge));
1192
1193 auto imageNodeIt = m_imageNodes.find(targetEdge->toImage);
1194 if (imageNodeIt != m_imageNodes.end()) {
1195 const auto& imageNode = imageNodeIt->second;
1196
1197 if (imageNode->getTargetIncomingEdges().size() == 1 &&
1198 imageNode->getDepthStencilIncomingEdges().empty() &&
1199 imageNode->getTextureOutgoingEdges().empty()) {
1200 imagesToCull.push_back(targetEdge->toImage);
1201 }
1202 }
1203 }
1204
1205 for (const auto* depthEdge : passNode.getDepthStencilOutgoingEdges()) {
1206 depthStencilEdgesToRemove.push_back(const_cast<DepthStencilEdge*>(depthEdge));
1207
1208 auto imageNodeIt = m_imageNodes.find(depthEdge->toImage);
1209 if (imageNodeIt != m_imageNodes.end()) {
1210 const auto& imageNode = imageNodeIt->second;
1211
1212 if (imageNode->getDepthStencilIncomingEdges().size() == 1 &&
1213 imageNode->getTargetIncomingEdges().empty() &&
1214 imageNode->getTextureOutgoingEdges().empty()) {
1215 imagesToCull.push_back(depthEdge->toImage);
1216 }
1217 }
1218 }
1219
1220 for (auto* edge : textureEdgesToRemove) {
1221 removeTextureEdge(edge);
1222 }
1223
1224 for (auto* edge : targetEdgesToRemove) {
1225 removeTargetEdge(edge);
1226 }
1227
1228 for (auto* edge : depthStencilEdgesToRemove) {
1230 }
1231
1232 for (const std::string& imageName : imagesToCull) {
1233 m_imageNodes.erase(imageName);
1234 }
1235
1236 m_passNodes.erase(passName);
1237
1238 auto it = std::find(m_topologicalSortPasses.begin(), m_topologicalSortPasses.end(), passName);
1239 if (it != m_topologicalSortPasses.end()) {
1240 m_topologicalSortPasses.erase(it);
1241 }
1242 }
1243
1245 {
1246 for (auto [passName,pass] : m_allocatedPasses)
1247 {
1248 PassInfo info{
1249 *pass
1250 };
1251 pipeHub
1252 .passPipe
1253 .provide(passName,
1254 PassInfo{
1255 *pass,
1256 [this, passName]() -> std::map<std::string, Image*>
1257 {
1258 std::map<std::string, Image*> textureImages;
1259 auto passNodeIt = m_passNodes.find(passName);
1260 if (passNodeIt != m_passNodes.end())
1261 {
1262 const auto& passNode = passNodeIt->second;
1263
1264 for (const auto* textureEdge : passNode.getTextureIncomingEdges())
1265 {
1266 auto imageNodeIt = m_imageNodes.find(textureEdge->fromImage);
1267 if (imageNodeIt != m_imageNodes.end())
1268 {
1269 Image* image = imageNodeIt->second->getImage();
1270 if (image)
1271 {
1272 textureImages[textureEdge->fromImage] = image;
1273 }
1274 }
1275 }
1276 }
1277 return textureImages;
1278 }.operator()(),
1279 [this, passName]() -> std::map<std::string, ShaderStage>
1280 {
1281 std::map<std::string, ShaderStage> textureStages;
1282 auto passNodeIt = m_passNodes.find(passName);
1283 if (passNodeIt != m_passNodes.end())
1284 {
1285 const auto& passNode = passNodeIt->second;
1286
1287 for (const auto* textureEdge : passNode.getTextureIncomingEdges())
1288 {
1289 textureStages[textureEdge->fromImage] = textureEdge->stage;
1290 }
1291 }
1292 return textureStages;
1293 }.operator()(),
1294 [this, passName]() -> std::map<std::string, Image*>
1295 {
1296 std::map<std::string, Image*> targetImages;
1297 auto passNodeIt = m_passNodes.find(passName);
1298 if (passNodeIt != m_passNodes.end())
1299 {
1300 const auto& passNode = passNodeIt->second;
1301
1302 for (const auto* targetEdge : passNode.getTargetOutgoingEdges())
1303 {
1304 auto imageNodeIt = m_imageNodes.find(targetEdge->toImage);
1305 if (imageNodeIt != m_imageNodes.end())
1306 {
1307 Image* image = imageNodeIt->second->getImage();
1308 if (image)
1309 {
1310 targetImages[targetEdge->toImage] = image;
1311 }
1312 }
1313 }
1314 }
1315 return targetImages;
1316 }.operator()(),
1317 [this, passName]() -> std::map<std::string, Image*>
1318 {
1319 std::map<std::string, Image*> depthStencilImages;
1320 auto passNodeIt = m_passNodes.find(passName);
1321 if (passNodeIt != m_passNodes.end())
1322 {
1323 const auto& passNode = passNodeIt->second;
1324
1325 for (const auto* depthEdge : passNode.getDepthStencilOutgoingEdges())
1326 {
1327 auto imageNodeIt = m_imageNodes.find(depthEdge->toImage);
1328 if (imageNodeIt != m_imageNodes.end())
1329 {
1330 Image* image = imageNodeIt->second->getImage();
1331 if (image)
1332 {
1333 depthStencilImages[depthEdge->toImage] = image;
1334 }
1335 }
1336 }
1337 }
1338 return depthStencilImages;
1339 }.operator()(),
1340 [this, passName]() -> OutputInfo
1341 {
1342 OutputInfo outputInfo;
1343 auto passNodeIt = m_passNodes.find(passName);
1344 if (passNodeIt != m_passNodes.end())
1345 {
1346 const auto& passNode = passNodeIt->second;
1347
1348 const SizeNode* rootNode = nullptr;
1349
1350 for (const auto* targetEdge : passNode.getTargetOutgoingEdges())
1351 {
1352 auto imageNodeIt = m_imageNodes.find(targetEdge->toImage);
1353 if (imageNodeIt != m_imageNodes.end())
1354 {
1355 rootNode = imageNodeIt->second->getRoot();
1356 break;
1357 }
1358 }
1359
1360 if (!rootNode)
1361 {
1362 for (const auto* depthEdge : passNode.getDepthStencilOutgoingEdges())
1363 {
1364 auto imageNodeIt = m_imageNodes.find(depthEdge->toImage);
1365 if (imageNodeIt != m_imageNodes.end())
1366 {
1367 rootNode = imageNodeIt->second->getRoot();
1368 break;
1369 }
1370 }
1371 }
1372
1373 if (rootNode)
1374 {
1375 if (auto windowTarget = dynamic_cast<const RenderGraphWindowTargetNode*>(rootNode))
1376 {
1377 outputInfo.isWindow = true;
1378 outputInfo.window = windowTarget->getWindow();
1379 if (outputInfo.window)
1380 {
1381 outputInfo.width = outputInfo.window->getWidth();
1382 outputInfo.height = outputInfo.window->getHeight();
1383 }
1384 }
1385 else if (auto windowDepth = dynamic_cast<const RenderGraphWindowDepthStencilNode*>(rootNode))
1386 {
1387 outputInfo.isWindow = true;
1388 outputInfo.window = windowDepth->getWindow();
1389 if (outputInfo.window)
1390 {
1391 outputInfo.width = outputInfo.window->getWidth();
1392 outputInfo.height = outputInfo.window->getHeight();
1393 }
1394 }
1395 else
1396 {
1397 outputInfo.isWindow = false;
1398 outputInfo.window = nullptr;
1399 rootNode->getComputedSize(outputInfo.width, outputInfo.height);
1400 }
1401 }
1402 }
1403 return outputInfo;
1404 }.operator()()
1405 });
1406 }
1407 }
1408
1410 {
1411 for (const std::string& groupLeader : m_passGroupExecutionOrder) {
1412 auto barrierIt = m_passGroupBarriers.find(groupLeader);
1413 if (barrierIt != m_passGroupBarriers.end()) {
1414 executeBarriers(cmdBuffer, barrierIt->second);
1415 }
1416 submitPassGroup(cmdBuffer, groupLeader);
1417 }
1418 }
1419
1420 RHI::Pass* RenderGraph::getPass(const std::string& name) const
1421 {
1422 return m_allocatedPasses.at(name);
1423 }
1424
1425 Image* RenderGraph::getImage(const std::string& name) const
1426 {
1427 auto imageNodeIt = m_imageNodes.find(name);
1428 if (imageNodeIt!= m_imageNodes.end()) {
1429 return imageNodeIt->second->getImage();
1430 }
1431 return nullptr;
1432 }
1433
1434 std::vector<TextureEdge*> RenderGraph::getTextureEdges(const std::string& passName) const
1435 {
1436 auto passNodeIt = m_passNodes.find(passName);
1437 if (passNodeIt!= m_passNodes.end()) {
1438 return passNodeIt->second.getTextureIncomingEdges();
1439 }
1440 return {};
1441 }
1442
1443}// FCT
virtual Image * getImage() const
定义 Image.h:70
virtual void barrier(FCT::Image *image, ImageLayout oldLayout, ImageLayout newLayout, PipelineStages srcStage, PipelineStages dstStage, AccessFlags srcAccess, AccessFlags dstAccess, ImageAspects aspectMask=ImageAspect::color)=0
void addPass(Pass *pass)
virtual void create()=0
void depthStencil(FCT::Image *depthStencil)
定义 Pass.h:40
static constexpr Pass * present
定义 Pass.h:25
void enableClear(ClearTypes type, Vec4 color, float depth=1.0f, uint8_t stencil=0)
定义 Pass.h:49
void bindTarget(uint32_t index, FCT::Image *target)
定义 Pass.h:32
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::unordered_map< std::string, Image * > m_allocatedImages
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
FlowControl * m_flowControl
std::vector< TextureEdge * > getTextureEdges(const std::string &passName) const
RenderGraphImageNode * getOrCreateImageNode(const std::string &name, const Texture &texture)
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
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
const std::vector< TargetEdge * > & getTargetIncomingEdges() const
const std::vector< DepthStencilEdge * > & getDepthStencilIncomingEdges() const
Image * getImage() const override
virtual int getHeight()=0
virtual int getWidth()=0
constexpr const char * CheckRecompiledSync
constexpr const char * RenderGraphSubmit
constexpr const char * SwapBufferSubmitTicker
ShaderStage getEarliestStage(ShaderStages stages)
std::vector< Texture > textures
std::vector< Target > targets
std::vector< DepthStencil > depthStencils
RHI::CommandBuffer * cmdBuf
const SizeNode * getRoot() const noexcept
bool isSizeDetermined() const noexcept
bool isSameSize(const SizeNode *other) const noexcept
bool unite(SizeNode *other, const FractionScale2D &scale=FractionScale2D()) const noexcept
bool getComputedSize(uint32_t &w, uint32_t &h) const noexcept