rendergraph work that is probably all for nothing
This commit is contained in:
parent
e8d4e1af98
commit
d66071f7bb
|
@ -5,17 +5,20 @@ use std::{collections::BTreeMap, fmt::Debug, sync::Arc};
|
|||
use crate::{
|
||||
buffers::{Buffer, BufferDesc},
|
||||
commands, def_monotonic_id,
|
||||
device::{self, Device, DeviceOwned},
|
||||
images::{self, Image, ImageDesc},
|
||||
device::{self, DeviceOwned},
|
||||
images::{self, Image, ImageDesc, SUBRESOURCERANGE_COLOR_ALL},
|
||||
texture,
|
||||
util::{self, Rgba},
|
||||
SwapchainFrame,
|
||||
EguiState, SwapchainFrame,
|
||||
};
|
||||
use ash::vk;
|
||||
use ash::{prelude::VkResult, vk};
|
||||
use egui::Color32;
|
||||
use itertools::Itertools;
|
||||
use petgraph::visit::NodeRef;
|
||||
|
||||
def_monotonic_id!(pub RenderGraphResourceId);
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum RenderGraphResourceDesc {
|
||||
Image(ImageDesc),
|
||||
Buffer(BufferDesc),
|
||||
|
@ -50,9 +53,10 @@ struct AttachmentInfo {
|
|||
store: StoreOp,
|
||||
}
|
||||
|
||||
pub struct RenderContext {
|
||||
pub struct RenderContext<'a> {
|
||||
device: device::Device,
|
||||
cmd: commands::SingleUseCommand,
|
||||
resources: &'a BTreeMap<RenderGraphResourceId, RenderGraphResource>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
|
@ -72,15 +76,450 @@ impl ResourceAccess {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct EguiPrePass {
|
||||
out_resources:
|
||||
BTreeMap<egui::TextureId, (RenderGraphResourceId, texture::TextureId, ResourceAccess)>,
|
||||
staging_image: Arc<Image>,
|
||||
staging_buffer: Arc<Buffer>,
|
||||
aliased_images: BTreeMap<egui::TextureId, (usize, usize, [usize; 2], Image)>,
|
||||
tessellated: Vec<egui::ClippedPrimitive>,
|
||||
texture_data: BTreeMap<egui::TextureId, egui::epaint::ImageDelta>,
|
||||
}
|
||||
|
||||
impl Debug for EguiPrePass {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("EguiPrePass")
|
||||
.field("out_resources", &self.out_resources)
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
impl EguiPrePass {
|
||||
pub fn new(
|
||||
dev: &device::Device,
|
||||
rg: &mut RenderGraph,
|
||||
textures: &mut crate::texture::TextureManager,
|
||||
egui_state: &mut EguiState,
|
||||
egui: &egui::Context,
|
||||
output: egui::FullOutput,
|
||||
) -> VkResult<Self> {
|
||||
// calculate size for staging buffer.
|
||||
// calculate size for staging image.
|
||||
// allocate resource ids for textures in tessellated list (imported from texture manager)
|
||||
// define accesses for resource ids
|
||||
for (egui_id, delta) in output
|
||||
.textures_delta
|
||||
.set
|
||||
.iter()
|
||||
.filter(|(_, image)| image.is_whole())
|
||||
{
|
||||
let image = Image::new(
|
||||
dev.clone(),
|
||||
ImageDesc {
|
||||
name: Some(format!("egui-texture-{egui_id:?}").into()),
|
||||
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::SAMPLED | vk::ImageUsageFlags::TRANSFER_DST,
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
|
||||
let tid = textures.insert_image(Arc::new(image));
|
||||
egui_state.textures.insert(
|
||||
*egui_id,
|
||||
crate::EguiTextureInfo {
|
||||
id: tid,
|
||||
options: delta.options,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
let (staging_size, image_size) = output.textures_delta.set.iter().fold(
|
||||
(0usize, 0usize),
|
||||
|(mut buffer, mut image), (_id, delta)| {
|
||||
let bytes =
|
||||
delta.image.height() * delta.image.width() * delta.image.bytes_per_pixel();
|
||||
if !delta.is_whole() {
|
||||
image = image.max(bytes);
|
||||
}
|
||||
buffer = buffer + bytes;
|
||||
|
||||
(buffer, image)
|
||||
},
|
||||
);
|
||||
|
||||
let tessellated = egui.tessellate(output.shapes, output.pixels_per_point);
|
||||
|
||||
let mut staging_buffer = Buffer::new(
|
||||
dev.clone(),
|
||||
BufferDesc {
|
||||
name: Some("egui-prepass-staging-buffer".into()),
|
||||
size: staging_size as u64,
|
||||
usage: vk::BufferUsageFlags::TRANSFER_SRC,
|
||||
queue_families: device::QueueFlags::empty(),
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferHost,
|
||||
alloc_flags: vk_mem::AllocationCreateFlags::MAPPED
|
||||
| vk_mem::AllocationCreateFlags::HOST_ACCESS_SEQUENTIAL_WRITE
|
||||
| vk_mem::AllocationCreateFlags::STRATEGY_FIRST_FIT,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
let staging_image = Arc::new(Image::new(
|
||||
dev.clone(),
|
||||
ImageDesc {
|
||||
name: Some("egui-prepass-staging-buffer".into()),
|
||||
format: vk::Format::R8G8B8A8_UNORM,
|
||||
extent: vk::Extent3D {
|
||||
width: (image_size / 2) as u32,
|
||||
height: (image_size - (image_size / 2)) as u32,
|
||||
depth: 1,
|
||||
},
|
||||
usage: vk::ImageUsageFlags::TRANSFER_SRC | vk::ImageUsageFlags::TRANSFER_DST,
|
||||
queue_families: device::QueueFlags::empty(),
|
||||
mem_usage: vk_mem::MemoryUsage::AutoPreferDevice,
|
||||
..Default::default()
|
||||
},
|
||||
)?);
|
||||
|
||||
let aliased_images = {
|
||||
let mut staging_map = staging_buffer.map()?;
|
||||
let mut offset = 0;
|
||||
|
||||
let aliased_images = output
|
||||
.textures_delta
|
||||
.set
|
||||
.iter()
|
||||
.filter_map(|(id, delta)| {
|
||||
let bytes =
|
||||
delta.image.height() * delta.image.width() * delta.image.bytes_per_pixel();
|
||||
|
||||
let mem = &mut staging_map[offset..offset + bytes];
|
||||
match &delta.image {
|
||||
egui::ImageData::Color(arc) => {
|
||||
let slice = unsafe {
|
||||
core::slice::from_raw_parts(
|
||||
arc.pixels.as_ptr().cast::<u8>(),
|
||||
arc.pixels.len() * size_of::<Color32>(),
|
||||
)
|
||||
};
|
||||
mem[..slice.len()].copy_from_slice(slice);
|
||||
}
|
||||
egui::ImageData::Font(font_image) => {
|
||||
for (i, c) in font_image.srgba_pixels(None).enumerate() {
|
||||
let bytes = c.to_array();
|
||||
mem[i * 4..(i + 1) * 4].copy_from_slice(&bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let old_offset = offset;
|
||||
offset += bytes;
|
||||
|
||||
if !delta.is_whole() {
|
||||
unsafe {
|
||||
let alias = staging_image
|
||||
.clone()
|
||||
.alias(ImageDesc {
|
||||
name: Some(
|
||||
format!("egui-prepass-staging-aliased-{id:?}").into(),
|
||||
),
|
||||
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();
|
||||
Some((*id, (old_offset, bytes, delta.pos.unwrap(), alias)))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<BTreeMap<_, _>>();
|
||||
|
||||
aliased_images
|
||||
};
|
||||
|
||||
let out_resources = tessellated
|
||||
.iter()
|
||||
.filter_map(|prim| {
|
||||
if let egui::epaint::Primitive::Mesh(ref mesh) = prim.primitive {
|
||||
Some(mesh.texture_id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.dedup()
|
||||
.filter_map(|egui_id| {
|
||||
egui_state
|
||||
.lookup_texture(egui_id)
|
||||
.and_then(|tid| textures.get_texture(tid).map(|image| (egui_id, tid, image)))
|
||||
})
|
||||
.map(|(egui_id, tid, image)| {
|
||||
let rid = rg.import_image(
|
||||
image,
|
||||
ResourceAccess {
|
||||
stage: vk::PipelineStageFlags2::NONE,
|
||||
mask: vk::AccessFlags2::empty(),
|
||||
layout: Some(vk::ImageLayout::GENERAL),
|
||||
},
|
||||
);
|
||||
|
||||
(
|
||||
egui_id,
|
||||
(
|
||||
rid,
|
||||
tid,
|
||||
ResourceAccess {
|
||||
stage: vk::PipelineStageFlags2::TRANSFER,
|
||||
mask: vk::AccessFlags2::TRANSFER_WRITE,
|
||||
layout: Some(vk::ImageLayout::TRANSFER_DST_OPTIMAL),
|
||||
},
|
||||
),
|
||||
)
|
||||
})
|
||||
.collect::<BTreeMap<_, _>>();
|
||||
|
||||
Ok(Self {
|
||||
aliased_images,
|
||||
staging_buffer: Arc::new(staging_buffer),
|
||||
staging_image,
|
||||
out_resources,
|
||||
tessellated,
|
||||
texture_data: output
|
||||
.textures_delta
|
||||
.set
|
||||
.into_iter()
|
||||
.collect::<BTreeMap<_, _>>(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Pass for EguiPrePass {
|
||||
fn get_read_resource_access(&self, _id: RenderGraphResourceId) -> ResourceAccess {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn get_write_resource_access(&self, id: RenderGraphResourceId) -> ResourceAccess {
|
||||
self.out_resources
|
||||
.iter()
|
||||
.find(|(_, (id2, _, _))| *id2 == id)
|
||||
.map(|(_, (_, _, access))| *access)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn get_queue_capability_requirements(&self) -> device::QueueFlags {
|
||||
device::QueueFlags::TRANSFER
|
||||
}
|
||||
|
||||
fn get_read_dependencies<'a>(&'a self) -> Box<dyn Iterator<Item = RenderGraphResourceId> + 'a> {
|
||||
Box::new([].into_iter())
|
||||
}
|
||||
|
||||
fn get_write_dependencies<'a>(
|
||||
&'a self,
|
||||
) -> Box<dyn Iterator<Item = RenderGraphResourceId> + 'a> {
|
||||
Box::new(self.out_resources.values().map(|(id, _, _)| *id))
|
||||
}
|
||||
|
||||
fn record(&self, ctx: &RenderContext) -> crate::Result<()> {
|
||||
let buffer: Barrier = buffer_barrier(
|
||||
self.staging_buffer.handle(),
|
||||
0,
|
||||
self.staging_buffer.len(),
|
||||
ResourceAccess {
|
||||
stage: vk::PipelineStageFlags2::NONE,
|
||||
mask: vk::AccessFlags2::empty(),
|
||||
layout: None,
|
||||
},
|
||||
ResourceAccess {
|
||||
stage: vk::PipelineStageFlags2::TRANSFER,
|
||||
mask: vk::AccessFlags2::TRANSFER_READ,
|
||||
layout: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
.into();
|
||||
|
||||
unsafe {
|
||||
ctx.device
|
||||
.dev()
|
||||
.cmd_pipeline_barrier2(ctx.cmd.buffer(), &((&buffer).into()));
|
||||
}
|
||||
|
||||
for (id, (offset, _, pos, alias)) in &self.aliased_images {
|
||||
let image: Barrier = image_barrier(
|
||||
alias.handle(),
|
||||
alias.format(),
|
||||
ResourceAccess {
|
||||
stage: vk::PipelineStageFlags2::NONE,
|
||||
mask: vk::AccessFlags2::empty(),
|
||||
layout: Some(vk::ImageLayout::UNDEFINED),
|
||||
},
|
||||
ResourceAccess {
|
||||
stage: vk::PipelineStageFlags2::TRANSFER,
|
||||
mask: vk::AccessFlags2::TRANSFER_WRITE,
|
||||
layout: Some(vk::ImageLayout::TRANSFER_DST_OPTIMAL),
|
||||
},
|
||||
None,
|
||||
)
|
||||
.into();
|
||||
|
||||
unsafe {
|
||||
ctx.device
|
||||
.dev()
|
||||
.cmd_pipeline_barrier2(ctx.cmd.buffer(), &((&image).into()));
|
||||
}
|
||||
|
||||
ctx.cmd.copy_buffer_to_image(
|
||||
self.staging_buffer.handle(),
|
||||
alias.handle(),
|
||||
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
||||
&[vk::BufferImageCopy {
|
||||
buffer_offset: *offset as u64,
|
||||
buffer_row_length: alias.width(),
|
||||
buffer_image_height: alias.height(),
|
||||
image_subresource: vk::ImageSubresourceLayers::default()
|
||||
.aspect_mask(vk::ImageAspectFlags::COLOR)
|
||||
.base_array_layer(0)
|
||||
.mip_level(0)
|
||||
.layer_count(1),
|
||||
image_offset: vk::Offset3D { x: 0, y: 0, z: 0 },
|
||||
image_extent: alias.size(),
|
||||
}],
|
||||
);
|
||||
|
||||
//self.
|
||||
let Some(RenderGraphResource::ImportedImage(texture)) = self
|
||||
.out_resources
|
||||
.get(id)
|
||||
.and_then(|(id, _, _)| ctx.resources.get(id))
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let from_barrier = image_barrier(
|
||||
alias.handle(),
|
||||
alias.format(),
|
||||
ResourceAccess {
|
||||
stage: vk::PipelineStageFlags2::TRANSFER,
|
||||
mask: vk::AccessFlags2::TRANSFER_WRITE,
|
||||
layout: Some(vk::ImageLayout::TRANSFER_DST_OPTIMAL),
|
||||
},
|
||||
ResourceAccess {
|
||||
stage: vk::PipelineStageFlags2::TRANSFER,
|
||||
mask: vk::AccessFlags2::TRANSFER_READ,
|
||||
layout: Some(vk::ImageLayout::TRANSFER_SRC_OPTIMAL),
|
||||
},
|
||||
None,
|
||||
);
|
||||
let to_barrier = image_barrier(
|
||||
texture.handle(),
|
||||
texture.format(),
|
||||
ResourceAccess {
|
||||
stage: vk::PipelineStageFlags2::NONE,
|
||||
mask: vk::AccessFlags2::empty(),
|
||||
layout: Some(vk::ImageLayout::GENERAL),
|
||||
},
|
||||
ResourceAccess {
|
||||
stage: vk::PipelineStageFlags2::TRANSFER,
|
||||
mask: vk::AccessFlags2::TRANSFER_WRITE,
|
||||
layout: Some(vk::ImageLayout::TRANSFER_DST_OPTIMAL),
|
||||
},
|
||||
None,
|
||||
);
|
||||
|
||||
unsafe {
|
||||
ctx.device.dev().cmd_pipeline_barrier2(
|
||||
ctx.cmd.buffer(),
|
||||
&vk::DependencyInfo::default()
|
||||
.image_memory_barriers(&[from_barrier, to_barrier]),
|
||||
);
|
||||
}
|
||||
ctx.cmd.copy_images(
|
||||
alias.handle(),
|
||||
vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
|
||||
texture.handle(),
|
||||
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
|
||||
&[vk::ImageCopy {
|
||||
src_subresource: vk::ImageSubresourceLayers::default()
|
||||
.aspect_mask(vk::ImageAspectFlags::COLOR)
|
||||
.base_array_layer(0)
|
||||
.mip_level(0)
|
||||
.layer_count(1),
|
||||
src_offset: vk::Offset3D { x: 0, y: 0, z: 0 },
|
||||
dst_subresource: vk::ImageSubresourceLayers::default()
|
||||
.aspect_mask(vk::ImageAspectFlags::COLOR)
|
||||
.base_array_layer(0)
|
||||
.mip_level(0)
|
||||
.layer_count(1),
|
||||
dst_offset: vk::Offset3D {
|
||||
x: pos[0] as i32,
|
||||
y: pos[1] as i32,
|
||||
z: 0,
|
||||
},
|
||||
extent: alias.size(),
|
||||
}],
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EguiRenderPass {
|
||||
descriptor_set: vk::DescriptorSet,
|
||||
vertices: Buffer,
|
||||
indices: Buffer,
|
||||
draw_calls: Buffer,
|
||||
texture_ids: Buffer,
|
||||
textures_to_free: Vec<crate::texture::TextureId>,
|
||||
num_draw_calls: usize,
|
||||
}
|
||||
|
||||
impl Pass for EguiRenderPass {
|
||||
fn get_read_resource_access(&self, id: RenderGraphResourceId) -> ResourceAccess {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_write_resource_access(&self, id: RenderGraphResourceId) -> ResourceAccess {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_queue_capability_requirements(&self) -> device::QueueFlags {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_read_dependencies<'a>(&'a self) -> Box<dyn Iterator<Item = RenderGraphResourceId> + 'a> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn get_write_dependencies<'a>(
|
||||
&'a self,
|
||||
) -> Box<dyn Iterator<Item = RenderGraphResourceId> + 'a> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn record(&self, ctx: &RenderContext) -> crate::Result<()> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Pass: Debug + Send {
|
||||
fn get_read_resource_access(&self, id: RenderGraphResourceId) -> ResourceAccess;
|
||||
fn get_write_resource_access(&self, id: RenderGraphResourceId) -> ResourceAccess;
|
||||
/// returns the layout the pass requires an image dependency to be in prior
|
||||
/// to the pass.
|
||||
fn get_layout_of_in_image_dependency(&self, id: RenderGraphResourceId) -> vk::ImageLayout;
|
||||
/// returns the layout the pass will leave an image dependency in after the
|
||||
/// pass.
|
||||
fn get_layout_of_out_image_dependency(&self, id: RenderGraphResourceId) -> vk::ImageLayout;
|
||||
/// mask of the queue capability requirements of this pass.
|
||||
fn get_queue_capability_requirements(&self) -> device::QueueFlags;
|
||||
/// returns an iterator over all (in) dependencies.
|
||||
|
@ -88,7 +527,7 @@ pub trait Pass: Debug + Send {
|
|||
fn get_write_dependencies<'a>(&'a self)
|
||||
-> Box<dyn Iterator<Item = RenderGraphResourceId> + 'a>;
|
||||
|
||||
fn record(self: Box<Self>, ctx: &RenderContext) -> crate::Result<()>;
|
||||
fn record(&self, ctx: &RenderContext) -> crate::Result<()>;
|
||||
}
|
||||
|
||||
def_monotonic_id!(pub RenderGraphPassId);
|
||||
|
@ -166,6 +605,24 @@ impl RenderGraph {
|
|||
// https://github.com/EmbarkStudios/kajiya/blob/main/crates/lib/kajiya-rg/src/graph.rs
|
||||
// https://themaister.net/blog/2017/08/15/render-graphs-and-vulkan-a-deep-dive/
|
||||
pub fn resolve(mut self, device: device::Device) -> crate::Result<()> {
|
||||
// create internal resources:
|
||||
for (&id, desc) in self.resource_descs.iter() {
|
||||
match desc.clone() {
|
||||
RenderGraphResourceDesc::Image(image_desc) => {
|
||||
self.resources.insert(
|
||||
id,
|
||||
RenderGraphResource::Image(Image::new(device.clone(), image_desc)?),
|
||||
);
|
||||
}
|
||||
RenderGraphResourceDesc::Buffer(buffer_desc) => {
|
||||
self.resources.insert(
|
||||
id,
|
||||
RenderGraphResource::Buffer(Buffer::new(device.clone(), buffer_desc)?),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eprintln!("{:#?}", &self);
|
||||
let mut last_write = BTreeMap::new();
|
||||
|
||||
|
@ -280,7 +737,8 @@ impl RenderGraph {
|
|||
let pool =
|
||||
commands::SingleUseCommandPool::new(device.clone(), device.graphics_queue().clone())?;
|
||||
|
||||
let tasks = topological_map
|
||||
let resources = &self.resources;
|
||||
let cmds = topological_map
|
||||
.iter()
|
||||
.map(|(set, accesses)| {
|
||||
let pool = pool.clone();
|
||||
|
@ -294,39 +752,43 @@ impl RenderGraph {
|
|||
|
||||
// transitions
|
||||
for (&id, &access) in accesses.iter() {
|
||||
self.transition_resource_to(device.dev(), unsafe { &cmd.buffer() }, id, access);
|
||||
Self::transition_resource_to(
|
||||
&mut self.accesses,
|
||||
resources,
|
||||
device.dev(),
|
||||
unsafe { &cmd.buffer() },
|
||||
id,
|
||||
access,
|
||||
);
|
||||
}
|
||||
|
||||
let task = smol::spawn(async move {
|
||||
let ctx = RenderContext { device, cmd };
|
||||
let ctx = RenderContext {
|
||||
device,
|
||||
cmd,
|
||||
resources,
|
||||
};
|
||||
|
||||
for pass in passes {
|
||||
pass.record(&ctx)?;
|
||||
}
|
||||
for pass in &passes {
|
||||
pass.record(&ctx)?;
|
||||
}
|
||||
|
||||
crate::Result::Ok(ctx.cmd)
|
||||
});
|
||||
|
||||
crate::Result::Ok(task)
|
||||
crate::Result::Ok(ctx.cmd)
|
||||
})
|
||||
.collect::<crate::Result<Vec<_>>>()?;
|
||||
|
||||
let commands = smol::block_on(futures::future::join_all(tasks))
|
||||
.into_iter()
|
||||
.collect::<crate::Result<Vec<_>>>()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn transition_resource_to(
|
||||
&mut self,
|
||||
accesses: &mut BTreeMap<RenderGraphResourceId, ResourceAccess>,
|
||||
resources: &BTreeMap<RenderGraphResourceId, RenderGraphResource>,
|
||||
dev: &ash::Device,
|
||||
cmd: &vk::CommandBuffer,
|
||||
id: RenderGraphResourceId,
|
||||
access: ResourceAccess,
|
||||
) {
|
||||
let old_access = self.accesses.get(&id);
|
||||
let res = self.resources.get(&id);
|
||||
let old_access = accesses.get(&id);
|
||||
let res = resources.get(&id);
|
||||
|
||||
if let (Some(&old_access), Some(res)) = (old_access, res) {
|
||||
let barrier: Barrier = match res {
|
||||
|
@ -348,7 +810,7 @@ impl RenderGraph {
|
|||
}
|
||||
};
|
||||
|
||||
self.accesses.insert(id, access);
|
||||
accesses.insert(id, access);
|
||||
|
||||
unsafe {
|
||||
dev.cmd_pipeline_barrier2(*cmd, &((&barrier).into()));
|
||||
|
@ -459,19 +921,6 @@ mod tests {
|
|||
fn get_write_resource_access(&self, _id: RenderGraphResourceId) -> ResourceAccess {
|
||||
ResourceAccess::default()
|
||||
}
|
||||
fn get_layout_of_in_image_dependency(
|
||||
&self,
|
||||
_id: RenderGraphResourceId,
|
||||
) -> vk::ImageLayout {
|
||||
$layout_in
|
||||
}
|
||||
|
||||
fn get_layout_of_out_image_dependency(
|
||||
&self,
|
||||
_id: RenderGraphResourceId,
|
||||
) -> vk::ImageLayout {
|
||||
$layout_out
|
||||
}
|
||||
|
||||
fn get_queue_capability_requirements(&self) -> device::QueueFlags {
|
||||
$queue
|
||||
|
@ -489,7 +938,7 @@ mod tests {
|
|||
Box::new(self.1.iter().cloned())
|
||||
}
|
||||
|
||||
fn record(self: Box<Self>, _ctx: &RenderContext) -> crate::Result<()> {
|
||||
fn record(&self, _ctx: &RenderContext) -> crate::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue