transition imported resources at the beginning of rendergraph

This commit is contained in:
Janis 2025-01-05 18:20:02 +01:00
parent 5a1ed9340e
commit 3deca28391

View file

@ -493,6 +493,7 @@ impl RenderGraph {
let mut topological_map = Vec::new();
let mut top_dag = dag.clone();
let mut root_barriers = BTreeMap::new();
// create topological map of DAG from sink to source
loop {
@ -514,20 +515,40 @@ impl RenderGraph {
.for_each(|edge| {
let (rid, (before, after)) = edge.weight();
barriers
.entry(*rid)
.and_modify(|(from, to)| {
*from = *from | *before;
*to = *to | *after;
})
.or_insert((*before, *after));
// initial access is transitioned at the beginning
// this affects imported resources only.
if edge.source() == root {
&mut root_barriers
} else {
&mut barriers
}
.entry(*rid)
.and_modify(|(from, to)| {
*from = *from | *before;
*to = *to | *after;
})
.or_insert((*before, *after));
});
top_dag.remove_node(sink);
}
let passes = passes
.into_iter()
.filter_map(|pass| {
if let PassNode::Pass(i) = pass {
Some(i)
} else {
None
}
})
.map(|i| core::mem::take(&mut self.pass_descs[i]))
.collect::<Vec<_>>();
topological_map.push((passes, barriers));
}
topological_map.push((vec![], root_barriers));
//tracing::debug!("mapping: {topological_map:#?}");
// I don't think this can currently happen with the way passes are added.
top_dag.remove_node(root);
if top_dag.node_count() > 0 {
@ -546,48 +567,35 @@ impl RenderGraph {
let resources = &self.resources;
let cmds = topological_map
.iter()
.into_iter()
.rev()
.map(|(set, accesses)| {
let pool = pool.clone();
let device = device.clone();
let passes = set
.into_iter()
.filter_map(|pass| {
if let &PassNode::Pass(i) = pass {
Some(i)
} else {
None
}
})
.map(|i| core::mem::take(&mut self.pass_descs[i]))
.collect::<Vec<_>>();
.map({
|(passes, accesses)| {
let cmd = pool.alloc()?;
// transitions
for (&id, &(from, to)) in accesses.iter() {
Self::transition_resource(
resources.get(&id).unwrap(),
device.dev(),
unsafe { &cmd.buffer() },
from,
to,
);
}
let cmd = pool.alloc()?;
let ctx = RenderContext {
device: device.clone(),
cmd,
resources,
};
// transitions
for (&id, &(from, to)) in accesses.iter() {
Self::transition_resource(
resources.get(&id).unwrap(),
device.dev(),
unsafe { &cmd.buffer() },
from,
to,
);
for pass in passes {
(pass.record)(&ctx)?;
}
ctx.cmd.end()?;
crate::Result::Ok(ctx.cmd)
}
let ctx = RenderContext {
device,
cmd,
resources,
};
for pass in passes {
(pass.record)(&ctx)?;
}
ctx.cmd.end()?;
crate::Result::Ok(ctx.cmd)
})
.collect::<crate::Result<Vec<_>>>()?;