From 492027fe6e390874b2ae987ea192fa456e474bb7 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Mon, 25 Jan 2021 22:16:33 +0100 Subject: [PATCH] command buffer buffer memory init tracking is only filled if necessary now --- wgpu-core/src/binding_model.rs | 4 +- wgpu-core/src/command/allocator.rs | 2 +- wgpu-core/src/command/bundle.rs | 18 ++-- wgpu-core/src/command/compute.rs | 40 ++++++--- wgpu-core/src/command/mod.rs | 15 +--- wgpu-core/src/command/render.rs | 127 ++++++++++++++++++--------- wgpu-core/src/command/transfer.rs | 88 ++++++++++++------- wgpu-core/src/device/mod.rs | 8 +- wgpu-core/src/device/queue.rs | 6 +- wgpu-core/src/memory_init_tracker.rs | 12 ++- 10 files changed, 198 insertions(+), 122 deletions(-) diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 1490b3dffb..dd40398ff0 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -9,7 +9,7 @@ use crate::{ }, hub::Resource, id::{BindGroupLayoutId, BufferId, DeviceId, SamplerId, TextureViewId, Valid}, - memory_init_tracker::ResourceMemoryInitTrackerAction, + memory_init_tracker::MemoryInitTrackerAction, track::{TrackerSet, DUMMY_SELECTOR}, validation::{MissingBufferUsageError, MissingTextureUsageError}, FastHashMap, Label, LifeGuard, MultiRefCount, Stored, MAX_BIND_GROUPS, @@ -589,7 +589,7 @@ pub struct BindGroup { pub(crate) layout_id: Valid, pub(crate) life_guard: LifeGuard, pub(crate) used: TrackerSet, - pub(crate) used_buffer_ranges: Vec>, + pub(crate) used_buffer_ranges: Vec>, pub(crate) dynamic_binding_info: Vec, } diff --git a/wgpu-core/src/command/allocator.rs b/wgpu-core/src/command/allocator.rs index fb75c69c19..4a021c9ab0 100644 --- a/wgpu-core/src/command/allocator.rs +++ b/wgpu-core/src/command/allocator.rs @@ -123,7 +123,7 @@ impl CommandAllocator { device_id, trackers: TrackerSet::new(B::VARIANT), used_swap_chains: Default::default(), - used_buffer_ranges: Default::default(), + buffer_memory_init_actions: Default::default(), limits, private_features, has_labels: label.is_some(), diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 357da0ab75..da37e1b447 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -49,7 +49,7 @@ use crate::{ }, hub::{GfxBackend, GlobalIdentityHandlerFactory, Hub, Resource, Storage, Token}, id, - memory_init_tracker::{MemoryInitKind, ResourceMemoryInitTrackerAction}, + memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction}, resource::BufferUse, span, track::{TrackerSet, UsageConflict}, @@ -160,7 +160,7 @@ impl RenderBundleEncoder { let mut commands = Vec::new(); let mut base = self.base.as_ref(); let mut pipeline_layout_id = None::>; - let mut used_buffer_ranges = Vec::new(); + let mut buffer_memory_init_actions = Vec::new(); for &command in base.commands { match command { @@ -206,7 +206,7 @@ impl RenderBundleEncoder { .map_pass_err(scope); } - used_buffer_ranges + buffer_memory_init_actions .extend(bind_group.used_buffer_ranges.iter().map(|x| x.clone())); state.set_bind_group(index, bind_group_id, bind_group.layout_id, offsets); @@ -267,7 +267,7 @@ impl RenderBundleEncoder { Some(s) => offset + s.get(), None => buffer.size, }; - used_buffer_ranges.push(ResourceMemoryInitTrackerAction { + buffer_memory_init_actions.push(MemoryInitTrackerAction { id: buffer_id, range: offset..end, kind: MemoryInitKind::NeedsInitializedMemory, @@ -294,7 +294,7 @@ impl RenderBundleEncoder { Some(s) => offset + s.get(), None => buffer.size, }; - used_buffer_ranges.push(ResourceMemoryInitTrackerAction { + buffer_memory_init_actions.push(MemoryInitTrackerAction { id: buffer_id, range: offset..end, kind: MemoryInitKind::NeedsInitializedMemory, @@ -411,7 +411,7 @@ impl RenderBundleEncoder { check_buffer_usage(buffer.usage, wgt::BufferUsage::INDIRECT) .map_pass_err(scope)?; - used_buffer_ranges.push(ResourceMemoryInitTrackerAction { + buffer_memory_init_actions.push(MemoryInitTrackerAction { id: buffer_id, range: 0..buffer.size, kind: MemoryInitKind::NeedsInitializedMemory, @@ -442,7 +442,7 @@ impl RenderBundleEncoder { .map_pass_err(scope)?; let stride = 4 * 4; // 4 integers, vertexCount, instanceCount, firstVertex, firstInstance - used_buffer_ranges.push(ResourceMemoryInitTrackerAction { + buffer_memory_init_actions.push(MemoryInitTrackerAction { id: buffer_id, range: 0..stride, kind: MemoryInitKind::NeedsInitializedMemory, @@ -482,7 +482,7 @@ impl RenderBundleEncoder { ref_count: device.life_guard.add_ref(), }, used: state.trackers, - used_buffer_ranges, + buffer_memory_init_actions, context: self.context, life_guard: LifeGuard::new(desc.label.borrow_or_default()), }) @@ -531,7 +531,7 @@ pub struct RenderBundle { base: BasePass, pub(crate) device_id: Stored, pub(crate) used: TrackerSet, - pub(crate) used_buffer_ranges: Vec>, + pub(crate) buffer_memory_init_actions: Vec>, pub(crate) context: RenderPassContext, pub(crate) life_guard: LifeGuard, } diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index f9119fedce..e9158d4c1a 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -11,7 +11,7 @@ use crate::{ }, hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Storage, Token}, id, - memory_init_tracker::{MemoryInitKind, ResourceMemoryInitTrackerAction}, + memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction}, resource::{Buffer, BufferUse, Texture}, span, track::{TrackerSet, UsageConflict}, @@ -147,6 +147,8 @@ pub enum ComputePassErrorInner { end_offset: u64, buffer_size: u64, }, + #[error("buffer {0:?} is invalid or destroyed")] + InvalidBuffer(id::BufferId), #[error(transparent)] ResourceUsageConflict(#[from] UsageConflict), #[error(transparent)] @@ -330,9 +332,18 @@ impl Global { .validate_dynamic_bindings(&temp_offsets) .map_pass_err(scope)?; - cmd_buf - .used_buffer_ranges - .extend(bind_group.used_buffer_ranges.iter().map(|x| x.clone())); + cmd_buf.buffer_memory_init_actions.extend( + bind_group + .used_buffer_ranges + .iter() + .filter(|action| match buffer_guard.get(action.id) { + Ok(buffer) => { + !buffer.initialization_status.is_initialized(&action.range) + } + Err(_) => false, + }) + .map(|action| action.clone()), + ); if let Some((pipeline_layout_id, follow_ups)) = state.binder.provide_entry( index as usize, @@ -519,13 +530,20 @@ impl Global { .map_pass_err(scope)?; let stride = 3 * 4; // 3 integers, x/y/z group size - cmd_buf - .used_buffer_ranges - .push(ResourceMemoryInitTrackerAction { - id: buffer_id, - range: offset..(offset + stride), - kind: MemoryInitKind::NeedsInitializedMemory, - }); + + let used_buffer_range = offset..(offset + stride); + if !indirect_buffer + .initialization_status + .is_initialized(&used_buffer_range) + { + cmd_buf + .buffer_memory_init_actions + .push(MemoryInitTrackerAction { + id: buffer_id, + range: used_buffer_range, + kind: MemoryInitKind::NeedsInitializedMemory, + }); + } state .flush_states( diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 88c3df314c..edbda616e5 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -24,7 +24,7 @@ use crate::{ device::{all_buffer_stages, all_image_stages}, hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Storage, Token}, id, - memory_init_tracker::ResourceMemoryInitTrackerAction, + memory_init_tracker::MemoryInitTrackerAction, resource::{Buffer, Texture}, span, track::TrackerSet, @@ -47,7 +47,7 @@ pub struct CommandBuffer { pub(crate) device_id: Stored, pub(crate) trackers: TrackerSet, pub(crate) used_swap_chains: SmallVec<[Stored; 1]>, - pub(crate) used_buffer_ranges: Vec>, + pub(crate) buffer_memory_init_actions: Vec>, limits: wgt::Limits, private_features: PrivateFeatures, has_labels: bool, @@ -58,17 +58,6 @@ pub struct CommandBuffer { } impl CommandBuffer { - fn get_encoder( - storage: &Storage, - id: id::CommandEncoderId, - ) -> Result<&Self, CommandEncoderError> { - match storage.get(id) { - Ok(cmd_buf) if cmd_buf.is_recording => Ok(cmd_buf), - Ok(_) => Err(CommandEncoderError::NotRecording), - Err(_) => Err(CommandEncoderError::Invalid), - } - } - fn get_encoder_mut( storage: &mut Storage, id: id::CommandEncoderId, diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index bf54a24a59..20ed60a15c 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -17,7 +17,7 @@ use crate::{ }, hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Storage, Token}, id, - memory_init_tracker::{MemoryInitKind, ResourceMemoryInitTrackerAction}, + memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction}, pipeline::PipelineFlags, resource::{BufferUse, Texture, TextureUse, TextureView, TextureViewInner}, span, @@ -1025,12 +1025,12 @@ impl Global { let (device_guard, mut token) = hub.devices.read(&mut token); - let (cmd_buf_raw, trackers, used_swapchain, used_buffer_ranges, query_reset_state) = { + let (cmd_buf_raw, trackers, used_swapchain, query_reset_state) = { // read-only lock guard - let (cmb_guard, mut token) = hub.command_buffers.read(&mut token); + let (mut cmb_guard, mut token) = hub.command_buffers.write(&mut token); let cmd_buf = - CommandBuffer::get_encoder(&*cmb_guard, encoder_id).map_pass_err(scope)?; + CommandBuffer::get_encoder_mut(&mut *cmb_guard, encoder_id).map_pass_err(scope)?; let device = &device_guard[cmd_buf.device_id.value]; let mut raw = device.cmd_allocator.extend(cmd_buf); unsafe { @@ -1080,7 +1080,6 @@ impl Global { let mut string_offset = 0; let mut active_query = None; let mut query_reset_state = QueryResetMap::new(); - let mut used_buffer_ranges = Vec::new(); for command in base.commands { match *command { @@ -1119,8 +1118,18 @@ impl Global { .merge_extend(&bind_group.used) .map_pass_err(scope)?; - used_buffer_ranges - .extend(bind_group.used_buffer_ranges.iter().map(|x| x.clone())); + cmd_buf.buffer_memory_init_actions.extend( + bind_group + .used_buffer_ranges + .iter() + .filter(|action| match buffer_guard.get(action.id) { + Ok(buffer) => { + !buffer.initialization_status.is_initialized(&action.range) + } + Err(_) => false, + }) + .map(|action| action.clone()), + ); if let Some((pipeline_layout_id, follow_ups)) = state.binder.provide_entry( index as usize, @@ -1298,11 +1307,15 @@ impl Global { state.index.format = Some(index_format); state.index.update_limit(); - used_buffer_ranges.push(ResourceMemoryInitTrackerAction { - id: buffer_id, - range: offset..end, - kind: MemoryInitKind::NeedsInitializedMemory, - }); + if !buffer.initialization_status.is_initialized(&(offset..end)) { + cmd_buf + .buffer_memory_init_actions + .push(MemoryInitTrackerAction { + id: buffer_id, + range: offset..end, + kind: MemoryInitKind::NeedsInitializedMemory, + }); + } let range = hal::buffer::SubRange { offset, @@ -1347,11 +1360,16 @@ impl Global { }; vertex_state.bound = true; - used_buffer_ranges.push(ResourceMemoryInitTrackerAction { - id: buffer_id, - range: offset..(offset + vertex_state.total_size), - kind: MemoryInitKind::NeedsInitializedMemory, - }); + let used_range = offset..(offset + vertex_state.total_size); + if !buffer.initialization_status.is_initialized(&used_range) { + cmd_buf + .buffer_memory_init_actions + .push(MemoryInitTrackerAction { + id: buffer_id, + range: used_range, + kind: MemoryInitKind::NeedsInitializedMemory, + }); + } let range = hal::buffer::SubRange { offset, @@ -1605,11 +1623,18 @@ impl Global { .map_pass_err(scope); } - used_buffer_ranges.push(ResourceMemoryInitTrackerAction { - id: buffer_id, - range: offset..end_offset, - kind: MemoryInitKind::NeedsInitializedMemory, - }); + if !indirect_buffer + .initialization_status + .is_initialized(&(offset..end_offset)) + { + cmd_buf + .buffer_memory_init_actions + .push(MemoryInitTrackerAction { + id: buffer_id, + range: offset..end_offset, + kind: MemoryInitKind::NeedsInitializedMemory, + }); + } match indexed { false => unsafe { @@ -1694,6 +1719,18 @@ impl Global { }) .map_pass_err(scope); } + if !indirect_buffer + .initialization_status + .is_initialized(&(offset..end_offset)) + { + cmd_buf + .buffer_memory_init_actions + .push(MemoryInitTrackerAction { + id: buffer_id, + range: offset..end_offset, + kind: MemoryInitKind::NeedsInitializedMemory, + }); + } let begin_count_offset = count_buffer_offset; let end_count_offset = count_buffer_offset + 4; @@ -1705,17 +1742,18 @@ impl Global { }) .map_pass_err(scope); } - - used_buffer_ranges.push(ResourceMemoryInitTrackerAction { - id: buffer_id, - range: offset..end_offset, - kind: MemoryInitKind::NeedsInitializedMemory, - }); - used_buffer_ranges.push(ResourceMemoryInitTrackerAction { - id: count_buffer_id, - range: count_buffer_offset..end_count_offset, - kind: MemoryInitKind::NeedsInitializedMemory, - }); + if !count_buffer + .initialization_status + .is_initialized(&(count_buffer_offset..end_count_offset)) + { + cmd_buf + .buffer_memory_init_actions + .push(MemoryInitTrackerAction { + id: count_buffer_id, + range: count_buffer_offset..end_count_offset, + kind: MemoryInitKind::NeedsInitializedMemory, + }); + } match indexed { false => unsafe { @@ -1849,8 +1887,18 @@ impl Global { .map_err(RenderPassErrorInner::IncompatibleRenderBundle) .map_pass_err(scope)?; - used_buffer_ranges - .extend(bundle.used_buffer_ranges.iter().map(|x| x.clone())); + cmd_buf.buffer_memory_init_actions.extend( + bundle + .buffer_memory_init_actions + .iter() + .filter(|action| match buffer_guard.get(action.id) { + Ok(buffer) => { + !buffer.initialization_status.is_initialized(&action.range) + } + Err(_) => false, + }) + .map(|action| action.clone()), + ); unsafe { bundle.execute( @@ -1882,13 +1930,7 @@ impl Global { } let (trackers, used_swapchain) = info.finish(&*texture_guard).map_pass_err(scope)?; - ( - raw, - trackers, - used_swapchain, - used_buffer_ranges, - query_reset_state, - ) + (raw, trackers, used_swapchain, query_reset_state) }; let (mut cmb_guard, mut token) = hub.command_buffers.write(&mut token); @@ -1899,7 +1941,6 @@ impl Global { CommandBuffer::get_encoder_mut(&mut *cmb_guard, encoder_id).map_pass_err(scope)?; cmd_buf.has_labels |= base.label.is_some(); cmd_buf.used_swap_chains.extend(used_swapchain); - cmd_buf.used_buffer_ranges.extend(used_buffer_ranges); #[cfg(feature = "trace")] if let Some(ref mut list) = cmd_buf.commands { diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 2f59ca37d3..23b99cc390 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -10,7 +10,7 @@ use crate::{ device::{all_buffer_stages, all_image_stages}, hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Storage, Token}, id::{BufferId, CommandEncoderId, TextureId}, - memory_init_tracker::{MemoryInitKind, ResourceMemoryInitTrackerAction}, + memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction}, resource::{BufferUse, Texture, TextureErrorDimension, TextureUse}, span, track::TextureSelector, @@ -404,20 +404,32 @@ impl Global { } // Make sure source is initialized memory and mark dest as initialized. - cmd_buf - .used_buffer_ranges - .push(ResourceMemoryInitTrackerAction { - id: destination, - range: destination_offset..(destination_offset + size), - kind: MemoryInitKind::ImplicitlyInitialized, - }); - cmd_buf - .used_buffer_ranges - .push(ResourceMemoryInitTrackerAction { - id: source, - range: source_offset..(source_offset + size), - kind: MemoryInitKind::NeedsInitializedMemory, - }); + let used_dst_buffer_range = destination_offset..(destination_offset + size); + if !dst_buffer + .initialization_status + .is_initialized(&used_dst_buffer_range) + { + cmd_buf + .buffer_memory_init_actions + .push(MemoryInitTrackerAction { + id: destination, + range: used_dst_buffer_range, + kind: MemoryInitKind::ImplicitlyInitialized, + }); + } + let used_src_buffer_range = source_offset..(source_offset + size); + if !src_buffer + .initialization_status + .is_initialized(&used_src_buffer_range) + { + cmd_buf + .buffer_memory_init_actions + .push(MemoryInitTrackerAction { + id: source, + range: used_src_buffer_range, + kind: MemoryInitKind::NeedsInitializedMemory, + }); + } let region = hal::command::BufferCopy { src: source_offset, @@ -532,14 +544,20 @@ impl Global { copy_size, )?; - cmd_buf - .used_buffer_ranges - .push(ResourceMemoryInitTrackerAction { - id: source.buffer, - range: source.layout.offset..(source.layout.offset + required_buffer_bytes_in_copy), - kind: MemoryInitKind::NeedsInitializedMemory, - }); - // TODO: Mark dest texture memory as implicitly initialized here. + let used_src_buffer_range = + source.layout.offset..(source.layout.offset + required_buffer_bytes_in_copy); + if !src_buffer + .initialization_status + .is_initialized(&used_src_buffer_range) + { + cmd_buf + .buffer_memory_init_actions + .push(MemoryInitTrackerAction { + id: source.buffer, + range: used_src_buffer_range, + kind: MemoryInitKind::NeedsInitializedMemory, + }); + } let (block_width, _) = dst_texture.format.describe().block_dimensions; if !conv::is_valid_copy_dst_texture_format(dst_texture.format) { @@ -688,16 +706,20 @@ impl Global { ))? } - cmd_buf - .used_buffer_ranges - .push(ResourceMemoryInitTrackerAction { - id: destination.buffer, - range: destination.layout.offset - ..(destination.layout.offset + required_buffer_bytes_in_copy), - kind: MemoryInitKind::ImplicitlyInitialized, - }); - // TODO: Mark dest texture memory as required to be initialized here. - + let used_dst_buffer_range = + destination.layout.offset..(destination.layout.offset + required_buffer_bytes_in_copy); + if !dst_buffer + .initialization_status + .is_initialized(&used_dst_buffer_range) + { + cmd_buf + .buffer_memory_init_actions + .push(MemoryInitTrackerAction { + id: destination.buffer, + range: used_dst_buffer_range, + kind: MemoryInitKind::ImplicitlyInitialized, + }); + } // WebGPU uses the physical size of the texture for copies whereas vulkan uses // the virtual size. We have passed validation, so it's safe to use the // image extent data directly. We want the provided copy size to be no larger than diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index fb61d4b823..64a0b199d3 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -211,7 +211,7 @@ fn map_buffer( if let Some(uninitialized_ranges) = buffer .initialization_status - .drain_uninitialized_ranges(offset..(size + offset)) + .drain_uninitialized_ranges(&(offset..(size + offset))) { for uninitialized_range in uninitialized_ranges { let num_bytes = uninitialized_range.end - uninitialized_range.start; @@ -1366,7 +1366,7 @@ impl Device { return Err(Error::BindingZeroSize(bb.buffer_id)); } - used_buffer_ranges.push(ResourceMemoryInitTrackerAction { + used_buffer_ranges.push(MemoryInitTrackerAction { id: bb.buffer_id, range: bb.offset..(bb.offset + bind_size), kind: MemoryInitKind::NeedsInitializedMemory, @@ -2611,12 +2611,12 @@ impl Global { unsafe { ptr::write_bytes(ptr.as_ptr(), 0, buffer.size as usize) }; buffer .initialization_status - .drain_uninitialized_ranges(0..buffer.size) + .drain_uninitialized_ranges(&(0..buffer.size)) .unwrap() .for_each(drop); stage .initialization_status - .drain_uninitialized_ranges(0..buffer.size) + .drain_uninitialized_ranges(&(0..buffer.size)) .unwrap() .for_each(drop); diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index e454ee3d80..e59ad116ff 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -277,7 +277,7 @@ impl Global { let dst = buffer_guard.get_mut(buffer_id).unwrap(); if let Some(uninitialized_ranges) = dst .initialization_status - .drain_uninitialized_ranges(buffer_offset..(buffer_offset + data_size)) + .drain_uninitialized_ranges(&(buffer_offset..(buffer_offset + data_size))) { uninitialized_ranges.for_each(drop); } @@ -498,14 +498,14 @@ impl Global { .get(cmb_id) .map_err(|_| QueueSubmitError::InvalidCommandBuffer(cmb_id))?; - for buffer_use in cmdbuf.used_buffer_ranges.iter() { + for buffer_use in cmdbuf.buffer_memory_init_actions.iter() { let buffer = buffer_guard .get_mut(buffer_use.id) .map_err(|_| QueueSubmitError::DestroyedBuffer(buffer_use.id))?; if let Some(uninitialized_ranges) = buffer .initialization_status - .drain_uninitialized_ranges(buffer_use.range.clone()) + .drain_uninitialized_ranges(&buffer_use.range) { match buffer_use.kind { MemoryInitKind::ImplicitlyInitialized => { diff --git a/wgpu-core/src/memory_init_tracker.rs b/wgpu-core/src/memory_init_tracker.rs index edc510fef8..4277e4efae 100644 --- a/wgpu-core/src/memory_init_tracker.rs +++ b/wgpu-core/src/memory_init_tracker.rs @@ -2,14 +2,14 @@ use std::ops::Range; #[derive(Debug, Clone)] pub(crate) enum MemoryInitKind { - // The memory range is going to be written by an already initialized source, thus doesn't need extra attention. + // The memory range is going to be written by an already initialized source, thus doesn't need extra attention other than marking as initialized. ImplicitlyInitialized, // The memory range is going to be read, therefore needs to ensure prior initialization. NeedsInitializedMemory, } #[derive(Debug, Clone)] -pub(crate) struct ResourceMemoryInitTrackerAction { +pub(crate) struct MemoryInitTrackerAction { pub(crate) id: ResourceId, pub(crate) range: Range, pub(crate) kind: MemoryInitKind, @@ -34,10 +34,16 @@ impl MemoryInitTracker { } } + pub(crate) fn is_initialized(&self, range: &Range) -> bool { + self.uninitialized_ranges + .allocated_ranges() + .all(|r: Range| r.start >= range.end || r.end <= range.start) + } + #[must_use] pub(crate) fn drain_uninitialized_ranges<'a>( &'a mut self, - range: Range, + range: &Range, ) -> Option> + 'a> { let mut uninitialized_ranges: Vec> = self .uninitialized_ranges