fix a FG crasher when we have more than 32 passes (#2911)
The FrameGraph cannot store pointers internally because all objects are stored in vectors. Unfortunately we were storing the writer of resources as a pointer. This is fixed by storing an index instead.
This commit is contained in:
@@ -258,7 +258,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::structure(FrameGraph& fg,
|
||||
// generate depth pass at the requested resolution
|
||||
auto& structurePass = fg.addPass<StructurePassData>("Structure Pass",
|
||||
[&](FrameGraph::Builder& builder, auto& data) {
|
||||
data.depth = builder.createTexture("Depth Buffer", {
|
||||
data.depth = builder.createTexture("Structure Buffer", {
|
||||
.width = width, .height = height,
|
||||
.levels = uint8_t(levelCount),
|
||||
.format = TextureFormat::DEPTH24 });
|
||||
|
||||
@@ -148,13 +148,14 @@ void FrameGraph::moveResourceBase(FrameGraphHandle fromHandle, FrameGraphHandle
|
||||
|
||||
// The pass that is writing to "fromHandle" no longer does (and might be culled)
|
||||
// (note: there can only be a single pass that can be a writer)
|
||||
PassNode* const pass = from.writer;
|
||||
if (pass) {
|
||||
if (from.writerIndex.isValid()) {
|
||||
PassNode* const pass = &mPassNodes[from.writerIndex.index];
|
||||
assert(pass);
|
||||
auto pos = std::find_if(pass->writes.begin(), pass->writes.end(),
|
||||
[fromHandle](auto handle) { return handle == fromHandle; });
|
||||
assert(pos != pass->writes.end());
|
||||
pass->writes.erase(pos);
|
||||
from.writer = to.writer;
|
||||
from.writerIndex = to.writerIndex;
|
||||
}
|
||||
|
||||
// The 'to' node becomes the 'from' node and therefore inherits passes that are reading
|
||||
@@ -284,12 +285,11 @@ FrameGraph& FrameGraph::compile() noexcept {
|
||||
resourceNodes[resource.index]->readerCount++;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
// set the writers
|
||||
for (FrameGraphHandle resource : pass.writes) {
|
||||
assert(resource.isValid());
|
||||
assert(resourceNodes[resource.index]->writer == &pass);
|
||||
resourceNodes[resource.index]->writer = &pass;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace filament {
|
||||
|
||||
namespace fg {
|
||||
struct PassNode;
|
||||
struct ResourceNode;
|
||||
class RenderTargetResourceEntry;
|
||||
} // namespace fg
|
||||
|
||||
@@ -69,6 +70,7 @@ class FrameGraphHandle {
|
||||
friend class FrameGraph;
|
||||
friend class FrameGraphPassResources;
|
||||
friend struct fg::PassNode;
|
||||
friend struct fg::ResourceNode;
|
||||
friend class fg::RenderTargetResourceEntry;
|
||||
|
||||
// private ctor -- this cannot be constructed by users
|
||||
|
||||
@@ -113,8 +113,8 @@ FrameGraphHandle PassNode::write(FrameGraph& fg, const FrameGraphHandle& handle)
|
||||
|
||||
// record the write
|
||||
auto& newNode = fg.getResourceNodeUnchecked(r);
|
||||
assert(!newNode.writer);
|
||||
newNode.writer = this; // needed by move resources
|
||||
assert(!newNode.writerIndex.isValid());
|
||||
newNode.writerIndex = r; // needed by move resources
|
||||
|
||||
writes.push_back(r);
|
||||
return r;
|
||||
|
||||
@@ -34,6 +34,8 @@ struct ResourceNode { // 24
|
||||
ResourceNode(ResourceNode&&) noexcept = default;
|
||||
ResourceNode& operator=(ResourceNode const&) = delete;
|
||||
|
||||
FrameGraphHandle writerIndex; // only needed by moveResource
|
||||
|
||||
// updated during compile()
|
||||
ResourceEntryBase* resource; // actual (aliased) resource data
|
||||
PassNode* writer = nullptr; // writer to this node
|
||||
|
||||
Reference in New Issue
Block a user