FCT
载入中...
搜索中...
未找到
CommandBufferGraph.cpp
浏览该文件的文档.
2#include "./Context.h"
3#include "./Context.hpp"
4#include "../UI/Window.h"
5namespace FCT {
7 {
8 if (frameIndex >= m_frameDirty.size() || !m_frameDirty[frameIndex]) {
9 return;
10 }
11
12 if (m_outputEdge && frameIndex < m_collectedImageAvailable.size()) {
13 auto* semaphore = m_outputEdge->getImageAvailableSemaphore(frameIndex);
14 m_collectedImageAvailable[frameIndex] = semaphore;
15
16 markFrameClean(frameIndex);
17 }
18 }
19
20 std::vector<RHI::Fence*> CommandBufferNodes::OutputToWindow::getCollectedFence(uint32_t frameIndex) const
21 {
22 if (frameIndex < m_collectedFences.size()) {
23 return m_collectedFences[frameIndex];
24 }
25 return std::vector<RHI::Fence*>{} ;
26 }
27
29 uint32_t frameIndex) const
30 {
31 if (frameIndex < m_collectedRenderFinished.size()) {
32 return m_collectedRenderFinished[frameIndex];
33 }
34 return std::vector<RHI::Semaphore*>{} ;
35 }
36
37
39 {
40 if (frameIndex >= m_frameDirty.size() || !m_frameDirty[frameIndex]) {
41 return;
42 }
43
44 if (frameIndex >= m_collectedFences.size() || frameIndex >= m_collectedRenderFinished.size()) {
45 return;
46 }
47
48 m_collectedFences[frameIndex].clear();
49 m_collectedRenderFinished[frameIndex].clear();
50
51 for (auto* edge : m_inputEdges) {
52 if (edge) {
53 auto* fence = edge->getFence(frameIndex);
54 auto* semaphore = edge->getRenderFinishedSemaphore(frameIndex);
55
56 if (fence) {
57 m_collectedFences[frameIndex].push_back(fence);
58 }
59 if (semaphore) {
60 m_collectedRenderFinished[frameIndex].push_back(semaphore);
61 }
62 }
63 }
64
65 markFrameClean(frameIndex);
66 }
67
72
74 {
75 for (auto& cmdBuffer : m_cmdBuffers) {
76 cmdBuffer->release();
77 }
78 m_cmdBuffers.clear();
79 }
80
82 {
83 if (m_cmdBuffers.size() != newMaxFrameInFlight) {
84 for (auto& cmdBuffer : m_cmdBuffers)
85 {
86 cmdBuffer->release();
87 }
88 m_cmdBuffers.clear();
89 m_cmdBuffers.reserve(newMaxFrameInFlight);
90 for (uint32_t i = 0; i < newMaxFrameInFlight; ++i) {
91 auto cmdBuf = m_pool->createCommandBuffer();
92 cmdBuf->create();
93 m_cmdBuffers.push_back(cmdBuf);
94 }
95 }
96 m_frameDirty.clear();
97 m_frameDirty.resize(newMaxFrameInFlight, 1);
98 }
99
101 {
102 std::fill(m_frameDirty.begin(), m_frameDirty.end(), true);
103 m_outputEdges.push_back(edge);
104 }
105
107 {
108 std::fill(m_frameDirty.begin(), m_frameDirty.end(), 1);
109 m_inputEdges.push_back(edge);
110 }
111
113 {
114 if (frameIndex < m_cmdBuffers.size()) {
115 return m_cmdBuffers[frameIndex];
116 }
117 return nullptr;
118 }
119
120
122 {
123 auto* cmdBuf = getCommandBuffer(frameIndex);
124 if (!cmdBuf || frameIndex >= m_frameDirty.size() || !m_frameDirty[frameIndex]) {
125 return;
126 }
127
128 cmdBuf->clearWaitSemaphores();
129 cmdBuf->signalSemaphores().clear();
130
131 for (auto* edge : m_inputEdges) {
132 if (auto* inputEdge = dynamic_cast<CommandBufferEdges::InputFromWindow*>(edge)) {
133 if (auto* semaphore = inputEdge->getImageAvailableSemaphore(frameIndex)) {
134 cmdBuf->addWaitSemaphore(semaphore, PipelineStage::colorAttachmentOutput);
135 }
136 }
137 // TODO: 处理其他类型的输入边
138 }
139
140 for (auto* edge : m_outputEdges) {
141 if (auto* outputEdge = dynamic_cast<CommandBufferEdges::OutputToWindow*>(edge)) {
142 auto* semaphore = outputEdge->getRenderFinishedSemaphore(frameIndex);
143 if (semaphore) {
144 cmdBuf->addSignalSemaphore(semaphore);
145 }
146
147 auto* fence = outputEdge->getFence(frameIndex);
148 if (fence) {
149 cmdBuf->fence(fence);
150 }
151 }
152 // TODO: 处理其他类型的输出边
153 }
154
155 m_frameDirty[frameIndex] = false;
156 }
157
159 {
160
161 if (m_imageAvailable.size() != newMaxFrameInFlight) {
162 for (auto& semaphore : m_imageAvailable)
163 {
164 semaphore->release();
165 }
166 m_imageAvailable.clear();
167 m_imageAvailable.reserve(newMaxFrameInFlight);
168 for (uint32_t i = 0; i < newMaxFrameInFlight; ++i) {
169 auto semaphore = m_semaphorePool->alloc();
170 semaphore->create();
171 m_imageAvailable.push_back(semaphore);
172 }
173 }
174 }
176 {
177 if (m_renderFinished.size() != newMaxFrameInFlight) {
178 for (auto& semaphore : m_renderFinished)
179 {
180 semaphore->release();
181 }
182 m_renderFinished.clear();
183 m_renderFinished.reserve(newMaxFrameInFlight);
184 for (uint32_t i = 0; i < newMaxFrameInFlight; ++i) {
185 auto semaphore = m_semaphorePool->alloc();
186 semaphore->create();
187 m_renderFinished.push_back(semaphore);
188 }
189 }
190
191 if (m_fences.size() != newMaxFrameInFlight) {
192 for (auto& fence : m_fences)
193 {
194 fence->release();
195 }
196 m_fences.clear();
197 m_fences.reserve(newMaxFrameInFlight);
198 for (uint32_t i = 0; i < newMaxFrameInFlight; ++i) {
199 auto fence = m_fencePool->alloc();
200 fence->createSignaled();
201 m_fences.push_back(fence);
202 }
203 }
204 }
205
214
216 {
217 m_windows.insert(window);
218 auto it = m_windowInputNodes.find(window);
219 if (it != m_windowInputNodes.end()) {
220 return it->second;
221 }
222
223 auto* nodePtr = FCT_NEW(CommandBufferNodes::InputFromWindow,window);
224 nodePtr->updateSynchronization(m_maxFrameInFlight);
225 m_nodes.insert(nodePtr);
226 m_windowInputNodes[window] = nodePtr;
227 return nodePtr;
228 }
229
231 {
232 m_windows.insert(window);
233 auto it = m_windowOutputNodes.find(window);
234 if (it != m_windowOutputNodes.end()) {
235 return it->second;
236 }
237
238 auto* nodePtr = FCT_NEW(CommandBufferNodes::OutputToWindow,window);
239 nodePtr->updateSynchronization(m_maxFrameInFlight);
240 m_nodes.insert(nodePtr);
241 m_windowOutputNodes[window] = nodePtr;
242 return nodePtr;
243 }
244
246 const std::vector<NodeRef>& predecessors)
247 {
248 for (const auto& pred : predecessors) {
249 if (pred.type == NodeRef::WindowType) {
250 connectWindowPredecessor(buffer, pred.window);
251 }
252 else if (pred.type == NodeRef::CommandBufferType) {
253 // CommandBuffer -> CommandBuffer
254 // todo:
255 // 创建CommandBuffer之间的边,并对CommandBuffers执行fillAllSynchronization
256 }
257 }
258 }
259
261 const std::vector<NodeRef>& successors)
262 {
263 for (const auto& succ : successors) {
264 if (succ.type == NodeRef::WindowType) {
265 connectWindowSuccessor(buffer, succ.window);
266 }
267 else if (succ.type == NodeRef::CommandBufferType) {
268 // CommandBuffer -> CommandBuffer
269 // todo:
270 // 创建CommandBuffer之间的边,并对CommandBuffers执行fillAllSynchronization
271 }
272 }
273 }
274
276 {
277 auto* windowInputNode = getOrCreateWindowInputNode(window);
278 auto edge = std::make_unique<CommandBufferEdges::InputFromWindow>(m_semaphorePool);
279 auto* edgePtr = edge.get();
280
281 edgePtr->setSourceNode(windowInputNode);
282 edgePtr->setTargetNode(buffer);
283 edgePtr->updateSynchronization(m_maxFrameInFlight);
284
285 windowInputNode->addOutputEdge(edgePtr);
286 buffer->addInputEdge(edgePtr);
287
288 m_edges.insert(std::move(edge));
289
290 windowInputNode->fillAllSynchronization();
291 }
292
294 {
295 auto* windowOutputNode = getOrCreateWindowOutputNode(window);
296 auto edge = std::make_unique<CommandBufferEdges::OutputToWindow>(m_fencePool,m_semaphorePool);
297 auto* edgePtr = edge.get();
298
299 edgePtr->setSourceNode(buffer);
300 edgePtr->setTargetNode(windowOutputNode);
301 edgePtr->updateSynchronization(m_maxFrameInFlight);
302
303 buffer->addOutputEdge(edgePtr);
304 windowOutputNode->addInputEdge(edgePtr);
305
306 m_edges.insert(std::move(edge));
307
308 windowOutputNode->fillAllSynchronization();
309 }
311 {
312 m_maxFrameInFlight = max;
313 for (auto& edge : m_edges) {
314 edge->updateSynchronization(m_maxFrameInFlight);
315 }
316 for (auto& node : m_nodes) {
317 node->updateSynchronization(m_maxFrameInFlight);
318 }
319 for (auto& node : m_nodes) {
320 node->fillAllSynchronization();
321 }
322 }
323
325 {
326 for (auto& wnd : m_windows)
327 {
328 if (m_windowOutputNodes.count(wnd))
329 {
330 wnd->clearRenderFinshSemaphores();
331 for (auto semaphore : m_windowOutputNodes[wnd]->getCollectedRenderFinishedSemaphores(m_frameIndex))
332 {
333 wnd->addRenderFinshSemaphore(semaphore);
334 }
335 }
336 }
338 for (auto& wnd : m_windows) {
339 if (m_windowInputNodes.count(wnd))
340 {
341 wnd->setPresentFinshSemaphore(m_windowInputNodes[wnd]->getCollectedImageAvailableSemaphore(m_frameIndex));
342 }
343 if (m_windowOutputNodes.count(wnd))
344 {
345 wnd->clearRenderFinshFences();
346 for (auto fence : m_windowOutputNodes[wnd]->getCollectedFences(m_frameIndex))
347 {
348 wnd->addRenderFinshFence(fence);
349 }
350 }
351 }
352 for (auto wnd : m_windows)
353 {
354 wnd->swapBuffers();
355 }
356 }
357
362
363 CommandBufferToken CommandBufferGraph::addBuffer(const std::vector<NodeRef>& predecessors,
364 const std::vector<NodeRef>& successors)
365 {
367 bufferPtr->updateSynchronization(m_maxFrameInFlight);
368 m_nodes.insert(bufferPtr);
369
370 connectPredecessors(bufferPtr, predecessors);
371 connectSuccessors(bufferPtr, successors);
372
373 bufferPtr->fillAllSynchronization();
374 return bufferPtr;
375 }
377 {
378 if (auto* inputEdge = dynamic_cast<CommandBufferEdges::InputFromWindow*>(edge))
379 {
380 inputEdge->getSourceNode()->removeOutputEdge(edge);
381 inputEdge->getSourceNode()->fillAllSynchronization();
382 inputEdge->getTargetNode()->removeInputEdge(edge);
383 inputEdge->getTargetNode()->fillAllSynchronization();
384 auto it = std::find_if(m_edges.begin(), m_edges.end(),
385 [edge](const std::unique_ptr<CommandBufferEdges::EdgeBase>& ptr) {
386 return ptr.get() == edge;
387 });
388 if (it != m_edges.end()) {
389 m_edges.erase(it);
390 }
391 } else if (auto* outputEdge = dynamic_cast<CommandBufferEdges::OutputToWindow*>(edge))
392 {
393 outputEdge->getSourceNode()->removeOutputEdge(edge);
394 outputEdge->getSourceNode()->fillAllSynchronization();
395 outputEdge->getTargetNode()->removeInputEdge(edge);
396 outputEdge->getTargetNode()->fillAllSynchronization();
397 auto it = std::find_if(m_edges.begin(), m_edges.end(),
398 [edge](const std::unique_ptr<CommandBufferEdges::EdgeBase>& ptr) {
399 return ptr.get() == edge;
400 });
401 if (it!= m_edges.end()) {
402 m_edges.erase(it);
403 }
404 } else
405 {
406
407 }
408 }
410 {
411 auto outputEdge = token->getOutputEdges();
412 for (auto& edge : outputEdge) {
413 removeEdge(edge);
414 }
415 auto inputEdge = token->getInputEdges();
416 for (auto& edge : inputEdge) {
417 removeEdge(edge);
418 }
419 m_nodes.erase(token);
420 FCT_DELETE(token);
421 }
422} // FCT
#define FCT_NEW(type,...)
#define FCT_DELETE(args)
void updateSynchronization(uint32_t newMaxFrameInFlight) override
std::vector< RHI::Semaphore * > m_imageAvailable
std::vector< RHI::Semaphore * > m_renderFinished
void updateSynchronization(uint32_t newMaxFrameInFlight) override
void connectWindowPredecessor(CommandBufferNodes::CommandBuffer *buffer, Window *window)
void connectSuccessors(CommandBufferNodes::CommandBuffer *buffer, const std::vector< NodeRef > &successors)
std::unordered_set< CommandBufferNodes::NodeBase * > m_nodes
void connectPredecessors(CommandBufferNodes::CommandBuffer *buffer, const std::vector< NodeRef > &predecessors)
void removeBuffer(CommandBufferToken token)
void removeEdge(CommandBufferEdges::EdgeBase *edge)
CommandBufferToken addBuffer(const std::vector< NodeRef > &predecessors, const std::vector< NodeRef > &successors)
RHI::CommandBuffer * getCommandBuffer(CommandBufferToken token) const
CommandBufferNodes::OutputToWindow * getOrCreateWindowOutputNode(Window *window)
std::unordered_map< Window *, CommandBufferNodes::InputFromWindow * > m_windowInputNodes
std::unordered_map< Window *, CommandBufferNodes::OutputToWindow * > m_windowOutputNodes
CommandBufferNodes::InputFromWindow * getOrCreateWindowInputNode(Window *window)
void connectWindowSuccessor(CommandBufferNodes::CommandBuffer *buffer, Window *window)
std::unordered_set< std::unique_ptr< CommandBufferEdges::EdgeBase > > m_edges
std::vector< CommandBufferEdges::EdgeBase * > & getInputEdges()
std::vector< CommandBufferEdges::EdgeBase * > & getOutputEdges()
RHI::CommandBuffer * getCommandBuffer(uint32_t frameIndex) const
std::vector< CommandBufferEdges::EdgeBase * > m_outputEdges
void fillSynchronization(uint32_t frameIndex) override
void updateSynchronization(uint32_t newMaxFrameInFlight) override
std::vector< RHI::CommandBuffer * > m_cmdBuffers
std::vector< CommandBufferEdges::EdgeBase * > m_inputEdges
void addInputEdge(CommandBufferEdges::EdgeBase *edge) override
void addOutputEdge(CommandBufferEdges::EdgeBase *edge) override
void fillSynchronization(uint32_t frameIndex) override
CommandBufferEdges::InputFromWindow * m_outputEdge
std::vector< RHI::Semaphore * > m_collectedImageAvailable
void fillSynchronization(uint32_t frameIndex) override
std::vector< CommandBufferEdges::OutputToWindow * > m_inputEdges
std::vector< RHI::Fence * > getCollectedFence(uint32_t frameIndex) const
std::vector< std::vector< RHI::Semaphore * > > m_collectedRenderFinished
std::vector< std::vector< RHI::Fence * > > m_collectedFences
std::vector< RHI::Semaphore * > getCollectedRenderFinishedSemaphore(uint32_t frameIndex) const
T * createResource()
CommandBufferNodes::CommandBuffer * CommandBufferToken