diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 12f60412d..e6b9f6d4d 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -13,6 +13,7 @@ path = "hello_triangle_rust/main.rs" [features] default = [] +remote = ["wgpu-native/remote"] metal = ["wgpu-native/metal"] dx12 = ["wgpu-native/dx12"] vulkan = ["wgpu-native/vulkan"] diff --git a/wgpu-bindings/src/main.rs b/wgpu-bindings/src/main.rs index 9d31ef501..a1d14669b 100644 --- a/wgpu-bindings/src/main.rs +++ b/wgpu-bindings/src/main.rs @@ -7,19 +7,27 @@ fn main() { crate_dir.push("../wgpu-native"); let config = cbindgen::Config { + header: Some(String::from("#ifdef WGPU_REMOTE\n typedef uint32_t WGPUId;\n#else\n typedef void *WGPUId;\n#endif")), enumeration: cbindgen::EnumConfig { prefix_with_name: true, ..Default::default() }, + export: cbindgen::ExportConfig { + prefix: Some(String::from("WGPU")), + exclude: vec![ + // We manually define `Id` is with an `#ifdef`, so exclude it here + String::from("Id"), + ], + ..Default::default() + }, + language: cbindgen::Language::C, ..Default::default() }; cbindgen::Builder::new() .with_crate(crate_dir) .with_config(config) - .with_language(cbindgen::Language::C) - .with_item_prefix("WGPU") .generate() - .expect("Unable to generate bindings") + .unwrap() .write_to_file("wgpu.h"); } diff --git a/wgpu-bindings/wgpu.h b/wgpu-bindings/wgpu.h index 93499b6c8..4c776af9e 100644 --- a/wgpu-bindings/wgpu.h +++ b/wgpu-bindings/wgpu.h @@ -1,3 +1,9 @@ +#ifdef WGPU_REMOTE + typedef uint32_t WGPUId; +#else + typedef void *WGPUId; +#endif + #include #include #include @@ -8,8 +14,6 @@ typedef enum { WGPUPowerPreference_HighPerformance = 2, } WGPUPowerPreference; -typedef uint32_t WGPUId; - typedef WGPUId WGPUDeviceId; typedef WGPUId WGPUAdapterId; diff --git a/wgpu-native/Cargo.toml b/wgpu-native/Cargo.toml index 0200a92b9..58694cb0f 100644 --- a/wgpu-native/Cargo.toml +++ b/wgpu-native/Cargo.toml @@ -11,6 +11,7 @@ crate-type = ["lib", "cdylib", "staticlib"] [features] default = [] +remote = [] metal = ["gfx-backend-metal"] dx12 = ["gfx-backend-dx12"] vulkan = ["gfx-backend-vulkan"] diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index c630725c7..c11acbfb4 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -1,7 +1,7 @@ use hal::{self, Device as _Device, QueueGroup}; use {conv, memory, pipeline, resource}; -use registry; +use registry::{self, Registry}; use {BufferId, CommandBufferId, DeviceId, ShaderModuleId}; #[repr(C)] diff --git a/wgpu-native/src/instance.rs b/wgpu-native/src/instance.rs index 5c3255fa0..3308defcd 100644 --- a/wgpu-native/src/instance.rs +++ b/wgpu-native/src/instance.rs @@ -1,6 +1,6 @@ use hal::{self, Instance as _Instance, PhysicalDevice as _PhysicalDevice}; -use registry; +use registry::{self, Registry}; use {AdapterId, Device, DeviceId, InstanceId}; #[repr(C)] diff --git a/wgpu-native/src/registry.rs b/wgpu-native/src/registry.rs index c418c2827..8d482c246 100644 --- a/wgpu-native/src/registry.rs +++ b/wgpu-native/src/registry.rs @@ -1,47 +1,100 @@ +use std::marker::PhantomData; +use std::os::raw::c_void; use std::sync::{Arc, Mutex}; use std::{borrow, cmp, fmt, ops, ptr}; use hal::backend::FastHashMap; use {AdapterHandle, DeviceHandle, InstanceHandle, ShaderModuleHandle}; +#[cfg(not(feature = "remote"))] +pub(crate) type Id = *mut c_void; +#[cfg(feature = "remote")] pub(crate) type Id = u32; -pub(crate) struct Registry { +pub(crate) trait Registry { + fn new() -> Self; + fn register(&mut self, handle: T) -> Id; + fn get(&self, id: Id) -> Option<&T>; + fn get_mut(&mut self, id: Id) -> Option<&mut T>; +} + +#[cfg(not(feature = "remote"))] +pub(crate) struct LocalRegistry { + marker: PhantomData, +} + +#[cfg(not(feature = "remote"))] +impl Registry for LocalRegistry { + fn new() -> Self { + LocalRegistry { + marker: PhantomData, + } + } + + fn register(&mut self, handle: T) -> Id { + ::std::boxed::Box::into_raw(Box::new(handle)) as *mut _ as *mut c_void + } + + fn get(&self, id: Id) -> Option<&T> { + unsafe { (id as *const T).as_ref() } + } + + fn get_mut(&mut self, id: Id) -> Option<&mut T> { + unsafe { (id as *mut T).as_mut() } + } +} + +#[cfg(feature = "remote")] +pub(crate) struct RemoteRegistry { next_id: Id, tracked: FastHashMap, } -impl Registry { +#[cfg(feature = "remote")] +impl Registry for RemoteRegistry { fn new() -> Self { - Registry { + RemoteRegistry { next_id: 0, tracked: FastHashMap::default(), } } - pub(crate) fn register(&mut self, handle: T) -> Id { + fn register(&mut self, handle: T) -> Id { let id = self.next_id; self.tracked.insert(id, handle); self.next_id += 1; id } - pub(crate) fn get(&self, id: Id) -> Option<&T> { + fn get(&self, id: Id) -> Option<&T> { self.tracked.get(&id) } - pub(crate) fn get_mut(&mut self, id: Id) -> Option<&mut T> { + fn get_mut(&mut self, id: Id) -> Option<&mut T> { self.tracked.get_mut(&id) } } +#[cfg(not(feature = "remote"))] lazy_static! { - pub(crate) static ref ADAPTER_REGISTRY: Arc>> = - Arc::new(Mutex::new(Registry::new())); - pub(crate) static ref DEVICE_REGISTRY: Arc>> = - Arc::new(Mutex::new(Registry::new())); - pub(crate) static ref INSTANCE_REGISTRY: Arc>> = - Arc::new(Mutex::new(Registry::new())); - pub(crate) static ref SHADER_MODULE_REGISTRY: Arc>> = - Arc::new(Mutex::new(Registry::new())); + pub(crate) static ref ADAPTER_REGISTRY: Mutex> = + Mutex::new(LocalRegistry::new()); + pub(crate) static ref DEVICE_REGISTRY: Mutex> = + Mutex::new(LocalRegistry::new()); + pub(crate) static ref INSTANCE_REGISTRY: Mutex> = + Mutex::new(LocalRegistry::new()); + pub(crate) static ref SHADER_MODULE_REGISTRY: Mutex> = + Mutex::new(LocalRegistry::new()); +} + +#[cfg(feature = "remote")] +lazy_static! { + pub(crate) static ref ADAPTER_REGISTRY: Arc>> = + Arc::new(Mutex::new(RemoteRegistry::new())); + pub(crate) static ref DEVICE_REGISTRY: Arc>> = + Arc::new(Mutex::new(RemoteRegistry::new())); + pub(crate) static ref INSTANCE_REGISTRY: Arc>> = + Arc::new(Mutex::new(RemoteRegistry::new())); + pub(crate) static ref SHADER_MODULE_REGISTRY: Arc>> = + Arc::new(Mutex::new(RemoteRegistry::new())); }