mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 06:44:14 +00:00
Snatch texture views of destroyed textures (#5131)
This commit is contained in:
parent
b0e4734a7e
commit
7d0f656dd9
@ -1,4 +1,5 @@
|
||||
use crate::resource::Resource;
|
||||
use crate::snatch::SnatchGuard;
|
||||
use crate::{
|
||||
api_log,
|
||||
binding_model::BindError,
|
||||
@ -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")]
|
||||
@ -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");
|
||||
|
||||
@ -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(),
|
||||
@ -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,
|
||||
@ -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 {
|
||||
@ -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,
|
||||
@ -1386,6 +1399,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
&*buffer_guard,
|
||||
&*texture_guard,
|
||||
&*query_set_guard,
|
||||
&snatch_guard,
|
||||
)
|
||||
.map_pass_err(pass_scope)?;
|
||||
|
||||
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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()),
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
@ -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)
|
||||
@ -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,
|
||||
});
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
@ -34,7 +34,7 @@ use std::{
|
||||
ptr::NonNull,
|
||||
sync::{
|
||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
Arc,
|
||||
Arc, Weak,
|
||||
},
|
||||
};
|
||||
|
||||
@ -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> {
|
||||
@ -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(),
|
||||
@ -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,
|
||||
@ -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());
|
||||
|
||||
@ -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>>,
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user