mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Free memory objects
This commit is contained in:
@@ -14,6 +14,7 @@ use crate::device::{
|
||||
all_buffer_stages, all_image_stages,
|
||||
};
|
||||
use crate::hub::{HUB, Storage};
|
||||
use crate::resource::TexturePlacement;
|
||||
use crate::swap_chain::{SwapChainLink, SwapImageEpoch};
|
||||
use crate::track::TrackerSet;
|
||||
use crate::conv;
|
||||
@@ -218,14 +219,15 @@ pub fn command_encoder_begin_render_pass(
|
||||
if view.is_owned_by_swap_chain {
|
||||
let link = match HUB.textures
|
||||
.read()
|
||||
[view.texture_id.value].swap_chain_link
|
||||
[view.texture_id.value].placement
|
||||
{
|
||||
Some(ref link) => SwapChainLink {
|
||||
TexturePlacement::SwapChain(ref link) => SwapChainLink {
|
||||
swap_chain_id: link.swap_chain_id.clone(),
|
||||
epoch: *link.epoch.lock(),
|
||||
image_index: link.image_index,
|
||||
},
|
||||
None => unreachable!()
|
||||
TexturePlacement::Memory(_) |
|
||||
TexturePlacement::Void => unreachable!()
|
||||
};
|
||||
swap_chain_links.push(link);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::device::{all_buffer_stages, all_image_stages};
|
||||
use crate::hub::HUB;
|
||||
use crate::resource::TexturePlacement;
|
||||
use crate::swap_chain::SwapChainLink;
|
||||
use crate::conv;
|
||||
use crate::{
|
||||
@@ -135,7 +136,7 @@ pub extern "C" fn wgpu_command_buffer_copy_buffer_to_texture(
|
||||
range: dst_texture.full_range.clone(),
|
||||
});
|
||||
|
||||
if let Some(ref link) = dst_texture.swap_chain_link {
|
||||
if let TexturePlacement::SwapChain(ref link) = dst_texture.placement {
|
||||
cmb.swap_chain_links.push(SwapChainLink {
|
||||
swap_chain_id: link.swap_chain_id.clone(),
|
||||
epoch: *link.epoch.lock(),
|
||||
@@ -203,7 +204,11 @@ pub extern "C" fn wgpu_command_buffer_copy_texture_to_buffer(
|
||||
families: None,
|
||||
range: src_texture.full_range.clone(),
|
||||
});
|
||||
assert!(src_texture.swap_chain_link.is_none()); //TODO
|
||||
match src_texture.placement {
|
||||
TexturePlacement::SwapChain(_) => unimplemented!(),
|
||||
TexturePlacement::Void => unreachable!(),
|
||||
TexturePlacement::Memory(_) => (),
|
||||
}
|
||||
|
||||
let (dst_buffer, dst_usage) = cmb.trackers.buffers
|
||||
.get_with_replaced_usage(
|
||||
@@ -295,7 +300,7 @@ pub extern "C" fn wgpu_command_buffer_copy_texture_to_texture(
|
||||
range: dst_texture.full_range.clone(),
|
||||
});
|
||||
|
||||
if let Some(ref link) = dst_texture.swap_chain_link {
|
||||
if let TexturePlacement::SwapChain(ref link) = dst_texture.placement {
|
||||
cmb.swap_chain_links.push(SwapChainLink {
|
||||
swap_chain_id: link.swap_chain_id.clone(),
|
||||
epoch: *link.epoch.lock(),
|
||||
|
||||
@@ -7,11 +7,11 @@ use crate::{
|
||||
};
|
||||
use crate::{
|
||||
BufferId, CommandBufferId, AdapterId, DeviceId, QueueId,
|
||||
TextureId, TextureViewId, SurfaceId,
|
||||
BindGroupId, TextureId, TextureViewId, SurfaceId,
|
||||
};
|
||||
#[cfg(feature = "local")]
|
||||
use crate::{
|
||||
BindGroupId, BindGroupLayoutId, PipelineLayoutId, SamplerId, SwapChainId,
|
||||
BindGroupLayoutId, PipelineLayoutId, SamplerId, SwapChainId,
|
||||
ShaderModuleId, CommandEncoderId, RenderPipelineId, ComputePipelineId,
|
||||
};
|
||||
|
||||
@@ -78,8 +78,8 @@ enum ResourceId {
|
||||
}
|
||||
|
||||
enum NativeResource<B: hal::Backend> {
|
||||
Buffer(B::Buffer),
|
||||
Image(B::Image),
|
||||
Buffer(B::Buffer, B::Memory),
|
||||
Image(B::Image, B::Memory),
|
||||
ImageView(B::ImageView),
|
||||
Framebuffer(B::Framebuffer),
|
||||
}
|
||||
@@ -140,17 +140,19 @@ impl<B: hal::Backend> DestroyedResources<B> {
|
||||
|
||||
for resource in self.free.drain(..) {
|
||||
match resource {
|
||||
NativeResource::Buffer(raw) => unsafe {
|
||||
device.destroy_buffer(raw)
|
||||
NativeResource::Buffer(raw, memory) => unsafe {
|
||||
device.destroy_buffer(raw);
|
||||
device.free_memory(memory);
|
||||
},
|
||||
NativeResource::Image(raw) => unsafe {
|
||||
device.destroy_image(raw)
|
||||
NativeResource::Image(raw, memory) => unsafe {
|
||||
device.destroy_image(raw);
|
||||
device.free_memory(memory);
|
||||
},
|
||||
NativeResource::ImageView(raw) => unsafe {
|
||||
device.destroy_image_view(raw)
|
||||
device.destroy_image_view(raw);
|
||||
},
|
||||
NativeResource::Framebuffer(raw) => unsafe {
|
||||
device.destroy_framebuffer(raw)
|
||||
device.destroy_framebuffer(raw);
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -177,12 +179,18 @@ impl DestroyedResources<back::Backend> {
|
||||
ResourceId::Buffer(id) => {
|
||||
trackers.buffers.remove(id);
|
||||
let buf = HUB.buffers.unregister(id);
|
||||
(buf.life_guard, NativeResource::Buffer(buf.raw))
|
||||
(buf.life_guard, NativeResource::Buffer(buf.raw, buf.memory))
|
||||
}
|
||||
ResourceId::Texture(id) => {
|
||||
trackers.textures.remove(id);
|
||||
let tex = HUB.textures.unregister(id);
|
||||
(tex.life_guard, NativeResource::Image(tex.raw))
|
||||
let memory = match tex.placement {
|
||||
// swapchain-owned images don't need explicit destruction
|
||||
resource::TexturePlacement::SwapChain(_) => continue,
|
||||
resource::TexturePlacement::Memory(mem) => mem,
|
||||
resource::TexturePlacement::Void => unreachable!(),
|
||||
};
|
||||
(tex.life_guard, NativeResource::Image(tex.raw, memory))
|
||||
}
|
||||
ResourceId::TextureView(id) => {
|
||||
trackers.views.remove(id);
|
||||
@@ -555,7 +563,7 @@ pub fn device_create_texture(
|
||||
levels: 0 .. 1, //TODO: mips
|
||||
layers: 0 .. desc.array_size as u16,
|
||||
},
|
||||
swap_chain_link: None,
|
||||
placement: resource::TexturePlacement::Memory(memory),
|
||||
life_guard: LifeGuard::new(),
|
||||
}
|
||||
}
|
||||
@@ -940,6 +948,11 @@ pub extern "C" fn wgpu_device_create_bind_group(
|
||||
HUB.bind_groups.register_local(bind_group)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_bind_group_destroy(bind_group_id: BindGroupId) {
|
||||
HUB.bind_groups.unregister(bind_group_id);
|
||||
}
|
||||
|
||||
|
||||
pub fn device_create_shader_module(
|
||||
device_id: DeviceId,
|
||||
@@ -1029,6 +1042,7 @@ pub extern "C" fn wgpu_queue_submit(
|
||||
let mut command_buffer_guard = HUB.command_buffers.write();
|
||||
let buffer_guard = HUB.buffers.read();
|
||||
let texture_guard = HUB.textures.read();
|
||||
let texture_view_guard = HUB.texture_views.read();
|
||||
|
||||
// finish all the command buffers first
|
||||
for &cmb_id in command_buffer_ids {
|
||||
@@ -1045,6 +1059,10 @@ pub extern "C" fn wgpu_queue_submit(
|
||||
texture_guard[id].life_guard.submission_index
|
||||
.store(old_submit_index, Ordering::Release);
|
||||
}
|
||||
for id in comb.trackers.views.used() {
|
||||
texture_view_guard[id].life_guard.submission_index
|
||||
.store(old_submit_index, Ordering::Release);
|
||||
}
|
||||
|
||||
// execute resource transitions
|
||||
let mut transit = device.com_allocator.extend(comb);
|
||||
@@ -1519,7 +1537,7 @@ pub fn device_create_swap_chain(
|
||||
levels: 0 .. 1,
|
||||
layers: 0 .. 1,
|
||||
},
|
||||
swap_chain_link: None,
|
||||
placement: resource::TexturePlacement::Void,
|
||||
life_guard: LifeGuard::new(),
|
||||
})
|
||||
.collect()
|
||||
@@ -1553,7 +1571,7 @@ pub fn swap_chain_populate_textures(
|
||||
)
|
||||
.unwrap()
|
||||
};
|
||||
texture.swap_chain_link = Some(swap_chain::SwapChainLink {
|
||||
texture.placement = resource::TexturePlacement::SwapChain(swap_chain::SwapChainLink {
|
||||
swap_chain_id, //TODO: strongly
|
||||
epoch: Mutex::new(0),
|
||||
image_index: i as hal::SwapImageIndex,
|
||||
|
||||
@@ -105,13 +105,29 @@ pub struct TextureDescriptor {
|
||||
pub usage: TextureUsageFlags,
|
||||
}
|
||||
|
||||
pub(crate) enum TexturePlacement<B: hal::Backend> {
|
||||
SwapChain(SwapChainLink<Mutex<SwapImageEpoch>>),
|
||||
Memory(B::Memory),
|
||||
Void,
|
||||
}
|
||||
|
||||
impl<B: hal::Backend> TexturePlacement<B> {
|
||||
pub fn as_swap_chain(&self) -> &SwapChainLink<Mutex<SwapImageEpoch>> {
|
||||
match *self {
|
||||
TexturePlacement::SwapChain(ref link) => link,
|
||||
TexturePlacement::Memory(_) |
|
||||
TexturePlacement::Void => panic!("Expected swap chain link!"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Texture<B: hal::Backend> {
|
||||
pub(crate) raw: B::Image,
|
||||
pub(crate) device_id: Stored<DeviceId>,
|
||||
pub(crate) kind: hal::image::Kind,
|
||||
pub(crate) format: TextureFormat,
|
||||
pub(crate) full_range: hal::image::SubresourceRange,
|
||||
pub(crate) swap_chain_link: Option<SwapChainLink<Mutex<SwapImageEpoch>>>,
|
||||
pub(crate) placement: TexturePlacement<B>,
|
||||
pub(crate) life_guard: LifeGuard,
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ use crate::track::{TrackPermit};
|
||||
use hal;
|
||||
use hal::{Device as _Device, Swapchain as _Swapchain};
|
||||
use log::{trace, warn};
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use std::{iter, mem};
|
||||
|
||||
@@ -22,6 +23,12 @@ pub(crate) struct SwapChainLink<E> {
|
||||
pub image_index: hal::SwapImageIndex,
|
||||
}
|
||||
|
||||
impl SwapChainLink<Mutex<SwapImageEpoch>> {
|
||||
pub fn bump_epoch(&self) {
|
||||
*self.epoch.lock() += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Surface<B: hal::Backend> {
|
||||
pub(crate) raw: B::Surface,
|
||||
pub(crate) swap_chain: Option<SwapChain<B>>,
|
||||
@@ -144,10 +151,7 @@ pub extern "C" fn wgpu_swap_chain_get_next_texture(
|
||||
}
|
||||
mem::swap(&mut frame.sem_available, &mut swap_chain.sem_available);
|
||||
|
||||
match HUB.textures.read()[frame.texture_id.value].swap_chain_link {
|
||||
Some(ref link) => *link.epoch.lock() += 1,
|
||||
None => unreachable!(),
|
||||
}
|
||||
HUB.textures.read()[frame.texture_id.value].placement.as_swap_chain().bump_epoch();
|
||||
|
||||
SwapChainOutput {
|
||||
texture_id: frame.texture_id.value,
|
||||
@@ -173,10 +177,7 @@ pub extern "C" fn wgpu_swap_chain_present(
|
||||
|
||||
let texture_guard = HUB.textures.read();
|
||||
let texture = &texture_guard[frame.texture_id.value];
|
||||
match texture.swap_chain_link {
|
||||
Some(ref link) => *link.epoch.lock() += 1,
|
||||
None => unreachable!(),
|
||||
}
|
||||
texture.placement.as_swap_chain().bump_epoch();
|
||||
|
||||
//TODO: support for swapchain being sampled or read by the shader?
|
||||
|
||||
|
||||
@@ -144,6 +144,11 @@ impl<I: NewId> DummyTracker<I> {
|
||||
self.query(I::new(index, epoch), ref_count);
|
||||
}
|
||||
}
|
||||
|
||||
/// Return an iterator over used resources keys.
|
||||
pub fn used<'a>(&'a self) -> impl 'a + Iterator<Item = I> {
|
||||
self.map.iter().map(|(&index, &(_, epoch))| I::new(index, epoch))
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: NewId, U: Copy + GenericUsage + BitOr<Output = U> + PartialEq> Tracker<I, U> {
|
||||
|
||||
@@ -83,6 +83,12 @@ pub struct BindGroup {
|
||||
id: wgn::BindGroupId,
|
||||
}
|
||||
|
||||
impl Drop for BindGroup {
|
||||
fn drop(&mut self) {
|
||||
wgn::wgpu_bind_group_destroy(self.id);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ShaderModule {
|
||||
id: wgn::ShaderModuleId,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user