diff --git a/wgpu-native/src/registry.rs b/wgpu-native/src/registry.rs deleted file mode 100644 index b5b450146..000000000 --- a/wgpu-native/src/registry.rs +++ /dev/null @@ -1,177 +0,0 @@ -#[cfg(feature = "remote")] -use hal::backend::FastHashMap; -#[cfg(feature = "remote")] -use parking_lot::{Mutex, MutexGuard}; -#[cfg(not(feature = "remote"))] -use std::marker::PhantomData; -#[cfg(not(feature = "remote"))] -use std::os::raw::c_void; -#[cfg(feature = "remote")] -use std::sync::Arc; - -use { - AdapterHandle, AttachmentStateHandle, BindGroupLayoutHandle, BlendStateHandle, - CommandBufferHandle, DepthStencilStateHandle, DeviceHandle, InstanceHandle, - RenderPassHandle, ComputePassHandle, - PipelineLayoutHandle, RenderPipelineHandle, ShaderModuleHandle, -}; - -#[cfg(not(feature = "remote"))] -pub type Id = *mut c_void; -#[cfg(feature = "remote")] -pub type Id = u32; - -type Item<'a, T> = &'a T; -type ItemMut<'a, T> = &'a mut T; - -#[cfg(not(feature = "remote"))] -type ItemsGuard<'a, T> = LocalItems; -#[cfg(feature = "remote")] -type ItemsGuard<'a, T> = MutexGuard<'a, RemoteItems>; - -pub trait Registry: Default { - fn lock(&self) -> ItemsGuard; -} - -pub trait Items { - fn register(&mut self, handle: T) -> Id; - fn get(&self, id: Id) -> Item; - fn get_mut(&mut self, id: Id) -> ItemMut; - fn take(&mut self, id: Id) -> T; -} - -#[cfg(not(feature = "remote"))] -pub struct LocalItems { - marker: PhantomData, -} - -#[cfg(not(feature = "remote"))] -impl Items for LocalItems { - fn register(&mut self, handle: T) -> Id { - Box::into_raw(Box::new(handle)) as *mut _ as *mut c_void - } - - fn get(&self, id: Id) -> Item { - unsafe { (id as *mut T).as_ref() }.unwrap() - } - - fn get_mut(&mut self, id: Id) -> ItemMut { - unsafe { (id as *mut T).as_mut() }.unwrap() - } - - fn take(&mut self, id: Id) -> T { - unsafe { *Box::from_raw(id as *mut T) } - } -} - -#[cfg(not(feature = "remote"))] -pub struct LocalRegistry { - marker: PhantomData, -} -#[cfg(not(feature = "remote"))] -impl Default for LocalRegistry { - fn default() -> Self { - LocalRegistry { - marker: PhantomData, - } - } -} -#[cfg(not(feature = "remote"))] -impl Registry for LocalRegistry { - fn lock(&self) -> ItemsGuard { - LocalItems { - marker: PhantomData, - } - } -} - -#[cfg(feature = "remote")] -pub struct RemoteItems { - next_id: Id, - tracked: FastHashMap, - free: Vec, -} - -#[cfg(feature = "remote")] -impl RemoteItems { - fn new() -> Self { - RemoteItems { - next_id: 0, - tracked: FastHashMap::default(), - free: Vec::new(), - } - } -} - -#[cfg(feature = "remote")] -impl Items for RemoteItems { - fn register(&mut self, handle: T) -> Id { - let id = match self.free.pop() { - Some(id) => id, - None => { - self.next_id += 1; - self.next_id - 1 - } - }; - self.tracked.insert(id, handle); - id - } - - fn get(&self, id: Id) -> Item { - self.tracked.get(&id).unwrap() - } - - fn get_mut(&mut self, id: Id) -> ItemMut { - self.tracked.get_mut(&id).unwrap() - } - - fn take(&mut self, id: Id) -> T { - self.free.push(id); - self.tracked.remove(&id).unwrap() - } -} - -#[cfg(feature = "remote")] -pub struct RemoteRegistry { - items: Arc>>, -} -#[cfg(feature = "remote")] -impl Default for RemoteRegistry { - fn default() -> Self { - RemoteRegistry { - items: Arc::new(Mutex::new(RemoteItems::new())), - } - } -} -#[cfg(feature = "remote")] -impl Registry for RemoteRegistry { - fn lock(&self) -> ItemsGuard { - self.items.lock() - } -} - -#[cfg(not(feature = "remote"))] -type ConcreteRegistry = LocalRegistry; -#[cfg(feature = "remote")] -type ConcreteRegistry = RemoteRegistry; - -#[derive(Default)] -pub struct Hub { - pub(crate) instances: ConcreteRegistry, - pub(crate) adapters: ConcreteRegistry, - pub(crate) devices: ConcreteRegistry, - pub(crate) pipeline_layouts: ConcreteRegistry, - pub(crate) bind_group_layouts: ConcreteRegistry, - pub(crate) attachment_states: ConcreteRegistry, - pub(crate) blend_states: ConcreteRegistry, - pub(crate) depth_stencil_states: ConcreteRegistry, - pub(crate) shader_modules: ConcreteRegistry, - pub(crate) command_buffers: ConcreteRegistry, - pub(crate) render_pipelines: ConcreteRegistry, - pub(crate) render_passes: ConcreteRegistry, - pub(crate) compute_passes: ConcreteRegistry, -} - -lazy_static! { - pub static ref HUB: Hub = Hub::default(); -} diff --git a/wgpu-native/src/registry/local.rs b/wgpu-native/src/registry/local.rs new file mode 100644 index 000000000..e4e4bae6d --- /dev/null +++ b/wgpu-native/src/registry/local.rs @@ -0,0 +1,48 @@ +use std::marker::PhantomData; +use std::os::raw::c_void; + + +pub type Id = *mut c_void; +pub type ItemsGuard<'a, T> = Items; + +pub struct Items { + marker: PhantomData, +} + +impl super::Items for Items { + fn register(&mut self, handle: T) -> Id { + Box::into_raw(Box::new(handle)) as *mut _ as *mut c_void + } + + fn get(&self, id: Id) -> super::Item { + unsafe { (id as *mut T).as_ref() }.unwrap() + } + + fn get_mut(&mut self, id: Id) -> super::ItemMut { + unsafe { (id as *mut T).as_mut() }.unwrap() + } + + fn take(&mut self, id: Id) -> T { + unsafe { *Box::from_raw(id as *mut T) } + } +} + +pub struct Registry { + marker: PhantomData, +} + +impl Default for Registry { + fn default() -> Self { + Registry { + marker: PhantomData, + } + } +} + +impl super::Registry for Registry { + fn lock(&self) -> ItemsGuard { + Items { + marker: PhantomData, + } + } +} diff --git a/wgpu-native/src/registry/mod.rs b/wgpu-native/src/registry/mod.rs new file mode 100644 index 000000000..fecdf2c2b --- /dev/null +++ b/wgpu-native/src/registry/mod.rs @@ -0,0 +1,52 @@ +#[cfg(not(feature = "remote"))] +mod local; +#[cfg(feature = "remote")] +mod remote; + +#[cfg(not(feature = "remote"))] +pub use self::local::{Id, ItemsGuard, Registry as ConcreteRegistry}; +#[cfg(feature = "remote")] +pub use self::remote::{Id, ItemsGuard, Registry as ConcreteRegistry}; + +use { + AdapterHandle, AttachmentStateHandle, BindGroupLayoutHandle, BlendStateHandle, + CommandBufferHandle, DepthStencilStateHandle, DeviceHandle, InstanceHandle, + RenderPassHandle, ComputePassHandle, + PipelineLayoutHandle, RenderPipelineHandle, ShaderModuleHandle, +}; + + +type Item<'a, T> = &'a T; +type ItemMut<'a, T> = &'a mut T; + +pub trait Registry: Default { + fn lock(&self) -> ItemsGuard; +} + +pub trait Items { + fn register(&mut self, handle: T) -> Id; + fn get(&self, id: Id) -> Item; + fn get_mut(&mut self, id: Id) -> ItemMut; + fn take(&mut self, id: Id) -> T; +} + +#[derive(Default)] +pub struct Hub { + pub(crate) instances: ConcreteRegistry, + pub(crate) adapters: ConcreteRegistry, + pub(crate) devices: ConcreteRegistry, + pub(crate) pipeline_layouts: ConcreteRegistry, + pub(crate) bind_group_layouts: ConcreteRegistry, + pub(crate) attachment_states: ConcreteRegistry, + pub(crate) blend_states: ConcreteRegistry, + pub(crate) depth_stencil_states: ConcreteRegistry, + pub(crate) shader_modules: ConcreteRegistry, + pub(crate) command_buffers: ConcreteRegistry, + pub(crate) render_pipelines: ConcreteRegistry, + pub(crate) render_passes: ConcreteRegistry, + pub(crate) compute_passes: ConcreteRegistry, +} + +lazy_static! { + pub static ref HUB: Hub = Hub::default(); +} diff --git a/wgpu-native/src/registry/remote.rs b/wgpu-native/src/registry/remote.rs new file mode 100644 index 000000000..1253ef05e --- /dev/null +++ b/wgpu-native/src/registry/remote.rs @@ -0,0 +1,68 @@ +use hal::backend::FastHashMap; +use parking_lot::{Mutex, MutexGuard}; +use std::sync::Arc; + + +pub type Id = u32; +pub type ItemsGuard<'a, T> = MutexGuard<'a, Items>; + +pub struct Items { + next_id: Id, + tracked: FastHashMap, + free: Vec, +} + +impl Items { + fn new() -> Self { + Items { + next_id: 0, + tracked: FastHashMap::default(), + free: Vec::new(), + } + } +} + +impl super::Items for Items { + fn register(&mut self, handle: T) -> Id { + let id = match self.free.pop() { + Some(id) => id, + None => { + self.next_id += 1; + self.next_id - 1 + } + }; + self.tracked.insert(id, handle); + id + } + + fn get(&self, id: Id) -> super::Item { + self.tracked.get(&id).unwrap() + } + + fn get_mut(&mut self, id: Id) -> super::ItemMut { + self.tracked.get_mut(&id).unwrap() + } + + fn take(&mut self, id: Id) -> T { + self.free.push(id); + self.tracked.remove(&id).unwrap() + } +} + +pub struct Registry { + items: Arc>>, +} + +impl Default for Registry { + fn default() -> Self { + Registry { + items: Arc::new(Mutex::new(Items::new())), + } + } +} + +impl super::Registry for Registry { + fn lock(&self) -> ItemsGuard { + self.items.lock() + } +}