Skip to content

Commit a9047c2

Browse files
authored
Change the DropGuard public API to a callback-based one. (#6164)
This patch also unifies the behavior of the the `DropGuard`-ish constructs in the Vulkan-based implementation.
1 parent fccd298 commit a9047c2

File tree

7 files changed

+62
-23
lines changed

7 files changed

+62
-23
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ By @teoxoy [#6134](https://github.com/gfx-rs/wgpu/pull/6134).
101101
- Reduce the amount of debug and trace logs emitted by wgpu-core and wgpu-hal. By @nical in [#6065](https://github.com/gfx-rs/wgpu/issues/6065)
102102
- `Rg11b10Float` is renamed to `Rg11b10UFloat`. By @sagudev in [#6108](https://github.com/gfx-rs/wgpu/pull/6108)
103103

104+
#### HAL
105+
106+
- Change the inconsistent `DropGuard` based API on Vulkan and GLES to a consistent, callback-based one. By @jerzywilczek in [#6164](https://github.com/gfx-rs/wgpu/pull/6164)
107+
104108
### Dependency Updates
105109

106110
#### GLES

wgpu-hal/src/gles/device.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,22 +110,21 @@ impl super::Device {
110110
///
111111
/// - `name` must be created respecting `desc`
112112
/// - `name` must be a texture
113-
/// - If `drop_guard` is [`None`], wgpu-hal will take ownership of the texture. If `drop_guard` is
114-
/// [`Some`], the texture must be valid until the drop implementation
115-
/// of the drop guard is called.
113+
/// - If `drop_callback` is [`None`], wgpu-hal will take ownership of the texture. If
114+
/// `drop_callback` is [`Some`], the texture must be valid until the callback is called.
116115
#[cfg(any(native, Emscripten))]
117116
pub unsafe fn texture_from_raw(
118117
&self,
119118
name: std::num::NonZeroU32,
120119
desc: &crate::TextureDescriptor,
121-
drop_guard: Option<crate::DropGuard>,
120+
drop_callback: Option<crate::DropCallback>,
122121
) -> super::Texture {
123122
super::Texture {
124123
inner: super::TextureInner::Texture {
125124
raw: glow::NativeTexture(name),
126125
target: super::Texture::get_info_from_desc(desc),
127126
},
128-
drop_guard,
127+
drop_guard: crate::DropGuard::from_option(drop_callback),
129128
mip_level_count: desc.mip_level_count,
130129
array_layer_count: desc.array_layer_count(),
131130
format: desc.format,
@@ -138,21 +137,20 @@ impl super::Device {
138137
///
139138
/// - `name` must be created respecting `desc`
140139
/// - `name` must be a renderbuffer
141-
/// - If `drop_guard` is [`None`], wgpu-hal will take ownership of the renderbuffer. If `drop_guard` is
142-
/// [`Some`], the renderbuffer must be valid until the drop implementation
143-
/// of the drop guard is called.
140+
/// - If `drop_callback` is [`None`], wgpu-hal will take ownership of the renderbuffer. If
141+
/// `drop_callback` is [`Some`], the renderbuffer must be valid until the callback is called.
144142
#[cfg(any(native, Emscripten))]
145143
pub unsafe fn texture_from_raw_renderbuffer(
146144
&self,
147145
name: std::num::NonZeroU32,
148146
desc: &crate::TextureDescriptor,
149-
drop_guard: Option<crate::DropGuard>,
147+
drop_callback: Option<crate::DropCallback>,
150148
) -> super::Texture {
151149
super::Texture {
152150
inner: super::TextureInner::Renderbuffer {
153151
raw: glow::NativeRenderbuffer(name),
154152
},
155-
drop_guard,
153+
drop_guard: crate::DropGuard::from_option(drop_callback),
156154
mip_level_count: desc.mip_level_count,
157155
array_layer_count: desc.array_layer_count(),
158156
format: desc.format,

wgpu-hal/src/lib.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,35 @@ pub type MemoryRange = Range<wgt::BufferAddress>;
303303
pub type FenceValue = u64;
304304
pub type AtomicFenceValue = std::sync::atomic::AtomicU64;
305305

306-
/// Drop guard to signal wgpu-hal is no longer using an externally created object.
307-
pub type DropGuard = Box<dyn std::any::Any + Send + Sync>;
306+
/// A callback to signal that wgpu is no longer using a resource.
307+
#[cfg(any(gles, vulkan))]
308+
pub type DropCallback = Box<dyn FnMut() + Send + Sync + 'static>;
309+
310+
#[cfg(any(gles, vulkan))]
311+
pub struct DropGuard {
312+
callback: DropCallback,
313+
}
314+
315+
#[cfg(all(any(gles, vulkan), any(native, Emscripten)))]
316+
impl DropGuard {
317+
fn from_option(callback: Option<DropCallback>) -> Option<Self> {
318+
callback.map(|callback| Self { callback })
319+
}
320+
}
321+
322+
#[cfg(any(gles, vulkan))]
323+
impl Drop for DropGuard {
324+
fn drop(&mut self) {
325+
(self.callback)();
326+
}
327+
}
328+
329+
#[cfg(any(gles, vulkan))]
330+
impl std::fmt::Debug for DropGuard {
331+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
332+
f.debug_struct("DropGuard").finish()
333+
}
334+
}
308335

309336
#[derive(Clone, Debug, PartialEq, Eq, Error)]
310337
pub enum DeviceError {

wgpu-hal/src/vulkan/adapter.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,11 +1603,13 @@ impl super::Adapter {
16031603
/// - `raw_device` must be created from this adapter.
16041604
/// - `raw_device` must be created using `family_index`, `enabled_extensions` and `physical_device_features()`
16051605
/// - `enabled_extensions` must be a superset of `required_device_extensions()`.
1606+
/// - If `drop_callback` is [`None`], wgpu-hal will take ownership of `raw_device`. If
1607+
/// `drop_callback` is [`Some`], `raw_device` must be valid until the callback is called.
16061608
#[allow(clippy::too_many_arguments)]
16071609
pub unsafe fn device_from_raw(
16081610
&self,
16091611
raw_device: ash::Device,
1610-
handle_is_owned: bool,
1612+
drop_callback: Option<crate::DropCallback>,
16111613
enabled_extensions: &[&'static CStr],
16121614
features: wgt::Features,
16131615
memory_hints: &wgt::MemoryHints,
@@ -1822,12 +1824,14 @@ impl super::Adapter {
18221824
0, 0, 0, 0,
18231825
];
18241826

1827+
let drop_guard = crate::DropGuard::from_option(drop_callback);
1828+
18251829
let shared = Arc::new(super::DeviceShared {
18261830
raw: raw_device,
18271831
family_index,
18281832
queue_index,
18291833
raw_queue,
1830-
handle_is_owned,
1834+
drop_guard,
18311835
instance: Arc::clone(&self.instance),
18321836
physical_device: self.raw,
18331837
enabled_extensions: enabled_extensions.into(),
@@ -2015,7 +2019,7 @@ impl crate::Adapter for super::Adapter {
20152019
unsafe {
20162020
self.device_from_raw(
20172021
raw_device,
2018-
true,
2022+
None,
20192023
&enabled_extensions,
20202024
features,
20212025
memory_hints,

wgpu-hal/src/vulkan/device.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ impl super::DeviceShared {
290290
for &raw in self.framebuffers.lock().values() {
291291
unsafe { self.raw.destroy_framebuffer(raw, None) };
292292
}
293-
if self.handle_is_owned {
293+
if self.drop_guard.is_none() {
294294
unsafe { self.raw.destroy_device(None) };
295295
}
296296
}
@@ -649,13 +649,13 @@ impl super::Device {
649649
/// # Safety
650650
///
651651
/// - `vk_image` must be created respecting `desc`
652-
/// - If `drop_guard` is `Some`, the application must manually destroy the image handle. This
653-
/// can be done inside the `Drop` impl of `drop_guard`.
652+
/// - If `drop_callback` is [`None`], wgpu-hal will take ownership of `vk_image`. If
653+
/// `drop_callback` is [`Some`], `vk_image` must be valid until the callback is called.
654654
/// - If the `ImageCreateFlags` does not contain `MUTABLE_FORMAT`, the `view_formats` of `desc` must be empty.
655655
pub unsafe fn texture_from_raw(
656656
vk_image: vk::Image,
657657
desc: &crate::TextureDescriptor,
658-
drop_guard: Option<crate::DropGuard>,
658+
drop_callback: Option<crate::DropCallback>,
659659
) -> super::Texture {
660660
let mut raw_flags = vk::ImageCreateFlags::empty();
661661
let mut view_formats = vec![];
@@ -674,6 +674,8 @@ impl super::Device {
674674
raw_flags |= vk::ImageCreateFlags::MUTABLE_FORMAT;
675675
}
676676

677+
let drop_guard = crate::DropGuard::from_option(drop_callback);
678+
677679
super::Texture {
678680
raw: vk_image,
679681
drop_guard,

wgpu-hal/src/vulkan/instance.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,8 @@ impl super::Instance {
310310
/// - `extensions` must be a superset of `desired_extensions()` and must be created from the
311311
/// same entry, `instance_api_version`` and flags.
312312
/// - `android_sdk_version` is ignored and can be `0` for all platforms besides Android
313+
/// - If `drop_callback` is [`None`], wgpu-hal will take ownership of `raw_instance`. If
314+
/// `drop_callback` is [`Some`], `raw_instance` must be valid until the callback is called.
313315
///
314316
/// If `debug_utils_user_data` is `Some`, then the validation layer is
315317
/// available, so create a [`vk::DebugUtilsMessengerEXT`].
@@ -323,7 +325,7 @@ impl super::Instance {
323325
extensions: Vec<&'static CStr>,
324326
flags: wgt::InstanceFlags,
325327
has_nv_optimus: bool,
326-
drop_guard: Option<crate::DropGuard>,
328+
drop_callback: Option<crate::DropCallback>,
327329
) -> Result<Self, crate::InstanceError> {
328330
log::debug!("Instance version: 0x{:x}", instance_api_version);
329331

@@ -364,6 +366,8 @@ impl super::Instance {
364366
None
365367
};
366368

369+
let drop_guard = crate::DropGuard::from_option(drop_callback);
370+
367371
Ok(Self {
368372
shared: Arc::new(super::InstanceShared {
369373
raw: raw_instance,
@@ -555,7 +559,7 @@ impl Drop for super::InstanceShared {
555559
.destroy_debug_utils_messenger(du.messenger, None);
556560
du
557561
});
558-
if let Some(_drop_guard) = self.drop_guard.take() {
562+
if self.drop_guard.is_none() {
559563
self.raw.destroy_instance(None);
560564
}
561565
}
@@ -829,7 +833,7 @@ impl crate::Instance for super::Instance {
829833
extensions,
830834
desc.flags,
831835
has_nv_optimus,
832-
Some(Box::new(())), // `Some` signals that wgpu-hal is in charge of destroying vk_instance
836+
None,
833837
)
834838
}
835839
}

wgpu-hal/src/vulkan/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ struct DeviceShared {
595595
family_index: u32,
596596
queue_index: u32,
597597
raw_queue: vk::Queue,
598-
handle_is_owned: bool,
598+
drop_guard: Option<crate::DropGuard>,
599599
instance: Arc<InstanceShared>,
600600
physical_device: vk::PhysicalDevice,
601601
enabled_extensions: Vec<&'static CStr>,

0 commit comments

Comments
 (0)