fgviewer improvement (#8450)
* Introduce FrameGraphInfo class * Move the assignment into pimpl * Make ctors explicit * Add ctors to fg info structs * Revert the macro change to align with existing * Address the comments * Remove pimpl and move func def to .cc * Fix * Convert the FrameGraph to FrameGraphInfo * Initialize and update debug server on engine side * Fix compile error * Address the comments * Update * Use camelCase * Use camelCase * Update * Add JsonWriter to convert fginfo to json * Add getStatus api and implement it * Add increment * Implement GET apis * Fix compile error * Update * Use c_str_safe * Add operator== for FrameGraphInfo * Call updateFrameGraph in appropriate locations * Address the comments * Add webview for fgviewer * Remove head and tail bracket * Fix the table element * Force web to re-render when fg info gets updated * Skip culled resources * Mark subresources as gray * Add parent info for subresources * Collapse subresources into their parent resource * Make the leftmost column fixed * Remove unused stuff in html * Fix the comment * Refactor the code * Cull unused resources * Update * Fix the naming * Format the file * Merge multiple resource node in to single resource * Improve the logic and naming * Refine the code
This commit is contained in:
@@ -43,13 +43,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace utils{
|
||||
template<>
|
||||
CString to_string<uint32_t>(uint32_t value) noexcept {
|
||||
return utils::CString(std::to_string(value).data());
|
||||
}
|
||||
} // namespace utils
|
||||
|
||||
namespace filament {
|
||||
|
||||
inline FrameGraph::Builder::Builder(FrameGraph& fg, PassNode* passNode) noexcept
|
||||
@@ -496,7 +489,7 @@ fgviewer::FrameGraphInfo FrameGraph::getFrameGraphInfo(const char *viewName) con
|
||||
const auto activePassNodesEnd = mActivePassNodesEnd;
|
||||
while (first != activePassNodesEnd) {
|
||||
PassNode *const pass = *first;
|
||||
first++;
|
||||
++first;
|
||||
|
||||
assert_invariant(!pass->isCulled());
|
||||
std::vector<fgviewer::ResourceId> reads;
|
||||
@@ -504,7 +497,12 @@ fgviewer::FrameGraphInfo FrameGraph::getFrameGraphInfo(const char *viewName) con
|
||||
for (auto const &edge: readEdges) {
|
||||
// all incoming edges should be valid by construction
|
||||
assert_invariant(mGraph.isEdgeValid(edge));
|
||||
reads.push_back(edge->from);
|
||||
auto resourceNode = static_cast<const ResourceNode*>(mGraph.getNode(edge->from));
|
||||
assert_invariant(resourceNode);
|
||||
if (resourceNode->getRefCount() == 0)
|
||||
continue;
|
||||
|
||||
reads.push_back(resourceNode->resourceHandle.index);
|
||||
}
|
||||
|
||||
std::vector<fgviewer::ResourceId> writes;
|
||||
@@ -515,7 +513,11 @@ fgviewer::FrameGraphInfo FrameGraph::getFrameGraphInfo(const char *viewName) con
|
||||
if (!mGraph.isEdgeValid(edge)) {
|
||||
continue;
|
||||
}
|
||||
writes.push_back(edge->to);
|
||||
auto resourceNode = static_cast<const ResourceNode*>(mGraph.getNode(edge->to));
|
||||
assert_invariant(resourceNode);
|
||||
if (resourceNode->getRefCount() == 0)
|
||||
continue;
|
||||
writes.push_back(resourceNode->resourceHandle.index);
|
||||
}
|
||||
passes.emplace_back(utils::CString(pass->getName()),
|
||||
std::move(reads), std::move(writes));
|
||||
@@ -523,20 +525,23 @@ fgviewer::FrameGraphInfo FrameGraph::getFrameGraphInfo(const char *viewName) con
|
||||
|
||||
std::unordered_map<fgviewer::ResourceId, fgviewer::FrameGraphInfo::Resource> resources;
|
||||
for (const auto &resourceNode: mResourceNodes) {
|
||||
const FrameGraphHandle resourceHandle = resourceNode->resourceHandle;
|
||||
if (resources.find(resourceHandle.index) != resources.end())
|
||||
continue;
|
||||
|
||||
std::vector<fgviewer::FrameGraphInfo::Resource::Property> resourceProps;
|
||||
// TODO: Fill in resource properties
|
||||
fgviewer::ResourceId id = resourceNode->getId();
|
||||
auto resource = getResource(resourceNode->resourceHandle);
|
||||
if (resource->refcount == 0)
|
||||
if (resourceNode->getRefCount() == 0)
|
||||
continue;
|
||||
if (resourceNode->getParentNode() != nullptr) {
|
||||
resourceProps.emplace_back(fgviewer::FrameGraphInfo::Resource::Property {
|
||||
.name = "is_subresource",
|
||||
.value = utils::to_string(resourceNode->getParentNode()->getId())
|
||||
.value = utils::CString(std::to_string(
|
||||
resourceNode->getParentHandle().index).data())
|
||||
});
|
||||
}
|
||||
resources.emplace(id, fgviewer::FrameGraphInfo::Resource(
|
||||
id, utils::CString(resourceNode->getName()),
|
||||
resources.emplace(resourceHandle.index, fgviewer::FrameGraphInfo::Resource(
|
||||
resourceHandle.index,
|
||||
utils::CString(resourceNode->getName()),
|
||||
std::move(resourceProps))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -356,14 +356,11 @@ class FrameGraphTable extends LitElement {
|
||||
}
|
||||
|
||||
_getRowHtml(allPasses, resourceId, defaultColor) {
|
||||
return allPasses.map((passName, index) => {
|
||||
const passData = this.frameGraphData.passes.find(pass => pass.name === passName);
|
||||
return allPasses.map((passData, index) => {
|
||||
const isRead = passData?.reads.includes(resourceId);
|
||||
const isWrite = passData?.writes.includes(resourceId);
|
||||
let type = null;
|
||||
const getPassData = (name) => this.frameGraphData.passes.find(pass => pass.name === name);
|
||||
const hasUsed = (name) => {
|
||||
const passData = getPassData(name);
|
||||
const hasUsed = (passData) => {
|
||||
return passData?.reads.includes(resourceId) || passData?.writes.includes(resourceId);
|
||||
};
|
||||
const hasBeenUsedBefore = allPasses.slice(0, index).some(hasUsed);
|
||||
@@ -388,7 +385,7 @@ class FrameGraphTable extends LitElement {
|
||||
|
||||
render() {
|
||||
if (!this.frameGraphData || !this.frameGraphData.passes || !this.frameGraphData.resources) return nothing;
|
||||
const allPasses = this.frameGraphData.passes.map(pass => pass.name);
|
||||
const allPasses = this.frameGraphData.passes;
|
||||
const resources = Object.values(this.frameGraphData.resources);
|
||||
return html`
|
||||
<div class="table-container">
|
||||
@@ -397,7 +394,7 @@ class FrameGraphTable extends LitElement {
|
||||
<tr>
|
||||
<th class="sticky-col">Resources/Passes</th>
|
||||
${allPasses.map(pass => html`
|
||||
<th>${pass}</th>`)}
|
||||
<th>${pass.name}</th>`)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
Reference in New Issue
Block a user