diff --git a/wgpu-native/src/command/mod.rs b/wgpu-native/src/command/mod.rs index cb24c8feb0..fb5e07a242 100644 --- a/wgpu-native/src/command/mod.rs +++ b/wgpu-native/src/command/mod.rs @@ -99,8 +99,8 @@ impl CommandBufferHandle { base: &mut TrackerSet, head: &TrackerSet, stitch: Stitch, - buffer_guard: &Storage, - texture_guard: &Storage, + buffer_guard: &Storage, + texture_guard: &Storage, ) { let buffer_barriers = base.buffers diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index 01201f217a..0252609e73 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -802,7 +802,7 @@ pub fn texture_create_view( } } -pub fn device_track_view(texture_id: TextureId, view_id: BufferId, ref_count: RefCount) { +pub fn device_track_view(texture_id: TextureId, view_id: TextureViewId, ref_count: RefCount) { let device_id = HUB.textures.read()[texture_id].device_id.value; let query = HUB.devices.read()[device_id] .trackers diff --git a/wgpu-native/src/hub.rs b/wgpu-native/src/hub.rs index 14ad6e7559..c0b7cf268a 100644 --- a/wgpu-native/src/hub.rs +++ b/wgpu-native/src/hub.rs @@ -87,107 +87,112 @@ impl IdentityManager { } } -pub struct Storage { +pub struct Storage { //TODO: consider concurrent hashmap? map: VecMap<(T, Epoch)>, + _phantom: std::marker::PhantomData<&'static I>, } -impl ops::Index for Storage { +impl ops::Index for Storage { type Output = T; - fn index(&self, id: Id) -> &T { - let (ref value, epoch) = self.map[id.0 as usize]; - assert_eq!(epoch, id.1); + fn index(&self, id: I) -> &T { + let (ref value, epoch) = self.map[id.id().0 as usize]; + assert_eq!(epoch, id.id().1); value } } -impl ops::IndexMut for Storage { - fn index_mut(&mut self, id: Id) -> &mut T { - let (ref mut value, epoch) = self.map[id.0 as usize]; - assert_eq!(epoch, id.1); +impl ops::IndexMut for Storage { + fn index_mut(&mut self, id: I) -> &mut T { + let (ref mut value, epoch) = self.map[id.id().0 as usize]; + assert_eq!(epoch, id.id().1); value } } -impl Storage { - pub fn contains(&self, id: Id) -> bool { - match self.map.get(id.0 as usize) { - Some(&(_, epoch)) if epoch == id.1 => true, +impl Storage { + pub fn contains(&self, id: I) -> bool { + match self.map.get(id.id().0 as usize) { + Some(&(_, epoch)) if epoch == id.id().1 => true, _ => false, } } } -pub struct Registry { +use crate::ToId; +pub struct Registry> { #[cfg(feature = "local")] identity: Mutex, - data: RwLock>, + data: RwLock>, + _phantom: std::marker::PhantomData<&'static I>, } -impl Default for Registry { +impl> Default for Registry { fn default() -> Self { Registry { #[cfg(feature = "local")] identity: Mutex::new(IdentityManager::default()), - data: RwLock::new(Storage { map: VecMap::new() }), + data: RwLock::new(Storage { map: VecMap::new(), _phantom: std::marker::PhantomData }), + _phantom: std::marker::PhantomData, } } } -impl ops::Deref for Registry { - type Target = RwLock>; +impl> ops::Deref for Registry { + type Target = RwLock>; fn deref(&self) -> &Self::Target { &self.data } } -impl ops::DerefMut for Registry { +impl> ops::DerefMut for Registry { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.data } } -impl Registry { - pub fn register(&self, id: Id, value: T) { - let old = self.data.write().map.insert(id.0 as usize, (value, id.1)); +impl + Clone> Registry { + pub fn register(&self, id: I, value: T) { + let old = self.data.write().map.insert(id.id().0 as usize, (value, id.id().1)); assert!(old.is_none()); } #[cfg(feature = "local")] - pub fn register_local(&self, value: T) -> Id { - let id = self.identity.lock().alloc(); - self.register(id, value); + pub fn register_local(&self, value: T) -> I { + let raw_id = self.identity.lock().alloc(); + let id:I = raw_id.into(); + self.register(id.clone(), value); id } - pub fn unregister(&self, id: Id) -> T { + pub fn unregister(&self, id: I) -> T { #[cfg(feature = "local")] - self.identity.lock().free(id); - let (value, epoch) = self.data.write().map.remove(id.0 as usize).unwrap(); - assert_eq!(epoch, id.1); + self.identity.lock().free(id.id()); + let (value, epoch) = self.data.write().map.remove(id.id().0 as usize).unwrap(); + assert_eq!(epoch, id.id().1); value } } - +use crate::*; #[derive(Default)] pub struct Hub { - pub instances: Arc>, - pub adapters: Arc>, - pub devices: Arc>, - pub pipeline_layouts: Arc>, - pub bind_group_layouts: Arc>, - pub bind_groups: Arc>, - pub shader_modules: Arc>, - pub command_buffers: Arc>, - pub render_pipelines: Arc>, - pub compute_pipelines: Arc>, - pub render_passes: Arc>, - pub compute_passes: Arc>, - pub buffers: Arc>, - pub textures: Arc>, - pub texture_views: Arc>, - pub samplers: Arc>, - pub surfaces: Arc>, + pub instances: Arc>, + pub adapters: Arc>, + pub devices: Arc>, + pub pipeline_layouts: Arc>, + pub bind_group_layouts: Arc>, + pub bind_groups: Arc>, + pub shader_modules: Arc>, + pub command_buffers: Arc>, + pub render_pipelines: Arc>, + pub compute_pipelines: Arc>, + pub render_passes: Arc>, + pub compute_passes: Arc>, + pub buffers: Arc>, + pub textures: Arc>, + pub texture_views: Arc>, + pub samplers: Arc>, + pub surfaces: Arc>, } lazy_static! { diff --git a/wgpu-native/src/lib.rs b/wgpu-native/src/lib.rs index 5b64d54946..fb17c265c0 100644 --- a/wgpu-native/src/lib.rs +++ b/wgpu-native/src/lib.rs @@ -166,46 +166,157 @@ pub struct ByteArray { pub length: usize, } -pub type InstanceId = hub::Id; +macro_rules! transparent { + ($i:item) => ( + #[repr(transparent)] + #[derive(Clone, Copy, Debug, Hash, PartialEq)] + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + $i + ) +} + +pub trait ToId { + fn id(&self) -> hub::Id; +} + +macro_rules! to_id { + ($i:ident) => ( + impl ToId for $i { + fn id(&self) -> hub::Id { + self.0 + } + } + ) +} + +macro_rules! from_id { + ($i:ident) => ( + impl From for $i { + fn from(id:hub::Id) -> $i { + $i(id) + } + } + ) +} + +use hub::{Index, Epoch, NewId, Id}; +macro_rules! new_id { + ($i:ident) => ( + impl NewId for $i { + fn new(index: Index, epoch: Epoch) -> Self { + let id = Id::new(index, epoch); + $i(id) + } + + fn index(&self) -> Index { + (self.id()).index() + } + + fn epoch(&self) -> Epoch { + (self.id()).epoch() + } + } + ) +} + +transparent!(pub struct InstanceId(hub::Id);); +to_id!(InstanceId); +from_id!(InstanceId); type InstanceHandle = back::Instance; -pub type AdapterId = hub::Id; + +transparent!(pub struct AdapterId(hub::Id);); +to_id!(AdapterId); +from_id!(AdapterId); type AdapterHandle = hal::Adapter; -pub type DeviceId = hub::Id; + +transparent!(pub struct DeviceId(hub::Id);); +to_id!(DeviceId); +from_id!(DeviceId); type DeviceHandle = Device; +//transparent!(pub struct QueueId(DeviceId);); pub type QueueId = DeviceId; -pub type BufferId = hub::Id; + +transparent!(pub struct BufferId(hub::Id);); +to_id!(BufferId); +from_id!(BufferId); +new_id!(BufferId); type BufferHandle = Buffer; + // Resource -pub type TextureViewId = hub::Id; +transparent!(pub struct TextureViewId(hub::Id);); +to_id!(TextureViewId); +from_id!(TextureViewId); +new_id!(TextureViewId); type TextureViewHandle = TextureView; -pub type TextureId = hub::Id; + +transparent!(pub struct TextureId(hub::Id);); +to_id!(TextureId); +from_id!(TextureId); +new_id!(TextureId); type TextureHandle = Texture; -pub type SamplerId = hub::Id; + +transparent!(pub struct SamplerId(hub::Id);); +to_id!(SamplerId); +from_id!(SamplerId); type SamplerHandle = Sampler; + // Binding model -pub type BindGroupLayoutId = hub::Id; +transparent!(pub struct BindGroupLayoutId(hub::Id);); +to_id!(BindGroupLayoutId); +from_id!(BindGroupLayoutId); type BindGroupLayoutHandle = BindGroupLayout; -pub type PipelineLayoutId = hub::Id; + +transparent!(pub struct PipelineLayoutId(hub::Id);); +to_id!(PipelineLayoutId); +from_id!(PipelineLayoutId); type PipelineLayoutHandle = PipelineLayout; -pub type BindGroupId = hub::Id; + +transparent!(pub struct BindGroupId(hub::Id);); +to_id!(BindGroupId); +from_id!(BindGroupId); type BindGroupHandle = BindGroup; + // Pipeline -pub type InputStateId = hub::Id; -pub type ShaderModuleId = hub::Id; +transparent!(pub struct InputStateId(hub::Id);); +to_id!(InputStateId); +from_id!(InputStateId); +transparent!(pub struct ShaderModuleId(hub::Id);); +to_id!(ShaderModuleId); +from_id!(ShaderModuleId); type ShaderModuleHandle = ShaderModule; -pub type RenderPipelineId = hub::Id; + +transparent!(pub struct RenderPipelineId(hub::Id);); +to_id!(RenderPipelineId); +from_id!(RenderPipelineId); type RenderPipelineHandle = RenderPipeline; -pub type ComputePipelineId = hub::Id; + +transparent!(pub struct ComputePipelineId(hub::Id);); +to_id!(ComputePipelineId); +from_id!(ComputePipelineId); type ComputePipelineHandle = ComputePipeline; + // Command -pub type CommandBufferId = hub::Id; +transparent!(pub struct CommandBufferId(hub::Id);); +to_id!(CommandBufferId); +from_id!(CommandBufferId); type CommandBufferHandle = CommandBuffer; +//transparent!(pub struct CommandEncoderId(CommandBufferId);); pub type CommandEncoderId = CommandBufferId; -pub type RenderPassId = hub::Id; + +transparent!(pub struct RenderPassId(hub::Id);); +to_id!(RenderPassId); +from_id!(RenderPassId); type RenderPassHandle = RenderPass; -pub type ComputePassId = hub::Id; + +transparent!(pub struct ComputePassId(hub::Id);); +to_id!(ComputePassId); +from_id!(ComputePassId); type ComputePassHandle = ComputePass; + // Swap chain -pub type SurfaceId = hub::Id; +transparent!(pub struct SurfaceId(hub::Id);); +to_id!(SurfaceId); +from_id!(SurfaceId); type SurfaceHandle = Surface; +//transparent!(pub struct SwapChainId(SurfaceId);); pub type SwapChainId = SurfaceId; diff --git a/wgpu-native/src/track.rs b/wgpu-native/src/track.rs index 83f130f4ad..dd4a70c5df 100644 --- a/wgpu-native/src/track.rs +++ b/wgpu-native/src/track.rs @@ -276,37 +276,37 @@ impl + PartialEq> Tracker + PartialEq> Tracker { +impl + PartialEq> Tracker { fn _get_with_usage<'a, T: 'a + Borrow>( &mut self, - storage: &'a Storage, - id: Id, + storage: &'a Storage, + id: I, usage: U, permit: TrackPermit, ) -> Result<(&'a T, Tracktion), U> { - let item = &storage[id]; + let item = &storage[id.clone()]; self.transit(id, item.borrow(), usage, permit) .map(|tracktion| (item, tracktion)) } pub(crate) fn get_with_extended_usage<'a, T: 'a + Borrow>( &mut self, - storage: &'a Storage, - id: Id, + storage: &'a Storage, + id: I, usage: U, ) -> Result<&'a T, U> { - let item = &storage[id]; + let item = &storage[id.clone()]; self.transit(id, item.borrow(), usage, TrackPermit::EXTEND) .map(|_tracktion| item) } pub(crate) fn get_with_replaced_usage<'a, T: 'a + Borrow>( &mut self, - storage: &'a Storage, - id: Id, + storage: &'a Storage, + id: I, usage: U, ) -> Result<(&'a T, Option), U> { - let item = &storage[id]; + let item = &storage[id.clone()]; self.transit(id, item.borrow(), usage, TrackPermit::REPLACE) .map(|tracktion| { (