rendergraph: barriers against write-after-read
This commit is contained in:
parent
fdfc74c668
commit
260275d694
|
@ -305,8 +305,6 @@ impl RenderGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut dag = petgraph::stable_graph::StableDiGraph::new();
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
enum PassNode {
|
enum PassNode {
|
||||||
First,
|
First,
|
||||||
|
@ -314,13 +312,23 @@ impl RenderGraph {
|
||||||
Last,
|
Last,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut dag = petgraph::stable_graph::StableDiGraph::new();
|
||||||
|
|
||||||
let root = dag.add_node(PassNode::First);
|
let root = dag.add_node(PassNode::First);
|
||||||
let mut last_write = self
|
let mut last_write: BTreeMap<GraphResourceId, (NodeIndex, Access)> = self
|
||||||
.resources
|
.resources
|
||||||
.keys()
|
.keys()
|
||||||
.filter_map(|id| self.accesses.get(id).map(|access| (*id, (root, *access))))
|
.filter_map(|id| self.accesses.get(id).map(|access| (*id, (root, *access))))
|
||||||
.collect::<BTreeMap<_, _>>();
|
.collect::<BTreeMap<_, _>>();
|
||||||
|
|
||||||
|
let mut last_read: BTreeMap<GraphResourceId, (NodeIndex, Access)> = BTreeMap::new();
|
||||||
|
|
||||||
|
// TODO: rewrite finding edges properly.
|
||||||
|
// finding out if this graph is cyclical is actually non-trivial
|
||||||
|
// some pass might require both a read of a resource 1, and a read of a resource 2, where 2 is the product of another pass writing to resource 1.
|
||||||
|
// this could be resolved by copying resource 1 before the write pass.
|
||||||
|
// tl;dr: write-after-read makes this all more complicated
|
||||||
|
|
||||||
// insert edges between write->read edges of 2 passes
|
// insert edges between write->read edges of 2 passes
|
||||||
for (i, pass) in self.pass_descs.iter().enumerate() {
|
for (i, pass) in self.pass_descs.iter().enumerate() {
|
||||||
let node = dag.add_node(PassNode::Pass(i));
|
let node = dag.add_node(PassNode::Pass(i));
|
||||||
|
@ -341,6 +349,7 @@ impl RenderGraph {
|
||||||
tracing::trace!("adding edge between {other:?} and {node:?} for {rid:?} with ({before:?} -> {after:?})");
|
tracing::trace!("adding edge between {other:?} and {node:?} for {rid:?} with ({before:?} -> {after:?})");
|
||||||
dag.add_edge(other, node, (rid, (before, after)));
|
dag.add_edge(other, node, (rid, (before, after)));
|
||||||
}
|
}
|
||||||
|
last_read.insert(rid, (node, after));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut write_accesses = BTreeMap::new();
|
let mut write_accesses = BTreeMap::new();
|
||||||
|
@ -356,6 +365,12 @@ impl RenderGraph {
|
||||||
|
|
||||||
for (rid, after) in write_accesses {
|
for (rid, after) in write_accesses {
|
||||||
last_write.insert(rid, (node, after));
|
last_write.insert(rid, (node, after));
|
||||||
|
if let Some(&(other, read)) = last_read.get(&rid)
|
||||||
|
&& other != node
|
||||||
|
{
|
||||||
|
tracing::trace!("adding edge between {other:?} and {node:?} for {rid:?} with ({read:?} -> {after:?}) (WaR)");
|
||||||
|
dag.add_edge(other, node, (rid, (read, after)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue