From 70a9c01b480b0d9cca93ff87e794d83128a11001 Mon Sep 17 00:00:00 2001 From: teoxoy <28601907+teoxoy@users.noreply.github.com> Date: Thu, 5 Sep 2024 12:28:46 +0200 Subject: [PATCH] [wgpu-core] make the `Registry` generic over `T: Clone` --- wgpu-core/src/command/bundle.rs | 10 ++++---- wgpu-core/src/device/global.rs | 12 ++++++---- wgpu-core/src/global.rs | 4 +++- wgpu-core/src/hub.rs | 40 +++++++++++++++---------------- wgpu-core/src/registry.rs | 13 ++++++---- wgpu-core/src/storage.rs | 42 +++++++++++++++++++++++---------- 6 files changed, 73 insertions(+), 48 deletions(-) diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 775bd5f82..d63388204 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -578,7 +578,7 @@ impl RenderBundleEncoder { fn set_bind_group( state: &mut State, - bind_group_guard: &crate::lock::RwLockReadGuard>, + bind_group_guard: &crate::lock::RwLockReadGuard>>, dynamic_offsets: &[u32], index: u32, num_dynamic_offsets: usize, @@ -630,7 +630,7 @@ fn set_bind_group( fn set_pipeline( state: &mut State, - pipeline_guard: &crate::lock::RwLockReadGuard>, + pipeline_guard: &crate::lock::RwLockReadGuard>>, context: &RenderPassContext, is_depth_read_only: bool, is_stencil_read_only: bool, @@ -673,7 +673,7 @@ fn set_pipeline( fn set_index_buffer( state: &mut State, - buffer_guard: &crate::lock::RwLockReadGuard>, + buffer_guard: &crate::lock::RwLockReadGuard>>, buffer_id: id::Id, index_format: wgt::IndexFormat, offset: u64, @@ -708,7 +708,7 @@ fn set_index_buffer( fn set_vertex_buffer( state: &mut State, - buffer_guard: &crate::lock::RwLockReadGuard>, + buffer_guard: &crate::lock::RwLockReadGuard>>, slot: u32, buffer_id: id::Id, offset: u64, @@ -852,7 +852,7 @@ fn draw_indexed( fn multi_draw_indirect( state: &mut State, dynamic_offsets: &[u32], - buffer_guard: &crate::lock::RwLockReadGuard>, + buffer_guard: &crate::lock::RwLockReadGuard>>, buffer_id: id::Id, offset: u64, indexed: bool, diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index a86651d87..ba5c99258 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -26,7 +26,11 @@ use crate::{ use wgt::{BufferAddress, TextureFormat}; -use std::{borrow::Cow, ptr::NonNull, sync::atomic::Ordering}; +use std::{ + borrow::Cow, + ptr::NonNull, + sync::{atomic::Ordering, Arc}, +}; use super::{ImplicitPipelineIds, UserClosures}; @@ -803,9 +807,9 @@ impl Global { fn resolve_entry<'a>( e: &BindGroupEntry<'a>, - buffer_storage: &Storage, - sampler_storage: &Storage, - texture_view_storage: &Storage, + buffer_storage: &Storage>, + sampler_storage: &Storage>, + texture_view_storage: &Storage>, ) -> Result, binding_model::CreateBindGroupError> { let resolve_buffer = |bb: &BufferBinding| { diff --git a/wgpu-core/src/global.rs b/wgpu-core/src/global.rs index 4d79a81e3..bb672612e 100644 --- a/wgpu-core/src/global.rs +++ b/wgpu-core/src/global.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use crate::{ hal_api::HalApi, hub::{Hub, HubReport}, @@ -23,7 +25,7 @@ impl GlobalReport { pub struct Global { pub instance: Instance, - pub(crate) surfaces: Registry, + pub(crate) surfaces: Registry>, pub(crate) hub: Hub, } diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 5cbb73630..d14986c01 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -110,7 +110,7 @@ use crate::{ resource::{Buffer, QuerySet, Sampler, StagingBuffer, Texture, TextureView}, storage::{Element, Storage}, }; -use std::fmt::Debug; +use std::{fmt::Debug, sync::Arc}; #[derive(Debug, PartialEq, Eq)] pub struct HubReport { @@ -162,24 +162,24 @@ impl HubReport { /// /// [`A::hub(global)`]: HalApi::hub pub struct Hub { - pub(crate) adapters: Registry, - pub(crate) devices: Registry, - pub(crate) queues: Registry, - pub(crate) pipeline_layouts: Registry, - pub(crate) shader_modules: Registry, - pub(crate) bind_group_layouts: Registry, - pub(crate) bind_groups: Registry, - pub(crate) command_buffers: Registry, - pub(crate) render_bundles: Registry, - pub(crate) render_pipelines: Registry, - pub(crate) compute_pipelines: Registry, - pub(crate) pipeline_caches: Registry, - pub(crate) query_sets: Registry, - pub(crate) buffers: Registry, - pub(crate) staging_buffers: Registry, - pub(crate) textures: Registry, - pub(crate) texture_views: Registry, - pub(crate) samplers: Registry, + pub(crate) adapters: Registry>, + pub(crate) devices: Registry>, + pub(crate) queues: Registry>, + pub(crate) pipeline_layouts: Registry>, + pub(crate) shader_modules: Registry>, + pub(crate) bind_group_layouts: Registry>, + pub(crate) bind_groups: Registry>, + pub(crate) command_buffers: Registry>, + pub(crate) render_bundles: Registry>, + pub(crate) render_pipelines: Registry>, + pub(crate) compute_pipelines: Registry>, + pub(crate) pipeline_caches: Registry>, + pub(crate) query_sets: Registry>, + pub(crate) buffers: Registry>, + pub(crate) staging_buffers: Registry>, + pub(crate) textures: Registry>, + pub(crate) texture_views: Registry>, + pub(crate) samplers: Registry>, } impl Hub { @@ -206,7 +206,7 @@ impl Hub { } } - pub(crate) fn clear(&self, surface_guard: &Storage) { + pub(crate) fn clear(&self, surface_guard: &Storage>) { let mut devices = self.devices.write(); for element in devices.map.iter() { if let Element::Occupied(ref device, _) = *element { diff --git a/wgpu-core/src/registry.rs b/wgpu-core/src/registry.rs index 84f073d08..82617d985 100644 --- a/wgpu-core/src/registry.rs +++ b/wgpu-core/src/registry.rs @@ -68,7 +68,7 @@ impl FutureId<'_, T> { /// Assign a new resource to this ID. /// /// Registers it with the registry. - pub fn assign(self, value: Arc) -> Id { + pub fn assign(self, value: T) -> Id { let mut data = self.data.write(); data.insert(self.id, value); self.id @@ -98,9 +98,6 @@ impl Registry { } } - pub(crate) fn get(&self, id: Id) -> Result, InvalidId> { - self.read().get_owned(id) - } #[track_caller] pub(crate) fn read<'a>(&'a self) -> RwLockReadGuard<'a, Storage> { self.storage.read() @@ -114,7 +111,7 @@ impl Registry { storage.remove(id); storage.insert_error(id); } - pub(crate) fn unregister(&self, id: Id) -> Option> { + pub(crate) fn unregister(&self, id: Id) -> Option { let value = self.storage.write().remove(id); // This needs to happen *after* removing it from the storage, to maintain the // invariant that `self.identity` only contains ids which are actually available @@ -142,6 +139,12 @@ impl Registry { } } +impl Registry { + pub(crate) fn get(&self, id: Id) -> Result { + self.read().get_owned(id) + } +} + #[cfg(test)] mod tests { use std::sync::Arc; diff --git a/wgpu-core/src/storage.rs b/wgpu-core/src/storage.rs index c5e91eedd..cdcf0ea16 100644 --- a/wgpu-core/src/storage.rs +++ b/wgpu-core/src/storage.rs @@ -8,13 +8,16 @@ use crate::{Epoch, Index}; /// An entry in a `Storage::map` table. #[derive(Debug)] -pub(crate) enum Element { +pub(crate) enum Element +where + T: StorageItem, +{ /// There are no live ids with this index. Vacant, /// There is one live id with this index, allocated at the given /// epoch. - Occupied(Arc, Epoch), + Occupied(T, Epoch), /// Like `Occupied`, but an error occurred when creating the /// resource. @@ -28,6 +31,14 @@ pub(crate) trait StorageItem: ResourceType { type Marker: Marker; } +impl ResourceType for Arc { + const TYPE: &'static str = T::TYPE; +} + +impl StorageItem for Arc { + type Marker = T::Marker; +} + #[macro_export] macro_rules! impl_storage_item { ($ty:ident) => { @@ -72,7 +83,7 @@ where { /// Get a reference to an item behind a potentially invalid ID. /// Panics if there is an epoch mismatch, or the entry is empty. - pub(crate) fn get(&self, id: Id) -> Result<&Arc, InvalidId> { + pub(crate) fn get(&self, id: Id) -> Result<&T, InvalidId> { let (index, epoch, _) = id.unzip(); let (result, storage_epoch) = match self.map.get(index as usize) { Some(&Element::Occupied(ref v, epoch)) => (Ok(v), epoch), @@ -87,12 +98,6 @@ where result } - /// Get an owned reference to an item behind a potentially invalid ID. - /// Panics if there is an epoch mismatch, or the entry is empty. - pub(crate) fn get_owned(&self, id: Id) -> Result, InvalidId> { - Ok(Arc::clone(self.get(id)?)) - } - fn insert_impl(&mut self, index: usize, epoch: Epoch, element: Element) { if index >= self.map.len() { self.map.resize_with(index + 1, || Element::Vacant); @@ -118,7 +123,7 @@ where } } - pub(crate) fn insert(&mut self, id: Id, value: Arc) { + pub(crate) fn insert(&mut self, id: Id, value: T) { let (index, epoch, _backend) = id.unzip(); self.insert_impl(index as usize, epoch, Element::Occupied(value, epoch)) } @@ -128,7 +133,7 @@ where self.insert_impl(index as usize, epoch, Element::Error(epoch)) } - pub(crate) fn replace_with_error(&mut self, id: Id) -> Result, InvalidId> { + pub(crate) fn replace_with_error(&mut self, id: Id) -> Result { let (index, epoch, _) = id.unzip(); match std::mem::replace(&mut self.map[index as usize], Element::Error(epoch)) { Element::Vacant => panic!("Cannot access vacant resource"), @@ -140,7 +145,7 @@ where } } - pub(crate) fn remove(&mut self, id: Id) -> Option> { + pub(crate) fn remove(&mut self, id: Id) -> Option { let (index, epoch, _) = id.unzip(); match std::mem::replace(&mut self.map[index as usize], Element::Vacant) { Element::Occupied(value, storage_epoch) => { @@ -152,7 +157,7 @@ where } } - pub(crate) fn iter(&self, backend: Backend) -> impl Iterator, &Arc)> { + pub(crate) fn iter(&self, backend: Backend) -> impl Iterator, &T)> { self.map .iter() .enumerate() @@ -168,3 +173,14 @@ where self.map.len() } } + +impl Storage +where + T: StorageItem + Clone, +{ + /// Get an owned reference to an item behind a potentially invalid ID. + /// Panics if there is an epoch mismatch, or the entry is empty. + pub(crate) fn get_owned(&self, id: Id) -> Result { + Ok(self.get(id)?.clone()) + } +}