rendergraph: works!! (i cant believe it does!)
This commit is contained in:
parent
5b5a7cba54
commit
a5ea706744
|
@ -26,6 +26,10 @@ pub fn egui_pre_pass(
|
||||||
// allocate resource ids for textures in tessellated list (imported from texture manager)
|
// allocate resource ids for textures in tessellated list (imported from texture manager)
|
||||||
// define accesses for resource ids
|
// define accesses for resource ids
|
||||||
|
|
||||||
|
if output.textures_delta.set.is_empty() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
// create textures for new egui textures
|
// create textures for new egui textures
|
||||||
for (egui_id, delta) in output
|
for (egui_id, delta) in output
|
||||||
.textures_delta
|
.textures_delta
|
||||||
|
@ -33,6 +37,7 @@ pub fn egui_pre_pass(
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(_, image)| image.is_whole())
|
.filter(|(_, image)| image.is_whole())
|
||||||
{
|
{
|
||||||
|
tracing::trace!("creating texture image for egui image {egui_id:?}");
|
||||||
let image = Image::new(
|
let image = Image::new(
|
||||||
dev.clone(),
|
dev.clone(),
|
||||||
ImageDesc {
|
ImageDesc {
|
||||||
|
@ -64,18 +69,23 @@ pub fn egui_pre_pass(
|
||||||
// calculate size for staging buffer.
|
// calculate size for staging buffer.
|
||||||
// calculate size for staging image.
|
// calculate size for staging image.
|
||||||
let (staging_size, image_size) = output.textures_delta.set.iter().fold(
|
let (staging_size, image_size) = output.textures_delta.set.iter().fold(
|
||||||
(0usize, 0usize),
|
(0usize, glam::UVec2::ZERO),
|
||||||
|(mut buffer, mut image), (_id, delta)| {
|
|(mut buffer, mut image), (_id, delta)| {
|
||||||
let bytes = delta.image.height() * delta.image.width() * delta.image.bytes_per_pixel();
|
let bytes = delta.image.height() * delta.image.width() * delta.image.bytes_per_pixel();
|
||||||
if !delta.is_whole() {
|
image = image.max(glam::uvec2(
|
||||||
image = image.max(bytes);
|
delta.image.width() as u32,
|
||||||
}
|
delta.image.height() as u32,
|
||||||
|
));
|
||||||
buffer = buffer + bytes;
|
buffer = buffer + bytes;
|
||||||
|
|
||||||
(buffer, image)
|
(buffer, image)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
tracing::trace!(
|
||||||
|
staging_size,
|
||||||
|
"creating staging buffer for uploading egui textures"
|
||||||
|
);
|
||||||
let mut staging_buffer = Buffer::new(
|
let mut staging_buffer = Buffer::new(
|
||||||
dev.clone(),
|
dev.clone(),
|
||||||
BufferDesc {
|
BufferDesc {
|
||||||
|
@ -90,14 +100,16 @@ pub fn egui_pre_pass(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
tracing::trace!("creating staging image for uploading egui textures with dims={image_size:?}");
|
||||||
let staging_image = Arc::new(Image::new(
|
let staging_image = Arc::new(Image::new(
|
||||||
dev.clone(),
|
dev.clone(),
|
||||||
ImageDesc {
|
ImageDesc {
|
||||||
name: Some("egui-prepass-staging-buffer".into()),
|
name: Some("egui-prepass-staging-buffer".into()),
|
||||||
format: vk::Format::R8G8B8A8_UNORM,
|
format: vk::Format::R8G8B8A8_UNORM,
|
||||||
extent: vk::Extent3D {
|
extent: vk::Extent3D {
|
||||||
width: (image_size / 2) as u32,
|
width: image_size.x,
|
||||||
height: (image_size - (image_size / 2)) as u32,
|
height: image_size.y,
|
||||||
depth: 1,
|
depth: 1,
|
||||||
},
|
},
|
||||||
usage: vk::ImageUsageFlags::TRANSFER_SRC | vk::ImageUsageFlags::TRANSFER_DST,
|
usage: vk::ImageUsageFlags::TRANSFER_SRC | vk::ImageUsageFlags::TRANSFER_DST,
|
||||||
|
@ -108,6 +120,7 @@ pub fn egui_pre_pass(
|
||||||
)?);
|
)?);
|
||||||
|
|
||||||
let aliased_images = {
|
let aliased_images = {
|
||||||
|
tracing::trace!("mmap-ing staging buffer");
|
||||||
let mut staging_map = staging_buffer.map()?;
|
let mut staging_map = staging_buffer.map()?;
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
|
|
||||||
|
@ -115,7 +128,7 @@ pub fn egui_pre_pass(
|
||||||
.textures_delta
|
.textures_delta
|
||||||
.set
|
.set
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(id, delta)| {
|
.map(|(id, delta)| {
|
||||||
let bytes =
|
let bytes =
|
||||||
delta.image.height() * delta.image.width() * delta.image.bytes_per_pixel();
|
delta.image.height() * delta.image.width() * delta.image.bytes_per_pixel();
|
||||||
|
|
||||||
|
@ -141,34 +154,12 @@ pub fn egui_pre_pass(
|
||||||
let old_offset = offset;
|
let old_offset = offset;
|
||||||
offset += bytes;
|
offset += bytes;
|
||||||
|
|
||||||
if !delta.is_whole() {
|
let pos = delta.pos.unwrap_or_default();
|
||||||
unsafe {
|
let rect = Rect2D::new_from_size(
|
||||||
let alias = staging_image
|
glam::ivec2(pos[0] as i32, pos[1] as i32),
|
||||||
.clone()
|
glam::ivec2(delta.image.width() as i32, delta.image.height() as i32),
|
||||||
.get_alias(ImageDesc {
|
);
|
||||||
name: Some(format!("egui-prepass-staging-aliased-{id:?}").into()),
|
(*id, (old_offset, bytes, rect))
|
||||||
format: vk::Format::R8G8B8A8_UNORM,
|
|
||||||
extent: vk::Extent3D {
|
|
||||||
width: delta.image.width() as u32,
|
|
||||||
height: delta.image.height() as u32,
|
|
||||||
depth: 1,
|
|
||||||
},
|
|
||||||
usage: vk::ImageUsageFlags::TRANSFER_SRC
|
|
||||||
| vk::ImageUsageFlags::TRANSFER_DST,
|
|
||||||
queue_families: device::QueueFlags::empty(),
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
let pos = delta.pos.unwrap();
|
|
||||||
let rect = Rect2D::new_from_size(
|
|
||||||
glam::ivec2(pos[0] as i32, pos[1] as i32),
|
|
||||||
glam::ivec2(delta.image.width() as i32, delta.image.height() as i32),
|
|
||||||
);
|
|
||||||
Some((*id, (old_offset, bytes, rect, alias)))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect::<BTreeMap<_, _>>();
|
.collect::<BTreeMap<_, _>>();
|
||||||
|
|
||||||
|
@ -210,7 +201,10 @@ pub fn egui_pre_pass(
|
||||||
let staging_image = ctx.get_image(staging_image).unwrap().clone();
|
let staging_image = ctx.get_image(staging_image).unwrap().clone();
|
||||||
let staging_buffer = ctx.get_buffer(staging_buffer).unwrap();
|
let staging_buffer = ctx.get_buffer(staging_buffer).unwrap();
|
||||||
|
|
||||||
for (id, (offset, _, rect, _)) in aliased_images {
|
for (id, (offset, _, rect)) in aliased_images {
|
||||||
|
tracing::trace!(
|
||||||
|
"record-prepass: fetching alias of prepass staging image id={id:?}"
|
||||||
|
);
|
||||||
let alias = unsafe {
|
let alias = unsafe {
|
||||||
staging_image.get_alias(ImageDesc {
|
staging_image.get_alias(ImageDesc {
|
||||||
name: Some(format!("egui-prepass-staging-aliased-{id:?}v").into()),
|
name: Some(format!("egui-prepass-staging-aliased-{id:?}v").into()),
|
||||||
|
@ -674,6 +668,36 @@ pub fn egui_pass(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let color_attachment = &vk::RenderingAttachmentInfo::default()
|
||||||
|
.image_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
|
||||||
|
.image_view(target.get_view(ImageViewDesc {
|
||||||
|
kind: vk::ImageViewType::TYPE_2D,
|
||||||
|
format: target.format(),
|
||||||
|
aspect: vk::ImageAspectFlags::COLOR,
|
||||||
|
..Default::default()
|
||||||
|
})?)
|
||||||
|
.load_op(vk::AttachmentLoadOp::LOAD)
|
||||||
|
.store_op(vk::AttachmentStoreOp::STORE);
|
||||||
|
|
||||||
|
cmd.begin_rendering(
|
||||||
|
vk::RenderingInfo::default()
|
||||||
|
.color_attachments(core::slice::from_ref(color_attachment))
|
||||||
|
.layer_count(1)
|
||||||
|
.render_area(vk::Rect2D::default().extent(target.extent_2d())),
|
||||||
|
);
|
||||||
|
|
||||||
|
cmd.set_scissors(&[vk::Rect2D::default()
|
||||||
|
.offset(vk::Offset2D::default())
|
||||||
|
.extent(target.extent_2d())]);
|
||||||
|
|
||||||
|
cmd.set_viewport(&[vk::Viewport::default()
|
||||||
|
.x(0.0)
|
||||||
|
.y(0.0)
|
||||||
|
.min_depth(0.0)
|
||||||
|
.max_depth(1.0)
|
||||||
|
.width(target.width() as f32)
|
||||||
|
.height(target.height() as f32)]);
|
||||||
|
|
||||||
cmd.bind_pipeline(&pipeline);
|
cmd.bind_pipeline(&pipeline);
|
||||||
cmd.bind_indices(indices.buffer(), 0, vk::IndexType::UINT32);
|
cmd.bind_indices(indices.buffer(), 0, vk::IndexType::UINT32);
|
||||||
cmd.bind_vertices(vertices.buffer(), 0);
|
cmd.bind_vertices(vertices.buffer(), 0);
|
||||||
|
@ -696,6 +720,9 @@ pub fn egui_pass(
|
||||||
num_draw_calls as u32,
|
num_draw_calls as u32,
|
||||||
size_of::<vk::DrawIndexedIndirectCommand>() as u32,
|
size_of::<vk::DrawIndexedIndirectCommand>() as u32,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
cmd.end_rendering();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
device::{self, DeviceOwned},
|
device::{self, DeviceOwned},
|
||||||
images::{self, Image, ImageDesc},
|
images::{self, Image, ImageDesc},
|
||||||
sync,
|
sync,
|
||||||
util::{self, Rgba},
|
util::{self, Rgba, WithLifetime},
|
||||||
SwapchainFrame,
|
SwapchainFrame,
|
||||||
};
|
};
|
||||||
use ash::vk;
|
use ash::vk;
|
||||||
|
@ -63,6 +63,7 @@ impl RenderContext<'_> {
|
||||||
self.resources.get(&id).and_then(|res| match res {
|
self.resources.get(&id).and_then(|res| match res {
|
||||||
GraphResource::ImportedImage(arc) => Some(arc),
|
GraphResource::ImportedImage(arc) => Some(arc),
|
||||||
GraphResource::Image(image) => Some(image),
|
GraphResource::Image(image) => Some(image),
|
||||||
|
GraphResource::Framebuffer(fb) => Some(&fb.image),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -147,26 +148,33 @@ impl Access {
|
||||||
}
|
}
|
||||||
pub fn color_attachment_read_only() -> Self {
|
pub fn color_attachment_read_only() -> Self {
|
||||||
Self {
|
Self {
|
||||||
stage: vk::PipelineStageFlags2::FRAGMENT_SHADER,
|
stage: vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
|
||||||
mask: vk::AccessFlags2::COLOR_ATTACHMENT_READ,
|
mask: vk::AccessFlags2::COLOR_ATTACHMENT_READ,
|
||||||
layout: Some(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL),
|
layout: Some(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn color_attachment_write_only() -> Self {
|
pub fn color_attachment_write_only() -> Self {
|
||||||
Self {
|
Self {
|
||||||
stage: vk::PipelineStageFlags2::FRAGMENT_SHADER,
|
stage: vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
|
||||||
mask: vk::AccessFlags2::COLOR_ATTACHMENT_WRITE,
|
mask: vk::AccessFlags2::COLOR_ATTACHMENT_WRITE,
|
||||||
layout: Some(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL),
|
layout: Some(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn color_attachment_read_write() -> Self {
|
pub fn color_attachment_read_write() -> Self {
|
||||||
Self {
|
Self {
|
||||||
stage: vk::PipelineStageFlags2::FRAGMENT_SHADER,
|
stage: vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
|
||||||
mask: vk::AccessFlags2::COLOR_ATTACHMENT_WRITE
|
mask: vk::AccessFlags2::COLOR_ATTACHMENT_WRITE
|
||||||
| vk::AccessFlags2::COLOR_ATTACHMENT_READ,
|
| vk::AccessFlags2::COLOR_ATTACHMENT_READ,
|
||||||
layout: Some(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL),
|
layout: Some(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn present() -> Self {
|
||||||
|
Self {
|
||||||
|
stage: vk::PipelineStageFlags2::NONE,
|
||||||
|
mask: vk::AccessFlags2::empty(),
|
||||||
|
layout: Some(vk::ImageLayout::PRESENT_SRC_KHR),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type RecordFn = dyn FnOnce(&RenderContext) -> crate::Result<()> + Send;
|
pub type RecordFn = dyn FnOnce(&RenderContext) -> crate::Result<()> + Send;
|
||||||
|
@ -181,6 +189,16 @@ pub struct PassDesc {
|
||||||
pub record: Box<RecordFn>,
|
pub record: Box<RecordFn>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for PassDesc {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
reads: Default::default(),
|
||||||
|
writes: Default::default(),
|
||||||
|
record: Box::new(|_| Ok(())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Debug for PassDesc {
|
impl Debug for PassDesc {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
f.debug_struct("PassDesc")
|
f.debug_struct("PassDesc")
|
||||||
|
@ -254,6 +272,7 @@ impl RenderGraph {
|
||||||
pub fn import_framebuffer(&mut self, frame: Arc<SwapchainFrame>) -> GraphResourceId {
|
pub fn import_framebuffer(&mut self, frame: Arc<SwapchainFrame>) -> GraphResourceId {
|
||||||
let id = GraphResourceId::new();
|
let id = GraphResourceId::new();
|
||||||
self.resources.insert(id, GraphResource::Framebuffer(frame));
|
self.resources.insert(id, GraphResource::Framebuffer(frame));
|
||||||
|
self.mark_as_output(id);
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
pub fn add_pass(&mut self, pass: PassDesc) {
|
pub fn add_pass(&mut self, pass: PassDesc) {
|
||||||
|
@ -266,9 +285,10 @@ impl RenderGraph {
|
||||||
pub fn resolve(
|
pub fn resolve(
|
||||||
&mut self,
|
&mut self,
|
||||||
device: device::Device,
|
device: device::Device,
|
||||||
) -> crate::Result<BTreeMap<GraphResourceId, GraphResource>> {
|
) -> crate::Result<WithLifetime<'_, commands::CommandList<commands::SingleUseCommand>>> {
|
||||||
// create internal resources:
|
// create internal resources:
|
||||||
for (&id, desc) in self.resource_descs.iter() {
|
for (&id, desc) in self.resource_descs.iter() {
|
||||||
|
tracing::trace!("creating resource {id:?} with {desc:?}");
|
||||||
match desc.clone() {
|
match desc.clone() {
|
||||||
GraphResourceDesc::Image(image_desc) => {
|
GraphResourceDesc::Image(image_desc) => {
|
||||||
self.resources.insert(
|
self.resources.insert(
|
||||||
|
@ -285,7 +305,6 @@ impl RenderGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("{:#?}", &self);
|
|
||||||
let mut dag = petgraph::stable_graph::StableDiGraph::new();
|
let mut dag = petgraph::stable_graph::StableDiGraph::new();
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
@ -319,6 +338,7 @@ impl RenderGraph {
|
||||||
|
|
||||||
for (rid, after) in read_accesses {
|
for (rid, after) in read_accesses {
|
||||||
if let Some(&(other, before)) = last_write.get(&rid) {
|
if let Some(&(other, before)) = last_write.get(&rid) {
|
||||||
|
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)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -432,23 +452,29 @@ impl RenderGraph {
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for ((from, to), edge) in edges {
|
for ((from, to), edge) in edges {
|
||||||
|
tracing::trace!(
|
||||||
|
"adding additional edge between {from:?} and {to:?} for {:?} with ({:?} -> {:?})",
|
||||||
|
edge.0,
|
||||||
|
edge.1 .0,
|
||||||
|
edge.1 .1
|
||||||
|
);
|
||||||
dag.add_edge(from, to, edge);
|
dag.add_edge(from, to, edge);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(debug_assertions, test))]
|
// #[cfg(any(debug_assertions, test))]
|
||||||
std::fs::write(
|
// std::fs::write(
|
||||||
"render_graph.dot",
|
// "render_graph.dot",
|
||||||
&format!(
|
// &format!(
|
||||||
"{:?}",
|
// "{:?}",
|
||||||
petgraph::dot::Dot::with_attr_getters(
|
// petgraph::dot::Dot::with_attr_getters(
|
||||||
&dag,
|
// &dag,
|
||||||
&[],
|
// &[],
|
||||||
&|_graph, edgeref| { format!("label = \"{:?}\"", edgeref.weight()) },
|
// &|_graph, edgeref| { format!("label = \"{:?}\"", edgeref.weight()) },
|
||||||
&|_graph, noderef| { format!("label = \"Pass({:?})\"", noderef.weight()) }
|
// &|_graph, noderef| { format!("label = \"Pass({:?})\"", noderef.weight()) }
|
||||||
)
|
// )
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
.expect("writing render_graph repr");
|
// .expect("writing render_graph repr");
|
||||||
|
|
||||||
let mut topological_map = Vec::new();
|
let mut topological_map = Vec::new();
|
||||||
let mut top_dag = dag.clone();
|
let mut top_dag = dag.clone();
|
||||||
|
@ -457,7 +483,7 @@ impl RenderGraph {
|
||||||
loop {
|
loop {
|
||||||
let (sinks, passes): (Vec<_>, Vec<_>) = top_dag
|
let (sinks, passes): (Vec<_>, Vec<_>) = top_dag
|
||||||
.externals(petgraph::Direction::Outgoing)
|
.externals(petgraph::Direction::Outgoing)
|
||||||
.filter(|&id| id != output)
|
.filter(|&id| id != root)
|
||||||
.filter_map(|id| top_dag.node_weight(id).cloned().map(|idx| (id, idx)))
|
.filter_map(|id| top_dag.node_weight(id).cloned().map(|idx| (id, idx)))
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
|
@ -488,13 +514,12 @@ impl RenderGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
// I don't think this can currently happen with the way passes are added.
|
// I don't think this can currently happen with the way passes are added.
|
||||||
top_dag.remove_node(output);
|
top_dag.remove_node(root);
|
||||||
if top_dag.node_count() > 0 {
|
if top_dag.node_count() > 0 {
|
||||||
|
eprintln!("dag: {top_dag:?}");
|
||||||
panic!("dag is cyclic!");
|
panic!("dag is cyclic!");
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("topology: {:?}", topological_map);
|
|
||||||
|
|
||||||
let pool =
|
let pool =
|
||||||
commands::SingleUseCommandPool::new(device.clone(), device.graphics_queue().clone())?;
|
commands::SingleUseCommandPool::new(device.clone(), device.graphics_queue().clone())?;
|
||||||
|
|
||||||
|
@ -514,7 +539,7 @@ impl RenderGraph {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|i| self.pass_descs.remove(i))
|
.map(|i| core::mem::take(&mut self.pass_descs[i]))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let cmd = pool.alloc()?;
|
let cmd = pool.alloc()?;
|
||||||
|
@ -540,21 +565,32 @@ impl RenderGraph {
|
||||||
(pass.record)(&ctx)?;
|
(pass.record)(&ctx)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx.cmd.end()?;
|
||||||
crate::Result::Ok(ctx.cmd)
|
crate::Result::Ok(ctx.cmd)
|
||||||
})
|
})
|
||||||
.collect::<crate::Result<Vec<_>>>()?;
|
.collect::<crate::Result<Vec<_>>>()?;
|
||||||
|
|
||||||
let cmd_list = commands::CommandList(cmds);
|
let cmd_list = commands::CommandList(cmds);
|
||||||
let future = cmd_list.submit(None, None, Arc::new(sync::Fence::create(device.clone())?))?;
|
// let future = cmd_list.submit(None, None, Arc::new(sync::Fence::create(device.clone())?))?;
|
||||||
|
|
||||||
future.block()?;
|
// future.block()?;
|
||||||
|
|
||||||
|
// let outputs = self
|
||||||
|
// .outputs
|
||||||
|
// .iter()
|
||||||
|
// .filter_map(|id| self.resources.remove(id).map(|res| (*id, res)))
|
||||||
|
// .collect::<BTreeMap<_, _>>();
|
||||||
|
Ok(WithLifetime::new(cmd_list))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_outputs(&mut self) -> BTreeMap<GraphResourceId, GraphResource> {
|
||||||
let outputs = self
|
let outputs = self
|
||||||
.outputs
|
.outputs
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|id| self.resources.remove(id).map(|res| (*id, res)))
|
.filter_map(|id| self.resources.remove(id).map(|res| (*id, res)))
|
||||||
.collect::<BTreeMap<_, _>>();
|
.collect::<BTreeMap<_, _>>();
|
||||||
Ok(outputs)
|
|
||||||
|
outputs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transition_resource(
|
pub fn transition_resource(
|
||||||
|
@ -566,7 +602,7 @@ impl RenderGraph {
|
||||||
) {
|
) {
|
||||||
let barrier: Barrier = match res {
|
let barrier: Barrier = match res {
|
||||||
GraphResource::Framebuffer(arc) => {
|
GraphResource::Framebuffer(arc) => {
|
||||||
image_barrier(arc.image, arc.format, from, to, None).into()
|
image_barrier(arc.image.handle(), arc.image.format(), from, to, None).into()
|
||||||
}
|
}
|
||||||
GraphResource::ImportedImage(arc) => {
|
GraphResource::ImportedImage(arc) => {
|
||||||
image_barrier(arc.handle(), arc.format(), from, to, None).into()
|
image_barrier(arc.handle(), arc.format(), from, to, None).into()
|
||||||
|
@ -737,7 +773,7 @@ pub fn image_barrier(
|
||||||
// vk::ImageLayout::DEPTH_ATTACHMENT_OPTIMAL});
|
// vk::ImageLayout::DEPTH_ATTACHMENT_OPTIMAL});
|
||||||
// def_dummy_pass!(RenderPass: {
|
// def_dummy_pass!(RenderPass: {
|
||||||
// device::QueueFlags::GRAPHICS,
|
// device::QueueFlags::GRAPHICS,
|
||||||
// vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
|
// vk::ImageLayout::COLORiATTACHMENT_OPTIMAL,
|
||||||
// vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL});
|
// vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL});
|
||||||
// def_dummy_pass!(AsyncPass: {
|
// def_dummy_pass!(AsyncPass: {
|
||||||
// device::QueueFlags::ASYNC_COMPUTE,
|
// device::QueueFlags::ASYNC_COMPUTE,
|
||||||
|
@ -789,3 +825,40 @@ pub fn image_barrier(
|
||||||
// // graph.resolve();
|
// // graph.resolve();
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
pub fn clear_pass(rg: &mut RenderGraph, color: Rgba, target: GraphResourceId) {
|
||||||
|
let reads = [(target, Access::transfer_write())].to_vec();
|
||||||
|
let writes = [(target, Access::transfer_write())].to_vec();
|
||||||
|
|
||||||
|
let record: Box<RecordFn> = Box::new({
|
||||||
|
move |ctx| {
|
||||||
|
let target = ctx.get_image(target).unwrap();
|
||||||
|
let cmd = &ctx.cmd;
|
||||||
|
|
||||||
|
cmd.clear_color_image(
|
||||||
|
target.handle(),
|
||||||
|
target.format(),
|
||||||
|
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
||||||
|
color,
|
||||||
|
&[images::SUBRESOURCERANGE_COLOR_ALL],
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
rg.add_pass(PassDesc {
|
||||||
|
reads,
|
||||||
|
writes,
|
||||||
|
record,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn present_pass(rg: &mut RenderGraph, target: GraphResourceId) {
|
||||||
|
let record: Box<RecordFn> = Box::new(|_| Ok(()));
|
||||||
|
let reads = vec![(target, Access::present())];
|
||||||
|
let writes = vec![(target, Access::present())];
|
||||||
|
rg.add_pass(PassDesc {
|
||||||
|
reads,
|
||||||
|
writes,
|
||||||
|
record,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue