@@ -165,7 +165,7 @@ namespace FCT
165165 }
166166 pass.addIncomingEdge (edgePtr);
167167
168- m_edges.push_back (std::move (edge));
168+ m_edges.insert (std::move (edge));
169169 }
170170
171171 void RenderGraph::createTargetEdge (const std::string& passName, const std::string& targetName, const Target& target)
@@ -184,7 +184,7 @@ namespace FCT
184184 }
185185 pass.addOutgoingEdge (edgePtr);
186186
187- m_edges.push_back (std::move (edge));
187+ m_edges.insert (std::move (edge));
188188 }
189189
190190 void RenderGraph::createDepthStencilEdge (const std::string& passName, const std::string& depthStencilName,
@@ -204,9 +204,94 @@ namespace FCT
204204 }
205205 pass.addOutgoingEdge (edgePtr);
206206
207- m_edges.push_back (std::move (edge));
207+ m_edges.insert (std::move (edge));
208208 }
209+ void RenderGraph::removeTextureEdge (TextureEdge* edgeToRemove) {
210+ if (!edgeToRemove) return ;
211+
212+ auto passIt = m_passNodes.find (edgeToRemove->toPass );
213+ if (passIt != m_passNodes.end ()) {
214+ auto & pass = passIt->second ;
215+ auto & incomingEdges = const_cast <std::vector<TextureEdge*>&>(pass.getTextureIncomingEdges ());
216+ incomingEdges.erase (
217+ std::remove (incomingEdges.begin (), incomingEdges.end (), edgeToRemove),
218+ incomingEdges.end ()
219+ );
220+ }
221+
222+ auto imageNodeIt = m_imageNodes.find (edgeToRemove->fromImage );
223+ if (imageNodeIt != m_imageNodes.end ()) {
224+ imageNodeIt->second ->removeOutgoingEdge (edgeToRemove);
225+ }
226+
227+ auto it = std::find_if (m_edges.begin (), m_edges.end (),
228+ [edgeToRemove](const std::unique_ptr<Edge>& edge) {
229+ return edge.get () == edgeToRemove;
230+ });
231+
232+ if (it != m_edges.end ()) {
233+ m_edges.erase (it);
234+ }
235+ }
236+
237+ void RenderGraph::removeTargetEdge (TargetEdge* edgeToRemove) {
238+ if (!edgeToRemove) return ;
239+
240+ auto passIt = m_passNodes.find (edgeToRemove->fromPass );
241+ if (passIt != m_passNodes.end ()) {
242+ auto & pass = passIt->second ;
243+ auto & outgoingEdges = const_cast <std::vector<TargetEdge*>&>(pass.getTargetOutgoingEdges ());
244+ outgoingEdges.erase (
245+ std::remove (outgoingEdges.begin (), outgoingEdges.end (), edgeToRemove),
246+ outgoingEdges.end ()
247+ );
248+ }
249+
250+ auto imageNodeIt = m_imageNodes.find (edgeToRemove->toImage );
251+ if (imageNodeIt != m_imageNodes.end ()) {
252+ imageNodeIt->second ->removeIncomingEdge (edgeToRemove);
253+ }
254+
255+ auto it = std::find_if (m_edges.begin (), m_edges.end (),
256+ [edgeToRemove](const std::unique_ptr<Edge>& edge) {
257+ return edge.get () == edgeToRemove;
258+ });
209259
260+ if (it != m_edges.end ()) {
261+ m_edges.erase (it);
262+ }
263+ }
264+
265+ void RenderGraph::removeDepthStencilEdge (DepthStencilEdge* edgeToRemove) {
266+ if (!edgeToRemove) return ;
267+
268+ // 从 pass 的 outgoing edges 中移除
269+ auto passIt = m_passNodes.find (edgeToRemove->fromPass );
270+ if (passIt != m_passNodes.end ()) {
271+ auto & pass = passIt->second ;
272+ auto & outgoingEdges = const_cast <std::vector<DepthStencilEdge*>&>(pass.getDepthStencilOutgoingEdges ());
273+ outgoingEdges.erase (
274+ std::remove (outgoingEdges.begin (), outgoingEdges.end (), edgeToRemove),
275+ outgoingEdges.end ()
276+ );
277+ }
278+
279+ // 从 image node 的 incoming edges 中移除
280+ auto imageNodeIt = m_imageNodes.find (edgeToRemove->toImage );
281+ if (imageNodeIt != m_imageNodes.end ()) {
282+ imageNodeIt->second ->removeIncomingEdge (edgeToRemove);
283+ }
284+
285+ // 从 m_edges 中移除并销毁
286+ auto it = std::find_if (m_edges.begin (), m_edges.end (),
287+ [edgeToRemove](const std::unique_ptr<Edge>& edge) {
288+ return edge.get () == edgeToRemove;
289+ });
290+
291+ if (it != m_edges.end ()) {
292+ m_edges.erase (it);
293+ }
294+ }
210295 void RenderGraph::addPass (const PassDesc& desc)
211296 {
212297 m_passNodes[desc.name ] = desc.name ;
@@ -993,6 +1078,123 @@ namespace FCT
9931078 );
9941079 }
9951080 }
1081+ void RenderGraph::cullPasses ()
1082+ {
1083+ std::vector<std::string> passesToCull;
1084+
1085+ for (const auto & [passName, passNode] : m_passNodes) {
1086+ bool shouldCull = false ;
1087+
1088+ for (const auto * targetEdge : passNode.getTargetOutgoingEdges ()) {
1089+ auto imageNodeIt = m_imageNodes.find (targetEdge->toImage );
1090+ if (imageNodeIt != m_imageNodes.end ()) {
1091+ const auto * imageNode = imageNodeIt->second .get ();
1092+
1093+ const auto * bufferNode = dynamic_cast <const RenderGraphBufferNode*>(imageNode);
1094+ if (bufferNode && !bufferNode->isSizeDetermined ()) {
1095+ shouldCull = true ;
1096+ break ;
1097+ }
1098+ }
1099+ }
1100+
1101+ if (!shouldCull) {
1102+ for (const auto * depthEdge : passNode.getDepthStencilOutgoingEdges ()) {
1103+ auto imageNodeIt = m_imageNodes.find (depthEdge->toImage );
1104+ if (imageNodeIt != m_imageNodes.end ()) {
1105+ const auto * imageNode = imageNodeIt->second .get ();
1106+
1107+ // 检查是否是 RenderGraphBufferNode 且大小未确定
1108+ const auto * bufferNode = dynamic_cast <const RenderGraphBufferNode*>(imageNode);
1109+ if (bufferNode && !bufferNode->isSizeDetermined ()) {
1110+ shouldCull = true ;
1111+ break ;
1112+ }
1113+ }
1114+ }
1115+ }
1116+
1117+ if (shouldCull) {
1118+ passesToCull.push_back (passName);
1119+ }
1120+ }
1121+
1122+ for (const std::string& passName : passesToCull) {
1123+ cullPass (passName);
1124+ }
1125+ }
1126+
1127+ void RenderGraph::cullPass (const std::string& passName)
1128+ {
1129+ auto passIt = m_passNodes.find (passName);
1130+ if (passIt == m_passNodes.end ()) {
1131+ return ;
1132+ }
1133+
1134+ const auto & passNode = passIt->second ;
1135+ std::vector<std::string> imagesToCull;
1136+
1137+ std::vector<TextureEdge*> textureEdgesToRemove;
1138+ std::vector<TargetEdge*> targetEdgesToRemove;
1139+ std::vector<DepthStencilEdge*> depthStencilEdgesToRemove;
1140+
1141+ for (const auto * textureEdge : passNode.getTextureIncomingEdges ()) {
1142+ textureEdgesToRemove.push_back (const_cast <TextureEdge*>(textureEdge));
1143+ }
1144+
1145+ for (const auto * targetEdge : passNode.getTargetOutgoingEdges ()) {
1146+ targetEdgesToRemove.push_back (const_cast <TargetEdge*>(targetEdge));
1147+
1148+ auto imageNodeIt = m_imageNodes.find (targetEdge->toImage );
1149+ if (imageNodeIt != m_imageNodes.end ()) {
1150+ const auto & imageNode = imageNodeIt->second ;
1151+
1152+ if (imageNode->getTargetIncomingEdges ().size () == 1 &&
1153+ imageNode->getDepthStencilIncomingEdges ().empty () &&
1154+ imageNode->getTextureOutgoingEdges ().empty ()) {
1155+ imagesToCull.push_back (targetEdge->toImage );
1156+ }
1157+ }
1158+ }
1159+
1160+ for (const auto * depthEdge : passNode.getDepthStencilOutgoingEdges ()) {
1161+ depthStencilEdgesToRemove.push_back (const_cast <DepthStencilEdge*>(depthEdge));
1162+
1163+ auto imageNodeIt = m_imageNodes.find (depthEdge->toImage );
1164+ if (imageNodeIt != m_imageNodes.end ()) {
1165+ const auto & imageNode = imageNodeIt->second ;
1166+
1167+ if (imageNode->getDepthStencilIncomingEdges ().size () == 1 &&
1168+ imageNode->getTargetIncomingEdges ().empty () &&
1169+ imageNode->getTextureOutgoingEdges ().empty ()) {
1170+ imagesToCull.push_back (depthEdge->toImage );
1171+ }
1172+ }
1173+ }
1174+
1175+ for (auto * edge : textureEdgesToRemove) {
1176+ removeTextureEdge (edge);
1177+ }
1178+
1179+ for (auto * edge : targetEdgesToRemove) {
1180+ removeTargetEdge (edge);
1181+ }
1182+
1183+ for (auto * edge : depthStencilEdgesToRemove) {
1184+ removeDepthStencilEdge (edge);
1185+ }
1186+
1187+ for (const std::string& imageName : imagesToCull) {
1188+ m_imageNodes.erase (imageName);
1189+ }
1190+
1191+ m_passNodes.erase (passName);
1192+
1193+ auto it = std::find (m_topologicalSortPasses.begin (), m_topologicalSortPasses.end (), passName);
1194+ if (it != m_topologicalSortPasses.end ()) {
1195+ m_topologicalSortPasses.erase (it);
1196+ }
1197+ }
9961198
9971199 void RenderGraph::pushPipe ()
9981200 {
0 commit comments