FCT
载入中...
搜索中...
未找到
OldRenderGraph.cpp
浏览该文件的文档.
1#include "../FCTAPI.h"
2namespace FCT
3{
8
9 void OldRenderGraph::addPass(const std::string& name, OldPass* pass)
10 {
11 pass->addRef();
13 v.name = name;
14 v.pass = pass;
15 PassGraphType::vertex_descriptor vd = boost::add_vertex(v, m_passGraph);
16 m_passVertex[name] = vd;
17 auto& vertex = m_passGraph[vd];
18
19 auto passResourceCallback = [this, name](PassResource* resource) {
20 auto passVdIt = m_passVertex.find(name);
21 if (passVdIt == m_passVertex.end()) {
22 return;
23 }
24
25 PassGraphType::vertex_descriptor passVd = passVdIt->second;
26 PassGraphVertex& passData = m_passGraph[passVd];
27
28 for (const auto& textureName : passData.textures) {
29 auto textureIt = m_textureLayouts.find(textureName);
30 auto imageIt = m_images.find(textureName);
31
32 if (textureIt != m_textureLayouts.end() && imageIt != m_images.end())
33 {
34 resource->setTexture(imageIt->second,textureIt->second);
35 resource->update();
36 }
37 }
38 };
39 pass->setPassResourceAddCallback(passResourceCallback);
40 }
41
43 {
44 if (std::find(m_bindedWindows.begin(), m_bindedWindows.end(), wnd) != m_bindedWindows.end())
45 {
46 return;;
47 }
48 m_bindedWindows.push_back(wnd);
49 std::string name = "WndBackBuffer" + std::to_string(m_unnameWndBackBufferCount++);
51 res.wnd = wnd;
52 res.img = wnd->getCurrentTarget()->targetImage();
53 m_windowImageResources[name] = res;
54 Image* img = res.img;
55 img->addRef();
56 m_images[name] = img;
57 m_windowBackBufferNames[wnd] = name;
59 std::string name = "WndDepthStencil" + std::to_string(m_unnameWndStencilDepthCount);
61 depthRes.wnd = wnd;
62 depthRes.img = wnd->getCurrentTarget()->depthStencilBuffer();
63 m_windowDepthStencilResources[name] = depthRes;
64 m_windowDepthStencilNames[wnd] = name;
65 m_images[name] = depthRes.img;
66 m_images[name]->addRef();
67 }
68 }
69
70 void OldRenderGraph::submit(Job* job, std::string name)
71 {
72 PassGraphType::vertex_descriptor vd = m_passVertex[name];
73 OldPass* pass = m_passGraph[vd].pass;
74 pass->submit(job);
75 }
76
77 void OldRenderGraph::addPassDenpendency(const std::string& from, const std::string& to)
78 {
81 PassGraphType::edge_descriptor ed = boost::add_edge(m_passVertex[from], m_passVertex[to], e, m_passGraph).first;
82 }
83
84 void OldRenderGraph::bindOutputImage(const std::string& name, std::string image, uint8_t slot)
85 {
88 m_passGraph[m_passVertex[name]].target[slot] = image;
89 }
90
91 void OldRenderGraph::bindTextureImage(std::string name, std::string image, uint32_t width, uint32_t height,
92 Samples samples)
93 {
95 desc.width |= width;
96 desc.height |= height;
97 desc.dynamicSize = false;
98 if (samples != Samples::sample_undefined)
99 desc.samples = samples;
101 m_passGraph[m_passVertex[name]].textures.push_back(image);
102 }
103
104 void OldRenderGraph::bindDepthStencil(const char* name, std::string image)
105 {
108 m_passGraph[m_passVertex[name]].depthStencil = image;
109 }
110
111 void OldRenderGraph::bindOutput(const char* name, Window* wnd, uint8_t slot)
112 {
114 {
116 }
118 {
120 }
121 }
122
124 {
125 bool needRecompute = false;
126
127 for (const auto& entry : m_windowImageResources) {
128 const std::string& imageName = entry.first;
129 const WindowImageResource& resource = entry.second;
130
131 uint32_t currentWidth = resource.wnd->getWidth();
132 uint32_t currentHeight = resource.wnd->getHeight();
133
134 if (m_imageResourceDescs[imageName].width != currentWidth ||
135 m_imageResourceDescs[imageName].height != currentHeight) {
136 m_imageResourceDescs[imageName].width = currentWidth;
137 m_imageResourceDescs[imageName].height = currentHeight;
138 needRecompute = true;
139 }
140 }
141
142 for (const auto& entry : m_windowDepthStencilResources) {
143 const std::string& imageName = entry.first;
144 const WindowDepthStencilResource& resource = entry.second;
145
146 uint32_t currentWidth = resource.wnd->getWidth();
147 uint32_t currentHeight = resource.wnd->getHeight();
148
149 if (m_imageResourceDescs[imageName].width != currentWidth ||
150 m_imageResourceDescs[imageName].height != currentHeight) {
151 m_imageResourceDescs[imageName].width = currentWidth;
152 m_imageResourceDescs[imageName].height = currentHeight;
153 needRecompute = true;
154 }
155 }
156
157 if (needRecompute) {
158 std::unordered_map<std::string, std::pair<uint32_t, uint32_t>> originalSizes;
159 for (const auto& entry : m_imageResourceDescs) {
160 if (entry.second.dynamicSize) {
161 originalSizes[entry.first] = {entry.second.width, entry.second.height};
162 }
163 }
164
165 for (auto& entry : m_imageResourceDescs) {
166 if (entry.second.dynamicSize && !entry.second.isWnd) {
167 entry.second.width = 0;
168 entry.second.height = 0;
169 }
170 }
171
172 computeSize();
173
174 for (const auto& entry : m_imageResourceDescs) {
175 const std::string& imageName = entry.first;
176 const ImageResourceDesc& desc = entry.second;
177
178 if (m_windowImageResources.find(imageName) != m_windowImageResources.end() ||
180 continue;
181 }
182
183 auto imgIt = m_images.find(imageName);
184 if (imgIt != m_images.end()) {
185 Image* img = imgIt->second;
186 auto originalSizeIt = originalSizes.find(imageName);
187
188 if (desc.dynamicSize && originalSizeIt != originalSizes.end()) {
189 auto originalSize = originalSizeIt->second;
190 if (img->width() != desc.width || img->height() != desc.height) {
191 img->resize(desc.width, desc.height);
192 }
193 }
194 }
195 }
196 }
197 }
198
200 {
201 for (const auto& imageEntry : m_imageResourceDescs) {
202 const std::string& imageName = imageEntry.first;
204 ResourceGraphType::vertex_descriptor vd = boost::add_vertex(v, m_resourceGraph);
205 m_resourceVertices[imageName] = vd;
206 }
207 for (const auto& passEntry : m_passVertex) {
208 const std::string& passName = passEntry.first;
209 PassGraphType::vertex_descriptor passVd = passEntry.second;
210 PassGraphVertex& passData = m_passGraph[passVd];
211
212 std::vector<std::string> outputResources;
213
214 for (uint8_t slot = 0; slot < 8; ++slot) {
215 if (!passData.target[slot].empty()) {
216 outputResources.push_back(passData.target[slot]);
217 }
218 }
219
220 if (!passData.depthStencil.empty()) {
221 outputResources.push_back(passData.depthStencil);
222 }
223
224 if (outputResources.empty()) {
225 continue;
226 }
227
228 std::string rootResource = outputResources[0];
229 bool foundFixedSizeResource = false;
230
231 for (const auto& resource : outputResources) {
232 const ImageResourceDesc& desc = m_imageResourceDescs[resource];
233 if (desc.isWnd || (desc.width > 0 && desc.height > 0)) {
234 rootResource = resource;
235 foundFixedSizeResource = true;
236 break;
237 }
238 }
239
240 for (const auto& resource : outputResources) {
241 if (resource != rootResource) {
244 boost::add_edge(
245 m_resourceVertices[rootResource],
246 m_resourceVertices[resource],
247 e,
249 );
250 }
251 }
252
253 for (const auto& texture : passData.textures) {
254 ImageResourceDesc& textureDesc = m_imageResourceDescs[texture];
255
256 if (textureDesc.width == 0 || textureDesc.height == 0) {
259 boost::add_edge(
260 m_resourceVertices[rootResource],
261 m_resourceVertices[texture],
262 e,
264 );
265 } else {
268 boost::add_edge(
269 m_resourceVertices[texture],
270 m_resourceVertices[rootResource],
271 e,
273 );
274 }
275 }
276 }
277 }
278
280 {
281 constexpr uint32_t DEFAULT_IMAGE_WIDTH = 256;
282 constexpr uint32_t DEFAULT_IMAGE_HEIGHT = 256;
283
284 std::set<std::string> processedResources;
285 std::queue<std::string> sizeQueue;
286
287 for (const auto& entry : m_windowImageResources) {
288 const std::string& imageName = entry.first;
289 const WindowImageResource& resource = entry.second;
290
291 m_imageResourceDescs[imageName].width = resource.wnd->getWidth();
292 m_imageResourceDescs[imageName].height = resource.wnd->getHeight();
293
294 sizeQueue.push(imageName);
295 processedResources.insert(imageName);
296 }
297
298 for (const auto& entry : m_windowDepthStencilResources) {
299 const std::string& imageName = entry.first;
300 const WindowDepthStencilResource& resource = entry.second;
301
302
303 m_imageResourceDescs[imageName].width = resource.wnd->getWidth();
304 m_imageResourceDescs[imageName].height = resource.wnd->getHeight();
305
306 sizeQueue.push(imageName);
307 processedResources.insert(imageName);
308 }
309
310 for (auto& entry : m_imageResourceDescs) {
311 const std::string& imageName = entry.first;
312 ImageResourceDesc& desc = entry.second;
313
314 if (!desc.isWnd && desc.width > 0 && desc.height > 0 && processedResources.find(imageName) == processedResources.end()) {
315 sizeQueue.push(imageName);
316 processedResources.insert(imageName);
317 }
318 }
319
320 while (!sizeQueue.empty()) {
321 std::string currentResource = sizeQueue.front();
322 sizeQueue.pop();
323
324 ResourceGraphType::vertex_descriptor currentVertex = m_resourceVertices[currentResource];
325 uint32_t currentWidth = m_imageResourceDescs[currentResource].width;
326 uint32_t currentHeight = m_imageResourceDescs[currentResource].height;
327
328 ResourceGraphType::out_edge_iterator ei, ei_end;
329 std::pair<ResourceGraphType::out_edge_iterator, ResourceGraphType::out_edge_iterator> edgeRange =
330 boost::out_edges(currentVertex, m_resourceGraph);
331 if (edgeRange.first != edgeRange.second)
332 {
333 for (boost::tie(ei, ei_end) = boost::out_edges(currentVertex, m_resourceGraph); ei != ei_end; ++ei) {
335
337 ResourceGraphType::vertex_descriptor childVertex = boost::target(*ei, m_resourceGraph);
338
339 std::string childResource;
340 for (const auto& entry : m_resourceVertices) {
341 if (entry.second == childVertex) {
342 childResource = entry.first;
343 break;
344 }
345 }
346
347 if (!childResource.empty() && processedResources.find(childResource) == processedResources.end()) {
348 m_imageResourceDescs[childResource].width = currentWidth;
349 m_imageResourceDescs[childResource].height = currentHeight;
350
351 processedResources.insert(childResource);
352 sizeQueue.push(childResource);
353 }
354 }
355 }
356 }
357 }
358
359 for (auto& entry : m_imageResourceDescs) {
360 const std::string& imageName = entry.first;
361 ImageResourceDesc& desc = entry.second;
362
363 if (desc.width == 0 || desc.height == 0) {
364 desc.width = DEFAULT_IMAGE_WIDTH;
365 desc.height = DEFAULT_IMAGE_HEIGHT;
366 }
367 }
368 }
369
371 {
372 uint32_t currentFrameIndex = m_ctx->currentSubmitFrameIndex();
373 for (auto* img : m_needUpdataFramesIndexImages) {
374 img->changeCurrentIndex(currentFrameIndex);
375 }
376 }
377
378 void OldRenderGraph::saveExecutionOrder(const std::vector<PassGraphType::vertex_descriptor>& sortedPasses,
379 const std::vector<std::vector<PassGraphType::vertex_descriptor>>& passGroups)
380 {
381 m_executionOrder.sortedPasses = sortedPasses;
382 m_executionOrder.passGroups = passGroups;
383 }
384
386 {
387 computeSize();
388 for (const auto& entry : m_windowImageResources) {
389 const std::string& imageName = entry.first;
390 m_images[imageName] = entry.second.img;
391 }
392
393 for (const auto& entry : m_windowDepthStencilResources) {
394 const std::string& imageName = entry.first;
395 m_images[imageName] = entry.second.img;
396 }
397
398 for (const auto& entry : m_imageResourceDescs)
399 {
400 const std::string& imageName = entry.first;
401 const ImageResourceDesc& desc = entry.second;
402
403 if (m_images.find(imageName) != m_images.end()) {
404 continue;
405 }
406
408 if (desc.usage & ImageUsage::DepthStencil) {
410 }
411
413 MutilBufferImage* img = m_ctx->createResource<MutilBufferImage>();
414 img->imageCount(m_ctx->maxFrameInFlight());
415 img->samples(desc.samples);
416 img->format(format);
417 img->width(desc.width);
418 img->height(desc.height);
419 img->as(desc.usage);
420 img->create();
421 m_images[imageName] = img;
422 m_needUpdataFramesIndexImages.push_back(img);
423 img->changeCurrentIndex(m_ctx->currentSubmitFrameIndex());
424 } else {
425 Image* img = m_ctx->createResource<Image>();
426 img->samples(desc.samples);
427 img->format(format);
428 img->width(desc.width);
429 img->height(desc.height);
430 img->as(desc.usage);
431 img->create();
432 m_images[imageName] = img;
433 }
434 ShaderGenerator* gen = m_ctx->getGenerator();
435
436 if (desc.usage & ImageUsage::Texture)
437 {
438 m_textureLayouts[imageName] = gen->findTextureElementByName(imageName);
439 if (m_textureLayouts[imageName]) {
440
441 } else
442 {
443 m_textureLayouts[imageName] = TextureElement(imageName.c_str());
445 }
446 }
447 }
448
449 for (auto& passEntry : m_passVertex) {
450 PassGraphType::vertex_descriptor passVd = passEntry.second;
451 PassGraphVertex& passData = m_passGraph[passVd];
452
453 for (uint8_t slot = 0; slot < 8; ++slot) {
454 if (!passData.target[slot].empty()) {
455 const std::string& targetName = passData.target[slot];
456 if (m_images.find(targetName) != m_images.end()) {
457 passData.rhiPass->bindTarget(slot, m_images[targetName]);
458 }
459 }
460 }
461
462 if (!passData.depthStencil.empty()) {
463 const std::string& dsName = passData.depthStencil;
464 if (m_images.find(dsName) != m_images.end()) {
465 passData.rhiPass->depthStencil(m_images[dsName]);
466 }
467 }
468 }
469 }
470
472 {
474 std::vector<PassGraphType::vertex_descriptor> sortedPasses;
475 std::unordered_map<PassGraphType::vertex_descriptor, boost::default_color_type> colorMap;
476
477 try {
478 boost::topological_sort(m_passGraph, std::back_inserter(sortedPasses),
479 boost::color_map(boost::make_assoc_property_map(colorMap)));
480 std::reverse(sortedPasses.begin(), sortedPasses.end());
481 } catch (const boost::not_a_dag& e) {
482 ferr << "拓扑排序失败,检查是否存在环" << std::endl;
483 return;
484 }
485
486 for (auto& passEntry : m_passVertex) {
487 PassGraphType::vertex_descriptor passVd = passEntry.second;
488 PassGraphVertex& passData = m_passGraph[passVd];
489
490 if (!passData.rhiPass)
491 {
492 passData.rhiPass = m_ctx->createResource<RHI::Pass>();
493 PassClearValue clearValue = passData.pass->getClearValue();
494 passData.rhiPass->enableClear(clearValue);
495 passData.pass->setRhiPass(passData.rhiPass);
496 }
497 }
498
499 auto getRenderTargetSignature = [this](PassGraphType::vertex_descriptor passVd) -> std::string {
500 PassGraphVertex& passData = m_passGraph[passVd];
501 std::stringstream ss;
502
503 for (uint8_t slot = 0; slot < 8; ++slot) {
504 ss << "T" << static_cast<int>(slot) << ":" << passData.target[slot] << ";";
505 }
506
507 ss << "DS:" << passData.depthStencil;
508
509 return ss.str();
510 };
511
512 std::vector<std::vector<PassGraphType::vertex_descriptor>> passGroups;
513 std::unordered_set<PassGraphType::vertex_descriptor> assignedPasses;
514
515 for (auto passVd : sortedPasses) {
516 if (assignedPasses.find(passVd) != assignedPasses.end()) {
517 continue;
518 }
519
520 std::string currentSignature = getRenderTargetSignature(passVd);
521
522 std::vector<PassGraphType::vertex_descriptor> currentGroup;
523 currentGroup.push_back(passVd);
524 assignedPasses.insert(passVd);
525
526 PassGraphType::vertex_descriptor currentPassVd = passVd;
527 bool continueChain = true;
528
529 while (continueChain) {
530 continueChain = false;
531
532 std::vector<PassGraphType::vertex_descriptor> candidatePasses;
533
534 PassGraphType::out_edge_iterator ei, ei_end;
535 for (boost::tie(ei, ei_end) = boost::out_edges(currentPassVd, m_passGraph); ei != ei_end; ++ei) {
536 PassGraphType::vertex_descriptor targetVd = boost::target(*ei, m_passGraph);
537
538 if (assignedPasses.find(targetVd) != assignedPasses.end()) {
539 continue;
540 }
541
542 std::string targetSignature = getRenderTargetSignature(targetVd);
543 if (targetSignature == currentSignature) {
544 bool allDependenciesProcessed = true;
545 PassGraphType::in_edge_iterator in_ei, in_ei_end;
546 for (boost::tie(in_ei, in_ei_end) = boost::in_edges(targetVd, m_passGraph); in_ei != in_ei_end; ++in_ei) {
547 PassGraphType::vertex_descriptor sourceVd = boost::source(*in_ei, m_passGraph);
548 if (assignedPasses.find(sourceVd) == assignedPasses.end()) {
549 allDependenciesProcessed = false;
550 break;
551 }
552 }
553
554 if (allDependenciesProcessed) {
555 candidatePasses.push_back(targetVd);
556 }
557 }
558 }
559
560 if (!candidatePasses.empty()) {
561 for (auto targetVd : candidatePasses) {
562 currentGroup.push_back(targetVd);
563 assignedPasses.insert(targetVd);
564 }
565
566 currentPassVd = candidatePasses.back();
567 continueChain = true;
568 }
569 }
570
571 passGroups.push_back(currentGroup);
572 }
573
574 saveExecutionOrder(sortedPasses, passGroups);
575
576 m_passGroups.clear();
577
578 for (const auto& group : passGroups) {
579 RHI::PassGroup* passGroup = m_ctx->createResource<RHI::PassGroup>();
580 m_passGroups.push_back(passGroup);
581
582 for (auto passVd : group) {
583 PassGraphVertex& passData = m_passGraph[passVd];
584 if (passData.rhiPass) {
585 passGroup->addPass(passData.rhiPass);
586 }
587 }
588 }
589
592
593 for (auto& group : m_passGroups) {
594 group->create();
595 }
596 }
597
599 {
600 std::unordered_map<std::string, std::vector<std::string>> resourceWriters;
601 std::unordered_map<std::string, std::vector<std::string>> resourceReaders;
602
603 for (const auto& passEntry : m_passVertex) {
604 const std::string& passName = passEntry.first;
605
606 for (const auto& imageEntry : m_imageResourceDescs) {
607 const std::string& imageName = imageEntry.first;
608
609 if (isPassWritingToResource(passName, imageName)) {
610 resourceWriters[imageName].push_back(passName);
611 }
612
613 if (isPassReadingFromResource(passName, imageName)) {
614 resourceReaders[imageName].push_back(passName);
615 }
616 }
617 }
618
619 for (const auto& resourceEntry : resourceReaders) {
620 const std::string& resourceName = resourceEntry.first;
621 const std::vector<std::string>& readers = resourceEntry.second;
622
623 if (resourceWriters.find(resourceName) != resourceWriters.end()) {
624 const std::vector<std::string>& writers = resourceWriters[resourceName];
625
626 for (const std::string& reader : readers) {
627 for (const std::string& writer : writers) {
628 if (reader != writer) {
629 addPassDenpendency(writer, reader);
630 }
631 }
632 }
633 }
634 }
635 }
636
637 bool OldRenderGraph::isPassWritingToResource(const std::string& passName, const std::string& resourceName)
638 {
639 auto it = m_passVertex.find(passName);
640 if (it == m_passVertex.end()) {
641 return false;
642 }
643
644 PassGraphType::vertex_descriptor passVertex = it->second;
645 PassGraphVertex& passData = m_passGraph[passVertex];
646
647 for (uint8_t slot = 0; slot < 8; ++slot) {
648 if (passData.target[slot] == resourceName) {
649 return true;
650 }
651 }
652
653 if (passData.depthStencil == resourceName) {
654 return true;
655 }
656
657 return false;
658 }
659
660 bool OldRenderGraph::isPassReadingFromResource(const std::string& passName, const std::string& resourceName)
661 {
662 auto it = m_passVertex.find(passName);
663 if (it == m_passVertex.end()) {
664 return false;
665 }
666
667 PassGraphType::vertex_descriptor passVertex = it->second;
668 PassGraphVertex& passData = m_passGraph[passVertex];
669
670 for (const auto& texture : passData.textures) {
671 if (texture == resourceName) {
672 return true;
673 }
674 }
675
676 return false;
677 }
678
680 {
681 ScopeTimer GraphExecuteTimer("GraphExecute");
682 for (size_t i = 0; i < m_executionOrder.passGroups.size(); ++i) {
683 if (i >= m_passGroups.size()) {
684 ferr << "PassGroup 索引超出范围: " << i << std::endl;
685 continue;
686 }
687
688 RHI::PassGroup* passGroup = m_passGroups[i];
689 const auto& group = m_executionOrder.passGroups[i];
690
691 passGroup->beginSubmit(cmdBuf);
692
693 for (auto passVd : group) {
694 PassGraphVertex& passData = m_passGraph[passVd];
695 passData.pass->submit(cmdBuf);
696 }
697
698 passGroup->endSubmit(cmdBuf);
699 }
700 }
702 {
703 if (m_executionOrder.passGroups.empty()) {
704 fout << "渲染图尚未编译,无法显示执行顺序" << std::endl;
705 return;
706 }
707
708 fout << "渲染图执行顺序:" << std::endl;
709
710 for (size_t i = 0; i < m_executionOrder.passGroups.size(); ++i) {
711 const auto& group = m_executionOrder.passGroups[i];
712
713 fout << "Group " << i << ":" << std::endl;
714
715 for (auto passVd : group) {
716 PassGraphVertex& passData = m_passGraph[passVd];
717
718 std::string passName = "未知";
719 for (const auto& entry : m_passVertex) {
720 if (entry.second == passVd) {
721 passName = entry.first;
722 break;
723 }
724 }
725
726 fout << " - " << passName << std::endl;
727 }
728 }
729 }
731 {
732 fout << "\n渲染图资源信息:" << std::endl;
733 fout << "总资源数量: " << m_imageResourceDescs.size() << std::endl;
734
735 std::vector<std::string> renderTargets;
736 std::vector<std::string> depthStencils;
737 std::vector<std::string> textures;
738 std::vector<std::string> windowResources;
739
740 for (const auto& entry : m_imageResourceDescs) {
741 const std::string& imageName = entry.first;
742 const ImageResourceDesc& desc = entry.second;
743
744 if (desc.isWnd) {
745 windowResources.push_back(imageName);
746 } else if (desc.usage & ImageUsage::RenderTarget) {
747 renderTargets.push_back(imageName);
748 } else if (desc.usage & ImageUsage::DepthStencil) {
749 depthStencils.push_back(imageName);
750 } else if (desc.usage & ImageUsage::Texture) {
751 textures.push_back(imageName);
752 }
753 }
754
755 if (!windowResources.empty()) {
756 fout << "\n窗口资源:" << std::endl;
757 for (const auto& name : windowResources) {
758 const ImageResourceDesc& desc = m_imageResourceDescs[name];
759 fout << " - " << name << " (" << desc.width << "x" << desc.height << ")";
760
761 Image* img = m_images[name];
762 if (img) {
763 fout << " 格式: " << formatToString(img->format());
764 }
765
766 fout << std::endl;
767 }
768 }
769
770 if (!renderTargets.empty()) {
771 fout << "\n渲染目标:" << std::endl;
772 for (const auto& name : renderTargets) {
773 const ImageResourceDesc& desc = m_imageResourceDescs[name];
774 fout << " - " << name << " (" << desc.width << "x" << desc.height << ")";
775
776 auto imgIt = m_images.find(name);
777 if (imgIt != m_images.end()) {
778 Image* img = imgIt->second;
779 fout << " 格式: " << formatToString(img->format());
780
781 MutilBufferImage* multiImg = dynamic_cast<MutilBufferImage*>(img);
782 if (multiImg) {
783 fout << " 多缓冲: 是 (数量: " << multiImg->imageCount() << ")";
784 }
785 }
786
787 fout << std::endl;
788 }
789 }
790
791 if (!depthStencils.empty()) {
792 fout << "\n深度模板缓冲:" << std::endl;
793 for (const auto& name : depthStencils) {
794 const ImageResourceDesc& desc = m_imageResourceDescs[name];
795 fout << " - " << name << " (" << desc.width << "x" << desc.height << ")";
796
797 // 输出格式
798 auto imgIt = m_images.find(name);
799 if (imgIt != m_images.end()) {
800 Image* img = imgIt->second;
801 fout << " 格式: " << formatToString(img->format());
802 }
803
804 fout << std::endl;
805 }
806 }
807
808 if (!textures.empty()) {
809 fout << "\n纹理:" << std::endl;
810 for (const auto& name : textures) {
811 const ImageResourceDesc& desc = m_imageResourceDescs[name];
812 fout << " - " << name << " (" << desc.width << "x" << desc.height << ")";
813
814 auto imgIt = m_images.find(name);
815 if (imgIt != m_images.end()) {
816 Image* img = imgIt->second;
817 fout << " 格式: " << formatToString(img->format());
818 }
819
820 auto layoutIt = m_textureLayouts.find(name);
821 if (layoutIt != m_textureLayouts.end()) {
822 const TextureElement& element = layoutIt->second;
823 }
824
825 fout << std::endl;
826 }
827 }
828
829 fout << "\n资源依赖关系:" << std::endl;
830 for (const auto& entry : m_resourceVertices) {
831 const std::string& resourceName = entry.first;
832 ResourceGraphType::vertex_descriptor vd = entry.second;
833
834 ResourceGraphType::out_edge_iterator ei, ei_end;
835 for (boost::tie(ei, ei_end) = boost::out_edges(vd, m_resourceGraph); ei != ei_end; ++ei) {
837 ResourceGraphType::vertex_descriptor targetVd = boost::target(*ei, m_resourceGraph);
838
839 std::string targetName = "未知";
840 for (const auto& targetEntry : m_resourceVertices) {
841 if (targetEntry.second == targetVd) {
842 targetName = targetEntry.first;
843 break;
844 }
845 }
846
847 std::string edgeType = (edge.type == ResourceGraphEdgeType::ParentChild) ? "父子关系" : "引用关系";
848 fout << " " << resourceName << " -> " << targetName << " (" << edgeType << ")" << std::endl;
849 }
850 }
851 }
852
853 std::vector<std::string> OldRenderGraph::getPassTargetToWnd(Window* wnd)
854 {
855 std::vector<std::string> result;
856
857 if (m_windowBackBufferNames.find(wnd) == m_windowBackBufferNames.end()) {
858 return result;
859 }
860
861 std::string wndBackBufferName = m_windowBackBufferNames[wnd];
862
863 std::unordered_set<std::string> wndRelatedResources;
864 wndRelatedResources.insert(wndBackBufferName);
865
867 wndRelatedResources.insert(m_windowDepthStencilNames[wnd]);
868 }
869
870 if (m_resourceVertices.find(wndBackBufferName) != m_resourceVertices.end()) {
871 std::queue<std::string> bfsQueue;
872 bfsQueue.push(wndBackBufferName);
873
874 while (!bfsQueue.empty()) {
875 std::string currentResource = bfsQueue.front();
876 bfsQueue.pop();
877
878 ResourceGraphType::vertex_descriptor currentVertex = m_resourceVertices[currentResource];
879
880 ResourceGraphType::out_edge_iterator ei, ei_end;
881 for (boost::tie(ei, ei_end) = boost::out_edges(currentVertex, m_resourceGraph); ei != ei_end; ++ei) {
884 ResourceGraphType::vertex_descriptor targetVertex = boost::target(*ei, m_resourceGraph);
885
886 for (const auto& entry : m_resourceVertices) {
887 if (entry.second == targetVertex) {
888 if (wndRelatedResources.find(entry.first) == wndRelatedResources.end()) {
889 wndRelatedResources.insert(entry.first);
890 bfsQueue.push(entry.first);
891 }
892 break;
893 }
894 }
895 }
896 }
897
898 ResourceGraphType::in_edge_iterator in_ei, in_ei_end;
899 for (boost::tie(in_ei, in_ei_end) = boost::in_edges(currentVertex, m_resourceGraph); in_ei != in_ei_end; ++in_ei) {
900 ResourceGraphEdge& edge = m_resourceGraph[*in_ei];
902 ResourceGraphType::vertex_descriptor sourceVertex = boost::source(*in_ei, m_resourceGraph);
903
904 for (const auto& entry : m_resourceVertices) {
905 if (entry.second == sourceVertex) {
906 if (wndRelatedResources.find(entry.first) == wndRelatedResources.end()) {
907 wndRelatedResources.insert(entry.first);
908 bfsQueue.push(entry.first);
909 }
910 break;
911 }
912 }
913 }
914 }
915 }
916 }
917
918 for (const auto& passEntry : m_passVertex) {
919 const std::string& passName = passEntry.first;
920 PassGraphType::vertex_descriptor passVd = passEntry.second;
921 PassGraphVertex& passData = m_passGraph[passVd];
922
923 bool passOutputsToWnd = false;
924
925 for (uint8_t slot = 0; slot < 8; ++slot) {
926 const std::string& targetName = passData.target[slot];
927 if (!targetName.empty() && wndRelatedResources.find(targetName) != wndRelatedResources.end()) {
928 passOutputsToWnd = true;
929 break;
930 }
931 }
932
933 if (!passOutputsToWnd && !passData.depthStencil.empty() &&
934 wndRelatedResources.find(passData.depthStencil) != wndRelatedResources.end()) {
935 passOutputsToWnd = true;
936 }
937
938 if (passOutputsToWnd) {
939 result.push_back(passName);
940 }
941 }
942
943 return result;
944 }
945
947 {
948 switch (format) {
949 case Format::R8G8B8A8_UNORM: return "R8G8B8A8_UNORM";
950 case Format::R8G8B8A8_SRGB: return "R8G8B8A8_SRGB";
951 case Format::R32G32B32A32_SFLOAT: return "R32G32B32A32_SFLOAT";
952 case Format::R16G16B16A16_SFLOAT: return "R16G16B16A16_SFLOAT";
953 case Format::D32_SFLOAT: return "D32_SFLOAT";
954 case Format::D32_SFLOAT_S8_UINT: return "D32_SFLOAT_S8_UINT";
955 case Format::D24_UNORM_S8_UINT: return "D24_UNORM_S8_UINT";
956 default: return "未知格式";
957 }
958 }
959
961 {
962 for (const auto& passEntry : m_passVertex) {
963 PassGraphType::vertex_descriptor passVd = passEntry.second;
964 PassGraphVertex& passData = m_passGraph[passVd];
965 passData.pass->updateResource();
966 }
967 }
968
970 {
971 for (auto& passEntry : m_passVertex)
972 {
973 PassGraphType::vertex_descriptor passVd = passEntry.second;
974 PassGraphVertex& passData = m_passGraph[passVd];
975 passData.pass->swapJobQueue();
976 }
977 }
978}
virtual void create()=0
Samples samples() const
定义 Image.h:65
virtual void as(ImageUsages usage)=0
Format format() const
定义 Image.h:64
int height() const
定义 Image.h:76
virtual void resize(uint32_t width, uint32_t height)=0
int width() const
定义 Image.h:75
void as(ImageUsages usage) override
void imageCount(size_t count)
virtual void swapJobQueue()=0
virtual void updateResource()=0
PassClearValue getClearValue() const
定义 Pass.h:54
void setPassResourceAddCallback(const RenderGraphPassResourceAddCallback &callback)
定义 Pass.h:40
void setRhiPass(RHI::Pass *pass)
定义 Pass.h:48
virtual void submit(RHI::CommandBuffer *cmdBuf)=0
std::vector< RHI::PassGroup * > m_passGroups
std::unordered_map< std::string, WindowImageResource > m_windowImageResources
bool isPassWritingToResource(const std::string &passName, const std::string &resourceName)
void execute(RHI::CommandBuffer *cmdBuf)
void addPass(const std::string &name, OldPass *pass)
void bindTextureImage(std::string name, std::string image, uint32_t width=0, uint32_t height=0, Samples samples=Samples::sample_undefined)
void bindOutputImage(const std::string &name, std::string image, uint8_t slot=0)
void addWindowResource(Window *wnd)
std::string formatToString(Format format)
std::vector< std::string > getPassTargetToWnd(Window *wnd)
bool isPassReadingFromResource(const std::string &passName, const std::string &resourceName)
std::unordered_map< std::string, Image * > m_images
std::unordered_map< std::string, WindowDepthStencilResource > m_windowDepthStencilResources
std::unordered_map< std::string, ResourceGraphType::vertex_descriptor > m_resourceVertices
std::vector< Window * > m_bindedWindows
std::vector< MutilBufferImage * > m_needUpdataFramesIndexImages
void saveExecutionOrder(const std::vector< PassGraphType::vertex_descriptor > &sortedPasses, const std::vector< std::vector< PassGraphType::vertex_descriptor > > &passGroups)
std::unordered_map< std::string, PassGraphType::vertex_descriptor > m_passVertex
void bindOutput(const char *name, Window *wnd, uint8_t slot=0)
std::unordered_map< std::string, ImageResourceDesc > m_imageResourceDescs
void bindDepthStencil(const char *name, std::string image)
ResourceGraphType m_resourceGraph
void addPassDenpendency(const std::string &from, const std::string &to)
void submit(Job *job, std::string name)
ExecutionOrder m_executionOrder
std::unordered_map< std::string, TextureElement > m_textureLayouts
std::unordered_map< Window *, std::string > m_windowDepthStencilNames
std::unordered_map< Window *, std::string > m_windowBackBufferNames
void addPass(Pass *pass)
virtual void beginSubmit(CommandBuffer *cmdBuf)=0
virtual void endSubmit(CommandBuffer *cmdBuf)=0
void depthStencil(FCT::Image *depthStencil)
定义 Pass.h:40
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
std::pair< uint32_t, uint32_t > allocateTextureBinding(const TextureElement &texture)
TextureElement findTextureElementByName(std::string name)
virtual int getHeight()=0
virtual int getWidth()=0
ImageRenderTarget * getCurrentTarget()
std::ostream & ferr
std::ostream & fout
PassGraphEdgeType type
std::vector< std::string > textures
ResourceGraphEdgeType type