mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-26 00:33:51 +00:00
Use strong type
This commit is contained in:
parent
1e177d0813
commit
44cf64495a
@ -99,8 +99,8 @@ impl CommandBufferHandle {
|
||||
base: &mut TrackerSet,
|
||||
head: &TrackerSet,
|
||||
stitch: Stitch,
|
||||
buffer_guard: &Storage<BufferHandle>,
|
||||
texture_guard: &Storage<TextureHandle>,
|
||||
buffer_guard: &Storage<BufferHandle, crate::BufferId>,
|
||||
texture_guard: &Storage<TextureHandle, crate::TextureId>,
|
||||
) {
|
||||
let buffer_barriers =
|
||||
base.buffers
|
||||
|
@ -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
|
||||
|
@ -87,107 +87,112 @@ impl IdentityManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Storage<T> {
|
||||
pub struct Storage<T, I:'static + ToId> {
|
||||
//TODO: consider concurrent hashmap?
|
||||
map: VecMap<(T, Epoch)>,
|
||||
_phantom: std::marker::PhantomData<&'static I>,
|
||||
}
|
||||
|
||||
impl<T> ops::Index<Id> for Storage<T> {
|
||||
impl<T, I:ToId> ops::Index<I> for Storage<T, I> {
|
||||
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<T> ops::IndexMut<Id> for Storage<T> {
|
||||
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<T, I:ToId> ops::IndexMut<I> for Storage<T, I> {
|
||||
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<T> Storage<T> {
|
||||
pub fn contains(&self, id: Id) -> bool {
|
||||
match self.map.get(id.0 as usize) {
|
||||
Some(&(_, epoch)) if epoch == id.1 => true,
|
||||
impl<T, I:ToId> Storage<T, I> {
|
||||
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<T> {
|
||||
use crate::ToId;
|
||||
pub struct Registry<T, I: 'static + ToId + From<Id>> {
|
||||
#[cfg(feature = "local")]
|
||||
identity: Mutex<IdentityManager>,
|
||||
data: RwLock<Storage<T>>,
|
||||
data: RwLock<Storage<T, I>>,
|
||||
_phantom: std::marker::PhantomData<&'static I>,
|
||||
}
|
||||
|
||||
impl<T> Default for Registry<T> {
|
||||
impl<T, I: ToId + From<Id>> Default for Registry<T, I> {
|
||||
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<T> ops::Deref for Registry<T> {
|
||||
type Target = RwLock<Storage<T>>;
|
||||
impl<T, I: ToId + From<Id>> ops::Deref for Registry<T, I> {
|
||||
type Target = RwLock<Storage<T, I>>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ops::DerefMut for Registry<T> {
|
||||
impl<T, I: ToId + From<Id>> ops::DerefMut for Registry<T, I> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Registry<T> {
|
||||
pub fn register(&self, id: Id, value: T) {
|
||||
let old = self.data.write().map.insert(id.0 as usize, (value, id.1));
|
||||
impl<T, I: ToId + From<Id> + Clone> Registry<T, I> {
|
||||
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<Registry<InstanceHandle>>,
|
||||
pub adapters: Arc<Registry<AdapterHandle>>,
|
||||
pub devices: Arc<Registry<DeviceHandle>>,
|
||||
pub pipeline_layouts: Arc<Registry<PipelineLayoutHandle>>,
|
||||
pub bind_group_layouts: Arc<Registry<BindGroupLayoutHandle>>,
|
||||
pub bind_groups: Arc<Registry<BindGroupHandle>>,
|
||||
pub shader_modules: Arc<Registry<ShaderModuleHandle>>,
|
||||
pub command_buffers: Arc<Registry<CommandBufferHandle>>,
|
||||
pub render_pipelines: Arc<Registry<RenderPipelineHandle>>,
|
||||
pub compute_pipelines: Arc<Registry<ComputePipelineHandle>>,
|
||||
pub render_passes: Arc<Registry<RenderPassHandle>>,
|
||||
pub compute_passes: Arc<Registry<ComputePassHandle>>,
|
||||
pub buffers: Arc<Registry<BufferHandle>>,
|
||||
pub textures: Arc<Registry<TextureHandle>>,
|
||||
pub texture_views: Arc<Registry<TextureViewHandle>>,
|
||||
pub samplers: Arc<Registry<SamplerHandle>>,
|
||||
pub surfaces: Arc<Registry<SurfaceHandle>>,
|
||||
pub instances: Arc<Registry<InstanceHandle, InstanceId>>,
|
||||
pub adapters: Arc<Registry<AdapterHandle, AdapterId>>,
|
||||
pub devices: Arc<Registry<DeviceHandle, DeviceId>>,
|
||||
pub pipeline_layouts: Arc<Registry<PipelineLayoutHandle, PipelineLayoutId>>,
|
||||
pub bind_group_layouts: Arc<Registry<BindGroupLayoutHandle, BindGroupLayoutId>>,
|
||||
pub bind_groups: Arc<Registry<BindGroupHandle, BindGroupId>>,
|
||||
pub shader_modules: Arc<Registry<ShaderModuleHandle, ShaderModuleId>>,
|
||||
pub command_buffers: Arc<Registry<CommandBufferHandle, CommandBufferId>>,
|
||||
pub render_pipelines: Arc<Registry<RenderPipelineHandle, RenderPipelineId>>,
|
||||
pub compute_pipelines: Arc<Registry<ComputePipelineHandle, ComputePipelineId>>,
|
||||
pub render_passes: Arc<Registry<RenderPassHandle, RenderPassId>>,
|
||||
pub compute_passes: Arc<Registry<ComputePassHandle, ComputePassId>>,
|
||||
pub buffers: Arc<Registry<BufferHandle, BufferId>>,
|
||||
pub textures: Arc<Registry<TextureHandle, TextureId>>,
|
||||
pub texture_views: Arc<Registry<TextureViewHandle, TextureViewId>>,
|
||||
pub samplers: Arc<Registry<SamplerHandle, SamplerId>>,
|
||||
pub surfaces: Arc<Registry<SurfaceHandle, SurfaceId>>,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
|
@ -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<hub::Id> 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<back::Backend>;
|
||||
pub type DeviceId = hub::Id;
|
||||
|
||||
transparent!(pub struct DeviceId(hub::Id););
|
||||
to_id!(DeviceId);
|
||||
from_id!(DeviceId);
|
||||
type DeviceHandle = Device<back::Backend>;
|
||||
//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<back::Backend>;
|
||||
|
||||
// Resource
|
||||
pub type TextureViewId = hub::Id;
|
||||
transparent!(pub struct TextureViewId(hub::Id););
|
||||
to_id!(TextureViewId);
|
||||
from_id!(TextureViewId);
|
||||
new_id!(TextureViewId);
|
||||
type TextureViewHandle = TextureView<back::Backend>;
|
||||
pub type TextureId = hub::Id;
|
||||
|
||||
transparent!(pub struct TextureId(hub::Id););
|
||||
to_id!(TextureId);
|
||||
from_id!(TextureId);
|
||||
new_id!(TextureId);
|
||||
type TextureHandle = Texture<back::Backend>;
|
||||
pub type SamplerId = hub::Id;
|
||||
|
||||
transparent!(pub struct SamplerId(hub::Id););
|
||||
to_id!(SamplerId);
|
||||
from_id!(SamplerId);
|
||||
type SamplerHandle = Sampler<back::Backend>;
|
||||
|
||||
// Binding model
|
||||
pub type BindGroupLayoutId = hub::Id;
|
||||
transparent!(pub struct BindGroupLayoutId(hub::Id););
|
||||
to_id!(BindGroupLayoutId);
|
||||
from_id!(BindGroupLayoutId);
|
||||
type BindGroupLayoutHandle = BindGroupLayout<back::Backend>;
|
||||
pub type PipelineLayoutId = hub::Id;
|
||||
|
||||
transparent!(pub struct PipelineLayoutId(hub::Id););
|
||||
to_id!(PipelineLayoutId);
|
||||
from_id!(PipelineLayoutId);
|
||||
type PipelineLayoutHandle = PipelineLayout<back::Backend>;
|
||||
pub type BindGroupId = hub::Id;
|
||||
|
||||
transparent!(pub struct BindGroupId(hub::Id););
|
||||
to_id!(BindGroupId);
|
||||
from_id!(BindGroupId);
|
||||
type BindGroupHandle = BindGroup<back::Backend>;
|
||||
|
||||
// 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<back::Backend>;
|
||||
pub type RenderPipelineId = hub::Id;
|
||||
|
||||
transparent!(pub struct RenderPipelineId(hub::Id););
|
||||
to_id!(RenderPipelineId);
|
||||
from_id!(RenderPipelineId);
|
||||
type RenderPipelineHandle = RenderPipeline<back::Backend>;
|
||||
pub type ComputePipelineId = hub::Id;
|
||||
|
||||
transparent!(pub struct ComputePipelineId(hub::Id););
|
||||
to_id!(ComputePipelineId);
|
||||
from_id!(ComputePipelineId);
|
||||
type ComputePipelineHandle = ComputePipeline<back::Backend>;
|
||||
|
||||
// Command
|
||||
pub type CommandBufferId = hub::Id;
|
||||
transparent!(pub struct CommandBufferId(hub::Id););
|
||||
to_id!(CommandBufferId);
|
||||
from_id!(CommandBufferId);
|
||||
type CommandBufferHandle = CommandBuffer<back::Backend>;
|
||||
//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<back::Backend>;
|
||||
pub type ComputePassId = hub::Id;
|
||||
|
||||
transparent!(pub struct ComputePassId(hub::Id););
|
||||
to_id!(ComputePassId);
|
||||
from_id!(ComputePassId);
|
||||
type ComputePassHandle = ComputePass<back::Backend>;
|
||||
|
||||
// Swap chain
|
||||
pub type SurfaceId = hub::Id;
|
||||
transparent!(pub struct SurfaceId(hub::Id););
|
||||
to_id!(SurfaceId);
|
||||
from_id!(SurfaceId);
|
||||
type SurfaceHandle = Surface<back::Backend>;
|
||||
//transparent!(pub struct SwapChainId(SurfaceId););
|
||||
pub type SwapChainId = SurfaceId;
|
||||
|
@ -276,37 +276,37 @@ impl<I: NewId, U: Copy + GenericUsage + BitOr<Output = U> + PartialEq> Tracker<I
|
||||
}
|
||||
}
|
||||
|
||||
impl<U: Copy + GenericUsage + BitOr<Output = U> + PartialEq> Tracker<Id, U> {
|
||||
impl<I: crate::ToId + NewId + Clone, U: Copy + GenericUsage + BitOr<Output = U> + PartialEq> Tracker<I, U> {
|
||||
fn _get_with_usage<'a, T: 'a + Borrow<RefCount>>(
|
||||
&mut self,
|
||||
storage: &'a Storage<T>,
|
||||
id: Id,
|
||||
storage: &'a Storage<T, I>,
|
||||
id: I,
|
||||
usage: U,
|
||||
permit: TrackPermit,
|
||||
) -> Result<(&'a T, Tracktion<U>), 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<RefCount>>(
|
||||
&mut self,
|
||||
storage: &'a Storage<T>,
|
||||
id: Id,
|
||||
storage: &'a Storage<T, I>,
|
||||
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<RefCount>>(
|
||||
&mut self,
|
||||
storage: &'a Storage<T>,
|
||||
id: Id,
|
||||
storage: &'a Storage<T, I>,
|
||||
id: I,
|
||||
usage: U,
|
||||
) -> Result<(&'a T, Option<U>), U> {
|
||||
let item = &storage[id];
|
||||
let item = &storage[id.clone()];
|
||||
self.transit(id, item.borrow(), usage, TrackPermit::REPLACE)
|
||||
.map(|tracktion| {
|
||||
(
|
||||
|
Loading…
Reference in New Issue
Block a user