From a51b4f92325699a4b7c1920ca86c8f71eb5a2db4 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Tue, 19 Jan 2021 22:59:34 +0100 Subject: [PATCH] buffer zero initialization prior to use in submit --- wgpu-core/src/command/mod.rs | 30 ++++++++++++++++++++++++++++++ wgpu-core/src/device/queue.rs | 8 +++++++- wgpu-core/src/resource.rs | 7 ++++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index b98ce39598..03999fad5d 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -78,6 +78,36 @@ impl CommandBuffer { } } + pub(crate) fn insert_zero_initializations( + raw: &mut B::CommandBuffer, + head: &TrackerSet, + buffer_guard: &mut Storage, id::BufferId>, + // TODO: Textures also need initialization! + _texture_guard: &mut Storage, id::TextureId>, + ) { + // Make sure all used buffers are fully initialized. + // TODO This is not optimal since buffer usage may be target of a copy operation. + for id in head.buffers.used() { + let buffer = &mut buffer_guard[id]; + let uninitialized_ranges: Vec> = + buffer.uninitialized_ranges().collect(); + for uninitialized_range in uninitialized_ranges { + // TODO this itself needs resource barriers. How can we make this work? + unsafe { + raw.fill_buffer( + &buffer.raw.as_ref().unwrap().0, + hal::buffer::SubRange { + offset: uninitialized_range.start, + size: Some(uninitialized_range.end - uninitialized_range.start), + }, + 0, + ); + } + buffer.mark_initialized(uninitialized_range); + } + } + } + pub(crate) fn insert_barriers( raw: &mut B::CommandBuffer, base: &mut TrackerSet, diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index fa09be5cfc..86b9a21bc6 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -505,7 +505,7 @@ impl Global { let (compute_pipe_guard, mut token) = hub.compute_pipelines.read(&mut token); let (render_pipe_guard, mut token) = hub.render_pipelines.read(&mut token); let (mut buffer_guard, mut token) = hub.buffers.write(&mut token); - let (texture_guard, mut token) = hub.textures.read(&mut token); + let (mut texture_guard, mut token) = hub.textures.write(&mut token); let (texture_view_guard, mut token) = hub.texture_views.read(&mut token); let (sampler_guard, _) = hub.samplers.read(&mut token); @@ -613,6 +613,12 @@ impl Global { .begin_primary(hal::command::CommandBufferFlags::ONE_TIME_SUBMIT); } tracing::trace!("Stitching command buffer {:?} before submission", cmb_id); + CommandBuffer::insert_zero_initializations( + &mut transit, + &cmdbuf.trackers, + &mut *buffer_guard, + &mut *texture_guard, + ); CommandBuffer::insert_barriers( &mut transit, &mut *trackers, diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 0510a3d776..ec21f9d736 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -169,7 +169,6 @@ pub struct Buffer { impl Buffer { pub(crate) fn uninitialized_ranges_in_range< - 'a, R: std::iter::FromIterator>, >( &self, @@ -190,6 +189,12 @@ impl Buffer { .collect::() } + pub(crate) fn uninitialized_ranges<'a>( + &'a self, + ) -> impl 'a + Iterator> { + self.uninitialized_ranges.allocated_ranges() + } + // Range must be continuous previously uninitialized section. pub(crate) fn mark_initialized(&mut self, range: Range) { self.uninitialized_ranges.free_range(range);