diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index a208f13eee..c58bd4d64f 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -268,6 +268,7 @@ impl State { Ok(()) } + // `extra_buffer` is there to represent the indirect buffer that is also part of the usage scope. fn flush_states( &mut self, raw_encoder: &mut A::CommandEncoder, @@ -275,6 +276,7 @@ impl State { bind_group_guard: &Storage, id::BindGroupId>, buffer_guard: &Storage, id::BufferId>, texture_guard: &Storage, id::TextureId>, + indirect_buffer: Option>, ) -> Result<(), UsageConflict> { for id in self.binder.list_active() { unsafe { @@ -295,6 +297,13 @@ impl State { } } + // Add the state of the indirect buffer if it hasn't been hit before. + unsafe { + base_trackers + .buffers + .set_and_remove_from_usage_scope_sparse(&mut self.scope.buffers, indirect_buffer); + } + log::trace!("Encoding dispatch barriers"); CommandBuffer::drain_barriers(raw_encoder, base_trackers, buffer_guard, texture_guard); @@ -584,6 +593,7 @@ impl Global { &*bind_group_guard, &*buffer_guard, &*texture_guard, + None, ) .map_pass_err(scope)?; @@ -659,6 +669,7 @@ impl Global { &*bind_group_guard, &*buffer_guard, &*texture_guard, + Some(id::Valid(buffer_id)), ) .map_pass_err(scope)?; unsafe { diff --git a/wgpu-core/src/track/buffer.rs b/wgpu-core/src/track/buffer.rs index 7770b42308..2ece124a81 100644 --- a/wgpu-core/src/track/buffer.rs +++ b/wgpu-core/src/track/buffer.rs @@ -467,8 +467,8 @@ impl BufferTracker { /// This is a really funky method used by Compute Passes to generate /// barriers after a call to dispatch without needing to iterate /// over all elements in the usage scope. We use each the - /// bind group as a source of which IDs to look at. The bind groups - /// must have first been added to the usage scope. + /// a given iterator of ids as a source of which IDs to look at. + /// All the IDs must have first been added to the usage scope. /// /// # Safety /// @@ -477,15 +477,15 @@ impl BufferTracker { pub unsafe fn set_and_remove_from_usage_scope_sparse( &mut self, scope: &mut BufferUsageScope, - bind_group_state: &BufferBindGroupState, + id_source: impl IntoIterator>, ) { let incoming_size = scope.state.len(); if incoming_size > self.start.len() { self.set_size(incoming_size); } - for &(id, ref ref_count, _) in bind_group_state.buffers.iter() { - let (index32, epoch, _) = id.0.unzip(); + for id in id_source { + let (index32, _, _) = id.0.unzip(); let index = index32 as usize; scope.debug_assert_in_bounds(index); @@ -504,9 +504,8 @@ impl BufferTracker { state: &scope.state, }, None, - ResourceMetadataProvider::Direct { - epoch, - ref_count: Cow::Borrowed(ref_count), + ResourceMetadataProvider::Indirect { + metadata: &scope.metadata, }, &mut self.temp, ); diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index 818c5b96c4..f1a43b3297 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -715,7 +715,7 @@ impl Tracker { bind_group: &BindGroupStates, ) { self.buffers - .set_and_remove_from_usage_scope_sparse(&mut scope.buffers, &bind_group.buffers); + .set_and_remove_from_usage_scope_sparse(&mut scope.buffers, bind_group.buffers.used()); self.textures.set_and_remove_from_usage_scope_sparse( textures, &mut scope.textures,