15 PassGraphType::vertex_descriptor vd = boost::add_vertex(v,
m_passGraph);
19 auto passResourceCallback = [
this, name](
PassResource* resource) {
25 PassGraphType::vertex_descriptor passVd = passVdIt->second;
28 for (
const auto& textureName : passData.
textures) {
30 auto imageIt =
m_images.find(textureName);
34 resource->setTexture(imageIt->second,textureIt->second);
72 PassGraphType::vertex_descriptor vd =
m_passVertex[name];
125 bool needRecompute =
false;
128 const std::string& imageName = entry.first;
138 needRecompute =
true;
143 const std::string& imageName = entry.first;
153 needRecompute =
true;
158 std::unordered_map<std::string, std::pair<uint32_t, uint32_t>> originalSizes;
160 if (entry.second.dynamicSize) {
161 originalSizes[entry.first] = {entry.second.width, entry.second.height};
166 if (entry.second.dynamicSize && !entry.second.isWnd) {
167 entry.second.width = 0;
168 entry.second.height = 0;
175 const std::string& imageName = entry.first;
183 auto imgIt =
m_images.find(imageName);
185 Image* img = imgIt->second;
186 auto originalSizeIt = originalSizes.find(imageName);
188 if (desc.
dynamicSize && originalSizeIt != originalSizes.end()) {
189 auto originalSize = originalSizeIt->second;
202 const std::string& imageName = imageEntry.first;
204 ResourceGraphType::vertex_descriptor vd = boost::add_vertex(v,
m_resourceGraph);
208 const std::string& passName = passEntry.first;
209 PassGraphType::vertex_descriptor passVd = passEntry.second;
212 std::vector<std::string> outputResources;
214 for (uint8_t slot = 0; slot < 8; ++slot) {
215 if (!passData.
target[slot].empty()) {
216 outputResources.push_back(passData.
target[slot]);
224 if (outputResources.empty()) {
228 std::string rootResource = outputResources[0];
229 bool foundFixedSizeResource =
false;
231 for (
const auto& resource : outputResources) {
234 rootResource = resource;
235 foundFixedSizeResource =
true;
240 for (
const auto& resource : outputResources) {
241 if (resource != rootResource) {
253 for (
const auto& texture : passData.
textures) {
256 if (textureDesc.
width == 0 || textureDesc.
height == 0) {
281 constexpr uint32_t DEFAULT_IMAGE_WIDTH = 256;
282 constexpr uint32_t DEFAULT_IMAGE_HEIGHT = 256;
284 std::set<std::string> processedResources;
285 std::queue<std::string> sizeQueue;
288 const std::string& imageName = entry.first;
294 sizeQueue.push(imageName);
295 processedResources.insert(imageName);
299 const std::string& imageName = entry.first;
306 sizeQueue.push(imageName);
307 processedResources.insert(imageName);
311 const std::string& imageName = entry.first;
314 if (!desc.
isWnd && desc.
width > 0 && desc.
height > 0 && processedResources.find(imageName) == processedResources.end()) {
315 sizeQueue.push(imageName);
316 processedResources.insert(imageName);
320 while (!sizeQueue.empty()) {
321 std::string currentResource = sizeQueue.front();
324 ResourceGraphType::vertex_descriptor currentVertex =
m_resourceVertices[currentResource];
328 ResourceGraphType::out_edge_iterator ei, ei_end;
329 std::pair<ResourceGraphType::out_edge_iterator, ResourceGraphType::out_edge_iterator> edgeRange =
331 if (edgeRange.first != edgeRange.second)
333 for (boost::tie(ei, ei_end) = boost::out_edges(currentVertex,
m_resourceGraph); ei != ei_end; ++ei) {
337 ResourceGraphType::vertex_descriptor childVertex = boost::target(*ei,
m_resourceGraph);
339 std::string childResource;
341 if (entry.second == childVertex) {
342 childResource = entry.first;
347 if (!childResource.empty() && processedResources.find(childResource) == processedResources.end()) {
351 processedResources.insert(childResource);
352 sizeQueue.push(childResource);
360 const std::string& imageName = entry.first;
364 desc.
width = DEFAULT_IMAGE_WIDTH;
365 desc.
height = DEFAULT_IMAGE_HEIGHT;
372 uint32_t currentFrameIndex =
m_ctx->currentSubmitFrameIndex();
374 img->changeCurrentIndex(currentFrameIndex);
379 const std::vector<std::vector<PassGraphType::vertex_descriptor>>& passGroups)
389 const std::string& imageName = entry.first;
390 m_images[imageName] = entry.second.img;
394 const std::string& imageName = entry.first;
395 m_images[imageName] = entry.second.img;
400 const std::string& imageName = entry.first;
450 PassGraphType::vertex_descriptor passVd = passEntry.second;
453 for (uint8_t slot = 0; slot < 8; ++slot) {
454 if (!passData.
target[slot].empty()) {
455 const std::string& targetName = passData.
target[slot];
474 std::vector<PassGraphType::vertex_descriptor> sortedPasses;
475 std::unordered_map<PassGraphType::vertex_descriptor, boost::default_color_type> colorMap;
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;
487 PassGraphType::vertex_descriptor passVd = passEntry.second;
499 auto getRenderTargetSignature = [
this](PassGraphType::vertex_descriptor passVd) -> std::string {
501 std::stringstream ss;
503 for (uint8_t slot = 0; slot < 8; ++slot) {
504 ss <<
"T" <<
static_cast<int>(slot) <<
":" << passData.
target[slot] <<
";";
512 std::vector<std::vector<PassGraphType::vertex_descriptor>> passGroups;
513 std::unordered_set<PassGraphType::vertex_descriptor> assignedPasses;
515 for (
auto passVd : sortedPasses) {
516 if (assignedPasses.find(passVd) != assignedPasses.end()) {
520 std::string currentSignature = getRenderTargetSignature(passVd);
522 std::vector<PassGraphType::vertex_descriptor> currentGroup;
523 currentGroup.push_back(passVd);
524 assignedPasses.insert(passVd);
526 PassGraphType::vertex_descriptor currentPassVd = passVd;
527 bool continueChain =
true;
529 while (continueChain) {
530 continueChain =
false;
532 std::vector<PassGraphType::vertex_descriptor> candidatePasses;
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);
538 if (assignedPasses.find(targetVd) != assignedPasses.end()) {
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;
554 if (allDependenciesProcessed) {
555 candidatePasses.push_back(targetVd);
560 if (!candidatePasses.empty()) {
561 for (
auto targetVd : candidatePasses) {
562 currentGroup.push_back(targetVd);
563 assignedPasses.insert(targetVd);
566 currentPassVd = candidatePasses.back();
567 continueChain =
true;
571 passGroups.push_back(currentGroup);
578 for (
const auto& group : passGroups) {
582 for (
auto passVd : group) {
600 std::unordered_map<std::string, std::vector<std::string>> resourceWriters;
601 std::unordered_map<std::string, std::vector<std::string>> resourceReaders;
604 const std::string& passName = passEntry.first;
607 const std::string& imageName = imageEntry.first;
610 resourceWriters[imageName].push_back(passName);
614 resourceReaders[imageName].push_back(passName);
619 for (
const auto& resourceEntry : resourceReaders) {
620 const std::string& resourceName = resourceEntry.first;
621 const std::vector<std::string>& readers = resourceEntry.second;
623 if (resourceWriters.find(resourceName) != resourceWriters.end()) {
624 const std::vector<std::string>& writers = resourceWriters[resourceName];
626 for (
const std::string& reader : readers) {
627 for (
const std::string& writer : writers) {
628 if (reader != writer) {
644 PassGraphType::vertex_descriptor passVertex = it->second;
647 for (uint8_t slot = 0; slot < 8; ++slot) {
648 if (passData.
target[slot] == resourceName) {
667 PassGraphType::vertex_descriptor passVertex = it->second;
670 for (
const auto& texture : passData.
textures) {
671 if (texture == resourceName) {
684 ferr <<
"PassGroup 索引超出范围: " << i << std::endl;
693 for (
auto passVd : group) {
704 fout <<
"渲染图尚未编译,无法显示执行顺序" << std::endl;
708 fout <<
"渲染图执行顺序:" << std::endl;
713 fout <<
"Group " << i <<
":" << std::endl;
715 for (
auto passVd : group) {
718 std::string passName =
"未知";
720 if (entry.second == passVd) {
721 passName = entry.first;
726 fout <<
" - " << passName << std::endl;
732 fout <<
"\n渲染图资源信息:" << std::endl;
735 std::vector<std::string> renderTargets;
736 std::vector<std::string> depthStencils;
737 std::vector<std::string> textures;
738 std::vector<std::string> windowResources;
741 const std::string& imageName = entry.first;
745 windowResources.push_back(imageName);
747 renderTargets.push_back(imageName);
749 depthStencils.push_back(imageName);
751 textures.push_back(imageName);
755 if (!windowResources.empty()) {
756 fout <<
"\n窗口资源:" << std::endl;
757 for (
const auto& name : windowResources) {
759 fout <<
" - " << name <<
" (" << desc.
width <<
"x" << desc.
height <<
")";
770 if (!renderTargets.empty()) {
771 fout <<
"\n渲染目标:" << std::endl;
772 for (
const auto& name : renderTargets) {
774 fout <<
" - " << name <<
" (" << desc.
width <<
"x" << desc.
height <<
")";
778 Image* img = imgIt->second;
791 if (!depthStencils.empty()) {
792 fout <<
"\n深度模板缓冲:" << std::endl;
793 for (
const auto& name : depthStencils) {
795 fout <<
" - " << name <<
" (" << desc.
width <<
"x" << desc.
height <<
")";
800 Image* img = imgIt->second;
808 if (!textures.empty()) {
809 fout <<
"\n纹理:" << std::endl;
810 for (
const auto& name : textures) {
812 fout <<
" - " << name <<
" (" << desc.
width <<
"x" << desc.
height <<
")";
816 Image* img = imgIt->second;
829 fout <<
"\n资源依赖关系:" << std::endl;
831 const std::string& resourceName = entry.first;
832 ResourceGraphType::vertex_descriptor vd = entry.second;
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);
839 std::string targetName =
"未知";
841 if (targetEntry.second == targetVd) {
842 targetName = targetEntry.first;
848 fout <<
" " << resourceName <<
" -> " << targetName <<
" (" << edgeType <<
")" << std::endl;
855 std::vector<std::string> result;
863 std::unordered_set<std::string> wndRelatedResources;
864 wndRelatedResources.insert(wndBackBufferName);
871 std::queue<std::string> bfsQueue;
872 bfsQueue.push(wndBackBufferName);
874 while (!bfsQueue.empty()) {
875 std::string currentResource = bfsQueue.front();
878 ResourceGraphType::vertex_descriptor currentVertex =
m_resourceVertices[currentResource];
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);
887 if (entry.second == targetVertex) {
888 if (wndRelatedResources.find(entry.first) == wndRelatedResources.end()) {
889 wndRelatedResources.insert(entry.first);
890 bfsQueue.push(entry.first);
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) {
902 ResourceGraphType::vertex_descriptor sourceVertex = boost::source(*in_ei,
m_resourceGraph);
905 if (entry.second == sourceVertex) {
906 if (wndRelatedResources.find(entry.first) == wndRelatedResources.end()) {
907 wndRelatedResources.insert(entry.first);
908 bfsQueue.push(entry.first);
919 const std::string& passName = passEntry.first;
920 PassGraphType::vertex_descriptor passVd = passEntry.second;
923 bool passOutputsToWnd =
false;
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;
933 if (!passOutputsToWnd && !passData.
depthStencil.empty() &&
934 wndRelatedResources.find(passData.
depthStencil) != wndRelatedResources.end()) {
935 passOutputsToWnd =
true;
938 if (passOutputsToWnd) {
939 result.push_back(passName);
956 default:
return "未知格式";
963 PassGraphType::vertex_descriptor passVd = passEntry.second;
973 PassGraphType::vertex_descriptor passVd = passEntry.second;
virtual void as(ImageUsages usage)=0
virtual void resize(uint32_t width, uint32_t height)=0
Image * targetImage() const
Image * depthStencilBuffer() const
void changeCurrentIndex(int index)
void as(ImageUsages usage) override
void imageCount(size_t count)
virtual void swapJobQueue()=0
virtual void updateResource()=0
PassClearValue getClearValue() const
void setPassResourceAddCallback(const RenderGraphPassResourceAddCallback &callback)
void setRhiPass(RHI::Pass *pass)
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 analyzeImplicitDependencies()
void addWindowResource(Window *wnd)
std::string formatToString(Format format)
void checkAndUpdateResourceSizes()
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
PassGraphType m_passGraph
std::vector< Window * > m_bindedWindows
void printExecutionOrder()
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)
void generateImageGraph()
ResourceGraphType m_resourceGraph
void addPassDenpendency(const std::string &from, const std::string &to)
OldRenderGraph(Context *ctx)
void submit(Job *job, std::string name)
ExecutionOrder m_executionOrder
void updateFrameIndices()
uint32_t m_unnameWndBackBufferCount
std::unordered_map< std::string, TextureElement > m_textureLayouts
std::unordered_map< Window *, std::string > m_windowDepthStencilNames
std::unordered_map< Window *, std::string > m_windowBackBufferNames
uint32_t m_unnameWndStencilDepthCount
void generateImageResource()
virtual void beginSubmit(CommandBuffer *cmdBuf)=0
virtual void endSubmit(CommandBuffer *cmdBuf)=0
void depthStencil(FCT::Image *depthStencil)
void enableClear(ClearTypes type, Vec4 color, float depth=1.0f, uint8_t stencil=0)
void bindTarget(uint32_t index, FCT::Image *target)
std::pair< uint32_t, uint32_t > allocateTextureBinding(const TextureElement &texture)
TextureElement findTextureElementByName(std::string name)
virtual int getHeight()=0
ImageRenderTarget * getCurrentTarget()
std::vector< std::string > textures
ResourceGraphEdgeType type