From d038a9d8d21456e4abd0c66bf2d285ef03a438ee Mon Sep 17 00:00:00 2001 From: Zeqiang Li Date: Wed, 20 Sep 2023 18:57:02 +0800 Subject: [PATCH 1/4] correct renderpass reorder logic --- .../pipeline/custom/FrameGraphDispatcher.cpp | 187 ++++++++++-------- 1 file changed, 108 insertions(+), 79 deletions(-) diff --git a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp index 4d0f5afe176..e8880f41526 100644 --- a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp +++ b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp @@ -791,15 +791,22 @@ struct AttachmentSortKey { gfx::SampleCount samples; AccessType accessType; uint32_t attachmentWeight; + uint32_t slotID; const ccstd::pmr::string name; }; -struct AttachmentComparator { +struct SubpassComparator { bool operator()(const AttachmentSortKey &lhs, const AttachmentSortKey &rhs) const { return std::tie(rhs.samples, lhs.accessType, lhs.attachmentWeight, lhs.name) < std::tie(lhs.samples, rhs.accessType, rhs.attachmentWeight, rhs.name); } }; +struct PassComparator { + bool operator()(const AttachmentSortKey &lhs, const AttachmentSortKey &rhs) const { + return std::tie(lhs.slotID, lhs.name) < std::tie(rhs.slotID, rhs.name); + } +}; + struct ViewInfo { gfx::Format format{gfx::Format::UNKNOWN}; LayoutAccess access; @@ -808,10 +815,12 @@ struct ViewInfo { AttachmentType attachmentType; }; -using AttachmentMap = ccstd::pmr::map; +template +using AttachmentMap = ccstd::pmr::map; } // namespace -void fillRenderPassInfo(const AttachmentMap &colorMap, +template +void fillRenderPassInfo(const T &colorMap, FGRenderPassInfo &fgRenderpassInfo, const ResourceGraph &resg) { for (const auto &pair : colorMap) { @@ -920,11 +929,12 @@ void extractNames(const ccstd::pmr::string &resName, } } +template auto checkRasterViews(const Graphs &graphs, ResourceAccessGraph::vertex_descriptor ragVertID, ResourceAccessNode &node, const RasterViewsMap &rasterViews, - AttachmentMap &colorMap) { + AttachmentMap &colorMap) { const auto &[renderGraph, layoutGraphData, resourceGraph, resourceAccessGraph, relationGraph] = graphs; const auto passID = get(ResourceAccessGraph::PassIDTag{}, resourceAccessGraph, ragVertID); bool dependent = false; @@ -956,6 +966,7 @@ auto checkRasterViews(const Graphs &graphs, colorMap.emplace(AttachmentSortKey{desc.sampleCount, rasterView.accessType, ATTACHMENT_TYPE_WEIGHT[static_cast(rasterView.attachmentType)], + rasterView.slotID, resName}, ViewInfo{desc.format, LayoutAccess{lastAccess, accessFlag}, @@ -1018,11 +1029,12 @@ bool checkComputeViews(const Graphs &graphs, ResourceAccessGraph::vertex_descrip return dependent; } +template bool checkResolveResource(const Graphs &graphs, uint32_t ragVertID, ResourceAccessNode &node, const ccstd::pmr::vector &resolves, - AttachmentMap &colorMap) { + AttachmentMap &colorMap) { const auto &[renderGraph, layoutGraphData, resourceGraph, resourceAccessGraph, relationGraph] = graphs; const auto passID = get(ResourceAccessGraph::PassIDTag{}, resourceAccessGraph, ragVertID); bool dependent = false; @@ -1051,6 +1063,7 @@ bool checkResolveResource(const Graphs &graphs, colorMap.emplace(AttachmentSortKey{desc.sampleCount, AccessType::WRITE, ATTACHMENT_TYPE_WEIGHT[static_cast(attachmentType)], + static_cast(colorMap.size()), resolveTargetName}, ViewInfo{desc.format, LayoutAccess{lastAccess, accessFlag}, @@ -1132,7 +1145,7 @@ void startRenderPass(const Graphs &graphs, uint32_t passID, const RasterPass &pa auto &fgRenderPassInfo = get(ResourceAccessGraph::RenderPassInfoTag{}, resourceAccessGraph, vertID); if (pass.subpassGraph.subpasses.empty()) { - AttachmentMap colorMap(resourceAccessGraph.get_allocator()); + AttachmentMap colorMap(resourceAccessGraph.get_allocator()); auto &accessNode = get(ResourceAccessGraph::PassNodeTag{}, resourceAccessGraph, vertID); std::ignore = checkRasterViews(graphs, rlgVertID, accessNode, pass.rasterViews, colorMap); std::ignore = checkComputeViews(graphs, rlgVertID, accessNode, pass.computeViews); @@ -1214,90 +1227,106 @@ void startRenderSubpass(const Graphs &graphs, uint32_t passID, const RasterSubpa auto parentID = parent(passID, renderGraph); auto parentRagVertID = resourceAccessGraph.passIndex.at(parentID); auto &fgRenderpassInfo = get(ResourceAccessGraph::RenderPassInfoTag{}, resourceAccessGraph, parentRagVertID); - AttachmentMap colorMap(resourceAccessGraph.get_allocator()); - - auto [hasDep, hasDS] = checkRasterViews(graphs, rlgVertID, accessNode, pass.rasterViews, colorMap); - hasDep |= checkComputeViews(graphs, rlgVertID, accessNode, pass.computeViews); - hasDep |= checkResolveResource(graphs, rlgVertID, accessNode, pass.resolvePairs, colorMap); - fillRenderPassInfo(colorMap, fgRenderpassInfo, resourceGraph); - auto &subpassInfo = fgRenderpassInfo.rpInfo.subpasses.emplace_back(); - auto &dependencies = fgRenderpassInfo.rpInfo.dependencies; + auto &rg = renderGraph; + auto &rag = resourceAccessGraph; + auto &resg = resourceGraph; - // subpass info & subpass dependencies - for (const auto &pair : colorMap) { - const auto &sortKey = pair.first; - const std::string_view name = sortKey.name; - auto resID = vertex(sortKey.name, resourceGraph); - const auto &desc = get(ResourceGraph::DescTag{}, resourceGraph, resID); - const auto &[ignored, cIndex, isResolveView] = fgRenderpassInfo.viewIndex.at(name.data()); - if (isResolveView) { - auto resolveIter = std::find_if(pass.resolvePairs.begin(), pass.resolvePairs.end(), [&name](const ResolvePair &resolve) { - return strcmp(resolve.target.c_str(), name.data()) == 0; - }); - if (desc.format == gfx::Format::DEPTH_STENCIL) { - subpassInfo.depthStencilResolve = getDepthStencilSlot(fgRenderpassInfo.uniqueRasterViewCount, fgRenderpassInfo.resolveCount, hasDS) + 1; - if (resolveIter->mode != gfx::ResolveMode::NONE) { - subpassInfo.depthResolveMode = resolveIter->mode; - } - if (resolveIter->mode1 != gfx::ResolveMode::NONE) { - subpassInfo.stencilResolveMode = resolveIter->mode1; + auto process = [&](auto &colorMap) { + auto [hasDep, hasDS] = checkRasterViews(graphs, rlgVertID, accessNode, pass.rasterViews, colorMap); + hasDep |= checkComputeViews(graphs, rlgVertID, accessNode, pass.computeViews); + hasDep |= checkResolveResource(graphs, rlgVertID, accessNode, pass.resolvePairs, colorMap); + fillRenderPassInfo(colorMap, fgRenderpassInfo, resg); + + auto &subpassInfo = fgRenderpassInfo.rpInfo.subpasses.emplace_back(); + auto &dependencies = fgRenderpassInfo.rpInfo.dependencies; + + // subpass info & subpass dependencies + for (const auto &pair : colorMap) { + const auto &sortKey = pair.first; + const std::string_view name = sortKey.name; + auto resID = vertex(sortKey.name, resg); + const auto &desc = get(ResourceGraph::DescTag{}, resg, resID); + const auto &[ignored, cIndex, isResolveView] = fgRenderpassInfo.viewIndex.at(name.data()); + if (isResolveView) { + auto resolveIter = std::find_if(pass.resolvePairs.begin(), pass.resolvePairs.end(), [&name](const ResolvePair &resolve) { + return strcmp(resolve.target.c_str(), name.data()) == 0; + }); + if (desc.format == gfx::Format::DEPTH_STENCIL) { + subpassInfo.depthStencilResolve = getDepthStencilSlot(fgRenderpassInfo.uniqueRasterViewCount, fgRenderpassInfo.resolveCount, hasDS) + 1; + if (resolveIter->mode != gfx::ResolveMode::NONE) { + subpassInfo.depthResolveMode = resolveIter->mode; + } + if (resolveIter->mode1 != gfx::ResolveMode::NONE) { + subpassInfo.stencilResolveMode = resolveIter->mode1; + } + } else { + if (subpassInfo.resolves.empty()) { + subpassInfo.resolves.resize(pass.rasterViews.size() - hasDS, gfx::INVALID_BINDING); + } + const auto &resolveSrc = resolveIter->source; + const auto &resourceSrcInfo = fgRenderpassInfo.viewIndex.at(resolveSrc); + subpassInfo.resolves[resourceSrcInfo.attachmentIndex] = cIndex; } } else { - if (subpassInfo.resolves.empty()) { - subpassInfo.resolves.resize(pass.rasterViews.size() - hasDS, gfx::INVALID_BINDING); + if (desc.format == gfx::Format::DEPTH_STENCIL) { + auto dsSlot = getDepthStencilSlot(fgRenderpassInfo.uniqueRasterViewCount, fgRenderpassInfo.resolveCount, hasDS); + if (sortKey.accessType != AccessType::WRITE) { + subpassInfo.inputs.emplace_back(dsSlot); + } + if (sortKey.accessType != AccessType::READ) { + subpassInfo.depthStencil = dsSlot; + } + } else { + if (sortKey.accessType != AccessType::WRITE) { + subpassInfo.inputs.emplace_back(cIndex); + } + if (sortKey.accessType != AccessType::READ) { + subpassInfo.colors.emplace_back(cIndex); + } + + if (sortKey.accessType == AccessType::READ_WRITE) { + auto &selfDependency = dependencies.emplace_back(); + selfDependency.srcSubpass = pass.subpassID; + selfDependency.dstSubpass = pass.subpassID; + selfDependency.prevAccesses = pair.second.access.nextAccess; + selfDependency.nextAccesses = pair.second.access.nextAccess; + } } - const auto &resolveSrc = resolveIter->source; - const auto &resourceSrcInfo = fgRenderpassInfo.viewIndex.at(resolveSrc); - subpassInfo.resolves[resourceSrcInfo.attachmentIndex] = cIndex; } - } else { - if (desc.format == gfx::Format::DEPTH_STENCIL) { - auto dsSlot = getDepthStencilSlot(fgRenderpassInfo.uniqueRasterViewCount, fgRenderpassInfo.resolveCount, hasDS); - if (sortKey.accessType != AccessType::WRITE) { - subpassInfo.inputs.emplace_back(dsSlot); - } - if (sortKey.accessType != AccessType::READ) { - subpassInfo.depthStencil = dsSlot; - } - } else { - if (sortKey.accessType != AccessType::WRITE) { - subpassInfo.inputs.emplace_back(cIndex); - } - if (sortKey.accessType != AccessType::READ) { - subpassInfo.colors.emplace_back(cIndex); - } - if (sortKey.accessType == AccessType::READ_WRITE) { - auto &selfDependency = dependencies.emplace_back(); - selfDependency.srcSubpass = pass.subpassID; - selfDependency.dstSubpass = pass.subpassID; - selfDependency.prevAccesses = pair.second.access.nextAccess; - selfDependency.nextAccesses = pair.second.access.nextAccess; + if (hasDep) { + auto &dependency = dependencies.emplace_back(); + auto lastIter = ++rag.resourceAccess[name.data()].rbegin(); + bool isBuffer = desc.dimension == ResourceDimension::BUFFER; + if (accessDependent(lastIter->second.accessFlag, accessNode.resourceStatus.at(name.data()).accessFlag, isBuffer) && lastIter->second.accessFlag != gfx::AccessFlagBit::NONE) { + auto lastVert = lastIter->first; + auto lastPassID = get(ResourceAccessGraph::PassIDTag{}, rag, lastVert); + auto lastPassIndex = INVALID_ID; + if (holds(lastPassID, rg) && (parent(lastPassID, rg) == parentID)) { + const auto *lastPass = get_if(lastPassID, &rg); + lastPassIndex = lastPass->subpassID; + } + + auto &dependency = dependencies.emplace_back(); + dependency.srcSubpass = lastPassIndex; + dependency.dstSubpass = pass.subpassID; + dependency.prevAccesses = lastIter->second.accessFlag; + dependency.nextAccesses = pair.second.access.nextAccess; } } } + }; - if (hasDep) { - auto &dependency = dependencies.emplace_back(); - auto lastIter = ++resourceAccessGraph.resourceAccess[name.data()].rbegin(); - bool isBuffer = desc.dimension == ResourceDimension::BUFFER; - if (accessDependent(lastIter->second.accessFlag, accessNode.resourceStatus.at(name.data()).accessFlag, isBuffer) && lastIter->second.accessFlag != gfx::AccessFlagBit::NONE) { - auto lastVert = lastIter->first; - auto lastPassID = get(ResourceAccessGraph::PassIDTag{}, resourceAccessGraph, lastVert); - auto lastPassIndex = INVALID_ID; - if (holds(lastPassID, renderGraph) && (parent(lastPassID, renderGraph) == parentID)) { - const auto *lastPass = get_if(lastPassID, &renderGraph); - lastPassIndex = lastPass->subpassID; - } + const auto *parentPass = get_if(parentID, &renderGraph); + CC_ASSERT(parentPass); - auto &dependency = dependencies.emplace_back(); - dependency.srcSubpass = lastPassIndex; - dependency.dstSubpass = pass.subpassID; - dependency.prevAccesses = lastIter->second.accessFlag; - dependency.nextAccesses = pair.second.access.nextAccess; - } - } + if (parentPass->subpassGraph.subpasses.size() == 1) { + AttachmentMap colorMap(resourceAccessGraph.get_allocator()); + process(colorMap); + } else { + AttachmentMap colorMap(resourceAccessGraph.get_allocator()); + process(colorMap); } } @@ -1309,7 +1338,7 @@ void startComputeSubpass(const Graphs &graphs, uint32_t passID, const ComputeSub CC_EXPECTS(static_cast(rlgVertID) == static_cast(vertID)); auto &accessNode = get(ResourceAccessGraph::PassNodeTag{}, resourceAccessGraph, rlgVertID); - AttachmentMap colorMap(resourceAccessGraph.get_allocator()); + AttachmentMap colorMap(resourceAccessGraph.get_allocator()); auto parentID = parent(passID, renderGraph); auto parentRagVertID = resourceAccessGraph.passIndex.at(parentID); From 72a0cbf10db42ab367f40a969e7e113e42c4501c Mon Sep 17 00:00:00 2001 From: Zeqiang Li Date: Wed, 20 Sep 2023 22:00:18 +0800 Subject: [PATCH 2/4] clang tidy --- native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp index e8880f41526..5c833132a6c 100644 --- a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp +++ b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp @@ -1228,7 +1228,7 @@ void startRenderSubpass(const Graphs &graphs, uint32_t passID, const RasterSubpa auto parentRagVertID = resourceAccessGraph.passIndex.at(parentID); auto &fgRenderpassInfo = get(ResourceAccessGraph::RenderPassInfoTag{}, resourceAccessGraph, parentRagVertID); - auto &rg = renderGraph; + const auto &rg = renderGraph; auto &rag = resourceAccessGraph; auto &resg = resourceGraph; From d21dd29a00e6bf08876ab88f881dea4b0e23547b Mon Sep 17 00:00:00 2001 From: Zeqiang Li Date: Wed, 20 Sep 2023 22:56:27 +0800 Subject: [PATCH 3/4] comment & rename --- .../renderer/pipeline/custom/FrameGraphDispatcher.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp index 5c833132a6c..d62b32525f4 100644 --- a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp +++ b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp @@ -803,7 +803,7 @@ struct SubpassComparator { struct PassComparator { bool operator()(const AttachmentSortKey &lhs, const AttachmentSortKey &rhs) const { - return std::tie(lhs.slotID, lhs.name) < std::tie(rhs.slotID, rhs.name); + return lhs.slotID < rhs.slotID; } }; @@ -819,8 +819,8 @@ template using AttachmentMap = ccstd::pmr::map; } // namespace -template -void fillRenderPassInfo(const T &colorMap, +template +void fillRenderPassInfo(const AttachmentMap &colorMap, FGRenderPassInfo &fgRenderpassInfo, const ResourceGraph &resg) { for (const auto &pair : colorMap) { @@ -1228,7 +1228,7 @@ void startRenderSubpass(const Graphs &graphs, uint32_t passID, const RasterSubpa auto parentRagVertID = resourceAccessGraph.passIndex.at(parentID); auto &fgRenderpassInfo = get(ResourceAccessGraph::RenderPassInfoTag{}, resourceAccessGraph, parentRagVertID); - const auto &rg = renderGraph; + auto &rg = renderGraph; auto &rag = resourceAccessGraph; auto &resg = resourceGraph; @@ -1322,6 +1322,7 @@ void startRenderSubpass(const Graphs &graphs, uint32_t passID, const RasterSubpa CC_ASSERT(parentPass); if (parentPass->subpassGraph.subpasses.size() == 1) { + // for those renderpass which consist of only 1 subpass AttachmentMap colorMap(resourceAccessGraph.get_allocator()); process(colorMap); } else { From ebac847e5d3ca376e1a5829948515d9963a2e7bc Mon Sep 17 00:00:00 2001 From: Zeqiang Li Date: Thu, 21 Sep 2023 11:01:27 +0800 Subject: [PATCH 4/4] clang tidy --- native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp index d62b32525f4..0324502effa 100644 --- a/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp +++ b/native/cocos/renderer/pipeline/custom/FrameGraphDispatcher.cpp @@ -1228,7 +1228,7 @@ void startRenderSubpass(const Graphs &graphs, uint32_t passID, const RasterSubpa auto parentRagVertID = resourceAccessGraph.passIndex.at(parentID); auto &fgRenderpassInfo = get(ResourceAccessGraph::RenderPassInfoTag{}, resourceAccessGraph, parentRagVertID); - auto &rg = renderGraph; + const auto &rg = renderGraph; auto &rag = resourceAccessGraph; auto &resg = resourceGraph;