summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wgpu-core/src/track
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/rust/wgpu-core/src/track/buffer.rs12
-rw-r--r--third_party/rust/wgpu-core/src/track/metadata.rs5
-rw-r--r--third_party/rust/wgpu-core/src/track/mod.rs50
-rw-r--r--third_party/rust/wgpu-core/src/track/texture.rs13
4 files changed, 60 insertions, 20 deletions
diff --git a/third_party/rust/wgpu-core/src/track/buffer.rs b/third_party/rust/wgpu-core/src/track/buffer.rs
index a30ac2a225..6cf1fdda6f 100644
--- a/third_party/rust/wgpu-core/src/track/buffer.rs
+++ b/third_party/rust/wgpu-core/src/track/buffer.rs
@@ -108,23 +108,27 @@ impl<A: HalApi> BufferBindGroupState<A> {
#[derive(Debug)]
pub(crate) struct BufferUsageScope<A: HalApi> {
state: Vec<BufferUses>,
-
metadata: ResourceMetadata<Buffer<A>>,
}
-impl<A: HalApi> BufferUsageScope<A> {
- pub fn new() -> Self {
+impl<A: HalApi> Default for BufferUsageScope<A> {
+ fn default() -> Self {
Self {
state: Vec::new(),
-
metadata: ResourceMetadata::new(),
}
}
+}
+impl<A: HalApi> BufferUsageScope<A> {
fn tracker_assert_in_bounds(&self, index: usize) {
strict_assert!(index < self.state.len());
self.metadata.tracker_assert_in_bounds(index);
}
+ pub fn clear(&mut self) {
+ self.state.clear();
+ self.metadata.clear();
+ }
/// Sets the size of all the vectors inside the tracker.
///
diff --git a/third_party/rust/wgpu-core/src/track/metadata.rs b/third_party/rust/wgpu-core/src/track/metadata.rs
index 744783a7fa..3e71e0e084 100644
--- a/third_party/rust/wgpu-core/src/track/metadata.rs
+++ b/third_party/rust/wgpu-core/src/track/metadata.rs
@@ -39,6 +39,11 @@ impl<T: Resource> ResourceMetadata<T> {
resize_bitvec(&mut self.owned, size);
}
+ pub(super) fn clear(&mut self) {
+ self.resources.clear();
+ self.owned.clear();
+ }
+
/// Ensures a given index is in bounds for all arrays and does
/// sanity checks of the presence of a refcount.
///
diff --git a/third_party/rust/wgpu-core/src/track/mod.rs b/third_party/rust/wgpu-core/src/track/mod.rs
index 9ca37ebadc..374dfe7493 100644
--- a/third_party/rust/wgpu-core/src/track/mod.rs
+++ b/third_party/rust/wgpu-core/src/track/mod.rs
@@ -480,8 +480,8 @@ impl<A: HalApi> RenderBundleScope<A> {
/// Create the render bundle scope and pull the maximum IDs from the hubs.
pub fn new() -> Self {
Self {
- buffers: RwLock::new(BufferUsageScope::new()),
- textures: RwLock::new(TextureUsageScope::new()),
+ buffers: RwLock::new(BufferUsageScope::default()),
+ textures: RwLock::new(TextureUsageScope::default()),
bind_groups: RwLock::new(StatelessTracker::new()),
render_pipelines: RwLock::new(StatelessTracker::new()),
query_sets: RwLock::new(StatelessTracker::new()),
@@ -512,28 +512,52 @@ impl<A: HalApi> RenderBundleScope<A> {
}
}
+/// A pool for storing the memory used by [`UsageScope`]s. We take and store this memory when the
+/// scope is dropped to avoid reallocating. The memory required only grows and allocation cost is
+/// significant when a large number of resources have been used.
+pub(crate) type UsageScopePool<A> = Mutex<Vec<(BufferUsageScope<A>, TextureUsageScope<A>)>>;
+
/// A usage scope tracker. Only needs to store stateful resources as stateless
/// resources cannot possibly have a usage conflict.
#[derive(Debug)]
-pub(crate) struct UsageScope<A: HalApi> {
+pub(crate) struct UsageScope<'a, A: HalApi> {
+ pub pool: &'a UsageScopePool<A>,
pub buffers: BufferUsageScope<A>,
pub textures: TextureUsageScope<A>,
}
-impl<A: HalApi> UsageScope<A> {
- /// Create the render bundle scope and pull the maximum IDs from the hubs.
- pub fn new(tracker_indices: &TrackerIndexAllocators) -> Self {
- let mut value = Self {
- buffers: BufferUsageScope::new(),
- textures: TextureUsageScope::new(),
- };
+impl<'a, A: HalApi> Drop for UsageScope<'a, A> {
+ fn drop(&mut self) {
+ // clear vecs and push into pool
+ self.buffers.clear();
+ self.textures.clear();
+ self.pool.lock().push((
+ std::mem::take(&mut self.buffers),
+ std::mem::take(&mut self.textures),
+ ));
+ }
+}
- value.buffers.set_size(tracker_indices.buffers.size());
- value.textures.set_size(tracker_indices.textures.size());
+impl<A: HalApi> UsageScope<'static, A> {
+ pub fn new_pooled<'d>(
+ pool: &'d UsageScopePool<A>,
+ tracker_indices: &TrackerIndexAllocators,
+ ) -> UsageScope<'d, A> {
+ let pooled = pool.lock().pop().unwrap_or_default();
+
+ let mut scope = UsageScope::<'d, A> {
+ pool,
+ buffers: pooled.0,
+ textures: pooled.1,
+ };
- value
+ scope.buffers.set_size(tracker_indices.buffers.size());
+ scope.textures.set_size(tracker_indices.textures.size());
+ scope
}
+}
+impl<'a, A: HalApi> UsageScope<'a, A> {
/// Merge the inner contents of a bind group into the usage scope.
///
/// Only stateful things are merged in here, all other resources are owned
diff --git a/third_party/rust/wgpu-core/src/track/texture.rs b/third_party/rust/wgpu-core/src/track/texture.rs
index e7c4707c93..3cf95ff38a 100644
--- a/third_party/rust/wgpu-core/src/track/texture.rs
+++ b/third_party/rust/wgpu-core/src/track/texture.rs
@@ -210,6 +210,7 @@ pub(crate) struct TextureStateSet {
simple: Vec<TextureUses>,
complex: FastHashMap<usize, ComplexTextureState>,
}
+
impl TextureStateSet {
fn new() -> Self {
Self {
@@ -235,15 +236,16 @@ pub(crate) struct TextureUsageScope<A: HalApi> {
metadata: ResourceMetadata<Texture<A>>,
}
-impl<A: HalApi> TextureUsageScope<A> {
- pub fn new() -> Self {
+impl<A: HalApi> Default for TextureUsageScope<A> {
+ fn default() -> Self {
Self {
set: TextureStateSet::new(),
-
metadata: ResourceMetadata::new(),
}
}
+}
+impl<A: HalApi> TextureUsageScope<A> {
fn tracker_assert_in_bounds(&self, index: usize) {
self.metadata.tracker_assert_in_bounds(index);
@@ -258,6 +260,11 @@ impl<A: HalApi> TextureUsageScope<A> {
});
}
+ pub fn clear(&mut self) {
+ self.set.clear();
+ self.metadata.clear();
+ }
+
/// Sets the size of all the vectors inside the tracker.
///
/// Must be called with the highest possible Texture ID before