diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index e102aff42..4ccddf02d 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -95,7 +95,7 @@ fn check_unstable(state: &OpState, api_name: &str) { } pub type Instance = - std::sync::Arc>; + std::sync::Arc>; struct WebGpuAdapter(Instance, wgpu_core::id::AdapterId); impl Resource for WebGpuAdapter { @@ -324,7 +324,7 @@ pub async fn op_webgpu_request_adapter( } else { state.put(std::sync::Arc::new(wgpu_core::global::Global::new( "webgpu", - wgpu_core::hub::IdentityManagerFactory, + wgpu_core::identity::IdentityManagerFactory, wgpu_types::InstanceDescriptor { backends, dx12_shader_compiler: wgpu_types::Dx12Compiler::Fxc, diff --git a/player/src/bin/play.rs b/player/src/bin/play.rs index a2b309acb..3623737b6 100644 --- a/player/src/bin/play.rs +++ b/player/src/bin/play.rs @@ -48,7 +48,7 @@ fn main() { IdentityPassThroughFactory, wgt::InstanceDescriptor::default(), ); - let mut command_buffer_id_manager = wgc::hub::IdentityManager::default(); + let mut command_buffer_id_manager = wgc::identity::IdentityManager::default(); #[cfg(feature = "winit")] let surface = global.instance_create_surface( diff --git a/player/src/lib.rs b/player/src/lib.rs index 59f461074..bbf87a8cd 100644 --- a/player/src/lib.rs +++ b/player/src/lib.rs @@ -15,7 +15,9 @@ use std::{borrow::Cow, fmt::Debug, fs, marker::PhantomData, path::Path}; #[derive(Debug)] pub struct IdentityPassThrough(PhantomData); -impl wgc::hub::IdentityHandler for IdentityPassThrough { +impl wgc::identity::IdentityHandler + for IdentityPassThrough +{ type Input = I; fn process(&self, id: I, backend: wgt::Backend) -> I { let (index, epoch, _backend) = id.unzip(); @@ -26,7 +28,7 @@ impl wgc::hub::IdentityHandler for Ident pub struct IdentityPassThroughFactory; -impl wgc::hub::IdentityHandlerFactory +impl wgc::identity::IdentityHandlerFactory for IdentityPassThroughFactory { type Filter = IdentityPassThrough; @@ -34,7 +36,7 @@ impl wgc::hub::IdentityHandlerFactory IdentityPassThrough(PhantomData) } } -impl wgc::hub::GlobalIdentityHandlerFactory for IdentityPassThroughFactory {} +impl wgc::identity::GlobalIdentityHandlerFactory for IdentityPassThroughFactory {} pub trait GlobalPlay { fn encode_commands( @@ -47,7 +49,7 @@ pub trait GlobalPlay { device: wgc::id::DeviceId, action: trace::Action, dir: &Path, - comb_manager: &mut wgc::hub::IdentityManager, + comb_manager: &mut wgc::identity::IdentityManager, ); } @@ -151,7 +153,7 @@ impl GlobalPlay for wgc::global::Global { device: wgc::id::DeviceId, action: trace::Action, dir: &Path, - comb_manager: &mut wgc::hub::IdentityManager, + comb_manager: &mut wgc::identity::IdentityManager, ) { use wgc::device::trace::Action; log::info!("action {:?}", action); diff --git a/player/tests/test.rs b/player/tests/test.rs index aae768159..7534e04b5 100644 --- a/player/tests/test.rs +++ b/player/tests/test.rs @@ -98,7 +98,7 @@ impl Test<'_> { panic!("{:?}", e); } - let mut command_buffer_id_manager = wgc::hub::IdentityManager::default(); + let mut command_buffer_id_manager = wgc::identity::IdentityManager::default(); println!("\t\t\tRunning..."); for action in self.actions { wgc::gfx_select!(device => global.process(device, action, dir, &mut command_buffer_id_manager)); diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index b98f9eb32..8372c41c8 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -91,8 +91,9 @@ use crate::{ }, error::{ErrorFormatter, PrettyError}, hal_api::HalApi, - hub::{GlobalIdentityHandlerFactory, Hub, Resource, Storage, Token}, + hub::{Hub, Resource, Storage, Token}, id, + identity::GlobalIdentityHandlerFactory, init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction}, pipeline::{self, PipelineFlags}, resource, diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index 964d47a0b..a180c3343 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -7,8 +7,9 @@ use crate::{ get_lowest_common_denom, global::Global, hal_api::HalApi, - hub::{self, GlobalIdentityHandlerFactory, Token}, + hub::{self, Token}, id::{BufferId, CommandEncoderId, DeviceId, TextureId, Valid}, + identity::GlobalIdentityHandlerFactory, init_tracker::{MemoryInitKind, TextureInitRange}, resource::{Texture, TextureClearMode}, track::{TextureSelector, TextureTracker}, diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index 59dcfaf49..bd5c26095 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -13,8 +13,9 @@ use crate::{ error::{ErrorFormatter, PrettyError}, global::Global, hal_api::HalApi, - hub::{GlobalIdentityHandlerFactory, Storage, Token}, + hub::{Storage, Token}, id, + identity::GlobalIdentityHandlerFactory, init_tracker::MemoryInitKind, pipeline, resource::{self, Buffer, Texture}, diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 90bcb261f..627bc80d7 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -23,8 +23,9 @@ use crate::track::{Tracker, UsageScope}; use crate::{ global::Global, hal_api::HalApi, - hub::{GlobalIdentityHandlerFactory, Storage, Token}, + hub::{Storage, Token}, id, + identity::GlobalIdentityHandlerFactory, resource::{Buffer, Texture}, Label, Stored, }; diff --git a/wgpu-core/src/command/query.rs b/wgpu-core/src/command/query.rs index bc1a38c29..b319f7ff3 100644 --- a/wgpu-core/src/command/query.rs +++ b/wgpu-core/src/command/query.rs @@ -6,8 +6,9 @@ use crate::{ command::{CommandBuffer, CommandEncoderError}, global::Global, hal_api::HalApi, - hub::{GlobalIdentityHandlerFactory, Storage, Token}, + hub::{Storage, Token}, id::{self, Id, TypedId}, + identity::GlobalIdentityHandlerFactory, init_tracker::MemoryInitKind, resource::QuerySet, Epoch, FastHashMap, Index, diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 13d872453..6aaa49858 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -16,8 +16,9 @@ use crate::{ error::{ErrorFormatter, PrettyError}, global::Global, hal_api::HalApi, - hub::{GlobalIdentityHandlerFactory, Storage, Token}, + hub::{Storage, Token}, id, + identity::GlobalIdentityHandlerFactory, init_tracker::{MemoryInitKind, TextureInitRange, TextureInitTrackerAction}, pipeline::{self, PipelineFlags}, resource::{self, Buffer, Texture, TextureView, TextureViewNotRenderableReason}, diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 339f35611..3a1763f09 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -7,8 +7,9 @@ use crate::{ error::{ErrorFormatter, PrettyError}, global::Global, hal_api::HalApi, - hub::{GlobalIdentityHandlerFactory, Storage, Token}, + hub::{Storage, Token}, id::{BufferId, CommandEncoderId, TextureId, Valid}, + identity::GlobalIdentityHandlerFactory, init_tracker::{ has_copy_partial_init_tracker_coverage, MemoryInitKind, TextureInitRange, TextureInitTrackerAction, diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 4d78926a6..75491d10c 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -6,8 +6,10 @@ use crate::{ DeviceError, }, hal_api::HalApi, - hub::{GlobalIdentityHandlerFactory, Hub, Token}, - id, resource, + hub::{Hub, Token}, + id, + identity::GlobalIdentityHandlerFactory, + resource, track::{BindGroupStates, RenderBundleScope, Tracker}, RefCount, Stored, SubmissionIndex, }; diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 4fcc97494..c688b6402 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -3,8 +3,9 @@ use crate::{ device::life::WaitIdleError, global::Global, hal_api::HalApi, - hub::{GlobalIdentityHandlerFactory, Hub, Input, InvalidId, Storage, Token}, + hub::{Hub, InvalidId, Storage, Token}, id, + identity::{GlobalIdentityHandlerFactory, Input}, init_tracker::{ BufferInitTracker, BufferInitTrackerAction, MemoryInitKind, TextureInitRange, TextureInitTracker, TextureInitTrackerAction, diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 6710d7dba..162c3cc4a 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -10,8 +10,9 @@ use crate::{ get_lowest_common_denom, global::Global, hal_api::HalApi, - hub::{GlobalIdentityHandlerFactory, Input, Token}, + hub::Token, id, + identity::{GlobalIdentityHandlerFactory, Input}, init_tracker::{has_copy_partial_init_tracker_coverage, TextureInitRange}, resource::{BufferAccessError, BufferMapState, StagingBuffer, TextureInner}, track, FastHashSet, SubmissionIndex, diff --git a/wgpu-core/src/error.rs b/wgpu-core/src/error.rs index f2e086cee..9a32e1f19 100644 --- a/wgpu-core/src/error.rs +++ b/wgpu-core/src/error.rs @@ -1,7 +1,7 @@ use core::fmt; use std::error::Error; -use crate::{gfx_select, global::Global, hub::IdentityManagerFactory}; +use crate::{gfx_select, global::Global, identity::IdentityManagerFactory}; pub struct ErrorFormatter<'a> { writer: &'a mut dyn fmt::Write, diff --git a/wgpu-core/src/global.rs b/wgpu-core/src/global.rs index e5c9023f7..979835a34 100644 --- a/wgpu-core/src/global.rs +++ b/wgpu-core/src/global.rs @@ -1,10 +1,10 @@ use crate::{ hal_api::HalApi, - hub::GlobalIdentityHandlerFactory, hub::Registry, hub::{Element, StorageReport}, hub::{HubReport, Hubs}, id, + identity::GlobalIdentityHandlerFactory, instance::{Instance, Surface}, }; @@ -156,7 +156,7 @@ impl Drop for Global { } #[cfg(test)] -fn _test_send_sync(global: &Global) { +fn _test_send_sync(global: &Global) { fn test_internal(_: T) {} test_internal(global) } diff --git a/wgpu-core/src/hal_api.rs b/wgpu-core/src/hal_api.rs index 0e7d0948c..00180d8ac 100644 --- a/wgpu-core/src/hal_api.rs +++ b/wgpu-core/src/hal_api.rs @@ -2,7 +2,8 @@ use wgt::Backend; use crate::{ global::Global, - hub::{GlobalIdentityHandlerFactory, Hub}, + hub::Hub, + identity::GlobalIdentityHandlerFactory, instance::{HalSurface, Instance, Surface}, }; diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 0468c42bc..ba546d8a8 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -148,6 +148,8 @@ flagged as errors as well. [`Id`]: crate::id::Id [wrapped in a mutex]: trait.IdentityHandler.html#impl-IdentityHandler%3CI%3E-for-Mutex%3CIdentityManager%3E [WebGPU]: https://www.w3.org/TR/webgpu/ +[`IdentityManager`]: crate::identity::IdentityManager +[`Input`]: crate::identity::Input */ @@ -157,93 +159,20 @@ use crate::{ device::Device, hal_api::HalApi, id, + identity::{GlobalIdentityHandlerFactory, IdentityHandler, IdentityHandlerFactory}, instance::{Adapter, HalSurface, Instance, Surface}, pipeline::{ComputePipeline, RenderPipeline, ShaderModule}, resource::{Buffer, QuerySet, Sampler, StagingBuffer, Texture, TextureClearMode, TextureView}, Epoch, Index, }; -use parking_lot::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}; +use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; use wgt::Backend; #[cfg(debug_assertions)] use std::cell::Cell; use std::{fmt::Debug, marker::PhantomData, mem, ops}; -/// A simple structure to allocate [`Id`] identifiers. -/// -/// Calling [`alloc`] returns a fresh, never-before-seen id. Calling [`free`] -/// marks an id as dead; it will never be returned again by `alloc`. -/// -/// Use `IdentityManager::default` to construct new instances. -/// -/// `IdentityManager` returns `Id`s whose index values are suitable for use as -/// indices into a `Storage` that holds those ids' referents: -/// -/// - Every live id has a distinct index value. Each live id's index selects a -/// distinct element in the vector. -/// -/// - `IdentityManager` prefers low index numbers. If you size your vector to -/// accommodate the indices produced here, the vector's length will reflect -/// the highwater mark of actual occupancy. -/// -/// - `IdentityManager` reuses the index values of freed ids before returning -/// ids with new index values. Freed vector entries get reused. -/// -/// See the module-level documentation for an overview of how this -/// fits together. -/// -/// [`Id`]: crate::id::Id -/// [`Backend`]: wgt::Backend; -/// [`alloc`]: IdentityManager::alloc -/// [`free`]: IdentityManager::free -#[derive(Debug, Default)] -pub struct IdentityManager { - /// Available index values. If empty, then `epochs.len()` is the next index - /// to allocate. - free: Vec, - - /// The next or currently-live epoch value associated with each `Id` index. - /// - /// If there is a live id with index `i`, then `epochs[i]` is its epoch; any - /// id with the same index but an older epoch is dead. - /// - /// If index `i` is currently unused, `epochs[i]` is the epoch to use in its - /// next `Id`. - epochs: Vec, -} - -impl IdentityManager { - /// Allocate a fresh, never-before-seen id with the given `backend`. - /// - /// The backend is incorporated into the id, so that ids allocated with - /// different `backend` values are always distinct. - pub fn alloc(&mut self, backend: Backend) -> I { - match self.free.pop() { - Some(index) => I::zip(index, self.epochs[index as usize], backend), - None => { - let epoch = 1; - let id = I::zip(self.epochs.len() as Index, epoch, backend); - self.epochs.push(epoch); - id - } - } - } - - /// Free `id`. It will never be returned from `alloc` again. - pub fn free(&mut self, id: I) { - let (index, epoch, _backend) = id.unzip(); - let pe = &mut self.epochs[index as usize]; - assert_eq!(*pe, epoch); - // If the epoch reaches EOL, the index doesn't go - // into the free list, will never be reused again. - if epoch < id::EPOCH_MASK { - *pe = epoch + 1; - self.free.push(index); - } - } -} - /// An entry in a `Storage::map` table. #[derive(Debug)] pub(crate) enum Element { @@ -654,96 +583,6 @@ impl<'a, T> Drop for Token<'a, T> { } } -/// A type that can build true ids from proto-ids, and free true ids. -/// -/// For some implementations, the true id is based on the proto-id. -/// The caller is responsible for providing well-allocated proto-ids. -/// -/// For other implementations, the proto-id carries no information -/// (it's `()`, say), and this `IdentityHandler` type takes care of -/// allocating a fresh true id. -/// -/// See the module-level documentation for details. -pub trait IdentityHandler: Debug { - /// The type of proto-id consumed by this filter, to produce a true id. - type Input: Clone + Debug; - - /// Given a proto-id value `id`, return a true id for `backend`. - fn process(&self, id: Self::Input, backend: Backend) -> I; - - /// Free the true id `id`. - fn free(&self, id: I); -} - -impl IdentityHandler for Mutex { - type Input = (); - fn process(&self, _id: Self::Input, backend: Backend) -> I { - self.lock().alloc(backend) - } - fn free(&self, id: I) { - self.lock().free(id) - } -} - -/// A type that can produce [`IdentityHandler`] filters for ids of type `I`. -/// -/// See the module-level documentation for details. -pub trait IdentityHandlerFactory { - /// The type of filter this factory constructs. - /// - /// "Filter" and "handler" seem to both mean the same thing here: - /// something that can produce true ids from proto-ids. - type Filter: IdentityHandler; - - /// Create an [`IdentityHandler`] implementation that can - /// transform proto-ids into ids of type `I`. - /// - /// [`IdentityHandler`]: IdentityHandler - fn spawn(&self) -> Self::Filter; -} - -/// A global identity handler factory based on [`IdentityManager`]. -/// -/// Each of this type's `IdentityHandlerFactory::spawn` methods -/// returns a `Mutex>`, which allocates fresh `I` -/// ids itself, and takes `()` as its proto-id type. -#[derive(Debug)] -pub struct IdentityManagerFactory; - -impl IdentityHandlerFactory for IdentityManagerFactory { - type Filter = Mutex; - fn spawn(&self) -> Self::Filter { - Mutex::new(IdentityManager::default()) - } -} - -/// A factory that can build [`IdentityHandler`]s for all resource -/// types. -pub trait GlobalIdentityHandlerFactory: - IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory - + IdentityHandlerFactory -{ -} - -impl GlobalIdentityHandlerFactory for IdentityManagerFactory {} - -pub type Input = <>::Filter as IdentityHandler>::Input; - pub trait Resource { const TYPE: &'static str; fn life_guard(&self) -> &crate::LifeGuard; @@ -1293,17 +1132,3 @@ impl Hubs { } } } - -#[test] -fn test_epoch_end_of_life() { - use id::TypedId as _; - let mut man = IdentityManager::default(); - man.epochs.push(id::EPOCH_MASK); - man.free.push(0); - let id1 = man.alloc::(Backend::Empty); - assert_eq!(id1.unzip().0, 0); - man.free(id1); - let id2 = man.alloc::(Backend::Empty); - // confirm that the index 0 is no longer re-used - assert_eq!(id2.unzip().0, 1); -} diff --git a/wgpu-core/src/identity.rs b/wgpu-core/src/identity.rs new file mode 100644 index 000000000..5f7cc0dc5 --- /dev/null +++ b/wgpu-core/src/identity.rs @@ -0,0 +1,183 @@ +use parking_lot::Mutex; +use wgt::Backend; + +use crate::{id, Epoch, Index}; +use std::fmt::Debug; + +/// A simple structure to allocate [`Id`] identifiers. +/// +/// Calling [`alloc`] returns a fresh, never-before-seen id. Calling [`free`] +/// marks an id as dead; it will never be returned again by `alloc`. +/// +/// Use `IdentityManager::default` to construct new instances. +/// +/// `IdentityManager` returns `Id`s whose index values are suitable for use as +/// indices into a `Storage` that holds those ids' referents: +/// +/// - Every live id has a distinct index value. Each live id's index selects a +/// distinct element in the vector. +/// +/// - `IdentityManager` prefers low index numbers. If you size your vector to +/// accommodate the indices produced here, the vector's length will reflect +/// the highwater mark of actual occupancy. +/// +/// - `IdentityManager` reuses the index values of freed ids before returning +/// ids with new index values. Freed vector entries get reused. +/// +/// See the module-level documentation for an overview of how this +/// fits together. +/// +/// [`Id`]: crate::id::Id +/// [`Backend`]: wgt::Backend; +/// [`alloc`]: IdentityManager::alloc +/// [`free`]: IdentityManager::free +#[derive(Debug, Default)] +pub struct IdentityManager { + /// Available index values. If empty, then `epochs.len()` is the next index + /// to allocate. + free: Vec, + + /// The next or currently-live epoch value associated with each `Id` index. + /// + /// If there is a live id with index `i`, then `epochs[i]` is its epoch; any + /// id with the same index but an older epoch is dead. + /// + /// If index `i` is currently unused, `epochs[i]` is the epoch to use in its + /// next `Id`. + epochs: Vec, +} + +impl IdentityManager { + /// Allocate a fresh, never-before-seen id with the given `backend`. + /// + /// The backend is incorporated into the id, so that ids allocated with + /// different `backend` values are always distinct. + pub fn alloc(&mut self, backend: Backend) -> I { + match self.free.pop() { + Some(index) => I::zip(index, self.epochs[index as usize], backend), + None => { + let epoch = 1; + let id = I::zip(self.epochs.len() as Index, epoch, backend); + self.epochs.push(epoch); + id + } + } + } + + /// Free `id`. It will never be returned from `alloc` again. + pub fn free(&mut self, id: I) { + let (index, epoch, _backend) = id.unzip(); + let pe = &mut self.epochs[index as usize]; + assert_eq!(*pe, epoch); + // If the epoch reaches EOL, the index doesn't go + // into the free list, will never be reused again. + if epoch < id::EPOCH_MASK { + *pe = epoch + 1; + self.free.push(index); + } + } +} + +/// A type that can build true ids from proto-ids, and free true ids. +/// +/// For some implementations, the true id is based on the proto-id. +/// The caller is responsible for providing well-allocated proto-ids. +/// +/// For other implementations, the proto-id carries no information +/// (it's `()`, say), and this `IdentityHandler` type takes care of +/// allocating a fresh true id. +/// +/// See the module-level documentation for details. +pub trait IdentityHandler: Debug { + /// The type of proto-id consumed by this filter, to produce a true id. + type Input: Clone + Debug; + + /// Given a proto-id value `id`, return a true id for `backend`. + fn process(&self, id: Self::Input, backend: Backend) -> I; + + /// Free the true id `id`. + fn free(&self, id: I); +} + +impl IdentityHandler for Mutex { + type Input = (); + fn process(&self, _id: Self::Input, backend: Backend) -> I { + self.lock().alloc(backend) + } + fn free(&self, id: I) { + self.lock().free(id) + } +} + +/// A type that can produce [`IdentityHandler`] filters for ids of type `I`. +/// +/// See the module-level documentation for details. +pub trait IdentityHandlerFactory { + /// The type of filter this factory constructs. + /// + /// "Filter" and "handler" seem to both mean the same thing here: + /// something that can produce true ids from proto-ids. + type Filter: IdentityHandler; + + /// Create an [`IdentityHandler`] implementation that can + /// transform proto-ids into ids of type `I`. + /// + /// [`IdentityHandler`]: IdentityHandler + fn spawn(&self) -> Self::Filter; +} + +/// A global identity handler factory based on [`IdentityManager`]. +/// +/// Each of this type's `IdentityHandlerFactory::spawn` methods +/// returns a `Mutex>`, which allocates fresh `I` +/// ids itself, and takes `()` as its proto-id type. +#[derive(Debug)] +pub struct IdentityManagerFactory; + +impl IdentityHandlerFactory for IdentityManagerFactory { + type Filter = Mutex; + fn spawn(&self) -> Self::Filter { + Mutex::new(IdentityManager::default()) + } +} + +/// A factory that can build [`IdentityHandler`]s for all resource +/// types. +pub trait GlobalIdentityHandlerFactory: + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory + + IdentityHandlerFactory +{ +} + +impl GlobalIdentityHandlerFactory for IdentityManagerFactory {} + +pub type Input = <>::Filter as IdentityHandler>::Input; + +#[test] +fn test_epoch_end_of_life() { + use id::TypedId as _; + let mut man = IdentityManager::default(); + man.epochs.push(id::EPOCH_MASK); + man.free.push(0); + let id1 = man.alloc::(Backend::Empty); + assert_eq!(id1.unzip().0, 0); + man.free(id1); + let id2 = man.alloc::(Backend::Empty); + // confirm that the index 0 is no longer re-used + assert_eq!(id2.unzip().0, 1); +} diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index c30af3093..9615a772c 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -2,8 +2,9 @@ use crate::{ device::{Device, DeviceDescriptor}, global::Global, hal_api::HalApi, - hub::{GlobalIdentityHandlerFactory, Input, Token}, + hub::Token, id::{AdapterId, DeviceId, SurfaceId, Valid}, + identity::{GlobalIdentityHandlerFactory, Input}, present::Presentation, LabelHelpers, LifeGuard, Stored, DOWNLEVEL_WARNING_MESSAGE, }; diff --git a/wgpu-core/src/lib.rs b/wgpu-core/src/lib.rs index 122e71984..52d03df6f 100644 --- a/wgpu-core/src/lib.rs +++ b/wgpu-core/src/lib.rs @@ -46,6 +46,7 @@ pub mod global; pub mod hal_api; pub mod hub; pub mod id; +pub mod identity; mod init_tracker; pub mod instance; pub mod pipeline; diff --git a/wgpu-core/src/present.rs b/wgpu-core/src/present.rs index e28ddbf1a..c9df46ad9 100644 --- a/wgpu-core/src/present.rs +++ b/wgpu-core/src/present.rs @@ -18,8 +18,9 @@ use crate::{ device::{DeviceError, MissingDownlevelFlags}, global::Global, hal_api::HalApi, - hub::{GlobalIdentityHandlerFactory, Input, Token}, + hub::Token, id::{DeviceId, SurfaceId, TextureId, Valid}, + identity::{GlobalIdentityHandlerFactory, Input}, init_tracker::TextureInitTracker, resource, track, LifeGuard, Stored, }; diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 20a79f538..c4aaa003e 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -2,8 +2,9 @@ use crate::{ device::{DeviceError, HostMap, MissingDownlevelFlags, MissingFeatures}, global::Global, hal_api::HalApi, - hub::{GlobalIdentityHandlerFactory, Resource, Token}, + hub::{Resource, Token}, id::{AdapterId, DeviceId, SurfaceId, TextureId, Valid}, + identity::GlobalIdentityHandlerFactory, init_tracker::{BufferInitTracker, TextureInitTracker}, track::TextureSelector, validation::MissingBufferUsageError, diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 62b4b70ca..d9e108593 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -26,7 +26,7 @@ use wgc::id::TypedId; const LABEL: &str = "label"; -pub struct Context(wgc::global::Global); +pub struct Context(wgc::global::Global); impl Drop for Context { fn drop(&mut self) { @@ -45,7 +45,7 @@ impl Context { Self(unsafe { wgc::global::Global::from_hal_instance::( "wgpu", - wgc::hub::IdentityManagerFactory, + wgc::identity::IdentityManagerFactory, hal_instance, ) }) @@ -60,11 +60,11 @@ impl Context { pub unsafe fn from_core_instance(core_instance: wgc::instance::Instance) -> Self { Self(unsafe { - wgc::global::Global::from_instance(wgc::hub::IdentityManagerFactory, core_instance) + wgc::global::Global::from_instance(wgc::identity::IdentityManagerFactory, core_instance) }) } - pub(crate) fn global(&self) -> &wgc::global::Global { + pub(crate) fn global(&self) -> &wgc::global::Global { &self.0 } @@ -542,7 +542,7 @@ impl crate::Context for Context { fn init(instance_desc: wgt::InstanceDescriptor) -> Self { Self(wgc::global::Global::new( "wgpu", - wgc::hub::IdentityManagerFactory, + wgc::identity::IdentityManagerFactory, instance_desc, )) }