/// A guard which holds alive a wgpu-core resource and dereferences to the Hal type. struct SimpleResourceGuard<Resource, HalType> {
_guard: Resource,
ptr: *const HalType,
}
impl<Resource, HalType> SimpleResourceGuard<Resource, HalType> { /// Creates a new guard from a resource, using a callback to derive the Hal type. pubfn new<C>(guard: Resource, callback: C) -> Option<Self> where
C: Fn(&Resource) -> Option<&HalType>,
{ // Derive the hal type from the resource and coerce it to a pointer. let ptr: *const HalType = callback(&guard)?;
Some(Self { _guard: guard, ptr })
}
}
impl<Resource, HalType> Deref for SimpleResourceGuard<Resource, HalType> { type Target = HalType;
fn deref(&self) -> &Self::Target { // SAFETY: The pointer is guaranteed to be valid as the original resource is // still alive and this guard cannot be used with snatchable resources. unsafe { &*self.ptr }
}
}
unsafeimpl<Resource, HalType> Send for SimpleResourceGuard<Resource, HalType> where
Resource: Send,
HalType: Send,
{
} unsafeimpl<Resource, HalType> Sync for SimpleResourceGuard<Resource, HalType> where
Resource: Sync,
HalType: Sync,
{
}
/// A guard which holds alive a snatchable wgpu-core resource and dereferences to the Hal type. struct SnatchableResourceGuard<Resource, HalType> where
Resource: RawResourceAccess,
{
resource: Arc<Resource>,
snatch_lock_rank_data: ManuallyDrop<RankData>,
ptr: *const HalType,
}
impl<Resource, HalType> SnatchableResourceGuard<Resource, HalType> where
Resource: RawResourceAccess,
HalType: 'static,
{ /// Creates a new guard from a snatchable resource. /// /// Returns `None` if: /// - The resource is not of the expected Hal type. /// - The resource has been destroyed. pubfn new(resource: Arc<Resource>) -> Option<Self> { // Grab the snatchable lock. let snatch_guard = resource.device().snatchable_lock.read();
// Get the raw resource and downcast it to the expected Hal type. let underlying = resource
.raw(&snatch_guard)?
.as_any()
.downcast_ref::<HalType>()?;
// Cast the raw resource to a pointer to get rid of the lifetime // connecting us to the snatch guard. let ptr: *const HalType = underlying;
// SAFETY: At this point all panicking or divergance has already happened, // so we can safely forget the snatch guard without causing the lock to be left open. let snatch_lock_rank_data = SnatchGuard::forget(snatch_guard);
// SAFETY: We only construct this guard while the snatchable lock is held, // as the `drop` implementation of this guard will unsafely release the lock.
Some(Self {
resource,
snatch_lock_rank_data: ManuallyDrop::new(snatch_lock_rank_data),
ptr,
})
}
}
impl<Resource, HalType> Deref for SnatchableResourceGuard<Resource, HalType> where
Resource: RawResourceAccess,
{ type Target = HalType;
fn deref(&self) -> &Self::Target { // SAFETY: The pointer is guaranteed to be valid as the original resource is // still alive and the snatchable lock is still being held due to the forgotten // snatch guard. unsafe { &*self.ptr }
}
}
impl<Resource, HalType> Drop for SnatchableResourceGuard<Resource, HalType> where
Resource: RawResourceAccess,
{ fn drop(&mutself) { // SAFETY: // - We are not going to access the rank data anymore. let data = unsafe { ManuallyDrop::take(&mutself.snatch_lock_rank_data) };
// SAFETY: // - The pointer is no longer going to be accessed. // - The snatchable lock is being held because this type was not created // until after the snatchable lock was forgotten. unsafe { self.resource
.device()
.snatchable_lock
.force_unlock_read(data)
};
}
}
unsafeimpl<Resource, HalType> Send for SnatchableResourceGuard<Resource, HalType> where
Resource: RawResourceAccess + Send,
HalType: Send,
{
} unsafeimpl<Resource, HalType> Sync for SnatchableResourceGuard<Resource, HalType> where
Resource: RawResourceAccess + Sync,
HalType: Sync,
{
}
impl Global { /// # Safety /// /// - The raw buffer handle must not be manually destroyed pubunsafefn buffer_as_hal<A: hal::Api>(
&self,
id: BufferId,
) -> Option<impl Deref<Target = A::Buffer>> {
profiling::scope!("Buffer::as_hal");
let hub = &self.hub;
let buffer = hub.buffers.get(id).get().ok()?;
SnatchableResourceGuard::new(buffer)
}
/// # Safety /// /// - The raw texture handle must not be manually destroyed pubunsafefn texture_as_hal<A: hal::Api>(
&self,
id: TextureId,
) -> Option<impl Deref<Target = A::Texture>> {
profiling::scope!("Texture::as_hal");
let hub = &self.hub;
let texture = hub.textures.get(id).get().ok()?;
SnatchableResourceGuard::new(texture)
}
/// # Safety /// /// - The raw texture view handle must not be manually destroyed pubunsafefn texture_view_as_hal<A: hal::Api>(
&self,
id: TextureViewId,
) -> Option<impl Deref<Target = A::TextureView>> {
profiling::scope!("TextureView::as_hal");
let hub = &self.hub;
let view = hub.texture_views.get(id).get().ok()?;
SnatchableResourceGuard::new(view)
}
/// # Safety /// /// - The raw adapter handle must not be manually destroyed pubunsafefn adapter_as_hal<A: hal::Api>(
&self,
id: AdapterId,
) -> Option<impl Deref<Target = A::Adapter>> {
profiling::scope!("Adapter::as_hal");
let hub = &self.hub; let adapter = hub.adapters.get(id);
/// Encode commands using the raw HAL command encoder. /// /// # Panics /// /// If the command encoder has already been used with the wgpu encoding API. /// /// # Safety /// /// - The raw command encoder handle must not be manually destroyed pubunsafefn command_encoder_as_hal_mut<
A: hal::Api,
F: FnOnce(Option<&mut A::CommandEncoder>) -> R,
R,
>(
&self,
id: CommandEncoderId,
hal_command_encoder_callback: F,
) -> R {
profiling::scope!("CommandEncoder::as_hal");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.