diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
commit | 40a355a42d4a9444dc753c04c6608dade2f06a23 (patch) | |
tree | 871fc667d2de662f171103ce5ec067014ef85e61 /third_party/rust/wgpu-core/src/device/resource.rs | |
parent | Adding upstream version 124.0.1. (diff) | |
download | firefox-40a355a42d4a9444dc753c04c6608dade2f06a23.tar.xz firefox-40a355a42d4a9444dc753c04c6608dade2f06a23.zip |
Adding upstream version 125.0.1.upstream/125.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/wgpu-core/src/device/resource.rs')
-rw-r--r-- | third_party/rust/wgpu-core/src/device/resource.rs | 204 |
1 files changed, 152 insertions, 52 deletions
diff --git a/third_party/rust/wgpu-core/src/device/resource.rs b/third_party/rust/wgpu-core/src/device/resource.rs index b2c85a056a..28ba0eafb1 100644 --- a/third_party/rust/wgpu-core/src/device/resource.rs +++ b/third_party/rust/wgpu-core/src/device/resource.rs @@ -13,7 +13,6 @@ use crate::{ hal_api::HalApi, hal_label, hub::Hub, - id::QueueId, init_tracker::{ BufferInitTracker, BufferInitTrackerAction, MemoryInitKind, TextureInitRange, TextureInitTracker, TextureInitTrackerAction, @@ -29,13 +28,16 @@ use crate::{ resource_log, snatch::{SnatchGuard, SnatchLock, Snatchable}, storage::Storage, - track::{BindGroupStates, TextureSelector, Tracker}, - validation::{self, check_buffer_usage, check_texture_usage}, + track::{BindGroupStates, TextureSelector, Tracker, TrackerIndexAllocators}, + validation::{ + self, check_buffer_usage, check_texture_usage, validate_color_attachment_bytes_per_sample, + }, FastHashMap, LabelHelpers as _, SubmissionIndex, }; use arrayvec::ArrayVec; use hal::{CommandEncoder as _, Device as _}; +use once_cell::sync::OnceCell; use parking_lot::{Mutex, MutexGuard, RwLock}; use smallvec::SmallVec; @@ -54,7 +56,7 @@ use std::{ use super::{ life::{self, ResourceMaps}, - queue::{self}, + queue::{self, Queue}, DeviceDescriptor, DeviceError, ImplicitPipelineContext, UserClosures, ENTRYPOINT_FAILURE_ERROR, IMPLICIT_BIND_GROUP_LAYOUT_ERROR_LABEL, ZERO_BUFFER_SIZE, }; @@ -87,8 +89,8 @@ use super::{ pub struct Device<A: HalApi> { raw: Option<A::Device>, pub(crate) adapter: Arc<Adapter<A>>, - pub(crate) queue_id: RwLock<Option<QueueId>>, - queue_to_drop: RwLock<Option<A::Queue>>, + pub(crate) queue: OnceCell<Weak<Queue<A>>>, + queue_to_drop: OnceCell<A::Queue>, pub(crate) zero_buffer: Option<A::Buffer>, pub(crate) info: ResourceInfo<Device<A>>, @@ -116,6 +118,7 @@ pub struct Device<A: HalApi> { /// Has to be locked temporarily only (locked last) /// and never before pending_writes pub(crate) trackers: Mutex<Tracker<A>>, + pub(crate) tracker_indices: TrackerIndexAllocators, // Life tracker should be locked right after the device and before anything else. life_tracker: Mutex<LifetimeTracker<A>>, /// Temporary storage for resource management functions. Cleared at the end @@ -160,7 +163,7 @@ impl<A: HalApi> Drop for Device<A> { unsafe { raw.destroy_buffer(self.zero_buffer.take().unwrap()); raw.destroy_fence(self.fence.write().take().unwrap()); - let queue = self.queue_to_drop.write().take().unwrap(); + let queue = self.queue_to_drop.take().unwrap(); raw.exit(queue); } } @@ -258,16 +261,17 @@ impl<A: HalApi> Device<A> { Ok(Self { raw: Some(raw_device), adapter: adapter.clone(), - queue_id: RwLock::new(None), - queue_to_drop: RwLock::new(None), + queue: OnceCell::new(), + queue_to_drop: OnceCell::new(), zero_buffer: Some(zero_buffer), - info: ResourceInfo::new("<device>"), + info: ResourceInfo::new("<device>", None), command_allocator: Mutex::new(Some(com_alloc)), active_submission_index: AtomicU64::new(0), fence: RwLock::new(Some(fence)), snatchable_lock: unsafe { SnatchLock::new() }, valid: AtomicBool::new(true), trackers: Mutex::new(Tracker::new()), + tracker_indices: TrackerIndexAllocators::new(), life_tracker: Mutex::new(life::LifetimeTracker::new()), temp_suspected: Mutex::new(Some(life::ResourceMaps::new())), bgl_pool: ResourcePool::new(), @@ -300,7 +304,7 @@ impl<A: HalApi> Device<A> { } pub(crate) fn release_queue(&self, queue: A::Queue) { - self.queue_to_drop.write().replace(queue); + assert!(self.queue_to_drop.set(queue).is_ok()); } pub(crate) fn lock_life<'a>(&'a self) -> MutexGuard<'a, LifetimeTracker<A>> { @@ -339,7 +343,8 @@ impl<A: HalApi> Device<A> { let Some(bind_group) = bind_group.upgrade() else { continue; }; - let Some(raw_bind_group) = bind_group.raw.snatch(self.snatchable_lock.write()) else { + let Some(raw_bind_group) = bind_group.raw.snatch(self.snatchable_lock.write()) + else { continue; }; @@ -357,6 +362,14 @@ impl<A: HalApi> Device<A> { } } + pub fn get_queue(&self) -> Option<Arc<Queue<A>>> { + self.queue.get().as_ref()?.upgrade() + } + + pub fn set_queue(&self, queue: Arc<Queue<A>>) { + assert!(self.queue.set(Arc::downgrade(&queue)).is_ok()); + } + /// Check this device for completed commands. /// /// The `maintain` argument tells how the maintence function should behave, either @@ -483,56 +496,56 @@ impl<A: HalApi> Device<A> { if resource.is_unique() { temp_suspected .buffers - .insert(resource.as_info().id(), resource.clone()); + .insert(resource.as_info().tracker_index(), resource.clone()); } } for resource in trackers.textures.used_resources() { if resource.is_unique() { temp_suspected .textures - .insert(resource.as_info().id(), resource.clone()); + .insert(resource.as_info().tracker_index(), resource.clone()); } } for resource in trackers.views.used_resources() { if resource.is_unique() { temp_suspected .texture_views - .insert(resource.as_info().id(), resource.clone()); + .insert(resource.as_info().tracker_index(), resource.clone()); } } for resource in trackers.bind_groups.used_resources() { if resource.is_unique() { temp_suspected .bind_groups - .insert(resource.as_info().id(), resource.clone()); + .insert(resource.as_info().tracker_index(), resource.clone()); } } for resource in trackers.samplers.used_resources() { if resource.is_unique() { temp_suspected .samplers - .insert(resource.as_info().id(), resource.clone()); + .insert(resource.as_info().tracker_index(), resource.clone()); } } for resource in trackers.compute_pipelines.used_resources() { if resource.is_unique() { temp_suspected .compute_pipelines - .insert(resource.as_info().id(), resource.clone()); + .insert(resource.as_info().tracker_index(), resource.clone()); } } for resource in trackers.render_pipelines.used_resources() { if resource.is_unique() { temp_suspected .render_pipelines - .insert(resource.as_info().id(), resource.clone()); + .insert(resource.as_info().tracker_index(), resource.clone()); } } for resource in trackers.query_sets.used_resources() { if resource.is_unique() { temp_suspected .query_sets - .insert(resource.as_info().id(), resource.clone()); + .insert(resource.as_info().tracker_index(), resource.clone()); } } } @@ -633,7 +646,10 @@ impl<A: HalApi> Device<A> { initialization_status: RwLock::new(BufferInitTracker::new(aligned_size)), sync_mapped_writes: Mutex::new(None), map_state: Mutex::new(resource::BufferMapState::Idle), - info: ResourceInfo::new(desc.label.borrow_or_default()), + info: ResourceInfo::new( + desc.label.borrow_or_default(), + Some(self.tracker_indices.buffers.clone()), + ), bind_groups: Mutex::new(Vec::new()), }) } @@ -662,7 +678,10 @@ impl<A: HalApi> Device<A> { mips: 0..desc.mip_level_count, layers: 0..desc.array_layer_count(), }, - info: ResourceInfo::new(desc.label.borrow_or_default()), + info: ResourceInfo::new( + desc.label.borrow_or_default(), + Some(self.tracker_indices.textures.clone()), + ), clear_mode: RwLock::new(clear_mode), views: Mutex::new(Vec::new()), bind_groups: Mutex::new(Vec::new()), @@ -684,7 +703,10 @@ impl<A: HalApi> Device<A> { initialization_status: RwLock::new(BufferInitTracker::new(0)), sync_mapped_writes: Mutex::new(None), map_state: Mutex::new(resource::BufferMapState::Idle), - info: ResourceInfo::new(desc.label.borrow_or_default()), + info: ResourceInfo::new( + desc.label.borrow_or_default(), + Some(self.tracker_indices.buffers.clone()), + ), bind_groups: Mutex::new(Vec::new()), } } @@ -1262,7 +1284,10 @@ impl<A: HalApi> Device<A> { render_extent, samples: texture.desc.sample_count, selector, - info: ResourceInfo::new(desc.label.borrow_or_default()), + info: ResourceInfo::new( + desc.label.borrow_or_default(), + Some(self.tracker_indices.texture_views.clone()), + ), }) } @@ -1366,7 +1391,10 @@ impl<A: HalApi> Device<A> { Ok(Sampler { raw: Some(raw), device: self.clone(), - info: ResourceInfo::new(desc.label.borrow_or_default()), + info: ResourceInfo::new( + desc.label.borrow_or_default(), + Some(self.tracker_indices.samplers.clone()), + ), comparison: desc.compare.is_some(), filtering: desc.min_filter == wgt::FilterMode::Linear || desc.mag_filter == wgt::FilterMode::Linear, @@ -1484,6 +1512,10 @@ impl<A: HalApi> Device<A> { .contains(wgt::Features::SHADER_EARLY_DEPTH_TEST), ); caps.set( + Caps::SHADER_INT64, + self.features.contains(wgt::Features::SHADER_INT64), + ); + caps.set( Caps::MULTISAMPLED_SHADING, self.downlevel .flags @@ -1559,7 +1591,7 @@ impl<A: HalApi> Device<A> { raw: Some(raw), device: self.clone(), interface: Some(interface), - info: ResourceInfo::new(desc.label.borrow_or_default()), + info: ResourceInfo::new(desc.label.borrow_or_default(), None), label: desc.label.borrow_or_default().to_string(), }) } @@ -1600,7 +1632,7 @@ impl<A: HalApi> Device<A> { raw: Some(raw), device: self.clone(), interface: None, - info: ResourceInfo::new(desc.label.borrow_or_default()), + info: ResourceInfo::new(desc.label.borrow_or_default(), None), label: desc.label.borrow_or_default().to_string(), }) } @@ -1704,10 +1736,23 @@ impl<A: HalApi> Device<A> { BindGroupLayoutEntryError::SampleTypeFloatFilterableBindingMultisampled, }); } - Bt::Texture { .. } => ( - Some(wgt::Features::TEXTURE_BINDING_ARRAY), - WritableStorage::No, - ), + Bt::Texture { + multisampled, + view_dimension, + .. + } => { + if multisampled && view_dimension != TextureViewDimension::D2 { + return Err(binding_model::CreateBindGroupLayoutError::Entry { + binding: entry.binding, + error: BindGroupLayoutEntryError::Non2DMultisampled(view_dimension), + }); + } + + ( + Some(wgt::Features::TEXTURE_BINDING_ARRAY), + WritableStorage::No, + ) + } Bt::StorageTexture { access, view_dimension, @@ -1840,7 +1885,10 @@ impl<A: HalApi> Device<A> { entries: entry_map, origin, binding_count_validator: count_validator, - info: ResourceInfo::new(label.unwrap_or("<BindGroupLayout>")), + info: ResourceInfo::new( + label.unwrap_or("<BindGroupLayout>"), + Some(self.tracker_indices.bind_group_layouts.clone()), + ), label: label.unwrap_or_default().to_string(), }) } @@ -1905,7 +1953,7 @@ impl<A: HalApi> Device<A> { .add_single(storage, bb.buffer_id, internal_use) .ok_or(Error::InvalidBuffer(bb.buffer_id))?; - check_buffer_usage(buffer.usage, pub_usage)?; + check_buffer_usage(bb.buffer_id, buffer.usage, pub_usage)?; let raw_buffer = buffer .raw .get(snatch_guard) @@ -2273,7 +2321,10 @@ impl<A: HalApi> Device<A> { raw: Snatchable::new(raw), device: self.clone(), layout: layout.clone(), - info: ResourceInfo::new(desc.label.borrow_or_default()), + info: ResourceInfo::new( + desc.label.borrow_or_default(), + Some(self.tracker_indices.bind_groups.clone()), + ), used, used_buffer_ranges, used_texture_ranges, @@ -2555,7 +2606,10 @@ impl<A: HalApi> Device<A> { Ok(binding_model::PipelineLayout { raw: Some(raw), device: self.clone(), - info: ResourceInfo::new(desc.label.borrow_or_default()), + info: ResourceInfo::new( + desc.label.borrow_or_default(), + Some(self.tracker_indices.pipeline_layouts.clone()), + ), bind_group_layouts, push_constant_ranges: desc.push_constant_ranges.iter().cloned().collect(), }) @@ -2656,14 +2710,21 @@ impl<A: HalApi> Device<A> { let mut shader_binding_sizes = FastHashMap::default(); let io = validation::StageIo::default(); + let final_entry_point_name; + { let stage = wgt::ShaderStages::COMPUTE; + final_entry_point_name = shader_module.finalize_entry_point_name( + stage, + desc.stage.entry_point.as_ref().map(|ep| ep.as_ref()), + )?; + if let Some(ref interface) = shader_module.interface { let _ = interface.check_stage( &mut binding_layout_source, &mut shader_binding_sizes, - &desc.stage.entry_point, + &final_entry_point_name, stage, io, None, @@ -2691,7 +2752,7 @@ impl<A: HalApi> Device<A> { label: desc.label.to_hal(self.instance_flags), layout: pipeline_layout.raw(), stage: hal::ProgrammableStage { - entry_point: desc.stage.entry_point.as_ref(), + entry_point: final_entry_point_name.as_ref(), module: shader_module.raw(), }, }; @@ -2720,7 +2781,10 @@ impl<A: HalApi> Device<A> { device: self.clone(), _shader_module: shader_module, late_sized_buffer_groups, - info: ResourceInfo::new(desc.label.borrow_or_default()), + info: ResourceInfo::new( + desc.label.borrow_or_default(), + Some(self.tracker_indices.compute_pipelines.clone()), + ), }; Ok(pipeline) } @@ -2749,11 +2813,12 @@ impl<A: HalApi> Device<A> { let mut shader_binding_sizes = FastHashMap::default(); let num_attachments = desc.fragment.as_ref().map(|f| f.targets.len()).unwrap_or(0); - if num_attachments > hal::MAX_COLOR_ATTACHMENTS { + let max_attachments = self.limits.max_color_attachments as usize; + if num_attachments > max_attachments { return Err(pipeline::CreateRenderPipelineError::ColorAttachment( command::ColorAttachmentError::TooMany { given: num_attachments, - limit: hal::MAX_COLOR_ATTACHMENTS, + limit: max_attachments, }, )); } @@ -2959,6 +3024,7 @@ impl<A: HalApi> Device<A> { } } } + break None; }; if let Some(e) = error { @@ -2967,6 +3033,16 @@ impl<A: HalApi> Device<A> { } } + let limit = self.limits.max_color_attachment_bytes_per_sample; + let formats = color_targets + .iter() + .map(|cs| cs.as_ref().map(|cs| cs.format)); + if let Err(total) = validate_color_attachment_bytes_per_sample(formats, limit) { + return Err(pipeline::CreateRenderPipelineError::ColorAttachment( + command::ColorAttachmentError::TooManyBytesPerSample { total, limit }, + )); + } + if let Some(ds) = depth_stencil_state { let error = loop { let format_features = self.describe_format_features(adapter, ds.format)?; @@ -3051,6 +3127,7 @@ impl<A: HalApi> Device<A> { }; let vertex_shader_module; + let vertex_entry_point_name; let vertex_stage = { let stage_desc = &desc.vertex.stage; let stage = wgt::ShaderStages::VERTEX; @@ -3065,27 +3142,37 @@ impl<A: HalApi> Device<A> { return Err(DeviceError::WrongDevice.into()); } + let stage_err = |error| pipeline::CreateRenderPipelineError::Stage { stage, error }; + + vertex_entry_point_name = vertex_shader_module + .finalize_entry_point_name( + stage, + stage_desc.entry_point.as_ref().map(|ep| ep.as_ref()), + ) + .map_err(stage_err)?; + if let Some(ref interface) = vertex_shader_module.interface { io = interface .check_stage( &mut binding_layout_source, &mut shader_binding_sizes, - &stage_desc.entry_point, + &vertex_entry_point_name, stage, io, desc.depth_stencil.as_ref().map(|d| d.depth_compare), ) - .map_err(|error| pipeline::CreateRenderPipelineError::Stage { stage, error })?; + .map_err(stage_err)?; validated_stages |= stage; } hal::ProgrammableStage { module: vertex_shader_module.raw(), - entry_point: stage_desc.entry_point.as_ref(), + entry_point: &vertex_entry_point_name, } }; let mut fragment_shader_module = None; + let fragment_entry_point_name; let fragment_stage = match desc.fragment { Some(ref fragment_state) => { let stage = wgt::ShaderStages::FRAGMENT; @@ -3099,28 +3186,38 @@ impl<A: HalApi> Device<A> { })?, ); + let stage_err = |error| pipeline::CreateRenderPipelineError::Stage { stage, error }; + + fragment_entry_point_name = shader_module + .finalize_entry_point_name( + stage, + fragment_state + .stage + .entry_point + .as_ref() + .map(|ep| ep.as_ref()), + ) + .map_err(stage_err)?; + if validated_stages == wgt::ShaderStages::VERTEX { if let Some(ref interface) = shader_module.interface { io = interface .check_stage( &mut binding_layout_source, &mut shader_binding_sizes, - &fragment_state.stage.entry_point, + &fragment_entry_point_name, stage, io, desc.depth_stencil.as_ref().map(|d| d.depth_compare), ) - .map_err(|error| pipeline::CreateRenderPipelineError::Stage { - stage, - error, - })?; + .map_err(stage_err)?; validated_stages |= stage; } } if let Some(ref interface) = shader_module.interface { shader_expects_dual_source_blending = interface - .fragment_uses_dual_source_blending(&fragment_state.stage.entry_point) + .fragment_uses_dual_source_blending(&fragment_entry_point_name) .map_err(|error| pipeline::CreateRenderPipelineError::Stage { stage, error, @@ -3129,7 +3226,7 @@ impl<A: HalApi> Device<A> { Some(hal::ProgrammableStage { module: shader_module.raw(), - entry_point: fragment_state.stage.entry_point.as_ref(), + entry_point: &fragment_entry_point_name, }) } None => None, @@ -3302,7 +3399,10 @@ impl<A: HalApi> Device<A> { strip_index_format: desc.primitive.strip_index_format, vertex_steps, late_sized_buffer_groups, - info: ResourceInfo::new(desc.label.borrow_or_default()), + info: ResourceInfo::new( + desc.label.borrow_or_default(), + Some(self.tracker_indices.render_pipelines.clone()), + ), }; Ok(pipeline) } @@ -3415,7 +3515,7 @@ impl<A: HalApi> Device<A> { Ok(QuerySet { raw: Some(unsafe { self.raw().create_query_set(&hal_desc).unwrap() }), device: self.clone(), - info: ResourceInfo::new(""), + info: ResourceInfo::new("", Some(self.tracker_indices.query_sets.clone())), desc: desc.map_label(|_| ()), }) } |