summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wgpu-core/src/track/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/rust/wgpu-core/src/track/mod.rs50
1 files changed, 37 insertions, 13 deletions
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