From 39f3f08b55eae75c32d4fde41edd689144bea5c0 Mon Sep 17 00:00:00 2001 From: Xiaopeng Li Date: Fri, 19 Nov 2021 06:34:01 +0800 Subject: [PATCH] Add Device::as_hal and always assume texture from hal is initialized (#2180) * Add Device::as_hal, create_texture_from_hal_initialized * Add Safety doc * Always assume that the texture from hal is initialized --- wgpu-core/src/device/mod.rs | 9 ++++++++- wgpu-core/src/resource.rs | 19 +++++++++++++++++++ wgpu-hal/src/metal/device.rs | 5 +++++ wgpu/src/backend/direct.rs | 10 ++++++++++ wgpu/src/lib.rs | 16 ++++++++++++++++ 5 files changed, 58 insertions(+), 1 deletion(-) diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 50f9ce8f00..44b3851c95 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -3204,6 +3204,7 @@ impl Global { /// /// - `hal_texture` must be created from `device_id` corresponding raw handle. /// - `hal_texture` must be created respecting `desc` + /// - `hal_texture` must be initialized pub unsafe fn create_texture_from_hal( &self, hal_texture: A::Texture, @@ -3243,8 +3244,14 @@ impl Global { Err(error) => break error, }; - let texture = + let mut texture = device.create_texture_from_hal(hal_texture, device_id, desc, format_features); + if desc.usage.contains(wgt::TextureUsages::COPY_DST) { + texture.hal_usage |= hal::TextureUses::COPY_DST; + } + + texture.initialization_status = TextureInitTracker::new(desc.mip_level_count, 0); + let num_levels = texture.full_range.levels.end; let num_layers = texture.full_range.layers.end; let ref_count = texture.life_guard.add_ref(); diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index ec5c7ac816..b83553b0ea 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -209,6 +209,25 @@ impl Global { hal_texture_callback(hal_texture); } + + /// # Safety + /// + /// - The raw device handle must not be manually destroyed + pub unsafe fn device_as_hal) -> R, R>( + &self, + id: DeviceId, + hal_device_callback: F, + ) -> R { + profiling::scope!("as_hal", "Device"); + + let hub = A::hub(self); + let mut token = Token::root(); + let (guard, _) = hub.devices.read(&mut token); + let device = guard.get(id).ok(); + let hal_device = device.map(|device| &device.raw); + + hal_device_callback(hal_device) + } } #[derive(Clone, Copy, Debug)] diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 172d5eb5d7..090fe2e174 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -1,3 +1,4 @@ +use parking_lot::Mutex; use std::{ ptr, sync::{atomic, Arc}, @@ -192,6 +193,10 @@ impl super::Device { copy_size, } } + + pub fn raw_device(&self) -> &Mutex { + &self.shared.device + } } impl crate::Device for super::Device { diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index fa3e24c254..89b3f23369 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -123,6 +123,16 @@ impl Context { } } + #[cfg(not(target_arch = "wasm32"))] + pub unsafe fn device_as_hal) -> R, R>( + &self, + device: &Device, + hal_device_callback: F, + ) -> R { + self.0 + .device_as_hal::(device.id, hal_device_callback) + } + #[cfg(not(target_arch = "wasm32"))] pub unsafe fn texture_as_hal)>( &self, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 495a722ae7..e255eb8a8d 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -1826,6 +1826,7 @@ impl Device { /// /// - `hal_texture` must be created from this device internal handle /// - `hal_texture` must be created respecting `desc` + /// - `hal_texture` must be initialized #[cfg(not(target_arch = "wasm32"))] pub unsafe fn create_texture_from_hal( &self, @@ -1873,6 +1874,21 @@ impl Device { pub fn stop_capture(&self) { Context::device_stop_capture(&*self.context, &self.id) } + + /// Returns the inner hal Device using a callback. The hal device will be `None` if the + /// backend type argument does not match with this wgpu Device + /// + /// # Safety + /// + /// - The raw handle obtained from the hal Device must not be manually destroyed + #[cfg(not(target_arch = "wasm32"))] + pub unsafe fn as_hal) -> R, R>( + &self, + hal_device_callback: F, + ) -> R { + self.context + .device_as_hal::(&self.id, hal_device_callback) + } } impl Drop for Device {