ursus_core/render/resource/
layout_tracker.rs1use crate::render::resource::desc::ResourceHandle;
2use crate::render::resource::make_barrier;
3use crate::render::resource::pool::ResourcePool;
4use ash::vk;
5use std::collections::HashMap;
6
7pub struct LayoutTracker {
8 layouts: HashMap<ResourceHandle, vk::ImageLayout>,
9 scratch: Vec<vk::ImageMemoryBarrier2<'static>>,
10}
11
12impl LayoutTracker {
13 pub fn new() -> Self {
14 Self { layouts: HashMap::new(), scratch: Vec::new() }
15 }
16
17 pub fn current(&self, handle: ResourceHandle) -> vk::ImageLayout {
18 self.layouts.get(&handle).copied().unwrap_or(vk::ImageLayout::UNDEFINED)
19 }
20
21 pub fn set(&mut self, handle: ResourceHandle, layout: vk::ImageLayout) {
22 self.layouts.insert(handle, layout);
23 }
24
25 pub fn plan_transition(
30 &mut self,
31 pool: &ResourcePool,
32 transitions: impl IntoIterator<Item = (ResourceHandle, vk::ImageLayout)>,
33 ) -> &[vk::ImageMemoryBarrier2<'static>] {
34 self.scratch.clear();
35 for (handle, new_layout) in transitions {
36 let old_layout = self.current(handle);
37 if old_layout == new_layout {
38 continue;
39 }
40 let img = pool.image(handle);
41 self.scratch.push(make_barrier(img.image, img.kind, old_layout, new_layout));
42 self.layouts.insert(handle, new_layout);
43 }
44 &self.scratch
45 }
46
47 pub fn invalidate(&mut self, handles: &[ResourceHandle]) {
48 for h in handles {
49 self.layouts.insert(*h, vk::ImageLayout::UNDEFINED);
50 }
51 }
52}
53
54impl Default for LayoutTracker {
55 fn default() -> Self {
56 Self::new()
57 }
58}