Skip to content

Commit

Permalink
Snatch texture views of destroyed textures (#5131)
Browse files Browse the repository at this point in the history
  • Loading branch information
nical authored Jan 24, 2024
1 parent b0e4734 commit 7d0f656
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 13 deletions.
24 changes: 19 additions & 5 deletions wgpu-core/src/command/render.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::resource::Resource;
use crate::snatch::SnatchGuard;
use crate::{
api_log,
binding_model::BindError,
Expand Down Expand Up @@ -533,6 +534,8 @@ pub enum RenderPassErrorInner {
Encoder(#[from] CommandEncoderError),
#[error("Attachment texture view {0:?} is invalid")]
InvalidAttachment(id::TextureViewId),
#[error("Attachment texture view {0:?} is invalid")]
InvalidResolveTarget(id::TextureViewId),
#[error("The format of the depth-stencil attachment ({0:?}) is not a depth-stencil format")]
InvalidDepthStencilAttachmentFormat(wgt::TextureFormat),
#[error("The format of the {location} ({format:?}) is not resolvable")]
Expand Down Expand Up @@ -789,6 +792,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
buffer_guard: &'a Storage<Buffer<A>, id::BufferId>,
texture_guard: &'a Storage<Texture<A>, id::TextureId>,
query_set_guard: &'a Storage<QuerySet<A>, id::QuerySetId>,
snatch_guard: &SnatchGuard<'a>,
) -> Result<Self, RenderPassErrorInner> {
profiling::scope!("RenderPassInfo::start");

Expand Down Expand Up @@ -993,7 +997,9 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {

depth_stencil = Some(hal::DepthStencilAttachment {
target: hal::Attachment {
view: view.raw(),
view: view
.raw(snatch_guard)
.ok_or_else(|| RenderPassErrorInner::InvalidAttachment(view.info.id()))?,
usage,
},
depth_ops: at.depth.hal_ops(),
Expand Down Expand Up @@ -1102,14 +1108,18 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
.push(resolve_view.to_render_attachment(hal::TextureUses::COLOR_TARGET));

hal_resolve_target = Some(hal::Attachment {
view: resolve_view.raw(),
view: resolve_view.raw(snatch_guard).ok_or_else(|| {
RenderPassErrorInner::InvalidResolveTarget(resolve_view.info.id())
})?,
usage: hal::TextureUses::COLOR_TARGET,
});
}

colors.push(Some(hal::ColorAttachment {
target: hal::Attachment {
view: color_view.raw(),
view: color_view.raw(snatch_guard).ok_or_else(|| {
RenderPassErrorInner::InvalidAttachment(color_view.info.id())
})?,
usage: hal::TextureUses::COLOR_TARGET,
},
resolve_target: hal_resolve_target,
Expand Down Expand Up @@ -1209,6 +1219,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
fn finish(
mut self,
raw: &mut A::CommandEncoder,
snatch_guard: &SnatchGuard,
) -> Result<(UsageScope<A>, SurfacesInDiscardState<A>), RenderPassErrorInner> {
profiling::scope!("RenderPassInfo::finish");
unsafe {
Expand Down Expand Up @@ -1256,7 +1267,9 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
color_attachments: &[],
depth_stencil_attachment: Some(hal::DepthStencilAttachment {
target: hal::Attachment {
view: view.raw(),
view: view.raw(snatch_guard).ok_or_else(|| {
RenderPassErrorInner::InvalidAttachment(view.info.id())
})?,
usage: hal::TextureUses::DEPTH_STENCIL_WRITE,
},
depth_ops,
Expand Down Expand Up @@ -1386,6 +1399,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
&*buffer_guard,
&*texture_guard,
&*query_set_guard,
&snatch_guard,
)
.map_pass_err(pass_scope)?;

Expand Down Expand Up @@ -2366,7 +2380,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {

log::trace!("Merging renderpass into cmd_buf {:?}", encoder_id);
let (trackers, pending_discard_init_fixups) =
info.finish(raw).map_pass_err(pass_scope)?;
info.finish(raw, &snatch_guard).map_pass_err(pass_scope)?;

encoder.close().map_pass_err(pass_scope)?;
(trackers, pending_discard_init_fixups)
Expand Down
6 changes: 6 additions & 0 deletions wgpu-core/src/device/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
};

let (id, resource) = fid.assign(view);

{
let mut views = texture.views.lock();
views.push(Arc::downgrade(&resource));
}

api_log!("Texture::create_view({texture_id:?}) -> {id:?}");
device.trackers.lock().views.insert_single(id, resource);
return (id, None);
Expand Down
11 changes: 8 additions & 3 deletions wgpu-core/src/device/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ impl<A: HalApi> Device<A> {
},
info: ResourceInfo::new(desc.label.borrow_or_default()),
clear_mode: RwLock::new(clear_mode),
views: Mutex::new(Vec::new()),
}
}

Expand Down Expand Up @@ -1177,7 +1178,7 @@ impl<A: HalApi> Device<A> {
};

Ok(TextureView {
raw: Some(raw),
raw: Snatchable::new(raw),
parent: texture.clone(),
device: self.clone(),
desc: resource::HalTextureViewDescriptor {
Expand Down Expand Up @@ -2126,7 +2127,9 @@ impl<A: HalApi> Device<A> {
)?;
let res_index = hal_textures.len();
hal_textures.push(hal::TextureBinding {
view: view.raw(),
view: view
.raw(&snatch_guard)
.ok_or(Error::InvalidTextureView(id))?,
usage: internal_use,
});
(res_index, 1)
Expand All @@ -2152,7 +2155,9 @@ impl<A: HalApi> Device<A> {
&mut used_texture_ranges,
)?;
hal_textures.push(hal::TextureBinding {
view: view.raw(),
view: view
.raw(&snatch_guard)
.ok_or(Error::InvalidTextureView(id))?,
usage: internal_use,
});
}
Expand Down
3 changes: 2 additions & 1 deletion wgpu-core/src/present.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use crate::{
};

use hal::{Queue as _, Surface as _};
use parking_lot::RwLock;
use parking_lot::{Mutex, RwLock};
use thiserror::Error;
use wgt::SurfaceStatus as Status;

Expand Down Expand Up @@ -231,6 +231,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
clear_mode: RwLock::new(resource::TextureClearMode::Surface {
clear_view: Some(clear_view),
}),
views: Mutex::new(Vec::new()),
};

let (id, resource) = fid.assign(texture);
Expand Down
34 changes: 30 additions & 4 deletions wgpu-core/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use std::{
ptr::NonNull,
sync::{
atomic::{AtomicBool, AtomicUsize, Ordering},
Arc,
Arc, Weak,
},
};

Expand Down Expand Up @@ -741,6 +741,7 @@ pub struct Texture<A: HalApi> {
pub(crate) full_range: TextureSelector,
pub(crate) info: ResourceInfo<TextureId>,
pub(crate) clear_mode: RwLock<TextureClearMode<A>>,
pub(crate) views: Mutex<Vec<Weak<TextureView<A>>>>,
}

impl<A: HalApi> Drop for Texture<A> {
Expand Down Expand Up @@ -852,8 +853,14 @@ impl<A: HalApi> Texture<A> {
}
};

let views = {
let mut guard = self.views.lock();
std::mem::take(&mut *guard)
};

queue::TempResource::DestroyedTexture(Arc::new(DestroyedTexture {
raw: Some(raw),
views,
device: Arc::clone(&self.device),
submission_index: self.info.submission_index(),
id: self.info.id.unwrap(),
Expand Down Expand Up @@ -970,6 +977,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
#[derive(Debug)]
pub struct DestroyedTexture<A: HalApi> {
raw: Option<A::Texture>,
views: Vec<Weak<TextureView<A>>>,
device: Arc<Device<A>>,
label: String,
pub(crate) id: TextureId,
Expand All @@ -988,6 +996,24 @@ impl<A: HalApi> DestroyedTexture<A> {

impl<A: HalApi> Drop for DestroyedTexture<A> {
fn drop(&mut self) {
let device = &self.device;
for view in self.views.drain(..) {
if let Some(view) = view.upgrade() {
if let Some(raw_view) = view.raw.snatch(device.snatchable_lock.write()) {
resource_log!("Destroy raw TextureView (destroyed) {:?}", view.label());

#[cfg(feature = "trace")]
if let Some(t) = self.device.trace.lock().as_mut() {
t.add(trace::Action::DestroyTextureView(view.info.id()));
}

unsafe {
use hal::Device;
self.device.raw().destroy_texture_view(raw_view);
}
}
}
}
if let Some(raw) = self.raw.take() {
resource_log!("Destroy raw Texture (destroyed) {:?}", self.label());

Expand Down Expand Up @@ -1170,7 +1196,7 @@ pub enum TextureViewNotRenderableReason {

#[derive(Debug)]
pub struct TextureView<A: HalApi> {
pub(crate) raw: Option<A::TextureView>,
pub(crate) raw: Snatchable<A::TextureView>,
// if it's a surface texture - it's none
pub(crate) parent: Arc<Texture<A>>,
pub(crate) device: Arc<Device<A>>,
Expand Down Expand Up @@ -1203,8 +1229,8 @@ impl<A: HalApi> Drop for TextureView<A> {
}

impl<A: HalApi> TextureView<A> {
pub(crate) fn raw(&self) -> &A::TextureView {
self.raw.as_ref().unwrap()
pub(crate) fn raw<'a>(&'a self, snatch_guard: &'a SnatchGuard) -> Option<&'a A::TextureView> {
self.raw.get(snatch_guard)
}
}

Expand Down

0 comments on commit 7d0f656

Please sign in to comment.