From 739adb9893bb156c519dd8b19fa71e5961f5617e Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Wed, 31 Jul 2024 09:53:52 +0200 Subject: [PATCH] wip: the big unraveling : core device now has a boxed `DynDevice`, ripple effects from there leading to boxing of almost all hal resources --- wgpu-core/src/binding_model.rs | 32 +++--- wgpu-core/src/command/allocator.rs | 22 ++--- wgpu-core/src/command/clear.rs | 8 +- wgpu-core/src/command/compute.rs | 6 +- wgpu-core/src/command/memory_init.rs | 11 +-- wgpu-core/src/command/mod.rs | 26 +++-- wgpu-core/src/command/query.rs | 2 +- wgpu-core/src/command/render.rs | 11 +-- wgpu-core/src/command/transfer.rs | 8 +- wgpu-core/src/device/global.rs | 25 +++-- wgpu-core/src/device/life.rs | 2 +- wgpu-core/src/device/queue.rs | 63 ++++++------ wgpu-core/src/device/resource.rs | 116 +++++++++++----------- wgpu-core/src/hub.rs | 2 +- wgpu-core/src/instance.rs | 6 +- wgpu-core/src/pipeline.rs | 46 ++++----- wgpu-core/src/present.rs | 13 ++- wgpu-core/src/resource.rs | 139 ++++++++++++++------------- wgpu-core/src/track/texture.rs | 2 +- 19 files changed, 268 insertions(+), 272 deletions(-) diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index ae21313d3b7..5a5d84e05bc 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -498,7 +498,7 @@ impl std::fmt::Display for ExclusivePipeline { /// Bind group layout. #[derive(Debug)] pub struct BindGroupLayout { - pub(crate) raw: Option, + pub(crate) raw: Option>, pub(crate) device: Arc>, pub(crate) entries: bgl::EntryMap, /// It is very important that we know if the bind group comes from the BGL pool. @@ -521,11 +521,10 @@ impl Drop for BindGroupLayout { if matches!(self.origin, bgl::Origin::Pool) { self.device.bgl_pool.remove(&self.entries); } - if let Some(mut raw) = self.raw.take() { + if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; - self.device.raw().destroy_bind_group_layout(&mut raw); + self.device.raw().destroy_bind_group_layout(raw); } } } @@ -538,8 +537,8 @@ crate::impl_storage_item!(BindGroupLayout); crate::impl_trackable!(BindGroupLayout); impl BindGroupLayout { - pub(crate) fn raw(&self) -> &A::BindGroupLayout { - self.raw.as_ref().unwrap() + pub(crate) fn raw(&self) -> &dyn hal::DynBindGroupLayout { + self.raw.as_ref().unwrap().as_ref() } } @@ -653,7 +652,7 @@ pub struct ResolvedPipelineLayoutDescriptor<'a, A: HalApi> { #[derive(Debug)] pub struct PipelineLayout { - pub(crate) raw: Option, + pub(crate) raw: Option>, pub(crate) device: Arc>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, @@ -664,19 +663,18 @@ pub struct PipelineLayout { impl Drop for PipelineLayout { fn drop(&mut self) { - if let Some(mut raw) = self.raw.take() { + if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; - self.device.raw().destroy_pipeline_layout(&mut raw); + self.device.raw().destroy_pipeline_layout(raw); } } } } impl PipelineLayout { - pub(crate) fn raw(&self) -> &A::PipelineLayout { - self.raw.as_ref().unwrap() + pub(crate) fn raw(&self) -> &dyn hal::DynPipelineLayout { + self.raw.as_ref().unwrap().as_ref() } pub(crate) fn get_binding_maps(&self) -> ArrayVec<&bgl::EntryMap, { hal::MAX_BIND_GROUPS }> { @@ -892,7 +890,7 @@ pub(crate) fn buffer_binding_type_alignment( #[derive(Debug)] pub struct BindGroup { - pub(crate) raw: Snatchable, + pub(crate) raw: Snatchable>, pub(crate) device: Arc>, pub(crate) layout: Arc>, /// The `label` from the descriptor used to create the resource. @@ -909,11 +907,10 @@ pub struct BindGroup { impl Drop for BindGroup { fn drop(&mut self) { - if let Some(mut raw) = self.raw.take() { + if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; - self.device.raw().destroy_bind_group(&mut raw); + self.device.raw().destroy_bind_group(raw); } } } @@ -923,7 +920,7 @@ impl BindGroup { pub(crate) fn try_raw<'a>( &'a self, guard: &'a SnatchGuard, - ) -> Result<&A::BindGroup, DestroyedResourceError> { + ) -> Result<&dyn hal::DynBindGroup, DestroyedResourceError> { // Clippy insist on writing it this way. The idea is to return None // if any of the raw buffer is not valid anymore. for buffer in &self.used_buffer_ranges { @@ -935,6 +932,7 @@ impl BindGroup { self.raw .get(guard) + .map(|raw| raw.as_ref()) .ok_or_else(|| DestroyedResourceError(self.error_ident())) } diff --git a/wgpu-core/src/command/allocator.rs b/wgpu-core/src/command/allocator.rs index c303e57e41a..b05898a5770 100644 --- a/wgpu-core/src/command/allocator.rs +++ b/wgpu-core/src/command/allocator.rs @@ -1,6 +1,4 @@ -use crate::hal_api::HalApi; use crate::resource_log; -use hal::Device as _; use crate::lock::{rank, Mutex}; @@ -14,11 +12,11 @@ use crate::lock::{rank, Mutex}; /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder /// [ce]: hal::CommandEncoder /// [cb]: hal::Api::CommandBuffer -pub(crate) struct CommandAllocator { - free_encoders: Mutex>, +pub(crate) struct CommandAllocator { + free_encoders: Mutex>>, } -impl CommandAllocator { +impl CommandAllocator { pub(crate) fn new() -> Self { Self { free_encoders: Mutex::new(rank::COMMAND_ALLOCATOR_FREE_ENCODERS, Vec::new()), @@ -33,9 +31,9 @@ impl CommandAllocator { /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder pub(crate) fn acquire_encoder( &self, - device: &A::Device, - queue: &A::Queue, - ) -> Result { + device: &dyn hal::DynDevice, + queue: &dyn hal::DynQueue, + ) -> Result, hal::DeviceError> { let mut free_encoders = self.free_encoders.lock(); match free_encoders.pop() { Some(encoder) => Ok(encoder), @@ -47,7 +45,7 @@ impl CommandAllocator { } /// Add `encoder` back to the free pool. - pub(crate) fn release_encoder(&self, encoder: A::CommandEncoder) { + pub(crate) fn release_encoder(&self, encoder: Box) { let mut free_encoders = self.free_encoders.lock(); free_encoders.push(encoder); } @@ -55,12 +53,12 @@ impl CommandAllocator { /// Free the pool of command encoders. /// /// This is only called when the `Device` is dropped. - pub(crate) fn dispose(&self, device: &A::Device) { + pub(crate) fn dispose(&self, device: &dyn hal::DynDevice) { let mut free_encoders = self.free_encoders.lock(); resource_log!("CommandAllocator::dispose encoders {}", free_encoders.len()); - for mut cmd_encoder in free_encoders.drain(..) { + for cmd_encoder in free_encoders.drain(..) { unsafe { - device.destroy_command_encoder(&mut cmd_encoder); + device.destroy_command_encoder(cmd_encoder); } } } diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index 98806a4ab03..5c4421a5e9f 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -262,7 +262,7 @@ impl Global { encoder, &mut tracker.textures, &device.alignments, - device.zero_buffer.as_ref().unwrap(), + device.zero_buffer.as_ref().unwrap().as_ref(), &snatch_guard, ) } @@ -274,7 +274,7 @@ pub(crate) fn clear_texture>( encoder: &mut dyn hal::DynCommandEncoder, texture_tracker: &mut T, alignments: &hal::Alignments, - zero_buffer: &A::Buffer, + zero_buffer: &dyn hal::DynBuffer, snatch_guard: &SnatchGuard<'_>, ) -> Result<(), ClearError> { let dst_raw = dst_texture.try_raw(snatch_guard)?; @@ -462,7 +462,7 @@ fn clear_texture_via_render_passes( let (color_attachments, depth_stencil_attachment) = if is_color { color_attachments_tmp = [Some(hal::ColorAttachment { target: hal::Attachment { - view: Texture::get_clear_view( + view: Texture::::get_clear_view( clear_mode, &dst_texture.desc, mip_level, @@ -480,7 +480,7 @@ fn clear_texture_via_render_passes( &[][..], Some(hal::DepthStencilAttachment { target: hal::Attachment { - view: Texture::get_clear_view( + view: Texture::::get_clear_view( clear_mode, &dst_texture.desc, mip_level, diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index ae03b700299..d427c126a53 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -517,14 +517,12 @@ impl Global { // But no point in erroring over that nuance here! if let Some(range) = range { unsafe { - state - .raw_encoder - .reset_queries(query_set.raw.as_ref().unwrap(), range); + state.raw_encoder.reset_queries(query_set.raw(), range); } } Some(hal::PassTimestampWrites { - query_set: query_set.raw.as_ref().unwrap(), + query_set: query_set.raw(), beginning_of_pass_write_index: tw.beginning_of_pass_write_index, end_of_pass_write_index: tw.end_of_pass_write_index, }) diff --git a/wgpu-core/src/command/memory_init.rs b/wgpu-core/src/command/memory_init.rs index 5dc06440734..d04a6a36b93 100644 --- a/wgpu-core/src/command/memory_init.rs +++ b/wgpu-core/src/command/memory_init.rs @@ -153,7 +153,7 @@ pub(crate) fn fixup_discarded_surfaces< encoder, texture_tracker, &device.alignments, - device.zero_buffer.as_ref().unwrap(), + device.zero_buffer.as_ref().unwrap().as_ref(), snatch_guard, ) .unwrap(); @@ -226,10 +226,9 @@ impl BakedCommands { .set_single(&buffer, hal::BufferUses::COPY_DST); let raw_buf = buffer.try_raw_dyn(snatch_guard)?; - let encoder: &mut dyn hal::DynCommandEncoder = &mut self.encoder; // TODO(#5124): temporary unsafe { - encoder.transition_buffers( + self.encoder.transition_buffers( transition .map(|pending| pending.into_hal(&buffer, snatch_guard)) .as_slice(), @@ -253,7 +252,7 @@ impl BakedCommands { ); unsafe { - encoder.clear_buffer(raw_buf, range.clone()); + self.encoder.clear_buffer(raw_buf, range.clone()); } } } @@ -306,10 +305,10 @@ impl BakedCommands { let clear_result = clear_texture( &texture_use.texture, range, - &mut self.encoder, + self.encoder.as_mut(), &mut device_tracker.textures, &device.alignments, - device.zero_buffer.as_ref().unwrap(), + device.zero_buffer.as_ref().unwrap().as_ref(), snatch_guard, ); diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index ff9ba51ee4a..bbc806d011d 100644 --- a/wgpu-core/src/command/mod.rs +++ b/wgpu-core/src/command/mod.rs @@ -39,7 +39,6 @@ use crate::track::{DeviceTracker, Tracker, UsageScope}; use crate::LabelHelpers; use crate::{api_log, global::Global, hal_api::HalApi, id, resource_log, Label}; -use hal::CommandEncoder as _; use thiserror::Error; #[cfg(feature = "trace")] @@ -115,7 +114,7 @@ pub(crate) enum CommandEncoderStatus { /// [rce]: hal::Api::CommandEncoder /// [rcb]: hal::Api::CommandBuffer /// [`CommandEncoderId`]: crate::id::CommandEncoderId -pub(crate) struct CommandEncoder { +pub(crate) struct CommandEncoder { /// The underlying `wgpu_hal` [`CommandEncoder`]. /// /// Successfully executed command buffers' encoders are saved in a @@ -123,7 +122,7 @@ pub(crate) struct CommandEncoder { /// /// [`CommandEncoder`]: hal::Api::CommandEncoder /// [`CommandAllocator`]: crate::command::CommandAllocator - raw: A::CommandEncoder, + raw: Box, /// All the raw command buffers for our owning [`CommandBuffer`], in /// submission order. @@ -136,7 +135,7 @@ pub(crate) struct CommandEncoder { /// /// [CE::ra]: hal::CommandEncoder::reset_all /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder - list: Vec, + list: Vec>, /// True if `raw` is in the "recording" state. /// @@ -150,7 +149,7 @@ pub(crate) struct CommandEncoder { } //TODO: handle errors better -impl CommandEncoder { +impl CommandEncoder { /// Finish the current command buffer, if any, and place it /// at the second-to-last position in our list. /// @@ -226,7 +225,7 @@ impl CommandEncoder { unsafe { self.raw.begin_encoding(hal_label)? }; } - Ok(&mut self.raw) + Ok(self.raw.as_mut()) } /// Begin recording a new command buffer for a render pass, with @@ -242,8 +241,8 @@ impl CommandEncoder { } pub(crate) struct BakedCommands { - pub(crate) encoder: A::CommandEncoder, - pub(crate) list: Vec, + pub(crate) encoder: Box, + pub(crate) list: Vec>, pub(crate) trackers: Tracker, buffer_memory_init_actions: Vec>, texture_memory_actions: CommandBufferTextureMemoryActions, @@ -255,7 +254,7 @@ pub struct CommandBufferMutable { /// they belong to. /// /// [`wgpu_hal::Api::CommandBuffer`]: hal::Api::CommandBuffer - pub(crate) encoder: CommandEncoder, + pub(crate) encoder: CommandEncoder, /// The current state of this command buffer's encoder. status: CommandEncoderStatus, @@ -329,20 +328,17 @@ impl Drop for CommandBuffer { } let mut baked = self.extract_baked_commands(); unsafe { - baked.encoder.reset_all(baked.list.iter_mut()); + baked.encoder.reset_all(baked.list); } unsafe { - use hal::Device; - self.device - .raw() - .destroy_command_encoder(&mut baked.encoder); + self.device.raw().destroy_command_encoder(baked.encoder); } } } impl CommandBuffer { pub(crate) fn new( - encoder: A::CommandEncoder, + encoder: Box, device: &Arc>, #[cfg(feature = "trace")] enable_tracing: bool, label: &Label, diff --git a/wgpu-core/src/command/query.rs b/wgpu-core/src/command/query.rs index befec4dfba2..26997ebd8bb 100644 --- a/wgpu-core/src/command/query.rs +++ b/wgpu-core/src/command/query.rs @@ -253,7 +253,7 @@ pub(super) fn end_occlusion_query( active_query: &mut Option<(Arc>, u32)>, ) -> Result<(), QueryUseError> { if let Some((query_set, query_index)) = active_query.take() { - unsafe { raw_encoder.end_query(query_set.raw.as_ref().unwrap(), query_index) }; + unsafe { raw_encoder.end_query(query_set.raw(), query_index) }; Ok(()) } else { Err(QueryUseError::AlreadyStopped) diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 3f1d24a2a39..890fcaa8010 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -34,7 +34,6 @@ use crate::{ }; use arrayvec::ArrayVec; -use hal::CommandEncoder as _; use thiserror::Error; use wgt::{ BufferAddress, BufferSize, BufferUsages, Color, DynamicOffset, IndexFormat, ShaderStages, @@ -826,7 +825,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { mut depth_stencil_attachment: Option>, mut timestamp_writes: Option>, mut occlusion_query_set: Option>>, - encoder: &mut CommandEncoder, + encoder: &mut CommandEncoder, trackers: &mut Tracker, texture_memory_actions: &mut CommandBufferTextureMemoryActions, pending_query_resets: &mut QueryResetMap, @@ -1193,7 +1192,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { } Some(hal::PassTimestampWrites { - query_set: query_set.raw.as_ref().unwrap(), + query_set: query_set.raw(), beginning_of_pass_write_index: tw.beginning_of_pass_write_index, end_of_pass_write_index: tw.end_of_pass_write_index, }) @@ -1203,7 +1202,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { let occlusion_query_set_hal = if let Some(query_set) = occlusion_query_set.as_ref() { query_set.same_device(device)?; - Some(query_set.raw.as_ref().unwrap()) + Some(query_set.raw()) } else { None }; @@ -1630,8 +1629,6 @@ impl Global { tracker.bundles.set_size(indices.bundles.size()); tracker.query_sets.set_size(indices.query_sets.size()); - let raw = &mut encoder.raw; - let mut state = State { pipeline_flags: PipelineFlags::empty(), binder: Binder::new(), @@ -1647,7 +1644,7 @@ impl Global { snatch_guard, device, - raw_encoder: raw, + raw_encoder: encoder.raw.as_mut(), tracker, buffer_memory_init_actions, texture_memory_actions, diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 34b6697625f..2137a42e29b 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -409,7 +409,7 @@ pub(crate) fn validate_texture_copy_range( fn handle_texture_init( init_kind: MemoryInitKind, - encoder: &mut CommandEncoder, + encoder: &mut CommandEncoder, trackers: &mut Tracker, texture_memory_actions: &mut CommandBufferTextureMemoryActions, device: &Device, @@ -444,7 +444,7 @@ fn handle_texture_init( cmd_buf_raw, &mut trackers.textures, &device.alignments, - device.zero_buffer.as_ref().unwrap(), + device.zero_buffer.as_ref().unwrap().as_ref(), snatch_guard, )?; } @@ -458,7 +458,7 @@ fn handle_texture_init( /// Ensure the source texture of a transfer is in the right initialization /// state, and record the state for after the transfer operation. fn handle_src_texture_init( - encoder: &mut CommandEncoder, + encoder: &mut CommandEncoder, trackers: &mut Tracker, texture_memory_actions: &mut CommandBufferTextureMemoryActions, device: &Device, @@ -486,7 +486,7 @@ fn handle_src_texture_init( /// Ensure the destination texture of a transfer is in the right initialization /// state, and record the state for after the transfer operation. fn handle_dst_texture_init( - encoder: &mut CommandEncoder, + encoder: &mut CommandEncoder, trackers: &mut Tracker, texture_memory_actions: &mut CommandBufferTextureMemoryActions, device: &Device, diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index 0df0bc377ad..fa59b4164de 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -281,15 +281,14 @@ impl Global { let raw_buf = buffer.try_raw(&snatch_guard)?; unsafe { let mapping = device - .raw() + .raw_typed() .map_buffer(raw_buf, offset..offset + data.len() as u64) .map_err(DeviceError::from)?; std::ptr::copy_nonoverlapping(data.as_ptr(), mapping.ptr.as_ptr(), data.len()); if !mapping.is_coherent { - device.raw().flush_mapped_ranges( - raw_buf, - std::iter::once(offset..offset + data.len() as u64), - ); + device + .raw() + .flush_mapped_ranges(raw_buf, &[offset..offset + data.len() as u64]); } device.raw().unmap_buffer(raw_buf); } @@ -395,7 +394,7 @@ impl Global { /// - `hal_texture` must be initialized pub unsafe fn create_texture_from_hal( &self, - hal_texture: A::Texture, + hal_texture: Box, device_id: DeviceId, desc: &resource::TextureDescriptor, id_in: Option, @@ -1977,6 +1976,7 @@ impl Global { // Wait for all work to finish before configuring the surface. let snatch_guard = device.snatchable_lock.read(); let fence = device.fence.read(); + // TODO(#5124): should already be a dynDevice match device.maintain(fence, wgt::Maintain::Wait, snatch_guard) { Ok((closures, _)) => { user_callbacks = closures; @@ -2002,7 +2002,7 @@ impl Global { match unsafe { A::surface_as_hal(surface) .unwrap() - .configure(device.raw(), &hal_config) + .configure(device.raw_typed(), &hal_config) } { Ok(()) => (), Err(error) => { @@ -2172,7 +2172,7 @@ impl Global { if !device.is_valid() { return; } - unsafe { device.raw().start_capture() }; + unsafe { device.raw_typed().start_capture() }; } } @@ -2185,7 +2185,7 @@ impl Global { if !device.is_valid() { return; } - unsafe { device.raw().stop_capture() }; + unsafe { device.raw_typed().stop_capture() }; } } @@ -2208,7 +2208,12 @@ impl Global { return None; } if let Some(raw_cache) = cache.raw.as_ref() { - let mut vec = unsafe { cache.device.raw().pipeline_cache_get_data(raw_cache) }?; + let mut vec = unsafe { + cache + .device + .raw() + .pipeline_cache_get_data(raw_cache.as_ref()) + }?; let validation_key = cache.device.raw().pipeline_cache_validation_key()?; let mut header_contents = [0; pipeline_cache::HEADER_LENGTH]; diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 3696d8abe4d..6ae7243ee0e 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -269,7 +269,7 @@ impl LifetimeTracker { pub fn triage_submissions( &mut self, last_done: SubmissionIndex, - command_allocator: &crate::command::CommandAllocator, + command_allocator: &crate::command::CommandAllocator, ) -> SmallVec<[SubmittedWorkDoneClosure; 1]> { profiling::scope!("triage_submissions"); diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 8eae1c120d2..8799e88d394 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -25,7 +25,6 @@ use crate::{ FastHashMap, SubmissionIndex, }; -use hal::{CommandEncoder as _, Device as _, Queue as _}; use smallvec::SmallVec; use std::{ @@ -39,20 +38,20 @@ use thiserror::Error; use super::Device; pub struct Queue { - raw: ManuallyDrop, + raw: ManuallyDrop>, pub(crate) device: Arc>, } impl Queue { - pub(crate) fn new(device: Arc>, raw: A::Queue) -> Self { + pub(crate) fn new(device: Arc>, raw: Box) -> Self { Queue { raw: ManuallyDrop::new(raw), device, } } - pub(crate) fn raw(&self) -> &A::Queue { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynQueue { + self.raw.as_ref() } } @@ -161,8 +160,8 @@ pub enum TempResource { /// [`CommandBuffer`]: hal::Api::CommandBuffer /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder pub(crate) struct EncoderInFlight { - raw: A::CommandEncoder, - cmd_buffers: Vec, + raw: Box, + cmd_buffers: Vec>, pub(crate) trackers: Tracker, /// These are the buffers that have been tracked by `PendingWrites`. @@ -176,8 +175,8 @@ impl EncoderInFlight { /// /// Return the command encoder, fully reset and ready to be /// reused. - pub(crate) unsafe fn land(mut self) -> A::CommandEncoder { - unsafe { self.raw.reset_all(self.cmd_buffers.iter_mut()) }; + pub(crate) unsafe fn land(mut self) -> Box { + unsafe { self.raw.reset_all(self.cmd_buffers) }; { // This involves actually decrementing the ref count of all command buffer // resources, so can be _very_ expensive. @@ -212,7 +211,7 @@ impl EncoderInFlight { /// All uses of [`StagingBuffer`]s end up here. #[derive(Debug)] pub(crate) struct PendingWrites { - pub command_encoder: A::CommandEncoder, + pub command_encoder: Box, /// True if `command_encoder` is in the "recording" state, as /// described in the docs for the [`wgpu_hal::CommandEncoder`] @@ -227,7 +226,7 @@ pub(crate) struct PendingWrites { } impl PendingWrites { - pub fn new(command_encoder: A::CommandEncoder) -> Self { + pub fn new(command_encoder: Box) -> Self { Self { command_encoder, is_recording: false, @@ -237,12 +236,12 @@ impl PendingWrites { } } - pub fn dispose(mut self, device: &A::Device) { + pub fn dispose(mut self, device: &dyn hal::DynDevice) { unsafe { if self.is_recording { self.command_encoder.discard_encoding(); } - device.destroy_command_encoder(&mut self.command_encoder); + device.destroy_command_encoder(self.command_encoder); } self.temp_resources.clear(); @@ -277,9 +276,9 @@ impl PendingWrites { fn pre_submit( &mut self, - command_allocator: &CommandAllocator, + command_allocator: &CommandAllocator, device: &A::Device, - queue: &A::Queue, + queue: &dyn hal::DynQueue, ) -> Result>, DeviceError> { if self.is_recording { let pending_buffers = mem::take(&mut self.dst_buffers); @@ -314,7 +313,7 @@ impl PendingWrites { } self.is_recording = true; } - &mut self.command_encoder + self.command_encoder.as_mut() } pub fn deactivate(&mut self) { @@ -731,7 +730,7 @@ impl Global { encoder, &mut trackers.textures, &device.alignments, - device.zero_buffer.as_ref().unwrap(), + device.zero_buffer.as_ref().unwrap().as_ref(), &device.snatchable_lock.read(), ) .map_err(QueueWriteError::from)?; @@ -1203,7 +1202,7 @@ impl Global { //Note: stateless trackers are not merged: // device already knows these resources exist. CommandBuffer::insert_barriers_from_device_tracker( - &mut baked.encoder, + baked.encoder.as_mut(), &mut *trackers, &baked.trackers, &snatch_guard, @@ -1232,10 +1231,8 @@ impl Global { &snatch_guard, ) .collect::>(); - let baked_encoder_dyn: &mut dyn hal::DynCommandEncoder = - &mut baked.encoder; // TODO(#5124) temporary let present = unsafe { - baked_encoder_dyn.transition_textures(&texture_barriers); + baked.encoder.transition_textures(&texture_barriers); baked.encoder.end_encoding().unwrap() }; baked.list.push(present); @@ -1289,32 +1286,36 @@ impl Global { &snatch_guard, ) .collect::>(); - let encoder: &mut dyn hal::DynCommandEncoder = - &mut pending_writes.command_encoder; // TODO(#5124) temporary unsafe { - encoder.transition_textures(&texture_barriers); + pending_writes + .command_encoder + .transition_textures(&texture_barriers); }; } } - if let Some(pending_execution) = - pending_writes.pre_submit(&device.command_allocator, device.raw(), queue.raw())? - { + if let Some(pending_execution) = pending_writes.pre_submit( + &device.command_allocator, + device.raw_typed(), + queue.raw(), + )? { active_executions.insert(0, pending_execution); } let hal_command_buffers = active_executions .iter() - .flat_map(|e| e.cmd_buffers.iter()) + .flat_map(|e| e.cmd_buffers.iter().map(|b| b.as_ref())) .collect::>(); { let mut submit_surface_textures = - SmallVec::<[_; 2]>::with_capacity(submit_surface_textures_owned.len()); + SmallVec::<[&dyn hal::DynSurfaceTexture; 2]>::with_capacity( + submit_surface_textures_owned.len(), + ); for texture in submit_surface_textures_owned.values() { submit_surface_textures.extend(match texture.inner.get(&snatch_guard) { - Some(TextureInner::Surface { raw, .. }) => raw.as_ref(), + Some(TextureInner::Surface { raw, .. }) => raw.as_ref().map(|r| r.as_ref()), _ => None, }); } @@ -1325,7 +1326,7 @@ impl Global { .submit( &hal_command_buffers, &submit_surface_textures, - (fence, submit_index), + (fence.as_mut(), submit_index), ) .map_err(DeviceError::from)?; } diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 20ff5de61f4..c375204d070 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -36,7 +36,7 @@ use crate::{ }; use arrayvec::ArrayVec; -use hal::{CommandEncoder as _, Device as _}; +use hal::Device as _; use once_cell::sync::OnceCell; use smallvec::SmallVec; @@ -45,7 +45,6 @@ use wgt::{DeviceLostReason, TextureFormat, TextureSampleType, TextureViewDimensi use std::{ borrow::Cow, - iter, mem::ManuallyDrop, num::NonZeroU32, sync::{ @@ -80,15 +79,15 @@ use super::{ /// When locking pending_writes please check that trackers is not locked /// trackers should be locked only when needed for the shortest time possible pub struct Device { - raw: Option, + raw: Option>, pub(crate) adapter: Arc>, pub(crate) queue: OnceCell>>, - queue_to_drop: OnceCell, - pub(crate) zero_buffer: Option, + queue_to_drop: OnceCell>, + pub(crate) zero_buffer: Option>, /// The `label` from the descriptor used to create the resource. label: String, - pub(crate) command_allocator: command::CommandAllocator, + pub(crate) command_allocator: command::CommandAllocator, /// The index of the last command submission that was attempted. /// @@ -112,7 +111,7 @@ pub struct Device { // NOTE: if both are needed, the `snatchable_lock` must be consistently acquired before the // `fence` lock to avoid deadlocks. - pub(crate) fence: RwLock>, + pub(crate) fence: RwLock>>, pub(crate) snatchable_lock: SnatchLock, /// Is this device valid? Valid is closely associated with "lose the device", @@ -172,13 +171,13 @@ impl Drop for Device { let raw = self.raw.take().unwrap(); // SAFETY: We are in the Drop impl and we don't use self.pending_writes anymore after this point. let pending_writes = unsafe { ManuallyDrop::take(&mut self.pending_writes.lock()) }; - pending_writes.dispose(&raw); - self.command_allocator.dispose(&raw); + pending_writes.dispose(raw.as_ref()); + self.command_allocator.dispose(raw.as_ref()); unsafe { - raw.destroy_buffer(&mut self.zero_buffer.take().unwrap()); - raw.destroy_fence(&mut self.fence.write().take().unwrap()); + raw.destroy_buffer(self.zero_buffer.take().unwrap()); + raw.destroy_fence(self.fence.write().take().unwrap()); let mut queue = self.queue_to_drop.take().unwrap(); - raw.exit(&mut queue); + raw.exit(queue); } } } @@ -192,8 +191,11 @@ pub enum CreateDeviceError { } impl Device { - pub(crate) fn raw(&self) -> &A::Device { - self.raw.as_ref().unwrap() + pub(crate) fn raw_typed(&self) -> &A::Device { + self.raw().as_any().downcast_ref().unwrap() + } + pub(crate) fn raw(&self) -> &dyn hal::DynDevice { + self.raw.as_ref().unwrap().as_ref() } pub(crate) fn require_features(&self, feature: wgt::Features) -> Result<(), MissingFeatures> { if self.features.contains(feature) { @@ -217,8 +219,8 @@ impl Device { impl Device { pub(crate) fn new( - raw_device: A::Device, - raw_queue: &A::Queue, + raw_device: Box, + raw_queue: &dyn hal::DynQueue, adapter: &Arc>, desc: &DeviceDescriptor, trace_path: Option<&std::path::Path>, @@ -233,7 +235,7 @@ impl Device { let command_allocator = command::CommandAllocator::new(); let pending_encoder = command_allocator - .acquire_encoder(&raw_device, raw_queue) + .acquire_encoder(raw_device.as_ref(), raw_queue) .map_err(|_| CreateDeviceError::OutOfMemory)?; let mut pending_writes = PendingWrites::::new(pending_encoder); @@ -252,19 +254,19 @@ impl Device { unsafe { pending_writes .command_encoder - .transition_buffers(iter::once(hal::BufferBarrier { - buffer: &zero_buffer, + .transition_buffers(&[hal::BufferBarrier { + buffer: zero_buffer.as_ref(), usage: hal::BufferUses::empty()..hal::BufferUses::COPY_DST, - })); + }]); pending_writes .command_encoder - .clear_buffer(&zero_buffer, 0..ZERO_BUFFER_SIZE); + .clear_buffer(zero_buffer.as_ref(), 0..ZERO_BUFFER_SIZE); pending_writes .command_encoder - .transition_buffers(iter::once(hal::BufferBarrier { - buffer: &zero_buffer, + .transition_buffers(&[hal::BufferBarrier { + buffer: zero_buffer.as_ref(), usage: hal::BufferUses::COPY_DST..hal::BufferUses::COPY_SRC, - })); + }]); } let alignments = adapter.raw.capabilities.alignments.clone(); @@ -330,7 +332,7 @@ impl Device { } } - pub(crate) fn release_queue(&self, queue: A::Queue) { + pub(crate) fn release_queue(&self, queue: Box) { assert!(self.queue_to_drop.set(queue).is_ok()); } @@ -352,23 +354,21 @@ impl Device { let Some(view) = view.upgrade() else { continue; }; - let Some(mut raw_view) = view.raw.snatch(self.snatchable_lock.write()) else { + let Some(raw_view) = view.raw.snatch(self.snatchable_lock.write()) else { continue; }; resource_log!("Destroy raw {}", view.error_ident()); unsafe { - use hal::Device; - self.raw().destroy_texture_view(&mut raw_view); + self.raw().destroy_texture_view(raw_view); } } DeferredDestroy::BindGroup(bind_group) => { let Some(bind_group) = bind_group.upgrade() else { continue; }; - let Some(mut raw_bind_group) = - bind_group.raw.snatch(self.snatchable_lock.write()) + let Some(raw_bind_group) = bind_group.raw.snatch(self.snatchable_lock.write()) else { continue; }; @@ -376,8 +376,7 @@ impl Device { resource_log!("Destroy raw {}", bind_group.error_ident()); unsafe { - use hal::Device; - self.raw().destroy_bind_group(&mut raw_bind_group); + self.raw().destroy_bind_group(raw_bind_group); } } } @@ -407,13 +406,13 @@ impl Device { /// return it to our callers.) pub(crate) fn maintain<'this>( &'this self, - fence_guard: crate::lock::RwLockReadGuard>, + fence_guard: crate::lock::RwLockReadGuard>>, maintain: wgt::Maintain, snatch_guard: SnatchGuard, ) -> Result<(UserClosures, bool), WaitIdleError> { profiling::scope!("Device::maintain"); - let fence = fence_guard.as_ref().unwrap(); + let fence = fence_guard.as_ref().unwrap().as_ref(); // Determine which submission index `maintain` represents. let submission_index = match maintain { @@ -452,7 +451,7 @@ impl Device { life_tracker.triage_mapped(); - let mapping_closures = life_tracker.handle_mapping(self.raw(), &snatch_guard); + let mapping_closures = life_tracker.handle_mapping(self.raw_typed(), &snatch_guard); let queue_empty = life_tracker.queue_empty(); @@ -576,7 +575,8 @@ impl Device { usage, memory_flags: hal::MemoryFlags::empty(), }; - let buffer = unsafe { self.raw().create_buffer(&hal_desc) }.map_err(DeviceError::from)?; + let buffer = + unsafe { self.raw_typed().create_buffer(&hal_desc) }.map_err(DeviceError::from)?; let buffer = Buffer { raw: Snatchable::new(Box::new(buffer)), @@ -606,7 +606,7 @@ impl Device { } else { let snatch_guard: SnatchGuard = self.snatchable_lock.read(); map_buffer( - self.raw(), + self.raw_typed(), &buffer, 0, map_size, @@ -643,7 +643,7 @@ impl Device { pub(crate) fn create_texture_from_hal( self: &Arc, - hal_texture: A::Texture, + hal_texture: Box, desc: &resource::TextureDescriptor, ) -> Result>, resource::CreateTextureError> { let format_features = self @@ -947,8 +947,10 @@ impl Device { }, }; clear_views.push(Some( - unsafe { self.raw().create_texture_view(&raw_texture, &desc) } - .map_err(DeviceError::from)?, + unsafe { + self.raw().create_texture_view(raw_texture.as_ref(), &desc) + } + .map_err(DeviceError::from)?, )); }; } @@ -1261,9 +1263,7 @@ impl Device { }; let raw = unsafe { - self.raw - .as_ref() - .unwrap() + self.raw() .create_texture_view(texture_raw, &hal_desc) .map_err(|_| resource::CreateTextureViewError::OutOfMemory)? }; @@ -1602,7 +1602,7 @@ impl Device { let encoder = self .command_allocator - .acquire_encoder(self.raw(), queue.raw())?; + .acquire_encoder(self.raw_typed(), queue.raw())?; Ok(command::CommandBuffer::new( encoder, @@ -1877,7 +1877,8 @@ impl Device { used: &mut BindGroupStates, limits: &wgt::Limits, snatch_guard: &'a SnatchGuard<'a>, - ) -> Result, binding_model::CreateBindGroupError> { + ) -> Result, binding_model::CreateBindGroupError> + { use crate::binding_model::CreateBindGroupError as Error; let (binding_ty, dynamic, min_size) = match decl.ty { @@ -2009,7 +2010,7 @@ impl Device { binding: u32, decl: &wgt::BindGroupLayoutEntry, sampler: &'a Arc>, - ) -> Result<&'a A::Sampler, binding_model::CreateBindGroupError> { + ) -> Result<&'a dyn hal::DynSampler, binding_model::CreateBindGroupError> { use crate::binding_model::CreateBindGroupError as Error; used.samplers.add_single(sampler); @@ -2060,7 +2061,8 @@ impl Device { used: &mut BindGroupStates, used_texture_ranges: &mut Vec>, snatch_guard: &'a SnatchGuard<'a>, - ) -> Result, binding_model::CreateBindGroupError> { + ) -> Result, binding_model::CreateBindGroupError> + { used.views.add_single(view); view.same_device(self)?; @@ -2714,7 +2716,7 @@ impl Device { constants: desc.stage.constants.as_ref(), zero_initialize_workgroup_memory: desc.stage.zero_initialize_workgroup_memory, }, - cache: cache.as_ref().and_then(|it| it.raw.as_ref()), + cache: cache.as_ref().and_then(|it| it.try_raw()), }; let raw = unsafe { @@ -3294,7 +3296,7 @@ impl Device { fragment_stage, color_targets, multiview: desc.multiview, - cache: cache.as_ref().and_then(|it| it.raw.as_ref()), + cache: cache.as_ref().and_then(|it| it.try_raw()), }; let raw = unsafe { self.raw @@ -3482,15 +3484,11 @@ impl Device { ) -> Result<(), DeviceError> { let guard = self.fence.read(); let fence = guard.as_ref().unwrap(); - let last_done_index = unsafe { self.raw.as_ref().unwrap().get_fence_value(fence)? }; + let last_done_index = + unsafe { self.raw.as_ref().unwrap().get_fence_value(fence.as_ref())? }; if last_done_index < submission_index { log::info!("Waiting for submission {:?}", submission_index); - unsafe { - self.raw - .as_ref() - .unwrap() - .wait(fence, submission_index, !0)? - }; + unsafe { self.raw().wait(fence.as_ref(), submission_index, !0)? }; drop(guard); let closures = self .lock_life() @@ -3623,13 +3621,13 @@ impl Device { pub(crate) fn destroy_command_buffer(&self, mut cmd_buf: command::CommandBuffer) { let mut baked = cmd_buf.extract_baked_commands(); unsafe { - baked.encoder.reset_all(baked.list.iter_mut()); + baked.encoder.reset_all(baked.list); } unsafe { self.raw .as_ref() .unwrap() - .destroy_command_encoder(&mut baked.encoder); + .destroy_command_encoder(baked.encoder); } } @@ -3645,7 +3643,7 @@ impl Device { self.raw .as_ref() .unwrap() - .wait(fence, current_index, CLEANUP_WAIT_MS) + .wait(fence.as_ref(), current_index, CLEANUP_WAIT_MS) } { log::error!("failed to wait for the device: {error}"); } diff --git a/wgpu-core/src/hub.rs b/wgpu-core/src/hub.rs index 1357a2e423a..e0e976afc32 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -244,7 +244,7 @@ impl Hub { if let Some(device) = present.device.downcast_ref::() { let suf = A::surface_as_hal(surface); unsafe { - suf.unwrap().unconfigure(device.raw()); + suf.unwrap().unconfigure(device.raw_typed()); } } } diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 9ddbaae2d55..681ed32db2e 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -267,7 +267,7 @@ impl Adapter { api_log!("Adapter::create_device"); if let Ok(device) = Device::new( - hal_device.device, + Box::new(hal_device.device), &hal_device.queue, self, desc, @@ -275,7 +275,7 @@ impl Adapter { instance_flags, ) { let device = Arc::new(device); - let queue = Arc::new(Queue::new(device.clone(), hal_device.queue)); + let queue = Arc::new(Queue::new(device.clone(), Box::new(hal_device.queue))); device.set_queue(&queue); return Ok((device, queue)); } @@ -662,7 +662,7 @@ impl Global { if let Some(surface) = surface { if let Some(device) = present.device.downcast_ref::() { use hal::Surface; - unsafe { surface.unconfigure(device.raw()) }; + unsafe { surface.unconfigure(device.raw_typed()) }; } } } diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index f9b58b69eb2..e0c1282ec33 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -47,7 +47,7 @@ pub struct ShaderModuleDescriptor<'a> { #[derive(Debug)] pub struct ShaderModule { - pub(crate) raw: Option, + pub(crate) raw: Option>, pub(crate) device: Arc>, pub(crate) interface: Option, /// The `label` from the descriptor used to create the resource. @@ -56,11 +56,10 @@ pub struct ShaderModule { impl Drop for ShaderModule { fn drop(&mut self) { - if let Some(mut raw) = self.raw.take() { + if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; - self.device.raw().destroy_shader_module(&mut raw); + self.device.raw().destroy_shader_module(raw); } } } @@ -72,8 +71,8 @@ crate::impl_parent_device!(ShaderModule); crate::impl_storage_item!(ShaderModule); impl ShaderModule { - pub(crate) fn raw(&self) -> &A::ShaderModule { - self.raw.as_ref().unwrap() + pub(crate) fn raw(&self) -> &dyn hal::DynShaderModule { + self.raw.as_ref().unwrap().as_ref() } pub(crate) fn finalize_entry_point_name( @@ -240,7 +239,7 @@ pub enum CreateComputePipelineError { #[derive(Debug)] pub struct ComputePipeline { - pub(crate) raw: Option, + pub(crate) raw: Option>, pub(crate) layout: Arc>, pub(crate) device: Arc>, pub(crate) _shader_module: Arc>, @@ -252,11 +251,10 @@ pub struct ComputePipeline { impl Drop for ComputePipeline { fn drop(&mut self) { - if let Some(mut raw) = self.raw.take() { + if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; - self.device.raw().destroy_compute_pipeline(&mut raw); + self.device.raw().destroy_compute_pipeline(raw); } } } @@ -269,8 +267,8 @@ crate::impl_storage_item!(ComputePipeline); crate::impl_trackable!(ComputePipeline); impl ComputePipeline { - pub(crate) fn raw(&self) -> &A::ComputePipeline { - self.raw.as_ref().unwrap() + pub(crate) fn raw(&self) -> &dyn hal::DynComputePipeline { + self.raw.as_ref().unwrap().as_ref() } } @@ -299,7 +297,7 @@ impl From for CreatePipelineCacheError { #[derive(Debug)] pub struct PipelineCache { - pub(crate) raw: Option, + pub(crate) raw: Option>, pub(crate) device: Arc>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, @@ -308,16 +306,21 @@ pub struct PipelineCache { impl Drop for PipelineCache { fn drop(&mut self) { - if let Some(mut raw) = self.raw.take() { + if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; - self.device.raw().destroy_pipeline_cache(&mut raw); + self.device.raw().destroy_pipeline_cache(raw); } } } } +impl PipelineCache { + pub(crate) fn try_raw(&self) -> Option<&dyn hal::DynPipelineCache> { + self.raw.as_ref().map(|it| it.as_ref()) + } +} + crate::impl_resource_type!(PipelineCache); crate::impl_labeled!(PipelineCache); crate::impl_parent_device!(PipelineCache); @@ -581,7 +584,7 @@ impl Default for VertexStep { #[derive(Debug)] pub struct RenderPipeline { - pub(crate) raw: Option, + pub(crate) raw: Option>, pub(crate) device: Arc>, pub(crate) layout: Arc>, pub(crate) _shader_modules: @@ -598,11 +601,10 @@ pub struct RenderPipeline { impl Drop for RenderPipeline { fn drop(&mut self) { - if let Some(mut raw) = self.raw.take() { + if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; - self.device.raw().destroy_render_pipeline(&mut raw); + self.device.raw().destroy_render_pipeline(raw); } } } @@ -615,7 +617,7 @@ crate::impl_storage_item!(RenderPipeline); crate::impl_trackable!(RenderPipeline); impl RenderPipeline { - pub(crate) fn raw(&self) -> &A::RenderPipeline { - self.raw.as_ref().unwrap() + pub(crate) fn raw(&self) -> &dyn hal::DynRenderPipeline { + self.raw.as_ref().unwrap().as_ref() } } diff --git a/wgpu-core/src/present.rs b/wgpu-core/src/present.rs index c39c168c19a..5832d00cadd 100644 --- a/wgpu-core/src/present.rs +++ b/wgpu-core/src/present.rs @@ -159,7 +159,7 @@ impl Global { let (texture_id, status) = match unsafe { suf.unwrap().acquire_texture( Some(std::time::Duration::from_millis(FRAME_TIMEOUT_MS as u64)), - fence, + fence.as_any().downcast_ref().unwrap(), // TODO(#5124): temporary downcast ) } { Ok(Some(ast)) => { @@ -196,11 +196,9 @@ impl Global { range: wgt::ImageSubresourceRange::default(), }; let clear_view = unsafe { - hal::Device::create_texture_view( - device.raw(), - ast.texture.borrow(), - &clear_view_desc, - ) + device + .raw() + .create_texture_view(ast.texture.borrow(), &clear_view_desc) } .map_err(DeviceError::from)?; @@ -326,7 +324,8 @@ impl Global { log::error!("Presented frame is from a different surface"); Err(hal::SurfaceError::Lost) } else { - unsafe { queue.raw().present(suf.unwrap(), &mut raw.take().unwrap()) } + let queue = queue.raw().as_any().downcast_ref::().unwrap(); // TODO(#5124): temporary downcast + unsafe { queue.present(suf.unwrap(), &mut raw.take().unwrap()) } } } _ => unreachable!(), diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 1a27a7f8d35..81fdc1d276e 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -23,7 +23,6 @@ use thiserror::Error; use std::{ borrow::{Borrow, Cow}, fmt::Debug, - iter, mem::{self, ManuallyDrop}, ops::Range, ptr::NonNull, @@ -441,7 +440,6 @@ pub struct Buffer { impl Drop for Buffer { fn drop(&mut self) { if let Some(raw) = self.raw.take() { - use hal::DynDevice as _; resource_log!("Destroy raw {}", self.error_ident()); unsafe { self.device.raw().destroy_buffer(raw); @@ -625,8 +623,6 @@ impl Buffer { self: &Arc, #[cfg(feature = "trace")] buffer_id: BufferId, ) -> Result, BufferAccessError> { - use hal::Device; - let device = &self.device; let snatch_guard = device.snatchable_lock.read(); let raw_buf = self.try_raw(&snatch_guard)?; @@ -827,7 +823,7 @@ unsafe impl Sync for StagingBuffer {} /// [`Device::pending_writes`]: crate::device::Device #[derive(Debug)] pub struct StagingBuffer { - raw: A::Buffer, + raw: Box, device: Arc>, pub(crate) size: wgt::BufferSize, is_coherent: bool, @@ -836,7 +832,6 @@ pub struct StagingBuffer { impl StagingBuffer { pub(crate) fn new(device: &Arc>, size: wgt::BufferSize) -> Result { - use hal::Device; profiling::scope!("StagingBuffer::new"); let stage_desc = hal::BufferDescriptor { label: crate::hal_label(Some("(wgpu internal) Staging"), device.instance_flags), @@ -846,7 +841,7 @@ impl StagingBuffer { }; let raw = unsafe { device.raw().create_buffer(&stage_desc)? }; - let mapping = unsafe { device.raw().map_buffer(&raw, 0..size.get()) }?; + let mapping = unsafe { device.raw().map_buffer(raw.as_ref(), 0..size.get()) }?; let staging_buffer = StagingBuffer { raw, @@ -905,12 +900,11 @@ impl StagingBuffer { } pub(crate) fn flush(self) -> FlushedStagingBuffer { - use hal::Device; let device = self.device.raw(); if !self.is_coherent { - unsafe { device.flush_mapped_ranges(&self.raw, iter::once(0..self.size.get())) }; + unsafe { device.flush_mapped_ranges(self.raw.as_ref(), &[0..self.size.get()]) }; } - unsafe { device.unmap_buffer(&self.raw) }; + unsafe { device.unmap_buffer(self.raw.as_ref()) }; let StagingBuffer { raw, device, size, .. @@ -929,61 +923,59 @@ crate::impl_storage_item!(StagingBuffer); #[derive(Debug)] pub struct FlushedStagingBuffer { - raw: ManuallyDrop, + raw: ManuallyDrop>, device: Arc>, pub(crate) size: wgt::BufferSize, } impl FlushedStagingBuffer { pub(crate) fn raw(&self) -> &dyn hal::DynBuffer { - let buffer: &A::Buffer = &self.raw; - buffer + self.raw.as_ref() } } impl Drop for FlushedStagingBuffer { fn drop(&mut self) { - use hal::Device; resource_log!("Destroy raw StagingBuffer"); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let mut raw = unsafe { ManuallyDrop::take(&mut self.raw) }; - unsafe { self.device.raw().destroy_buffer(&mut raw) }; + unsafe { self.device.raw().destroy_buffer(raw) }; } } pub type TextureDescriptor<'a> = wgt::TextureDescriptor, Vec>; #[derive(Debug)] -pub(crate) enum TextureInner { +pub(crate) enum TextureInner { Native { - raw: A::Texture, + raw: Box, }, Surface { - raw: Option, + raw: Option>, parent_id: SurfaceId, }, } -impl TextureInner { - pub(crate) fn raw(&self) -> Option<&A::Texture> { +impl TextureInner { + pub(crate) fn raw(&self) -> Option<&dyn hal::DynTexture> { match self { - Self::Native { raw } => Some(raw), - Self::Surface { raw: Some(tex), .. } => Some(tex.borrow()), + Self::Native { raw } => Some(raw.as_ref()), + Self::Surface { raw: Some(tex), .. } => Some(tex.as_ref().borrow()), _ => None, } } } #[derive(Debug)] -pub enum TextureClearMode { +pub enum TextureClearMode { BufferCopy, // View for clear via RenderPass for every subsurface (mip/layer/slice) RenderPass { - clear_views: SmallVec<[Option; 1]>, + clear_views: SmallVec<[Option>; 1]>, is_color: bool, }, Surface { - clear_view: Option, + clear_view: Option>, }, // Texture can't be cleared, attempting to do so will cause panic. // (either because it is impossible for the type of texture or it is being destroyed) @@ -992,7 +984,7 @@ pub enum TextureClearMode { #[derive(Debug)] pub struct Texture { - pub(crate) inner: Snatchable>, + pub(crate) inner: Snatchable, pub(crate) device: Arc>, pub(crate) desc: wgt::TextureDescriptor<(), Vec>, pub(crate) hal_usage: hal::TextureUses, @@ -1002,7 +994,7 @@ pub struct Texture { /// The `label` from the descriptor used to create the resource. pub(crate) label: String, pub(crate) tracking_data: TrackingData, - pub(crate) clear_mode: RwLock>, + pub(crate) clear_mode: RwLock, pub(crate) views: Mutex>>>, pub(crate) bind_groups: Mutex>>>, } @@ -1010,11 +1002,11 @@ pub struct Texture { impl Texture { pub(crate) fn new( device: &Arc>, - inner: TextureInner, + inner: TextureInner, hal_usage: hal::TextureUses, desc: &TextureDescriptor, format_features: wgt::TextureFormatFeatures, - clear_mode: TextureClearMode, + clear_mode: TextureClearMode, init: bool, ) -> Self { Texture { @@ -1062,16 +1054,15 @@ impl Texture { impl Drop for Texture { fn drop(&mut self) { - use hal::Device; let mut clear_mode = self.clear_mode.write(); let clear_mode = &mut *clear_mode; match *clear_mode { TextureClearMode::Surface { ref mut clear_view, .. } => { - if let Some(mut view) = clear_view.take() { + if let Some(view) = clear_view.take() { unsafe { - self.device.raw().destroy_texture_view(&mut view); + self.device.raw().destroy_texture_view(view); } } } @@ -1080,9 +1071,9 @@ impl Drop for Texture { .. } => { clear_views.iter_mut().for_each(|clear_view| { - if let Some(mut view) = clear_view.take() { + if let Some(view) = clear_view.take() { unsafe { - self.device.raw().destroy_texture_view(&mut view); + self.device.raw().destroy_texture_view(view); } } }); @@ -1090,10 +1081,10 @@ impl Drop for Texture { _ => {} }; - if let Some(TextureInner::Native { mut raw }) = self.inner.take() { + if let Some(TextureInner::Native { raw }) = self.inner.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - self.device.raw().destroy_texture(&mut raw); + self.device.raw().destroy_texture(raw); } } } @@ -1103,20 +1094,23 @@ impl Texture { pub(crate) fn try_inner<'a>( &'a self, guard: &'a SnatchGuard, - ) -> Result<&'a TextureInner, DestroyedResourceError> { + ) -> Result<&'a TextureInner, DestroyedResourceError> { self.inner .get(guard) .ok_or_else(|| DestroyedResourceError(self.error_ident())) } - pub(crate) fn raw<'a>(&'a self, snatch_guard: &'a SnatchGuard) -> Option<&'a A::Texture> { + pub(crate) fn raw<'a>( + &'a self, + snatch_guard: &'a SnatchGuard, + ) -> Option<&'a dyn hal::DynTexture> { self.inner.get(snatch_guard)?.raw() } pub(crate) fn try_raw<'a>( &'a self, guard: &'a SnatchGuard, - ) -> Result<&'a A::Texture, DestroyedResourceError> { + ) -> Result<&'a dyn hal::DynTexture, DestroyedResourceError> { self.inner .get(guard) .and_then(|t| t.raw()) @@ -1126,11 +1120,11 @@ impl Texture { pub(crate) fn inner_mut<'a>( &'a self, guard: &'a mut ExclusiveSnatchGuard, - ) -> Option<&'a mut TextureInner> { + ) -> Option<&'a mut TextureInner> { self.inner.get_mut(guard) } pub(crate) fn get_clear_view<'a>( - clear_mode: &'a TextureClearMode, + clear_mode: &'a TextureClearMode, desc: &'a wgt::TextureDescriptor<(), Vec>, mip_level: u32, depth_or_layer: u32, @@ -1142,7 +1136,9 @@ impl Texture { TextureClearMode::None => { panic!("Given texture can't be cleared") } - TextureClearMode::Surface { ref clear_view, .. } => clear_view.as_ref().unwrap(), + TextureClearMode::Surface { ref clear_view, .. } => { + clear_view.as_ref().unwrap().as_ref() + } TextureClearMode::RenderPass { ref clear_views, .. } => { @@ -1153,7 +1149,7 @@ impl Texture { } else { mip_level * desc.size.depth_or_array_layers } + depth_or_layer; - clear_views[index as usize].as_ref().unwrap() + clear_views[index as usize].as_ref().unwrap().as_ref() } } } @@ -1246,6 +1242,9 @@ impl Global { if let Ok(texture) = hub.textures.get(id) { let snatch_guard = texture.device.snatchable_lock.read(); let hal_texture = texture.raw(&snatch_guard); + let hal_texture = hal_texture + .as_ref() + .and_then(|it| it.as_any().downcast_ref()); hal_texture_callback(hal_texture) } else { hal_texture_callback(None) @@ -1267,6 +1266,9 @@ impl Global { if let Ok(texture_view) = hub.texture_views.get(id) { let snatch_guard = texture_view.device.snatchable_lock.read(); let hal_texture_view = texture_view.raw(&snatch_guard); + let hal_texture_view = hal_texture_view + .as_ref() + .and_then(|it| it.as_any().downcast_ref()); hal_texture_view_callback(hal_texture_view) } else { hal_texture_view_callback(None) @@ -1302,7 +1304,7 @@ impl Global { let hub = A::hub(self); let device = hub.devices.get(id).ok(); - let hal_device = device.as_ref().map(|device| device.raw()); + let hal_device = device.as_ref().map(|device| device.raw_typed()); hal_device_callback(hal_device) } @@ -1321,7 +1323,9 @@ impl Global { if let Ok(device) = hub.devices.get(id) { let hal_fence = device.fence.read(); - let hal_fence = hal_fence.as_ref(); + let hal_fence = hal_fence + .as_ref() + .and_then(|fence| fence.as_any().downcast_ref()); hal_fence_callback(hal_fence) } else { hal_fence_callback(None) @@ -1379,7 +1383,7 @@ impl Global { /// A texture that has been marked as destroyed and is staged for actual deletion soon. #[derive(Debug)] pub struct DestroyedTexture { - raw: ManuallyDrop, + raw: ManuallyDrop>, views: Vec>>, bind_groups: Vec>>, device: Arc>, @@ -1407,9 +1411,9 @@ impl Drop for DestroyedTexture { resource_log!("Destroy raw Texture (destroyed) {:?}", self.label()); // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. - let mut raw = unsafe { ManuallyDrop::take(&mut self.raw) }; + let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - self.device.raw().destroy_texture(&mut raw); + self.device.raw().destroy_texture(raw); } } } @@ -1574,7 +1578,7 @@ pub enum TextureViewNotRenderableReason { #[derive(Debug)] pub struct TextureView { - pub(crate) raw: Snatchable, + pub(crate) raw: Snatchable>, // if it's a surface texture - it's none pub(crate) parent: Arc>, pub(crate) device: Arc>, @@ -1591,27 +1595,30 @@ pub struct TextureView { impl Drop for TextureView { fn drop(&mut self) { - if let Some(mut raw) = self.raw.take() { + if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; - self.device.raw().destroy_texture_view(&mut raw); + self.device.raw().destroy_texture_view(raw); } } } } impl TextureView { - pub(crate) fn raw<'a>(&'a self, snatch_guard: &'a SnatchGuard) -> Option<&'a A::TextureView> { - self.raw.get(snatch_guard) + pub(crate) fn raw<'a>( + &'a self, + snatch_guard: &'a SnatchGuard, + ) -> Option<&'a dyn hal::DynTextureView> { + self.raw.get(snatch_guard).map(|it| it.as_ref()) } pub(crate) fn try_raw<'a>( &'a self, guard: &'a SnatchGuard, - ) -> Result<&A::TextureView, DestroyedResourceError> { + ) -> Result<&'a dyn hal::DynTextureView, DestroyedResourceError> { self.raw .get(guard) + .map(|it| it.as_ref()) .ok_or_else(|| DestroyedResourceError(self.error_ident())) } } @@ -1708,7 +1715,7 @@ pub struct SamplerDescriptor<'a> { #[derive(Debug)] pub struct Sampler { - pub(crate) raw: Option, + pub(crate) raw: Option>, pub(crate) device: Arc>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, @@ -1721,19 +1728,18 @@ pub struct Sampler { impl Drop for Sampler { fn drop(&mut self) { - if let Some(mut raw) = self.raw.take() { + if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; - self.device.raw().destroy_sampler(&mut raw); + self.device.raw().destroy_sampler(raw); } } } } impl Sampler { - pub(crate) fn raw(&self) -> &A::Sampler { - self.raw.as_ref().unwrap() + pub(crate) fn raw(&self) -> &dyn hal::DynSampler { + self.raw.as_ref().unwrap().as_ref() } } @@ -1804,7 +1810,7 @@ pub type QuerySetDescriptor<'a> = wgt::QuerySetDescriptor>; #[derive(Debug)] pub struct QuerySet { - pub(crate) raw: Option, + pub(crate) raw: Option>, pub(crate) device: Arc>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, @@ -1814,11 +1820,10 @@ pub struct QuerySet { impl Drop for QuerySet { fn drop(&mut self) { - if let Some(mut raw) = self.raw.take() { + if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; - self.device.raw().destroy_query_set(&mut raw); + self.device.raw().destroy_query_set(raw); } } } @@ -1831,8 +1836,8 @@ crate::impl_storage_item!(QuerySet); crate::impl_trackable!(QuerySet); impl QuerySet { - pub(crate) fn raw(&self) -> &A::QuerySet { - self.raw.as_ref().unwrap() + pub(crate) fn raw(&self) -> &dyn hal::DynQuerySet { + self.raw.as_ref().unwrap().as_ref() } } diff --git a/wgpu-core/src/track/texture.rs b/wgpu-core/src/track/texture.rs index 6c2d01744af..545e2ee6733 100644 --- a/wgpu-core/src/track/texture.rs +++ b/wgpu-core/src/track/texture.rs @@ -459,7 +459,7 @@ impl TextureTracker { pub fn drain_transitions<'a>( &'a mut self, snatch_guard: &'a SnatchGuard<'a>, - ) -> (PendingTransitionList, Vec>>) { + ) -> (PendingTransitionList, Vec>) { let mut textures = Vec::new(); let transitions = self .temp