Skip to content

Commit 616a3dd

Browse files
committed
Fix leaking swapchain textures
1 parent cfe3da1 commit 616a3dd

File tree

2 files changed

+31
-10
lines changed

2 files changed

+31
-10
lines changed

wgpu-native/src/device.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ use crate::{
1515
};
1616

1717
use back;
18+
use hal::backend::FastHashMap;
1819
use hal::command::RawCommandBuffer;
1920
use hal::queue::RawCommandQueue;
20-
use hal::{self,
21+
use hal::{
22+
self,
2123
DescriptorPool as _DescriptorPool,
2224
Device as _Device,
2325
Surface as _Surface,
@@ -27,7 +29,7 @@ use log::{info, trace};
2729
use parking_lot::{Mutex};
2830

2931
use std::{ffi, iter, slice};
30-
use std::collections::hash_map::{Entry, HashMap};
32+
use std::collections::hash_map::Entry;
3133
use std::sync::atomic::Ordering;
3234

3335

@@ -64,7 +66,7 @@ pub(crate) struct FramebufferKey {
6466
}
6567
impl Eq for FramebufferKey {}
6668

67-
#[derive(Debug)]
69+
#[derive(Debug, PartialEq)]
6870
enum ResourceId {
6971
Buffer(BufferId),
7072
Texture(TextureId),
@@ -100,6 +102,7 @@ unsafe impl<B: hal::Backend> Sync for DestroyedResources<B> {}
100102

101103
impl<B: hal::Backend> DestroyedResources<B> {
102104
fn add(&mut self, resource_id: ResourceId, ref_count: RefCount) {
105+
debug_assert!(!self.referenced.iter().any(|r| r.0 == resource_id));
103106
self.referenced.push((resource_id, ref_count));
104107
}
105108

@@ -195,8 +198,8 @@ pub struct Device<B: hal::Backend> {
195198
life_guard: LifeGuard,
196199
pub(crate) trackers: Mutex<TrackerSet>,
197200
mem_props: hal::MemoryProperties,
198-
pub(crate) render_passes: Mutex<HashMap<RenderPassKey, B::RenderPass>>,
199-
pub(crate) framebuffers: Mutex<HashMap<FramebufferKey, B::Framebuffer>>,
201+
pub(crate) render_passes: Mutex<FastHashMap<RenderPassKey, B::RenderPass>>,
202+
pub(crate) framebuffers: Mutex<FastHashMap<FramebufferKey, B::Framebuffer>>,
200203
desc_pool: Mutex<B::DescriptorPool>,
201204
destroyed: Mutex<DestroyedResources<B>>,
202205
}
@@ -269,8 +272,8 @@ impl<B: hal::Backend> Device<B> {
269272
life_guard,
270273
trackers: Mutex::new(TrackerSet::new()),
271274
mem_props,
272-
render_passes: Mutex::new(HashMap::new()),
273-
framebuffers: Mutex::new(HashMap::new()),
275+
render_passes: Mutex::new(FastHashMap::default()),
276+
framebuffers: Mutex::new(FastHashMap::default()),
274277
desc_pool,
275278
destroyed: Mutex::new(DestroyedResources {
276279
referenced: Vec::new(),
@@ -1380,7 +1383,12 @@ pub fn device_create_swap_chain(
13801383

13811384
let (old_raw, sem_available, command_pool) = match surface.swap_chain.take() {
13821385
Some(mut old) => {
1386+
let mut destroyed = device.destroyed.lock();
13831387
assert_eq!(old.device_id.value, device_id);
1388+
for frame in old.frames {
1389+
destroyed.add(ResourceId::Texture(frame.texture_id.value), frame.texture_id.ref_count);
1390+
destroyed.add(ResourceId::TextureView(frame.view_id.value), frame.view_id.ref_count);
1391+
}
13841392
unsafe {
13851393
old.command_pool.reset()
13861394
};

wgpu-rs/src/lib.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ pub struct Buffer {
5454

5555
pub struct Texture {
5656
id: wgn::TextureId,
57+
owned: bool,
5758
}
5859

5960
pub struct TextureView {
6061
id: wgn::TextureViewId,
62+
owned: bool,
6163
}
6264

6365
pub struct Sampler {
@@ -427,6 +429,7 @@ impl Device {
427429
pub fn create_texture(&self, desc: &TextureDescriptor) -> Texture {
428430
Texture {
429431
id: wgn::wgpu_device_create_texture(self.id, desc),
432+
owned: true,
430433
}
431434
}
432435

@@ -467,25 +470,31 @@ impl Texture {
467470
pub fn create_view(&self, desc: &TextureViewDescriptor) -> TextureView {
468471
TextureView {
469472
id: wgn::wgpu_texture_create_view(self.id, desc),
473+
owned: true,
470474
}
471475
}
472476

473477
pub fn create_default_view(&self) -> TextureView {
474478
TextureView {
475479
id: wgn::wgpu_texture_create_default_view(self.id),
480+
owned: true,
476481
}
477482
}
478483
}
479484

480485
impl Drop for Texture {
481486
fn drop(&mut self) {
482-
wgn::wgpu_texture_destroy(self.id);
487+
if self.owned {
488+
wgn::wgpu_texture_destroy(self.id);
489+
}
483490
}
484491
}
485492

486493
impl Drop for TextureView {
487494
fn drop(&mut self) {
488-
wgn::wgpu_texture_view_destroy(self.id);
495+
if self.owned {
496+
wgn::wgpu_texture_view_destroy(self.id);
497+
}
489498
}
490499
}
491500

@@ -707,8 +716,12 @@ impl SwapChain {
707716
SwapChainOutput {
708717
texture: Texture {
709718
id: output.texture_id,
719+
owned: false,
720+
},
721+
view: TextureView {
722+
id: output.view_id,
723+
owned: false,
710724
},
711-
view: TextureView { id: output.view_id },
712725
swap_chain_id: &self.id,
713726
}
714727
}

0 commit comments

Comments
 (0)