10 return m_window->getCurrentTarget()->targetImage();
15 return m_window->getCurrentTarget()->depthStencilBuffer();
49 std::vector<CommandBufferGraph::NodeRef> windowNodes;
51 for (
const auto& [imageName, imageNode] :
m_imageNodes) {
55 if (windowTargetNode && windowTargetNode->isValidWindowTarget()) {
56 window = windowTargetNode->getWindow();
61 if (windowDepthNode && windowDepthNode->isValidWindowDepthStencil()) {
62 window = windowDepthNode->getWindow();
67 bool alreadyAdded =
false;
68 for (
const auto& node : windowNodes) {
75 windowNodes.emplace_back(window);
105 syncTickers.update();
112 syncTickers.update();
115 submitGraph.update();
122 *(it->second) |= texture;
123 return it->second.get();
125 auto node = std::make_unique<RenderGraphBufferNode>(texture);
136 *(it->second) |= target;
137 return it->second.get();
140 auto node = std::make_unique<RenderGraphWindowTargetNode>(target);
145 auto node = std::make_unique<RenderGraphBufferNode>(target);
158 return it->second.get();
161 auto node = std::make_unique<RenderGraphWindowDepthStencilNode>(
depthStencil);
166 auto node = std::make_unique<RenderGraphBufferNode>(
depthStencil);
179 auto edge = std::make_unique<TextureEdge>();
180 edge->size = texture.
size;
181 edge->fromImage = textureName;
182 edge->toPass = passName;
189 imageNodeIt->second->addOutgoingEdge(edgePtr);
191 pass.addIncomingEdge(edgePtr);
193 m_edges.insert(std::move(edge));
200 auto edge = std::make_unique<TargetEdge>();
201 edge->fromPass = passName;
202 edge->toImage = targetName;
208 imageNodeIt->second->addIncomingEdge(edgePtr);
210 pass.addOutgoingEdge(edgePtr);
212 m_edges.insert(std::move(edge));
220 auto edge = std::make_unique<DepthStencilEdge>();
221 edge->fromPass = passName;
222 edge->toImage = depthStencilName;
228 imageNodeIt->second->addIncomingEdge(edgePtr);
230 pass.addOutgoingEdge(edgePtr);
232 m_edges.insert(std::move(edge));
235 if (!edgeToRemove)
return;
239 auto& pass = passIt->second;
240 auto& incomingEdges =
const_cast<std::vector<TextureEdge*>&
>(pass.getTextureIncomingEdges());
242 std::remove(incomingEdges.begin(), incomingEdges.end(), edgeToRemove),
249 imageNodeIt->second->removeOutgoingEdge(edgeToRemove);
253 [edgeToRemove](
const std::unique_ptr<Edge>& edge) {
254 return edge.get() == edgeToRemove;
263 if (!edgeToRemove)
return;
267 auto& pass = passIt->second;
268 auto& outgoingEdges =
const_cast<std::vector<TargetEdge*>&
>(pass.getTargetOutgoingEdges());
270 std::remove(outgoingEdges.begin(), outgoingEdges.end(), edgeToRemove),
277 imageNodeIt->second->removeIncomingEdge(edgeToRemove);
281 [edgeToRemove](
const std::unique_ptr<Edge>& edge) {
282 return edge.get() == edgeToRemove;
291 if (!edgeToRemove)
return;
296 auto& pass = passIt->second;
297 auto& outgoingEdges =
const_cast<std::vector<DepthStencilEdge*>&
>(pass.getDepthStencilOutgoingEdges());
299 std::remove(outgoingEdges.begin(), outgoingEdges.end(), edgeToRemove),
307 imageNodeIt->second->removeIncomingEdge(edgeToRemove);
312 [edgeToRemove](
const std::unique_ptr<Edge>& edge) {
313 return edge.get() == edgeToRemove;
325 pass.applyPassDesc(desc);
333 std::vector<RenderGraphImageNode*> renderTargetNodes;
335 for (
auto& target : desc.
targets)
338 renderTargetNodes.push_back(node);
345 renderTargetNodes.push_back(node);
349 if (renderTargetNodes.size() > 1) {
351 for (
size_t i = 1; i < renderTargetNodes.size(); ++i) {
352 firstNode->
unite(renderTargetNodes[i]);
372 std::vector<RenderGraphImageNode*> referenceNodes;
374 for (
auto* targetEdge : pass.getTargetOutgoingEdges()) {
375 auto imageNodeIt =
m_imageNodes.find(targetEdge->toImage);
377 referenceNodes.push_back(imageNodeIt->second.get());
381 for (
auto* depthStencilEdge : pass.getDepthStencilOutgoingEdges()) {
382 auto imageNodeIt =
m_imageNodes.find(depthStencilEdge->toImage);
384 referenceNodes.push_back(imageNodeIt->second.get());
388 if (referenceNodes.empty()) {
394 for (
auto* textureEdge : pass.getTextureIncomingEdges()) {
395 auto imageNodeIt =
m_imageNodes.find(textureEdge->fromImage);
409 FractionScale2D scale(textureEdge->size.relativeWidth, textureEdge->size.relativeHeight);
410 textureNode->
unite(referenceNode, scale);
418 for (
const auto& [passName, passNode] :
m_passNodes) {
422 for (
const auto& [passName, passNode] :
m_passNodes) {
423 for (
auto* textureEdge : passNode.getTextureIncomingEdges()) {
424 std::string imageName = textureEdge->fromImage;
433 for (
auto* targetEdge : passNode.getTargetOutgoingEdges()) {
436 passRenderTarget = targetIt->second.get();
441 if (!passRenderTarget) {
442 for (
auto* depthEdge : passNode.getDepthStencilOutgoingEdges()) {
445 passRenderTarget = depthIt->second.get();
451 if (passRenderTarget && imageNode->
isSameSize(passRenderTarget)) {
463 for (
const auto& [imageName, imageNode] :
m_imageNodes) {
464 std::vector<std::string> targetPasses;
465 std::vector<std::string> depthStencilPasses;
467 for (
auto* targetEdge : imageNode->getTargetIncomingEdges()) {
468 targetPasses.push_back(targetEdge->fromPass);
471 for (
auto* depthEdge : imageNode->getDepthStencilIncomingEdges()) {
472 depthStencilPasses.push_back(depthEdge->fromPass);
475 for (
size_t i = 1; i < targetPasses.size(); i++) {
479 for (
size_t i = 1; i < depthStencilPasses.size(); i++) {
480 m_passesUnions.unite(depthStencilPasses[0], depthStencilPasses[i]);
483 if (!targetPasses.empty() && !depthStencilPasses.empty()) {
500 imageNode->fillDefaultData();
503 if (!resourceManager) {
504 throw std::runtime_error(
"ResourceManager not available");
507 std::set<const SizeNode*> processedRoots;
511 if (!bufferNode || !bufferNode->isFilled()) {
517 if (root == bufferNode && processedRoots.find(root) == processedRoots.end()) {
518 processedRoots.insert(root);
520 uint32_t width, height;
521 bool hasFixedSize = bufferNode->getComputedSize(width, height);
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();
531 Image* allocatedImage = resourceManager->allocateTarget(name, targetDesc);
532 bufferNode->setAllocatedImage(allocatedImage);
535 throw std::runtime_error(
"Root node has no fixed size: " + name);
542 if (!bufferNode || !bufferNode->isFilled()) {
548 if (root != bufferNode) {
550 imageDesc.
format = bufferNode->getFormat();
551 imageDesc.
samples = bufferNode->getSamples();
552 imageDesc.
usage = bufferNode->getUsage();
554 Image* allocatedImage =
nullptr;
556 std::string dependencyName;
558 if (otherNode->getRoot() == root && otherNode->
getRoot() == otherNode.get()) {
559 dependencyName = otherName;
564 if (!dependencyName.empty()) {
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);
577 allocatedImage = resourceManager->allocateImage(
578 name, dependencyName, imageDesc);
581 bufferNode->setAllocatedImage(allocatedImage);
584 throw std::runtime_error(
"Cannot determine dependency for image: " + name);
591 for (
const auto& [passName, passNode] :
m_passNodes) {
595 if (clearInfo.types) {
596 rhiPass->
enableClear(clearInfo.types, clearInfo.color, clearInfo.depth, clearInfo.stencil);
599 const auto& targetEdges = passNode.getTargetOutgoingEdges();
600 for (
size_t i = 0; i < targetEdges.size(); ++i) {
601 const auto& edge = targetEdges[i];
606 rhiPass->
bindTarget(
static_cast<int>(i), image);
611 const auto& depthStencilEdges = passNode.getDepthStencilOutgoingEdges();
612 for (
const auto& edge : depthStencilEdges) {
626 const std::string& groupLeader,
627 const std::vector<std::string>& groupMembers,
628 std::map<std::string, std::set<std::string>>& dependencies
630 if (dependencies.find(groupLeader) == dependencies.end()) {
631 dependencies[groupLeader] = std::set<std::string>();
634 for (
const std::string& passName : groupMembers) {
638 const auto& passNode = passNodeIt->second;
640 for (
const auto* textureEdge : passNode.getTextureIncomingEdges()) {
641 auto imageNodeIt =
m_imageNodes.find(textureEdge->fromImage);
644 const auto& imageNode = imageNodeIt->second;
646 for (
const auto* targetEdge : imageNode->getTargetIncomingEdges()) {
647 std::string producerPass = targetEdge->fromPass;
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);
659 for (
const auto* depthEdge : imageNode->getDepthStencilIncomingEdges()) {
660 std::string producerPass = depthEdge->fromPass;
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);
682 std::map<std::string, std::set<std::string>> dependencies;
684 for (
const auto& [passName, passNode] :
m_passNodes) {
685 dependencies[passName] = std::set<std::string>();
688 for (
const auto& [consumerPassName, consumerPassNode] :
m_passNodes) {
689 for (
const auto* textureEdge : consumerPassNode.getTextureIncomingEdges()) {
690 std::string imageName = textureEdge->fromImage;
694 const auto& imageNode = imageIt->second;
696 for (
const auto* targetEdge : imageNode->getTargetIncomingEdges()) {
697 std::string producerPassName = targetEdge->fromPass;
698 if (producerPassName != consumerPassName) {
699 dependencies[consumerPassName].insert(producerPassName);
703 for (
const auto* depthEdge : imageNode->getDepthStencilIncomingEdges()) {
704 std::string producerPassName = depthEdge->fromPass;
705 if (producerPassName != consumerPassName) {
706 dependencies[consumerPassName].insert(producerPassName);
717 const std::map<std::string, std::set<std::string>>& dependencies
719 std::vector<std::string> result;
720 std::map<std::string, int> inDegree;
721 std::queue<std::string> queue;
723 for (
const auto& [node, deps] : dependencies) {
727 for (
const auto& [node, deps] : dependencies) {
728 for (
const std::string& dep : deps) {
729 if (inDegree.find(dep) != inDegree.end()) {
735 for (
const auto& [node, degree] : inDegree) {
741 while (!queue.empty()) {
742 std::string current = queue.front();
744 result.push_back(current);
746 for (
const auto& [node, deps] : dependencies) {
747 if (deps.find(current) != deps.end()) {
749 if (inDegree[node] == 0) {
756 if (result.size() != dependencies.size()) {
757 throw std::runtime_error(
"Circular dependency detected in PassGroups");
765 std::map<std::string, std::set<std::string>> dependencies;
767 for (
const auto& [groupLeader, groupMembers] : passGroups) {
780 for (
const auto& [groupLeader, groupMembers] : passGroups) {
783 std::vector<std::string> orderedPassNames;
785 for (
const std::string& passName : groupMembers) {
790 std::vector<RHI::PassNeighbors> predecessors;
791 std::vector<RHI::PassNeighbors> successors;
795 const auto& passNode = passNodeIt->second;
797 bool outputsToWindow =
false;
799 for (
const auto* targetEdge : passNode.getTargetOutgoingEdges()) {
800 auto imageNodeIt =
m_imageNodes.find(targetEdge->toImage);
803 imageNodeIt->second.get());
804 if (windowTargetNode && windowTargetNode->isValidWindowTarget()) {
805 outputsToWindow =
true;
811 if (!outputsToWindow) {
812 for (
const auto* depthEdge : passNode.getDepthStencilOutgoingEdges()) {
813 auto imageNodeIt =
m_imageNodes.find(depthEdge->toImage);
816 imageNodeIt->second.get());
817 if (windowDepthNode && windowDepthNode->isValidWindowDepthStencil()) {
818 outputsToWindow =
true;
825 if (outputsToWindow) {
826 successors.emplace_back(
831 for (
const auto* textureEdge : passNode.getTextureIncomingEdges()) {
832 auto imageNodeIt =
m_imageNodes.find(textureEdge->fromImage);
834 const auto& imageNode = imageNodeIt->second;
837 for (
const auto* targetEdge : imageNode->getTargetIncomingEdges()) {
838 if (std::find(groupMembers.begin(), groupMembers.end(), targetEdge->fromPass) != groupMembers.end()) {
841 predecessors.emplace_back(
842 predecessorPassIt->second,
853 for (
const auto* depthEdge : imageNode->getDepthStencilIncomingEdges()) {
854 if (std::find(groupMembers.begin(), groupMembers.end(), depthEdge->fromPass) != groupMembers.end()) {
857 predecessors.emplace_back(
858 predecessorPassIt->second,
871 orderedPassNames.push_back(passName);
888 const std::string& groupLeader) {
895 const std::vector<std::string>& orderedPassNames = orderIt->second;
897 passGroup->beginSubmit(cmdBuffer);
899 for (
size_t i = 0; i < orderedPassNames.size(); ++i) {
900 const std::string& passName = orderedPassNames[i];
907 if (i < orderedPassNames.size() - 1) {
908 passGroup->nextPass(cmdBuffer);
912 passGroup->endSubmit(cmdBuffer);
916 std::unordered_map<Image*, ImageState> imageStates;
918 for (
const auto& [imageName, imageNode] :
m_imageNodes) {
926 auto groupIt = passGroups.find(groupLeader);
927 if (groupIt == passGroups.end())
continue;
929 const auto& groupMembers = groupIt->second;
933 if (!barriers.empty()) {
942 const std::string& groupLeader,
943 const std::vector<std::string>& groupMembers,
944 const std::unordered_map<Image*, ImageState>& imageStates) {
946 std::vector<BarrierInfo> barriers;
947 std::set<Image*> processedImages;
949 for (
const std::string& passName : groupMembers) {
953 const auto& passNode = passIt->second;
955 for (
const auto* textureEdge : passNode.getTextureIncomingEdges()) {
956 auto imageNodeIt =
m_imageNodes.find(textureEdge->fromImage);
960 if (!image || processedImages.
count(image))
continue;
962 auto stateIt = imageStates.find(image);
963 if (stateIt == imageStates.end())
continue;
965 const ImageState& currentState = stateIt->second;
971 bool needsBarrier =
false;
986 barrier.
image = image;
1001 barriers.push_back(barrier);
1002 processedImages.insert(image);
1011 const std::string& groupLeader,
1012 const std::vector<std::string>& groupMembers,
1013 std::unordered_map<Image*, ImageState>& imageStates) {
1015 for (
const std::string& passName : groupMembers) {
1019 const auto& passNode = passIt->second;
1021 for (
const auto* targetEdge : passNode.getTargetOutgoingEdges()) {
1022 auto imageNodeIt =
m_imageNodes.find(targetEdge->toImage);
1026 if (!image)
continue;
1035 for (
const auto* depthEdge : passNode.getDepthStencilOutgoingEdges()) {
1036 auto imageNodeIt =
m_imageNodes.find(depthEdge->toImage);
1040 if (!image)
continue;
1049 for (
const auto* textureEdge : passNode.getTextureIncomingEdges()) {
1050 auto imageNodeIt =
m_imageNodes.find(textureEdge->fromImage);
1054 if (!image)
continue;
1090 passGroup->release();
1107 for (
const auto& barrier : barriers) {
1122 std::vector<std::string> passesToCull;
1124 for (
const auto& [passName, passNode] :
m_passNodes) {
1125 bool shouldCull =
false;
1127 bool hasTargetOutput = !passNode.getTargetOutgoingEdges().empty();
1128 bool hasDepthStencilOutput = !passNode.getDepthStencilOutgoingEdges().empty();
1130 if (!hasTargetOutput && !hasDepthStencilOutput) {
1133 for (
const auto* targetEdge : passNode.getTargetOutgoingEdges()) {
1134 auto imageNodeIt =
m_imageNodes.find(targetEdge->toImage);
1136 const auto* imageNode = imageNodeIt->second.get();
1139 if (bufferNode && !bufferNode->isSizeDetermined()) {
1147 for (
const auto* depthEdge : passNode.getDepthStencilOutgoingEdges()) {
1148 auto imageNodeIt =
m_imageNodes.find(depthEdge->toImage);
1150 const auto* imageNode = imageNodeIt->second.get();
1153 if (bufferNode && !bufferNode->isSizeDetermined()) {
1163 passesToCull.push_back(passName);
1167 for (
const std::string& passName : passesToCull) {
1179 const auto& passNode = passIt->second;
1180 std::vector<std::string> imagesToCull;
1182 std::vector<TextureEdge*> textureEdgesToRemove;
1183 std::vector<TargetEdge*> targetEdgesToRemove;
1184 std::vector<DepthStencilEdge*> depthStencilEdgesToRemove;
1186 for (
const auto* textureEdge : passNode.getTextureIncomingEdges()) {
1187 textureEdgesToRemove.push_back(
const_cast<TextureEdge*
>(textureEdge));
1190 for (
const auto* targetEdge : passNode.getTargetOutgoingEdges()) {
1191 targetEdgesToRemove.push_back(
const_cast<TargetEdge*
>(targetEdge));
1193 auto imageNodeIt =
m_imageNodes.find(targetEdge->toImage);
1195 const auto& imageNode = imageNodeIt->second;
1197 if (imageNode->getTargetIncomingEdges().size() == 1 &&
1198 imageNode->getDepthStencilIncomingEdges().empty() &&
1199 imageNode->getTextureOutgoingEdges().empty()) {
1200 imagesToCull.push_back(targetEdge->toImage);
1205 for (
const auto* depthEdge : passNode.getDepthStencilOutgoingEdges()) {
1206 depthStencilEdgesToRemove.push_back(
const_cast<DepthStencilEdge*
>(depthEdge));
1208 auto imageNodeIt =
m_imageNodes.find(depthEdge->toImage);
1210 const auto& imageNode = imageNodeIt->second;
1212 if (imageNode->getDepthStencilIncomingEdges().size() == 1 &&
1213 imageNode->getTargetIncomingEdges().empty() &&
1214 imageNode->getTextureOutgoingEdges().empty()) {
1215 imagesToCull.push_back(depthEdge->toImage);
1220 for (
auto* edge : textureEdgesToRemove) {
1224 for (
auto* edge : targetEdgesToRemove) {
1228 for (
auto* edge : depthStencilEdgesToRemove) {
1232 for (
const std::string& imageName : imagesToCull) {
1256 [
this, passName]() -> std::map<std::string, Image*>
1258 std::map<std::string, Image*> textureImages;
1262 const auto& passNode = passNodeIt->second;
1264 for (
const auto* textureEdge : passNode.getTextureIncomingEdges())
1266 auto imageNodeIt =
m_imageNodes.find(textureEdge->fromImage);
1272 textureImages[textureEdge->fromImage] = image;
1277 return textureImages;
1279 [
this, passName]() -> std::map<std::string, ShaderStage>
1281 std::map<std::string, ShaderStage> textureStages;
1285 const auto& passNode = passNodeIt->second;
1287 for (
const auto* textureEdge : passNode.getTextureIncomingEdges())
1289 textureStages[textureEdge->fromImage] = textureEdge->stage;
1292 return textureStages;
1294 [
this, passName]() -> std::map<std::string, Image*>
1296 std::map<std::string, Image*> targetImages;
1300 const auto& passNode = passNodeIt->second;
1302 for (
const auto* targetEdge : passNode.getTargetOutgoingEdges())
1304 auto imageNodeIt =
m_imageNodes.find(targetEdge->toImage);
1310 targetImages[targetEdge->toImage] = image;
1315 return targetImages;
1317 [
this, passName]() -> std::map<std::string, Image*>
1319 std::map<std::string, Image*> depthStencilImages;
1323 const auto& passNode = passNodeIt->second;
1325 for (
const auto* depthEdge : passNode.getDepthStencilOutgoingEdges())
1327 auto imageNodeIt =
m_imageNodes.find(depthEdge->toImage);
1333 depthStencilImages[depthEdge->toImage] = image;
1338 return depthStencilImages;
1346 const auto& passNode = passNodeIt->second;
1348 const SizeNode* rootNode =
nullptr;
1350 for (
const auto* targetEdge : passNode.getTargetOutgoingEdges())
1352 auto imageNodeIt =
m_imageNodes.find(targetEdge->toImage);
1355 rootNode = imageNodeIt->second->
getRoot();
1362 for (
const auto* depthEdge : passNode.getDepthStencilOutgoingEdges())
1364 auto imageNodeIt =
m_imageNodes.find(depthEdge->toImage);
1367 rootNode = imageNodeIt->second->
getRoot();
1378 outputInfo.
window = windowTarget->getWindow();
1388 outputInfo.
window = windowDepth->getWindow();
1398 outputInfo.
window =
nullptr;
1429 return imageNodeIt->second->getImage();
1438 return passNodeIt->second.getTextureIncomingEdges();
void trigger(const Event &event)
virtual Image * getImage() const
virtual void barrier(FCT::Image *image, ImageLayout oldLayout, ImageLayout newLayout, PipelineStages srcStage, PipelineStages dstStage, AccessFlags srcAccess, AccessFlags dstAccess, ImageAspects aspectMask=ImageAspect::color)=0
void depthStencil(FCT::Image *depthStencil)
static constexpr Pass * present
void enableClear(ClearTypes type, Vec4 color, float depth=1.0f, uint8_t stencil=0)
void bindTarget(uint32_t index, FCT::Image *target)
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
void allocateCommandBuffer()
Device * m_resourceDevice
FlowControl * m_flowControl
std::vector< TextureEdge * > getTextureEdges(const std::string &passName) const
void computePassGroupExecutionOrder()
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 resolveTextureSizes()
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
Image * getImage() const override
virtual int getHeight()=0
constexpr const char * CheckRecompiledSync
constexpr const char * RenderGraphSubmit
@ depthStencilAttachmentWrite
constexpr const char * SwapBufferSubmitTicker
@ depthStencilAttachmentOptimal
ShaderStage getEarliestStage(ShaderStages stages)
std::vector< Texture > textures
std::vector< Target > targets
std::vector< DepthStencil > depthStencils
RHI::CommandBuffer * cmdBuf
ImageLayout currentLayout
std::string lastWriterGroup
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