Skip to content

Commit 8d5f24f

Browse files
committed
Free memory objects
1 parent 185e23e commit 8d5f24f

File tree

6 files changed

+77
-30
lines changed

6 files changed

+77
-30
lines changed

src/command/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::device::{
1414
all_buffer_stages, all_image_stages,
1515
};
1616
use crate::hub::{HUB, Storage};
17+
use crate::resource::TexturePlacement;
1718
use crate::swap_chain::{SwapChainLink, SwapImageEpoch};
1819
use crate::track::TrackerSet;
1920
use crate::conv;
@@ -218,14 +219,15 @@ pub fn command_encoder_begin_render_pass(
218219
if view.is_owned_by_swap_chain {
219220
let link = match HUB.textures
220221
.read()
221-
[view.texture_id.value].swap_chain_link
222+
[view.texture_id.value].placement
222223
{
223-
Some(ref link) => SwapChainLink {
224+
TexturePlacement::SwapChain(ref link) => SwapChainLink {
224225
swap_chain_id: link.swap_chain_id.clone(),
225226
epoch: *link.epoch.lock(),
226227
image_index: link.image_index,
227228
},
228-
None => unreachable!()
229+
TexturePlacement::Memory(_) |
230+
TexturePlacement::Void => unreachable!()
229231
};
230232
swap_chain_links.push(link);
231233
}

src/command/transfer.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::device::{all_buffer_stages, all_image_stages};
22
use crate::hub::HUB;
3+
use crate::resource::TexturePlacement;
34
use crate::swap_chain::SwapChainLink;
45
use crate::conv;
56
use crate::{
@@ -135,7 +136,7 @@ pub extern "C" fn wgpu_command_buffer_copy_buffer_to_texture(
135136
range: dst_texture.full_range.clone(),
136137
});
137138

138-
if let Some(ref link) = dst_texture.swap_chain_link {
139+
if let TexturePlacement::SwapChain(ref link) = dst_texture.placement {
139140
cmb.swap_chain_links.push(SwapChainLink {
140141
swap_chain_id: link.swap_chain_id.clone(),
141142
epoch: *link.epoch.lock(),
@@ -203,7 +204,11 @@ pub extern "C" fn wgpu_command_buffer_copy_texture_to_buffer(
203204
families: None,
204205
range: src_texture.full_range.clone(),
205206
});
206-
assert!(src_texture.swap_chain_link.is_none()); //TODO
207+
match src_texture.placement {
208+
TexturePlacement::SwapChain(_) => unimplemented!(),
209+
TexturePlacement::Void => unreachable!(),
210+
TexturePlacement::Memory(_) => (),
211+
}
207212

208213
let (dst_buffer, dst_usage) = cmb.trackers.buffers
209214
.get_with_replaced_usage(
@@ -295,7 +300,7 @@ pub extern "C" fn wgpu_command_buffer_copy_texture_to_texture(
295300
range: dst_texture.full_range.clone(),
296301
});
297302

298-
if let Some(ref link) = dst_texture.swap_chain_link {
303+
if let TexturePlacement::SwapChain(ref link) = dst_texture.placement {
299304
cmb.swap_chain_links.push(SwapChainLink {
300305
swap_chain_id: link.swap_chain_id.clone(),
301306
epoch: *link.epoch.lock(),

src/device.rs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ use crate::{
77
};
88
use crate::{
99
BufferId, CommandBufferId, AdapterId, DeviceId, QueueId,
10-
TextureId, TextureViewId, SurfaceId,
10+
BindGroupId, TextureId, TextureViewId, SurfaceId,
1111
};
1212
#[cfg(feature = "local")]
1313
use crate::{
14-
BindGroupId, BindGroupLayoutId, PipelineLayoutId, SamplerId, SwapChainId,
14+
BindGroupLayoutId, PipelineLayoutId, SamplerId, SwapChainId,
1515
ShaderModuleId, CommandEncoderId, RenderPipelineId, ComputePipelineId,
1616
};
1717

@@ -78,8 +78,8 @@ enum ResourceId {
7878
}
7979

8080
enum NativeResource<B: hal::Backend> {
81-
Buffer(B::Buffer),
82-
Image(B::Image),
81+
Buffer(B::Buffer, B::Memory),
82+
Image(B::Image, B::Memory),
8383
ImageView(B::ImageView),
8484
Framebuffer(B::Framebuffer),
8585
}
@@ -140,17 +140,19 @@ impl<B: hal::Backend> DestroyedResources<B> {
140140

141141
for resource in self.free.drain(..) {
142142
match resource {
143-
NativeResource::Buffer(raw) => unsafe {
144-
device.destroy_buffer(raw)
143+
NativeResource::Buffer(raw, memory) => unsafe {
144+
device.destroy_buffer(raw);
145+
device.free_memory(memory);
145146
},
146-
NativeResource::Image(raw) => unsafe {
147-
device.destroy_image(raw)
147+
NativeResource::Image(raw, memory) => unsafe {
148+
device.destroy_image(raw);
149+
device.free_memory(memory);
148150
},
149151
NativeResource::ImageView(raw) => unsafe {
150-
device.destroy_image_view(raw)
152+
device.destroy_image_view(raw);
151153
},
152154
NativeResource::Framebuffer(raw) => unsafe {
153-
device.destroy_framebuffer(raw)
155+
device.destroy_framebuffer(raw);
154156
},
155157
}
156158
}
@@ -177,12 +179,18 @@ impl DestroyedResources<back::Backend> {
177179
ResourceId::Buffer(id) => {
178180
trackers.buffers.remove(id);
179181
let buf = HUB.buffers.unregister(id);
180-
(buf.life_guard, NativeResource::Buffer(buf.raw))
182+
(buf.life_guard, NativeResource::Buffer(buf.raw, buf.memory))
181183
}
182184
ResourceId::Texture(id) => {
183185
trackers.textures.remove(id);
184186
let tex = HUB.textures.unregister(id);
185-
(tex.life_guard, NativeResource::Image(tex.raw))
187+
let memory = match tex.placement {
188+
// swapchain-owned images don't need explicit destruction
189+
resource::TexturePlacement::SwapChain(_) => continue,
190+
resource::TexturePlacement::Memory(mem) => mem,
191+
resource::TexturePlacement::Void => unreachable!(),
192+
};
193+
(tex.life_guard, NativeResource::Image(tex.raw, memory))
186194
}
187195
ResourceId::TextureView(id) => {
188196
trackers.views.remove(id);
@@ -555,7 +563,7 @@ pub fn device_create_texture(
555563
levels: 0 .. 1, //TODO: mips
556564
layers: 0 .. desc.array_size as u16,
557565
},
558-
swap_chain_link: None,
566+
placement: resource::TexturePlacement::Memory(memory),
559567
life_guard: LifeGuard::new(),
560568
}
561569
}
@@ -940,6 +948,11 @@ pub extern "C" fn wgpu_device_create_bind_group(
940948
HUB.bind_groups.register_local(bind_group)
941949
}
942950

951+
#[no_mangle]
952+
pub extern "C" fn wgpu_bind_group_destroy(bind_group_id: BindGroupId) {
953+
HUB.bind_groups.unregister(bind_group_id);
954+
}
955+
943956

944957
pub fn device_create_shader_module(
945958
device_id: DeviceId,
@@ -1029,6 +1042,7 @@ pub extern "C" fn wgpu_queue_submit(
10291042
let mut command_buffer_guard = HUB.command_buffers.write();
10301043
let buffer_guard = HUB.buffers.read();
10311044
let texture_guard = HUB.textures.read();
1045+
let texture_view_guard = HUB.texture_views.read();
10321046

10331047
// finish all the command buffers first
10341048
for &cmb_id in command_buffer_ids {
@@ -1045,6 +1059,10 @@ pub extern "C" fn wgpu_queue_submit(
10451059
texture_guard[id].life_guard.submission_index
10461060
.store(old_submit_index, Ordering::Release);
10471061
}
1062+
for id in comb.trackers.views.used() {
1063+
texture_view_guard[id].life_guard.submission_index
1064+
.store(old_submit_index, Ordering::Release);
1065+
}
10481066

10491067
// execute resource transitions
10501068
let mut transit = device.com_allocator.extend(comb);
@@ -1519,7 +1537,7 @@ pub fn device_create_swap_chain(
15191537
levels: 0 .. 1,
15201538
layers: 0 .. 1,
15211539
},
1522-
swap_chain_link: None,
1540+
placement: resource::TexturePlacement::Void,
15231541
life_guard: LifeGuard::new(),
15241542
})
15251543
.collect()
@@ -1553,7 +1571,7 @@ pub fn swap_chain_populate_textures(
15531571
)
15541572
.unwrap()
15551573
};
1556-
texture.swap_chain_link = Some(swap_chain::SwapChainLink {
1574+
texture.placement = resource::TexturePlacement::SwapChain(swap_chain::SwapChainLink {
15571575
swap_chain_id, //TODO: strongly
15581576
epoch: Mutex::new(0),
15591577
image_index: i as hal::SwapImageIndex,

src/resource.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,29 @@ pub struct TextureDescriptor {
105105
pub usage: TextureUsageFlags,
106106
}
107107

108+
pub(crate) enum TexturePlacement<B: hal::Backend> {
109+
SwapChain(SwapChainLink<Mutex<SwapImageEpoch>>),
110+
Memory(B::Memory),
111+
Void,
112+
}
113+
114+
impl<B: hal::Backend> TexturePlacement<B> {
115+
pub fn as_swap_chain(&self) -> &SwapChainLink<Mutex<SwapImageEpoch>> {
116+
match *self {
117+
TexturePlacement::SwapChain(ref link) => link,
118+
TexturePlacement::Memory(_) |
119+
TexturePlacement::Void => panic!("Expected swap chain link!"),
120+
}
121+
}
122+
}
123+
108124
pub struct Texture<B: hal::Backend> {
109125
pub(crate) raw: B::Image,
110126
pub(crate) device_id: Stored<DeviceId>,
111127
pub(crate) kind: hal::image::Kind,
112128
pub(crate) format: TextureFormat,
113129
pub(crate) full_range: hal::image::SubresourceRange,
114-
pub(crate) swap_chain_link: Option<SwapChainLink<Mutex<SwapImageEpoch>>>,
130+
pub(crate) placement: TexturePlacement<B>,
115131
pub(crate) life_guard: LifeGuard,
116132
}
117133

src/swap_chain.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::track::{TrackPermit};
1010
use hal;
1111
use hal::{Device as _Device, Swapchain as _Swapchain};
1212
use log::{trace, warn};
13+
use parking_lot::Mutex;
1314

1415
use std::{iter, mem};
1516

@@ -22,6 +23,12 @@ pub(crate) struct SwapChainLink<E> {
2223
pub image_index: hal::SwapImageIndex,
2324
}
2425

26+
impl SwapChainLink<Mutex<SwapImageEpoch>> {
27+
pub fn bump_epoch(&self) {
28+
*self.epoch.lock() += 1;
29+
}
30+
}
31+
2532
pub struct Surface<B: hal::Backend> {
2633
pub(crate) raw: B::Surface,
2734
pub(crate) swap_chain: Option<SwapChain<B>>,
@@ -144,10 +151,7 @@ pub extern "C" fn wgpu_swap_chain_get_next_texture(
144151
}
145152
mem::swap(&mut frame.sem_available, &mut swap_chain.sem_available);
146153

147-
match HUB.textures.read()[frame.texture_id.value].swap_chain_link {
148-
Some(ref link) => *link.epoch.lock() += 1,
149-
None => unreachable!(),
150-
}
154+
HUB.textures.read()[frame.texture_id.value].placement.as_swap_chain().bump_epoch();
151155

152156
SwapChainOutput {
153157
texture_id: frame.texture_id.value,
@@ -173,10 +177,7 @@ pub extern "C" fn wgpu_swap_chain_present(
173177

174178
let texture_guard = HUB.textures.read();
175179
let texture = &texture_guard[frame.texture_id.value];
176-
match texture.swap_chain_link {
177-
Some(ref link) => *link.epoch.lock() += 1,
178-
None => unreachable!(),
179-
}
180+
texture.placement.as_swap_chain().bump_epoch();
180181

181182
//TODO: support for swapchain being sampled or read by the shader?
182183

src/track.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ impl<I: NewId> DummyTracker<I> {
144144
self.query(I::new(index, epoch), ref_count);
145145
}
146146
}
147+
148+
/// Return an iterator over used resources keys.
149+
pub fn used<'a>(&'a self) -> impl 'a + Iterator<Item = I> {
150+
self.map.iter().map(|(&index, &(_, epoch))| I::new(index, epoch))
151+
}
147152
}
148153

149154
impl<I: NewId, U: Copy + GenericUsage + BitOr<Output = U> + PartialEq> Tracker<I, U> {

0 commit comments

Comments
 (0)