Skip to content

Commit 31d522b

Browse files
committed
RenderGraph再编译(一)
1 parent d31989f commit 31d522b

3 files changed

Lines changed: 259 additions & 6 deletions

File tree

src/Context/CommandBufferGraph.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ namespace FCT {
3434
return std::vector<RHI::Semaphore*>{} ;
3535
}
3636

37+
3738
void CommandBufferNodes::OutputToWindow::fillSynchronization(uint32_t frameIndex)
3839
{
3940
if (frameIndex >= m_frameDirty.size() || !m_frameDirty[frameIndex]) {

src/Context/RenderGraph.cpp

Lines changed: 205 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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
{

src/Context/RenderGraph.h

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,27 @@ namespace FCT
106106
m_depthStencilIncomingEdges.push_back(edge);
107107
}
108108

109+
void removeOutgoingEdge(TextureEdge* edge) {
110+
m_textureOutgoingEdges.erase(
111+
std::remove(m_textureOutgoingEdges.begin(), m_textureOutgoingEdges.end(), edge),
112+
m_textureOutgoingEdges.end()
113+
);
114+
}
115+
116+
void removeIncomingEdge(TargetEdge* edge) {
117+
m_targetIncomingEdges.erase(
118+
std::remove(m_targetIncomingEdges.begin(), m_targetIncomingEdges.end(), edge),
119+
m_targetIncomingEdges.end()
120+
);
121+
}
122+
123+
void removeIncomingEdge(DepthStencilEdge* edge) {
124+
m_depthStencilIncomingEdges.erase(
125+
std::remove(m_depthStencilIncomingEdges.begin(), m_depthStencilIncomingEdges.end(), edge),
126+
m_depthStencilIncomingEdges.end()
127+
);
128+
}
129+
109130
const std::vector<TextureEdge*>& getTextureOutgoingEdges() const {
110131
return m_textureOutgoingEdges;
111132
}
@@ -178,6 +199,27 @@ namespace FCT
178199
const std::vector<DepthStencilEdge*>& getDepthStencilOutgoingEdges() const {
179200
return m_depthStencilOutgoingEdges;
180201
}
202+
void removeIncomingEdge(TextureEdge* edge) {
203+
m_textureIncomingEdges.erase(
204+
std::remove(m_textureIncomingEdges.begin(), m_textureIncomingEdges.end(), edge),
205+
m_textureIncomingEdges.end()
206+
);
207+
}
208+
209+
void removeOutgoingEdge(TargetEdge* edge) {
210+
m_targetOutgoingEdges.erase(
211+
std::remove(m_targetOutgoingEdges.begin(), m_targetOutgoingEdges.end(), edge),
212+
m_targetOutgoingEdges.end()
213+
);
214+
}
215+
216+
void removeOutgoingEdge(DepthStencilEdge* edge) {
217+
m_depthStencilOutgoingEdges.erase(
218+
std::remove(m_depthStencilOutgoingEdges.begin(), m_depthStencilOutgoingEdges.end(), edge),
219+
m_depthStencilOutgoingEdges.end()
220+
);
221+
}
222+
181223
void applyPassDesc(const PassDesc& desc) {
182224
m_clearInfo = desc.clear;
183225
}
@@ -242,7 +284,7 @@ namespace FCT
242284
std::unordered_map<std::string, std::unique_ptr<RenderGraphImageNode>> m_imageNodes;
243285
std::unordered_map<std::string,RenderGraphPassNode> m_passNodes;
244286
UnionFind<std::string,char> m_passesUnions;
245-
std::vector<std::unique_ptr<Edge>> m_edges;
287+
std::unordered_set<std::unique_ptr<Edge>> m_edges;
246288
std::unordered_map<std::string, Image*> m_allocatedImages;
247289
std::unordered_map<std::string, RHI::Pass*> m_allocatedPasses;
248290
std::vector<PassDesc> m_originalPasses; // 存储编译前的PassDesc
@@ -262,15 +304,18 @@ namespace FCT
262304
void createTextureEdge(const std::string& passName, const std::string& textureName, const Texture& texture);
263305
void createTargetEdge(const std::string& passName, const std::string& targetName, const Target& target);
264306
void createDepthStencilEdge(const std::string& passName, const std::string& depthStencilName, const DepthStencil& depthStencil);
307+
void removeTextureEdge(TextureEdge* edgeToRemove);
265308
void simulatePassGroupExecution(const std::string& groupLeader,
266-
const std::vector<std::string>& groupMembers,
267-
std::unordered_map<Image*, ImageState>& imageStates);
309+
const std::vector<std::string>& groupMembers,
310+
std::unordered_map<Image*, ImageState>& imageStates);
268311
void simulateExecutionAndAnalyzeBarriers();
269312
std::vector<BarrierInfo> checkBarriersBeforePassGroup(const std::string& groupLeader,
270313
const std::vector<std::string>& groupMembers,
271314
const std::unordered_map<Image*, ImageState>& imageStates);
272315

273316
void executeBarriers(RHI::CommandBuffer* cmdBuffer, const std::vector<BarrierInfo>& barriers);
317+
void removeTargetEdge(TargetEdge* edgeToRemove);
318+
void removeDepthStencilEdge(DepthStencilEdge* edgeToRemove);
274319
void addPass(const PassDesc& desc);
275320

276321
void cleanUp();
@@ -292,6 +337,10 @@ namespace FCT
292337
* @endcond
293338
*/
294339
void resolveTextureSizes();
340+
void cullPasses();
341+
void cullPass(const std::string& passName);
342+
void cullSinglePass(const std::string& passName);
343+
void cullUnusedImageNode(const std::string& imageName);
295344
/**
296345
* @cond CHINESE
297346
* @note 在compile时调用,用于将Pass分组到PassGroup中
@@ -371,6 +420,7 @@ namespace FCT
371420
allocateCommandBuffer();
372421
m_topologicalSortPasses = topologicalSortPasses();
373422
resolveTextureSizes();
423+
cullPasses();
374424
groupPasses();
375425
allocateResources();
376426
createRHIPasses();

0 commit comments

Comments
 (0)