Skip to content

Commit 2d73eb3

Browse files
committed
[vk] move framebuffer cache into CommandEncoder
This makes texture view destruction cheap since users of wgpu-hal are required to keep resources referenced by encoders alive for at least as long as the encoder is alive. This is also a prerequisite to implement rendering to slices of 3D textures (by creating temporary texture views). On the other hand the cache won't be as effective but that is probably ok, we can reevaluate the implementation if it turns out to be a problem.
1 parent da8ff2a commit 2d73eb3

File tree

4 files changed

+37
-44
lines changed

4 files changed

+37
-44
lines changed

wgpu-hal/src/vulkan/adapter.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2054,7 +2054,6 @@ impl super::Adapter {
20542054
features,
20552055
workarounds: self.workarounds,
20562056
render_passes: Mutex::new(Default::default()),
2057-
framebuffers: Mutex::new(Default::default()),
20582057
sampler_cache: Mutex::new(super::sampler::SamplerCache::new(
20592058
self.private_caps.maximum_samplers,
20602059
)),

wgpu-hal/src/vulkan/command.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
use super::conv;
2-
32
use arrayvec::ArrayVec;
43
use ash::vk;
5-
64
use core::{mem, ops::Range};
5+
use hashbrown::hash_map::Entry;
76

87
const ALLOCATION_GRANULARITY: u32 = 16;
98
const DST_IMAGE_LAYOUT: vk::ImageLayout = vk::ImageLayout::TRANSFER_DST_OPTIMAL;
@@ -52,6 +51,26 @@ impl super::CommandEncoder {
5251
}
5352
}
5453
}
54+
55+
fn make_framebuffer(
56+
&mut self,
57+
key: super::FramebufferKey,
58+
) -> Result<vk::Framebuffer, crate::DeviceError> {
59+
Ok(match self.framebuffers.entry(key) {
60+
Entry::Occupied(e) => *e.get(),
61+
Entry::Vacant(e) => {
62+
let vk_info = vk::FramebufferCreateInfo::default()
63+
.render_pass(e.key().raw_pass)
64+
.width(e.key().extent.width)
65+
.height(e.key().extent.height)
66+
.layers(e.key().extent.depth_or_array_layers)
67+
.attachments(&e.key().attachments);
68+
69+
let raw = unsafe { self.device.raw.create_framebuffer(&vk_info, None).unwrap() };
70+
*e.insert(raw)
71+
}
72+
})
73+
}
5574
}
5675

5776
impl crate::CommandEncoder for super::CommandEncoder {
@@ -796,7 +815,7 @@ impl crate::CommandEncoder for super::CommandEncoder {
796815

797816
let raw_pass = self.device.make_render_pass(rp_key).unwrap();
798817
fb_key.raw_pass = raw_pass;
799-
let raw_framebuffer = self.device.make_framebuffer(fb_key).unwrap();
818+
let raw_framebuffer = self.make_framebuffer(fb_key).unwrap();
800819

801820
let vk_info = vk::RenderPassBeginInfo::default()
802821
.render_pass(raw_pass)

wgpu-hal/src/vulkan/device.rs

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -202,26 +202,6 @@ impl super::DeviceShared {
202202
})
203203
}
204204

205-
pub fn make_framebuffer(
206-
&self,
207-
key: super::FramebufferKey,
208-
) -> Result<vk::Framebuffer, crate::DeviceError> {
209-
Ok(match self.framebuffers.lock().entry(key) {
210-
Entry::Occupied(e) => *e.get(),
211-
Entry::Vacant(e) => {
212-
let vk_info = vk::FramebufferCreateInfo::default()
213-
.render_pass(e.key().raw_pass)
214-
.width(e.key().extent.width)
215-
.height(e.key().extent.height)
216-
.layers(e.key().extent.depth_or_array_layers)
217-
.attachments(&e.key().attachments);
218-
219-
let raw = unsafe { self.raw.create_framebuffer(&vk_info, None).unwrap() };
220-
*e.insert(raw)
221-
}
222-
})
223-
}
224-
225205
fn make_memory_ranges<'a, I: 'a + Iterator<Item = crate::MemoryRange>>(
226206
&self,
227207
buffer: &'a super::Buffer,
@@ -1312,15 +1292,6 @@ impl crate::Device for super::Device {
13121292
})
13131293
}
13141294
unsafe fn destroy_texture_view(&self, view: super::TextureView) {
1315-
{
1316-
let mut fbuf_lock = self.shared.framebuffers.lock();
1317-
for (key, &raw_fbuf) in fbuf_lock.iter() {
1318-
if key.attachments.iter().any(|at_view| *at_view == view.raw) {
1319-
unsafe { self.shared.raw.destroy_framebuffer(raw_fbuf, None) };
1320-
}
1321-
}
1322-
fbuf_lock.retain(|key, _| !key.attachments.iter().any(|at_view| *at_view == view.raw));
1323-
}
13241295
unsafe { self.shared.raw.destroy_image_view(view.raw, None) };
13251296

13261297
self.counters.texture_views.sub(1);
@@ -1413,6 +1384,7 @@ impl crate::Device for super::Device {
14131384
discarded: Vec::new(),
14141385
rpass_debug_marker_active: false,
14151386
end_of_pass_timer_query: None,
1387+
framebuffers: Default::default(),
14161388
counters: Arc::clone(&self.counters),
14171389
})
14181390
}

wgpu-hal/src/vulkan/mod.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -602,13 +602,6 @@ struct RenderPassKey {
602602
multiview: Option<NonZeroU32>,
603603
}
604604

605-
#[derive(Clone, Eq, Hash, PartialEq)]
606-
struct FramebufferKey {
607-
raw_pass: vk::RenderPass,
608-
attachments: ArrayVec<vk::ImageView, { MAX_TOTAL_ATTACHMENTS }>,
609-
extent: wgt::Extent3d,
610-
}
611-
612605
struct DeviceShared {
613606
raw: ash::Device,
614607
family_index: u32,
@@ -626,7 +619,6 @@ struct DeviceShared {
626619
workarounds: Workarounds,
627620
features: wgt::Features,
628621
render_passes: Mutex<FastHashMap<RenderPassKey, vk::RenderPass>>,
629-
framebuffers: Mutex<FastHashMap<FramebufferKey, vk::Framebuffer>>,
630622
sampler_cache: Mutex<sampler::SamplerCache>,
631623
memory_allocations_counter: InternalCounter,
632624
}
@@ -636,9 +628,6 @@ impl Drop for DeviceShared {
636628
for &raw in self.render_passes.lock().values() {
637629
unsafe { self.raw.destroy_render_pass(raw, None) };
638630
}
639-
for &raw in self.framebuffers.lock().values() {
640-
unsafe { self.raw.destroy_framebuffer(raw, None) };
641-
}
642631
if self.drop_guard.is_none() {
643632
unsafe { self.raw.destroy_device(None) };
644633
}
@@ -874,6 +863,13 @@ impl Temp {
874863
}
875864
}
876865

866+
#[derive(Clone, Eq, Hash, PartialEq)]
867+
struct FramebufferKey {
868+
raw_pass: vk::RenderPass,
869+
attachments: ArrayVec<vk::ImageView, { MAX_TOTAL_ATTACHMENTS }>,
870+
extent: wgt::Extent3d,
871+
}
872+
877873
pub struct CommandEncoder {
878874
raw: vk::CommandPool,
879875
device: Arc<DeviceShared>,
@@ -910,6 +906,8 @@ pub struct CommandEncoder {
910906
/// the given pool & location.
911907
end_of_pass_timer_query: Option<(vk::QueryPool, u32)>,
912908

909+
framebuffers: FastHashMap<FramebufferKey, vk::Framebuffer>,
910+
913911
counters: Arc<wgt::HalCounters>,
914912
}
915913

@@ -931,6 +929,11 @@ impl Drop for CommandEncoder {
931929
// fields.
932930
self.device.raw.destroy_command_pool(self.raw, None);
933931
}
932+
933+
for (_, fb) in self.framebuffers.drain() {
934+
unsafe { self.device.raw.destroy_framebuffer(fb, None) };
935+
}
936+
934937
self.counters.command_encoders.sub(1);
935938
}
936939
}

0 commit comments

Comments
 (0)