From 7c7e4164f178d951c80cb937786f3ae4b1022e32 Mon Sep 17 00:00:00 2001 From: Andreas Reich Date: Thu, 11 Jul 2024 00:35:36 +0200 Subject: [PATCH] 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 | 20 ++-- wgpu-core/src/command/allocator.rs | 18 ++-- wgpu-core/src/command/bundle.rs | 6 +- wgpu-core/src/command/clear.rs | 32 +++--- wgpu-core/src/command/compute.rs | 65 ++++++------ wgpu-core/src/command/memory_init.rs | 12 +-- wgpu-core/src/command/mod.rs | 60 ++++++----- wgpu-core/src/command/query.rs | 16 ++- wgpu-core/src/command/render.rs | 17 ++- wgpu-core/src/command/transfer.rs | 115 ++++++++++++--------- wgpu-core/src/device/global.rs | 14 ++- wgpu-core/src/device/life.rs | 4 +- wgpu-core/src/device/mod.rs | 10 +- wgpu-core/src/device/queue.rs | 110 +++++++++++--------- wgpu-core/src/device/resource.rs | 95 ++++++++--------- wgpu-core/src/hub.rs | 3 +- wgpu-core/src/instance.rs | 6 +- wgpu-core/src/pipeline.rs | 28 +++-- wgpu-core/src/present.rs | 15 ++- wgpu-core/src/resource.rs | 148 ++++++++++++++------------- wgpu-core/src/track/buffer.rs | 4 +- wgpu-core/src/track/mod.rs | 8 +- wgpu-core/src/track/texture.rs | 6 +- wgpu/src/backend/wgpu_core.rs | 2 +- 24 files changed, 418 insertions(+), 396 deletions(-) diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 0687e6e0f..825a96418 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -499,7 +499,7 @@ impl std::fmt::Display for ExclusivePipeline { /// Bind group layout. #[derive(Debug)] pub struct BindGroupLayout { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, 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. @@ -525,7 +525,6 @@ impl Drop for BindGroupLayout { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_bind_group_layout(raw); } } @@ -537,8 +536,8 @@ crate::impl_parent_device!(BindGroupLayout); crate::impl_storage_item!(BindGroupLayout); impl BindGroupLayout { - pub(crate) fn raw(&self) -> &A::BindGroupLayout { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynBindGroupLayout { + self.raw.as_ref() } } @@ -652,7 +651,7 @@ pub struct ResolvedPipelineLayoutDescriptor<'a, A: HalApi> { #[derive(Debug)] pub struct PipelineLayout { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, @@ -666,15 +665,14 @@ impl Drop for PipelineLayout { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_pipeline_layout(raw); } } } impl PipelineLayout { - pub(crate) fn raw(&self) -> &A::PipelineLayout { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynPipelineLayout { + self.raw.as_ref() } pub(crate) fn get_binding_maps(&self) -> ArrayVec<&bgl::EntryMap, { hal::MAX_BIND_GROUPS }> { @@ -889,7 +887,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,7 +907,6 @@ impl Drop for BindGroup { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; self.device.raw().destroy_bind_group(raw); } } @@ -920,7 +917,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 { @@ -932,6 +929,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 e17fd08d7..b05898a57 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,7 +53,7 @@ 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 cmd_encoder in free_encoders.drain(..) { diff --git a/wgpu-core/src/command/bundle.rs b/wgpu-core/src/command/bundle.rs index 542c52b88..2f040e615 100644 --- a/wgpu-core/src/command/bundle.rs +++ b/wgpu-core/src/command/bundle.rs @@ -104,8 +104,6 @@ use arrayvec::ArrayVec; use std::{borrow::Cow, mem, num::NonZeroU32, ops::Range, sync::Arc}; use thiserror::Error; -use hal::CommandEncoder as _; - use super::{ render_command::{ArcRenderCommand, RenderCommand}, DrawKind, @@ -965,7 +963,7 @@ impl RenderBundle { /// The only failure condition is if some of the used buffers are destroyed. pub(super) unsafe fn execute( &self, - raw: &mut A::CommandEncoder, + raw: &mut dyn hal::DynCommandEncoder, snatch_guard: &SnatchGuard, ) -> Result<(), ExecutionError> { let mut offsets = self.base.dynamic_offsets.as_slice(); @@ -1006,7 +1004,7 @@ impl RenderBundle { offset, size, } => { - let buffer: &A::Buffer = buffer.try_raw(snatch_guard)?; + let buffer = buffer.try_raw(snatch_guard)?; let bb = hal::BufferBinding { buffer, offset: *offset, diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index a93fe8345..487bdf756 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -19,7 +19,6 @@ use crate::{ track::{TextureSelector, TextureTrackerSetSingle}, }; -use hal::CommandEncoder as _; use thiserror::Error; use wgt::{math::align_to, BufferAddress, BufferUsages, ImageSubresourceRange, TextureAspect}; @@ -167,7 +166,7 @@ impl Global { let dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard)); let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { - cmd_buf_raw.transition_buffers(dst_barrier.into_iter()); + cmd_buf_raw.transition_buffers(dst_barrier.as_slice()); cmd_buf_raw.clear_buffer(dst_raw, offset..end_offset); } Ok(()) @@ -263,7 +262,7 @@ impl Global { encoder, &mut tracker.textures, &device.alignments, - &device.zero_buffer, + device.zero_buffer.as_ref(), &snatch_guard, ) } @@ -272,10 +271,10 @@ impl Global { pub(crate) fn clear_texture>( dst_texture: &Arc>, range: TextureInitRange, - encoder: &mut A::CommandEncoder, + 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)?; @@ -316,14 +315,15 @@ pub(crate) fn clear_texture>( // change_replace_tracked whenever possible. let dst_barrier = texture_tracker .set_single(dst_texture, selector, clear_usage) - .map(|pending| pending.into_hal(dst_raw)); + .map(|pending| pending.into_hal(dst_raw)) + .collect::>(); unsafe { - encoder.transition_textures(dst_barrier.into_iter()); + encoder.transition_textures(&dst_barrier); } // Record actual clearing match dst_texture.clear_mode { - TextureClearMode::BufferCopy => clear_texture_via_buffer_copies::( + TextureClearMode::BufferCopy => clear_texture_via_buffer_copies( &dst_texture.desc, alignments, zero_buffer, @@ -346,13 +346,13 @@ pub(crate) fn clear_texture>( Ok(()) } -fn clear_texture_via_buffer_copies( +fn clear_texture_via_buffer_copies( texture_desc: &wgt::TextureDescriptor<(), Vec>, alignments: &hal::Alignments, - zero_buffer: &A::Buffer, // Buffer of size device::ZERO_BUFFER_SIZE + zero_buffer: &dyn hal::DynBuffer, // Buffer of size device::ZERO_BUFFER_SIZE range: TextureInitRange, - encoder: &mut A::CommandEncoder, - dst_raw: &A::Texture, + encoder: &mut dyn hal::DynCommandEncoder, + dst_raw: &dyn hal::DynTexture, ) { assert!(!texture_desc.format.is_depth_stencil_format()); @@ -436,7 +436,7 @@ fn clear_texture_via_buffer_copies( } unsafe { - encoder.copy_buffer_to_texture(zero_buffer, dst_raw, zero_buffer_copy_regions.into_iter()); + encoder.copy_buffer_to_texture(zero_buffer, dst_raw, &zero_buffer_copy_regions); } } @@ -444,7 +444,7 @@ fn clear_texture_via_render_passes( dst_texture: &Texture, range: TextureInitRange, is_color: bool, - encoder: &mut A::CommandEncoder, + encoder: &mut dyn hal::DynCommandEncoder, ) { assert_eq!(dst_texture.desc.dimension, wgt::TextureDimension::D2); @@ -461,7 +461,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( &dst_texture.clear_mode, &dst_texture.desc, mip_level, @@ -479,7 +479,7 @@ fn clear_texture_via_render_passes( &[][..], Some(hal::DepthStencilAttachment { target: hal::Attachment { - view: Texture::get_clear_view( + view: Texture::::get_clear_view( &dst_texture.clear_mode, &dst_texture.desc, mip_level, diff --git a/wgpu-core/src/command/compute.rs b/wgpu-core/src/command/compute.rs index c31db544d..a23370527 100644 --- a/wgpu-core/src/command/compute.rs +++ b/wgpu-core/src/command/compute.rs @@ -26,8 +26,6 @@ use crate::{ Label, }; -use hal::CommandEncoder as _; - use thiserror::Error; use wgt::{BufferAddress, DynamicOffset}; @@ -212,7 +210,7 @@ struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi> { device: &'cmd_buf Arc>, - raw_encoder: &'raw_encoder mut A::CommandEncoder, + raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder, tracker: &'cmd_buf mut Tracker, buffer_memory_init_actions: &'cmd_buf mut Vec>, @@ -485,40 +483,41 @@ impl Global { state.tracker.buffers.set_size(indices.buffers.size()); state.tracker.textures.set_size(indices.textures.size()); - let timestamp_writes = if let Some(tw) = timestamp_writes.take() { - tw.query_set - .same_device_as(cmd_buf) - .map_pass_err(pass_scope)?; + let timestamp_writes: Option> = + if let Some(tw) = timestamp_writes.take() { + tw.query_set + .same_device_as(cmd_buf) + .map_pass_err(pass_scope)?; - let query_set = state.tracker.query_sets.insert_single(tw.query_set); + let query_set = state.tracker.query_sets.insert_single(tw.query_set); - // Unlike in render passes we can't delay resetting the query sets since - // there is no auxiliary pass. - let range = if let (Some(index_a), Some(index_b)) = - (tw.beginning_of_pass_write_index, tw.end_of_pass_write_index) - { - Some(index_a.min(index_b)..index_a.max(index_b) + 1) - } else { - tw.beginning_of_pass_write_index - .or(tw.end_of_pass_write_index) - .map(|i| i..i + 1) - }; - // Range should always be Some, both values being None should lead to a validation error. - // But no point in erroring over that nuance here! - if let Some(range) = range { - unsafe { - state.raw_encoder.reset_queries(query_set.raw(), range); + // Unlike in render passes we can't delay resetting the query sets since + // there is no auxiliary pass. + let range = if let (Some(index_a), Some(index_b)) = + (tw.beginning_of_pass_write_index, tw.end_of_pass_write_index) + { + Some(index_a.min(index_b)..index_a.max(index_b) + 1) + } else { + tw.beginning_of_pass_write_index + .or(tw.end_of_pass_write_index) + .map(|i| i..i + 1) + }; + // Range should always be Some, both values being None should lead to a validation error. + // But no point in erroring over that nuance here! + if let Some(range) = range { + unsafe { + state.raw_encoder.reset_queries(query_set.raw(), range); + } } - } - Some(hal::PassTimestampWrites { - 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, - }) - } else { - None - }; + Some(hal::PassTimestampWrites { + 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, + }) + } else { + None + }; let hal_desc = hal::ComputePassDescriptor { label: hal_label(base.label.as_deref(), self.instance.flags), diff --git a/wgpu-core/src/command/memory_init.rs b/wgpu-core/src/command/memory_init.rs index 96427eacc..7e672393f 100644 --- a/wgpu-core/src/command/memory_init.rs +++ b/wgpu-core/src/command/memory_init.rs @@ -1,7 +1,5 @@ use std::{collections::hash_map::Entry, ops::Range, sync::Arc, vec::Drain}; -use hal::CommandEncoder; - use crate::{ device::Device, hal_api::HalApi, @@ -140,7 +138,7 @@ pub(crate) fn fixup_discarded_surfaces< InitIter: Iterator>, >( inits: InitIter, - encoder: &mut A::CommandEncoder, + encoder: &mut dyn hal::DynCommandEncoder, texture_tracker: &mut TextureTracker, device: &Device, snatch_guard: &SnatchGuard<'_>, @@ -155,7 +153,7 @@ pub(crate) fn fixup_discarded_surfaces< encoder, texture_tracker, &device.alignments, - &device.zero_buffer, + device.zero_buffer.as_ref(), snatch_guard, ) .unwrap(); @@ -233,7 +231,7 @@ impl BakedCommands { self.encoder.transition_buffers( transition .map(|pending| pending.into_hal(&buffer, snatch_guard)) - .into_iter(), + .as_slice(), ); } @@ -307,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, + device.zero_buffer.as_ref(), snatch_guard, ); diff --git a/wgpu-core/src/command/mod.rs b/wgpu-core/src/command/mod.rs index 7314e8f04..d16e7f6d0 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. /// @@ -219,14 +218,14 @@ impl CommandEncoder { /// Begin recording a new command buffer, if we haven't already. /// /// The underlying hal encoder is put in the "recording" state. - pub(crate) fn open(&mut self) -> Result<&mut A::CommandEncoder, DeviceError> { + pub(crate) fn open(&mut self) -> Result<&mut dyn hal::DynCommandEncoder, DeviceError> { if !self.is_open { self.is_open = true; let hal_label = self.hal_label.as_deref(); 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, @@ -280,7 +279,7 @@ pub struct CommandBufferMutable { impl CommandBufferMutable { pub(crate) fn open_encoder_and_tracker( &mut self, - ) -> Result<(&mut A::CommandEncoder, &mut Tracker), DeviceError> { + ) -> Result<(&mut dyn hal::DynCommandEncoder, &mut Tracker), DeviceError> { let encoder = self.encoder.open()?; let tracker = &mut self.trackers; @@ -329,17 +328,20 @@ impl Drop for CommandBuffer { } let mut baked = self.extract_baked_commands(); unsafe { - baked.encoder.reset_all(baked.list.into_iter()); + baked.encoder.reset_all(baked.list); } unsafe { - use hal::Device; self.device.raw().destroy_command_encoder(baked.encoder); } } } impl CommandBuffer { - pub(crate) fn new(encoder: A::CommandEncoder, device: &Arc>, label: &Label) -> Self { + pub(crate) fn new( + encoder: Box, + device: &Arc>, + label: &Label, + ) -> Self { CommandBuffer { device: device.clone(), support_clear_texture: device.features.contains(wgt::Features::CLEAR_TEXTURE), @@ -370,7 +372,7 @@ impl CommandBuffer { } pub(crate) fn insert_barriers_from_tracker( - raw: &mut A::CommandEncoder, + raw: &mut dyn hal::DynCommandEncoder, base: &mut Tracker, head: &Tracker, snatch_guard: &SnatchGuard, @@ -384,7 +386,7 @@ impl CommandBuffer { } pub(crate) fn insert_barriers_from_scope( - raw: &mut A::CommandEncoder, + raw: &mut dyn hal::DynCommandEncoder, base: &mut Tracker, head: &UsageScope, snatch_guard: &SnatchGuard, @@ -398,27 +400,31 @@ impl CommandBuffer { } pub(crate) fn drain_barriers( - raw: &mut A::CommandEncoder, + raw: &mut dyn hal::DynCommandEncoder, base: &mut Tracker, snatch_guard: &SnatchGuard, ) { profiling::scope!("drain_barriers"); - let buffer_barriers = base.buffers.drain_transitions(snatch_guard); + let buffer_barriers = base + .buffers + .drain_transitions(snatch_guard) + .collect::>(); let (transitions, textures) = base.textures.drain_transitions(snatch_guard); let texture_barriers = transitions .into_iter() .enumerate() - .map(|(i, p)| p.into_hal(textures[i].unwrap().raw())); + .map(|(i, p)| p.into_hal(textures[i].unwrap().raw())) + .collect::>(); unsafe { - raw.transition_buffers(buffer_barriers); - raw.transition_textures(texture_barriers); + raw.transition_buffers(&buffer_barriers); + raw.transition_textures(&texture_barriers); } } pub(crate) fn insert_barriers_from_device_tracker( - raw: &mut A::CommandEncoder, + raw: &mut dyn hal::DynCommandEncoder, base: &mut DeviceTracker, head: &Tracker, snatch_guard: &SnatchGuard, @@ -427,15 +433,17 @@ impl CommandBuffer { let buffer_barriers = base .buffers - .set_from_tracker_and_drain_transitions(&head.buffers, snatch_guard); + .set_from_tracker_and_drain_transitions(&head.buffers, snatch_guard) + .collect::>(); let texture_barriers = base .textures - .set_from_tracker_and_drain_transitions(&head.textures, snatch_guard); + .set_from_tracker_and_drain_transitions(&head.textures, snatch_guard) + .collect::>(); unsafe { - raw.transition_buffers(buffer_barriers); - raw.transition_textures(texture_barriers); + raw.transition_buffers(&buffer_barriers); + raw.transition_textures(&texture_barriers); } } } diff --git a/wgpu-core/src/command/query.rs b/wgpu-core/src/command/query.rs index 382fa2d29..26997ebd8 100644 --- a/wgpu-core/src/command/query.rs +++ b/wgpu-core/src/command/query.rs @@ -1,5 +1,3 @@ -use hal::CommandEncoder as _; - #[cfg(feature = "trace")] use crate::device::trace::Command as TraceCommand; use crate::{ @@ -44,7 +42,7 @@ impl QueryResetMap { std::mem::replace(&mut vec_pair.0[query as usize], true) } - pub fn reset_queries(&mut self, raw_encoder: &mut A::CommandEncoder) { + pub fn reset_queries(&mut self, raw_encoder: &mut dyn hal::DynCommandEncoder) { for (_, (state, query_set)) in self.map.drain() { debug_assert_eq!(state.len(), query_set.desc.count as usize); @@ -199,7 +197,7 @@ impl QuerySet { pub(super) fn validate_and_write_timestamp( self: &Arc, - raw_encoder: &mut A::CommandEncoder, + raw_encoder: &mut dyn hal::DynCommandEncoder, query_index: u32, reset_state: Option<&mut QueryResetMap>, ) -> Result<(), QueryUseError> { @@ -220,7 +218,7 @@ impl QuerySet { pub(super) fn validate_and_begin_occlusion_query( query_set: Arc>, - raw_encoder: &mut A::CommandEncoder, + raw_encoder: &mut dyn hal::DynCommandEncoder, tracker: &mut StatelessTracker>, query_index: u32, reset_state: Option<&mut QueryResetMap>, @@ -251,7 +249,7 @@ pub(super) fn validate_and_begin_occlusion_query( } pub(super) fn end_occlusion_query( - raw_encoder: &mut A::CommandEncoder, + raw_encoder: &mut dyn hal::DynCommandEncoder, active_query: &mut Option<(Arc>, u32)>, ) -> Result<(), QueryUseError> { if let Some((query_set, query_index)) = active_query.take() { @@ -264,7 +262,7 @@ pub(super) fn end_occlusion_query( pub(super) fn validate_and_begin_pipeline_statistics_query( query_set: Arc>, - raw_encoder: &mut A::CommandEncoder, + raw_encoder: &mut dyn hal::DynCommandEncoder, tracker: &mut StatelessTracker>, cmd_buf: &CommandBuffer, query_index: u32, @@ -302,7 +300,7 @@ pub(super) fn validate_and_begin_pipeline_statistics_query( } pub(super) fn end_pipeline_statistics_query( - raw_encoder: &mut A::CommandEncoder, + raw_encoder: &mut dyn hal::DynCommandEncoder, active_query: &mut Option<(Arc>, u32)>, ) -> Result<(), QueryUseError> { if let Some((query_set, query_index)) = active_query.take() { @@ -477,7 +475,7 @@ impl Global { let raw_dst_buffer = dst_buffer.try_raw(&snatch_guard)?; unsafe { - raw_encoder.transition_buffers(dst_barrier.into_iter()); + raw_encoder.transition_buffers(dst_barrier.as_slice()); raw_encoder.copy_query_results( query_set.raw(), start_query..end_query, diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index 73ce837ba..7e7f9a1af 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, @@ -461,7 +460,7 @@ struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi> { device: &'cmd_buf Arc>, - raw_encoder: &'raw_encoder mut A::CommandEncoder, + raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder, tracker: &'cmd_buf mut Tracker, buffer_memory_init_actions: &'cmd_buf mut Vec>, @@ -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, @@ -1255,7 +1254,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { fn finish( mut self, - raw: &mut A::CommandEncoder, + raw: &mut dyn hal::DynCommandEncoder, snatch_guard: &SnatchGuard, ) -> Result<(UsageScope<'d, A>, SurfacesInDiscardState), RenderPassErrorInner> { profiling::scope!("RenderPassInfo::finish"); @@ -1298,7 +1297,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> { hal::AttachmentOps::STORE, // clear depth ) }; - let desc = hal::RenderPassDescriptor { + let desc = hal::RenderPassDescriptor::<'_, _, dyn hal::DynTextureView> { label: Some("(wgpu internal) Zero init discarded depth/stencil aspect"), extent: view.render_extent.unwrap(), sample_count: view.samples, @@ -1632,8 +1631,6 @@ impl Global { tracker.buffers.set_size(indices.buffers.size()); tracker.textures.set_size(indices.textures.size()); - let raw = &mut encoder.raw; - let mut state = State { pipeline_flags: PipelineFlags::empty(), binder: Binder::new(), @@ -1649,7 +1646,7 @@ impl Global { snatch_guard, device, - raw_encoder: raw, + raw_encoder: encoder.raw.as_mut(), tracker, buffer_memory_init_actions, texture_memory_actions, @@ -2179,7 +2176,7 @@ fn set_index_buffer( size, }; unsafe { - state.raw_encoder.set_index_buffer(bb, index_format); + hal::DynCommandEncoder::set_index_buffer(state.raw_encoder, bb, index_format); } Ok(()) } @@ -2244,7 +2241,7 @@ fn set_vertex_buffer( size, }; unsafe { - state.raw_encoder.set_vertex_buffer(slot, bb); + hal::DynCommandEncoder::set_vertex_buffer(state.raw_encoder, slot, bb); } state.vertex.update_limits(); Ok(()) diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index b8208f5dd..4ccc76272 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -21,11 +21,10 @@ use crate::{ }; use arrayvec::ArrayVec; -use hal::CommandEncoder as _; use thiserror::Error; use wgt::{BufferAddress, BufferUsages, Extent3d, TextureUsages}; -use std::{iter, sync::Arc}; +use std::sync::Arc; use super::{memory_init::CommandBufferTextureMemoryActions, ClearError, CommandEncoder}; @@ -410,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, @@ -445,7 +444,7 @@ fn handle_texture_init( cmd_buf_raw, &mut trackers.textures, &device.alignments, - &device.zero_buffer, + device.zero_buffer.as_ref(), snatch_guard, )?; } @@ -459,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, @@ -487,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, @@ -687,9 +686,13 @@ impl Global { size: wgt::BufferSize::new(size).unwrap(), }; let cmd_buf_raw = cmd_buf_data.encoder.open()?; + let barriers = src_barrier + .into_iter() + .chain(dst_barrier) + .collect::>(); unsafe { - cmd_buf_raw.transition_buffers(src_barrier.into_iter().chain(dst_barrier)); - cmd_buf_raw.copy_buffer_to_buffer(src_raw, dst_raw, iter::once(region)); + cmd_buf_raw.transition_buffers(&barriers); + cmd_buf_raw.copy_buffer_to_buffer(src_raw, dst_raw, &[region]); } Ok(()) } @@ -801,7 +804,9 @@ impl Global { dst_texture .check_usage(TextureUsages::COPY_DST) .map_err(TransferError::MissingTextureUsage)?; - let dst_barrier = dst_pending.map(|pending| pending.into_hal(dst_raw)); + let dst_barrier = dst_pending + .map(|pending| pending.into_hal(dst_raw)) + .collect::>(); if !dst_base.aspect.is_one() { return Err(TransferError::CopyAspectNotOne.into()); @@ -837,23 +842,25 @@ impl Global { MemoryInitKind::NeedsInitializedMemory, )); - let regions = (0..array_layer_count).map(|rel_array_layer| { - let mut texture_base = dst_base.clone(); - texture_base.array_layer += rel_array_layer; - let mut buffer_layout = source.layout; - buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; - hal::BufferTextureCopy { - buffer_layout, - texture_base, - size: hal_copy_size, - } - }); + let regions = (0..array_layer_count) + .map(|rel_array_layer| { + let mut texture_base = dst_base.clone(); + texture_base.array_layer += rel_array_layer; + let mut buffer_layout = source.layout; + buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; + hal::BufferTextureCopy { + buffer_layout, + texture_base, + size: hal_copy_size, + } + }) + .collect::>(); let cmd_buf_raw = encoder.open()?; unsafe { - cmd_buf_raw.transition_textures(dst_barrier.into_iter()); - cmd_buf_raw.transition_buffers(src_barrier.into_iter()); - cmd_buf_raw.copy_buffer_to_texture(src_raw, dst_raw, regions); + cmd_buf_raw.transition_textures(&dst_barrier); + cmd_buf_raw.transition_buffers(src_barrier.as_slice()); + cmd_buf_raw.copy_buffer_to_texture(src_raw, dst_raw, ®ions); } Ok(()) } @@ -956,7 +963,9 @@ impl Global { } .into()); } - let src_barrier = src_pending.map(|pending| pending.into_hal(src_raw)); + let src_barrier = src_pending + .map(|pending| pending.into_hal(src_raw)) + .collect::>(); let dst_buffer = hub .buffers @@ -1009,26 +1018,28 @@ impl Global { MemoryInitKind::ImplicitlyInitialized, )); - let regions = (0..array_layer_count).map(|rel_array_layer| { - let mut texture_base = src_base.clone(); - texture_base.array_layer += rel_array_layer; - let mut buffer_layout = destination.layout; - buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; - hal::BufferTextureCopy { - buffer_layout, - texture_base, - size: hal_copy_size, - } - }); + let regions = (0..array_layer_count) + .map(|rel_array_layer| { + let mut texture_base = src_base.clone(); + texture_base.array_layer += rel_array_layer; + let mut buffer_layout = destination.layout; + buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; + hal::BufferTextureCopy { + buffer_layout, + texture_base, + size: hal_copy_size, + } + }) + .collect::>(); let cmd_buf_raw = encoder.open()?; unsafe { - cmd_buf_raw.transition_buffers(dst_barrier.into_iter()); - cmd_buf_raw.transition_textures(src_barrier.into_iter()); + cmd_buf_raw.transition_buffers(dst_barrier.as_slice()); + cmd_buf_raw.transition_textures(&src_barrier); cmd_buf_raw.copy_texture_to_buffer( src_raw, hal::TextureUses::COPY_SRC, dst_raw, - regions, + ®ions, ); } Ok(()) @@ -1186,25 +1197,27 @@ impl Global { height: src_copy_size.height.min(dst_copy_size.height), depth: src_copy_size.depth.min(dst_copy_size.depth), }; - let regions = (0..array_layer_count).map(|rel_array_layer| { - let mut src_base = src_tex_base.clone(); - let mut dst_base = dst_tex_base.clone(); - src_base.array_layer += rel_array_layer; - dst_base.array_layer += rel_array_layer; - hal::TextureCopy { - src_base, - dst_base, - size: hal_copy_size, - } - }); + let regions = (0..array_layer_count) + .map(|rel_array_layer| { + let mut src_base = src_tex_base.clone(); + let mut dst_base = dst_tex_base.clone(); + src_base.array_layer += rel_array_layer; + dst_base.array_layer += rel_array_layer; + hal::TextureCopy { + src_base, + dst_base, + size: hal_copy_size, + } + }) + .collect::>(); let cmd_buf_raw = cmd_buf_data.encoder.open()?; unsafe { - cmd_buf_raw.transition_textures(barriers.into_iter()); + cmd_buf_raw.transition_textures(&barriers); cmd_buf_raw.copy_texture_to_texture( src_raw, hal::TextureUses::COPY_SRC, dst_raw, - regions, + ®ions, ); } diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index 7fd82e8ce..cb9f62ea0 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -24,8 +24,6 @@ use crate::{ Label, }; -use hal::Device as _; - use wgt::{BufferAddress, TextureFormat}; use std::{borrow::Cow, ptr::NonNull, sync::atomic::Ordering}; @@ -282,10 +280,10 @@ impl Global { .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), - ); + #[allow(clippy::single_range_in_vec_init)] + device + .raw() + .flush_mapped_ranges(raw_buf, &[offset..offset + data.len() as u64]); } device.raw().unmap_buffer(raw_buf); } @@ -391,7 +389,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, @@ -1995,7 +1993,7 @@ impl Global { match unsafe { A::surface_as_hal(surface) .unwrap() - .configure(device.raw(), &hal_config) + .configure(device.raw().as_any().downcast_ref().unwrap(), &hal_config) } { Ok(()) => (), Err(error) => { diff --git a/wgpu-core/src/device/life.rs b/wgpu-core/src/device/life.rs index 7408c184d..1ee84be93 100644 --- a/wgpu-core/src/device/life.rs +++ b/wgpu-core/src/device/life.rs @@ -268,7 +268,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"); @@ -351,7 +351,7 @@ impl LifetimeTracker { #[must_use] pub(crate) fn handle_mapping( &mut self, - raw: &A::Device, + raw: &dyn hal::DynDevice, snatch_guard: &SnatchGuard, ) -> Vec { if self.ready_to_map.is_empty() { diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 1f890de90..c6f88b263 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -12,13 +12,12 @@ use crate::{ }; use arrayvec::ArrayVec; -use hal::Device as _; use smallvec::SmallVec; use std::os::raw::c_char; use thiserror::Error; use wgt::{BufferAddress, DeviceLostReason, TextureFormat}; -use std::{iter, num::NonZeroU32}; +use std::num::NonZeroU32; pub mod any_device; pub(crate) mod bgl; @@ -301,7 +300,7 @@ impl DeviceLostClosure { } fn map_buffer( - raw: &A::Device, + raw: &dyn hal::DynDevice, buffer: &Buffer, offset: BufferAddress, size: BufferAddress, @@ -315,8 +314,9 @@ fn map_buffer( }; if !mapping.is_coherent && kind == HostMap::Read { + #[allow(clippy::single_range_in_vec_init)] unsafe { - raw.invalidate_mapped_ranges(raw_buffer, iter::once(offset..offset + size)); + raw.invalidate_mapped_ranges(raw_buffer, &[offset..offset + size]); } } @@ -350,7 +350,7 @@ fn map_buffer( mapped[fill_range].fill(0); if !mapping.is_coherent && kind == HostMap::Read { - unsafe { raw.flush_mapped_ranges(raw_buffer, iter::once(uninitialized)) }; + unsafe { raw.flush_mapped_ranges(raw_buffer, &[uninitialized]) }; } } diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index 27f13e2f4..fbcbbdcbe 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() } } @@ -154,8 +153,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`. @@ -169,8 +168,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.into_iter()) }; + 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. @@ -205,7 +204,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`] @@ -220,7 +219,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, @@ -230,7 +229,7 @@ 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(); @@ -270,9 +269,9 @@ impl PendingWrites { fn pre_submit( &mut self, - command_allocator: &CommandAllocator, - device: &A::Device, - queue: &A::Queue, + command_allocator: &CommandAllocator, + device: &dyn hal::DynDevice, + queue: &dyn hal::DynQueue, ) -> Result>, DeviceError> { if self.is_recording { let pending_buffers = mem::take(&mut self.dst_buffers); @@ -298,7 +297,7 @@ impl PendingWrites { } } - pub fn activate(&mut self) -> &mut A::CommandEncoder { + pub fn activate(&mut self) -> &mut dyn hal::DynCommandEncoder { if !self.is_recording { unsafe { self.command_encoder @@ -307,7 +306,7 @@ impl PendingWrites { } self.is_recording = true; } - &mut self.command_encoder + self.command_encoder.as_mut() } pub fn deactivate(&mut self) { @@ -586,11 +585,12 @@ impl Global { buffer: staging_buffer.raw(), usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, }) - .chain(transition.map(|pending| pending.into_hal(&dst, &snatch_guard))); + .chain(transition.map(|pending| pending.into_hal(&dst, &snatch_guard))) + .collect::>(); let encoder = pending_writes.activate(); unsafe { - encoder.transition_buffers(barriers); - encoder.copy_buffer_to_buffer(staging_buffer.raw(), dst_raw, iter::once(region)); + encoder.transition_buffers(&barriers); + encoder.copy_buffer_to_buffer(staging_buffer.raw(), dst_raw, &[region]); } pending_writes.insert_buffer(&dst); @@ -723,7 +723,7 @@ impl Global { encoder, &mut trackers.textures, &device.alignments, - &device.zero_buffer, + device.zero_buffer.as_ref(), &device.snatchable_lock.read(), ) .map_err(QueueWriteError::from)?; @@ -802,24 +802,26 @@ impl Global { let staging_buffer = staging_buffer.flush(); - let regions = (0..array_layer_count).map(|array_layer_offset| { - let mut texture_base = dst_base.clone(); - texture_base.array_layer += array_layer_offset; - hal::BufferTextureCopy { - buffer_layout: wgt::ImageDataLayout { - offset: array_layer_offset as u64 - * rows_per_image as u64 - * stage_bytes_per_row as u64, - bytes_per_row: Some(stage_bytes_per_row), - rows_per_image: Some(rows_per_image), - }, - texture_base, - size: hal_copy_size, - } - }); + let regions = (0..array_layer_count) + .map(|array_layer_offset| { + let mut texture_base = dst_base.clone(); + texture_base.array_layer += array_layer_offset; + hal::BufferTextureCopy { + buffer_layout: wgt::ImageDataLayout { + offset: array_layer_offset as u64 + * rows_per_image as u64 + * stage_bytes_per_row as u64, + bytes_per_row: Some(stage_bytes_per_row), + rows_per_image: Some(rows_per_image), + }, + texture_base, + size: hal_copy_size, + } + }) + .collect::>(); { - let barrier = hal::BufferBarrier { + let buffer_barrier = hal::BufferBarrier { buffer: staging_buffer.raw(), usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, }; @@ -829,10 +831,14 @@ impl Global { trackers .textures .set_single(&dst, selector, hal::TextureUses::COPY_DST); + let texture_barriers = transition + .map(|pending| pending.into_hal(dst_raw)) + .collect::>(); + unsafe { - encoder.transition_textures(transition.map(|pending| pending.into_hal(dst_raw))); - encoder.transition_buffers(iter::once(barrier)); - encoder.copy_buffer_to_texture(staging_buffer.raw(), dst_raw, regions); + encoder.transition_textures(&texture_barriers); + encoder.transition_buffers(&[buffer_barrier]); + encoder.copy_buffer_to_texture(staging_buffer.raw(), dst_raw, ®ions); } } @@ -990,7 +996,7 @@ impl Global { encoder, &mut trackers.textures, &device.alignments, - &device.zero_buffer, + device.zero_buffer.as_ref(), &device.snatchable_lock.read(), ) .map_err(QueueWriteError::from)?; @@ -1185,7 +1191,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, @@ -1212,9 +1218,10 @@ impl Global { .set_from_usage_scope_and_drain_transitions( &used_surface_textures, &snatch_guard, - ); + ) + .collect::>(); let present = unsafe { - baked.encoder.transition_textures(texture_barriers); + baked.encoder.transition_textures(&texture_barriers); baked.encoder.end_encoding().unwrap() }; baked.list.push(present); @@ -1262,11 +1269,12 @@ impl Global { .set_from_usage_scope_and_drain_transitions( &used_surface_textures, &snatch_guard, - ); + ) + .collect::>(); unsafe { pending_writes .command_encoder - .transition_textures(texture_barriers); + .transition_textures(&texture_barriers); }; } } @@ -1279,16 +1287,18 @@ impl Global { 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() { let raw = match texture.inner.get(&snatch_guard) { - Some(TextureInner::Surface { raw, .. }) => raw, + Some(TextureInner::Surface { raw, .. }) => raw.as_ref(), _ => unreachable!(), }; submit_surface_textures.push(raw); @@ -1300,7 +1310,7 @@ impl Global { .submit( &hal_command_buffers, &submit_surface_textures, - (&mut 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 104f54a40..7801ccd05 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -36,7 +36,6 @@ use crate::{ }; use arrayvec::ArrayVec; -use hal::{CommandEncoder as _, Device as _}; use once_cell::sync::OnceCell; use smallvec::SmallVec; @@ -45,7 +44,6 @@ use wgt::{DeviceLostReason, TextureFormat, TextureSampleType, TextureViewDimensi use std::{ borrow::Cow, - iter, mem::ManuallyDrop, num::NonZeroU32, sync::{ @@ -80,15 +78,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: ManuallyDrop, + raw: ManuallyDrop>, pub(crate) adapter: Arc>, pub(crate) queue: OnceCell>>, - queue_to_drop: OnceCell, - pub(crate) zero_buffer: ManuallyDrop, + queue_to_drop: OnceCell>, + pub(crate) zero_buffer: ManuallyDrop>, /// 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 +110,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", @@ -177,8 +175,8 @@ impl Drop for Device { let pending_writes = unsafe { ManuallyDrop::take(&mut self.pending_writes.lock()) }; // SAFETY: We are in the Drop impl and we don't use self.fence anymore after this point. let fence = unsafe { ManuallyDrop::take(&mut self.fence.write()) }; - 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(zero_buffer); raw.destroy_fence(fence); @@ -197,8 +195,8 @@ pub enum CreateDeviceError { } impl Device { - pub(crate) fn raw(&self) -> &A::Device { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynDevice { + self.raw.as_ref() } pub(crate) fn require_features(&self, feature: wgt::Features) -> Result<(), MissingFeatures> { if self.features.contains(feature) { @@ -222,8 +220,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>, @@ -238,7 +236,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); @@ -257,19 +255,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(); @@ -335,7 +333,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()); } @@ -364,7 +362,6 @@ impl Device { resource_log!("Destroy raw {}", view.error_ident()); unsafe { - use hal::Device; self.raw().destroy_texture_view(raw_view); } } @@ -380,7 +377,6 @@ impl Device { resource_log!("Destroy raw {}", bind_group.error_ident()); unsafe { - use hal::Device; self.raw().destroy_bind_group(raw_bind_group); } } @@ -411,7 +407,7 @@ impl Device { /// return it to our callers.) pub(crate) fn maintain<'this>( &'this self, - fence: crate::lock::RwLockReadGuard>, + fence: crate::lock::RwLockReadGuard>>, maintain: wgt::Maintain, snatch_guard: SnatchGuard, ) -> Result<(UserClosures, bool), WaitIdleError> { @@ -440,7 +436,7 @@ impl Device { .load(Ordering::Acquire), wgt::Maintain::Poll => unsafe { self.raw() - .get_fence_value(&fence) + .get_fence_value(fence.as_ref()) .map_err(DeviceError::from)? }, }; @@ -449,7 +445,7 @@ impl Device { if maintain.is_wait() { unsafe { self.raw() - .wait(&fence, submission_index, CLEANUP_WAIT_MS) + .wait(fence.as_ref(), submission_index, CLEANUP_WAIT_MS) .map_err(DeviceError::from)? }; } @@ -654,7 +650,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 @@ -687,7 +683,7 @@ impl Device { desc: &resource::BufferDescriptor, ) -> Arc> { let buffer = Buffer { - raw: Snatchable::new(hal_buffer), + raw: Snatchable::new(Box::new(hal_buffer)), device: self.clone(), usage: desc.usage, size: desc.size, @@ -972,8 +968,10 @@ impl Device { }, }; clear_views.push(ManuallyDrop::new( - 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)?, )); }; } @@ -1889,7 +1887,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 { @@ -2021,7 +2020,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.insert_single(sampler.clone()); @@ -2072,7 +2071,8 @@ impl Device { used: &mut BindGroupStates, used_texture_ranges: &mut Vec>, snatch_guard: &'a SnatchGuard<'a>, - ) -> Result, binding_model::CreateBindGroupError> { + ) -> Result, binding_model::CreateBindGroupError> + { view.same_device(self)?; let (pub_usage, internal_use) = self.texture_use_parameters( @@ -2389,14 +2389,14 @@ impl Device { .unwrap(); match (sample_type, compat_sample_type) { (Tst::Uint, Tst::Uint) | - (Tst::Sint, Tst::Sint) | - (Tst::Depth, Tst::Depth) | - // if we expect non-filterable, accept anything float - (Tst::Float { filterable: false }, Tst::Float { .. }) | - // if we expect filterable, require it - (Tst::Float { filterable: true }, Tst::Float { filterable: true }) | - // if we expect non-filterable, also accept depth - (Tst::Float { filterable: false }, Tst::Depth) => {} + (Tst::Sint, Tst::Sint) | + (Tst::Depth, Tst::Depth) | + // if we expect non-filterable, accept anything float + (Tst::Float { filterable: false }, Tst::Float { .. }) | + // if we expect filterable, require it + (Tst::Float { filterable: true }, Tst::Float { filterable: true }) | + // if we expect non-filterable, also accept depth + (Tst::Float { filterable: false }, Tst::Depth) => {} // if we expect filterable, also accept Float that is defined as // unfilterable if filterable feature is explicitly enabled (only hit // if wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES is @@ -2999,7 +2999,7 @@ impl Device { break; } else { return Err(pipeline::CreateRenderPipelineError - ::BlendFactorOnUnsupportedTarget { factor, target: i as u32 }); + ::BlendFactorOnUnsupportedTarget { factor, target: i as u32 }); } } } @@ -3491,9 +3491,9 @@ impl Device { submission_index: crate::SubmissionIndex, ) -> Result<(), DeviceError> { let fence = self.fence.read(); - let last_done_index = unsafe { self.raw().get_fence_value(&fence)? }; + let last_done_index = unsafe { self.raw().get_fence_value(fence.as_ref())? }; if last_done_index < submission_index { - unsafe { self.raw().wait(&fence, submission_index, !0)? }; + unsafe { self.raw().wait(fence.as_ref(), submission_index, !0)? }; drop(fence); let closures = self .lock_life() @@ -3622,7 +3622,7 @@ 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.into_iter()); + baked.encoder.reset_all(baked.list); } unsafe { self.raw().destroy_command_encoder(baked.encoder); @@ -3637,7 +3637,8 @@ impl Device { .load(Ordering::Acquire); if let Err(error) = unsafe { let fence = self.fence.read(); - self.raw().wait(&fence, current_index, CLEANUP_WAIT_MS) + self.raw() + .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 1357a2e42..02049a4c3 100644 --- a/wgpu-core/src/hub.rs +++ b/wgpu-core/src/hub.rs @@ -244,7 +244,8 @@ 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().as_any().downcast_ref().unwrap()); } } } diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index 9ddbaae2d..4c1b9960c 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().as_any().downcast_ref().unwrap()) }; } } } diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index 59226051e..80929c3b8 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: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, pub(crate) interface: Option, /// The `label` from the descriptor used to create the resource. @@ -60,7 +60,6 @@ impl Drop for ShaderModule { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; 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 + pub(crate) fn raw(&self) -> &dyn hal::DynShaderModule { + self.raw.as_ref() } pub(crate) fn finalize_entry_point_name( @@ -242,7 +241,7 @@ pub enum CreateComputePipelineError { #[derive(Debug)] pub struct ComputePipeline { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) layout: Arc>, pub(crate) device: Arc>, pub(crate) _shader_module: Arc>, @@ -258,7 +257,6 @@ impl Drop for ComputePipeline { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_compute_pipeline(raw); } } @@ -271,8 +269,8 @@ crate::impl_storage_item!(ComputePipeline); crate::impl_trackable!(ComputePipeline); impl ComputePipeline { - pub(crate) fn raw(&self) -> &A::ComputePipeline { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynComputePipeline { + self.raw.as_ref() } } @@ -301,7 +299,7 @@ impl From for CreatePipelineCacheError { #[derive(Debug)] pub struct PipelineCache { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, @@ -313,7 +311,6 @@ impl Drop for PipelineCache { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_pipeline_cache(raw); } } @@ -325,8 +322,8 @@ crate::impl_parent_device!(PipelineCache); crate::impl_storage_item!(PipelineCache); impl PipelineCache { - pub(crate) fn raw(&self) -> &A::PipelineCache { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynPipelineCache { + self.raw.as_ref() } } @@ -592,7 +589,7 @@ impl Default for VertexStep { #[derive(Debug)] pub struct RenderPipeline { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, pub(crate) layout: Arc>, pub(crate) _shader_modules: @@ -613,7 +610,6 @@ impl Drop for RenderPipeline { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_render_pipeline(raw); } } @@ -626,7 +622,7 @@ crate::impl_storage_item!(RenderPipeline); crate::impl_trackable!(RenderPipeline); impl RenderPipeline { - pub(crate) fn raw(&self) -> &A::RenderPipeline { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynRenderPipeline { + self.raw.as_ref() } } diff --git a/wgpu-core/src/present.rs b/wgpu-core/src/present.rs index 3521f0438..d0f09a97f 100644 --- a/wgpu-core/src/present.rs +++ b/wgpu-core/src/present.rs @@ -9,7 +9,7 @@ When this texture is presented, we remove it from the device tracker as well as extract it from the hub. !*/ -use std::{borrow::Borrow, mem::ManuallyDrop, sync::Arc}; +use std::{mem::ManuallyDrop, sync::Arc}; #[cfg(feature = "trace")] use crate::device::trace::Action; @@ -23,7 +23,6 @@ use crate::{ resource::{self, Trackable}, }; -use hal::{Queue as _, Surface as _}; use thiserror::Error; use wgt::SurfaceStatus as Status; @@ -156,9 +155,10 @@ impl Global { let suf = A::surface_as_hal(surface.as_ref()); let (texture_id, status) = match unsafe { + use hal::DynSurface; suf.unwrap().acquire_texture( Some(std::time::Duration::from_millis(FRAME_TIMEOUT_MS as u64)), - &fence, + fence.as_ref(), ) } { Ok(Some(ast)) => { @@ -195,11 +195,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.as_ref().borrow(), &clear_view_desc) } .map_err(DeviceError::from)?; @@ -386,6 +384,7 @@ impl Global { match texture.inner.snatch(exclusive_snatch_guard).unwrap() { resource::TextureInner::Surface { raw, parent_id } => { if surface_id == parent_id { + use hal::DynSurface; unsafe { suf.unwrap().discard_texture(raw) }; } else { log::warn!("Surface texture is outdated"); diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index f6742ba82..6a3c02ece 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -17,14 +17,12 @@ use crate::{ Label, LabelHelpers, }; -use hal::CommandEncoder; use smallvec::SmallVec; use thiserror::Error; use std::{ borrow::{Borrow, Cow}, fmt::Debug, - iter, mem::{self, ManuallyDrop}, ops::Range, ptr::NonNull, @@ -426,7 +424,7 @@ pub type BufferDescriptor<'a> = wgt::BufferDescriptor>; #[derive(Debug)] pub struct Buffer { - pub(crate) raw: Snatchable, + pub(crate) raw: Snatchable>, pub(crate) device: Arc>, pub(crate) usage: wgt::BufferUsages, pub(crate) size: wgt::BufferAddress, @@ -443,7 +441,6 @@ impl Drop for Buffer { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; self.device.raw().destroy_buffer(raw); } } @@ -451,16 +448,17 @@ impl Drop for Buffer { } impl Buffer { - pub(crate) fn raw<'a>(&'a self, guard: &'a SnatchGuard) -> Option<&'a A::Buffer> { - self.raw.get(guard) + pub(crate) fn raw<'a>(&'a self, guard: &'a SnatchGuard) -> Option<&'a dyn hal::DynBuffer> { + self.raw.get(guard).map(|b| b.as_ref()) } pub(crate) fn try_raw<'a>( &'a self, guard: &'a SnatchGuard, - ) -> Result<&A::Buffer, DestroyedResourceError> { + ) -> Result<&dyn hal::DynBuffer, DestroyedResourceError> { self.raw .get(guard) + .map(|raw| raw.as_ref()) .ok_or_else(|| DestroyedResourceError(self.error_ident())) } @@ -611,8 +609,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)?; @@ -642,20 +638,18 @@ impl Buffer { buffer: staging_buffer.raw(), usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, }; - let transition_dst = hal::BufferBarrier { + let transition_dst = hal::BufferBarrier:: { buffer: raw_buf, usage: hal::BufferUses::empty()..hal::BufferUses::COPY_DST, }; let encoder = pending_writes.activate(); unsafe { - encoder.transition_buffers( - iter::once(transition_src).chain(iter::once(transition_dst)), - ); + encoder.transition_buffers(&[transition_src, transition_dst]); if self.size > 0 { encoder.copy_buffer_to_buffer( staging_buffer.raw(), raw_buf, - region.into_iter(), + region.as_slice(), ); } } @@ -689,7 +683,7 @@ impl Buffer { }); } if !mapping.is_coherent { - unsafe { device.raw().flush_mapped_ranges(raw_buf, iter::once(range)) }; + unsafe { device.raw().flush_mapped_ranges(raw_buf, &[range]) }; } } unsafe { device.raw().unmap_buffer(raw_buf) }; @@ -766,7 +760,7 @@ crate::impl_trackable!(Buffer); /// A buffer that has been marked as destroyed and is staged for actual deletion soon. #[derive(Debug)] pub struct DestroyedBuffer { - raw: ManuallyDrop, + raw: ManuallyDrop>, device: Arc>, label: String, bind_groups: Vec>>, @@ -790,8 +784,7 @@ impl Drop for DestroyedBuffer { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; - self.device.raw().destroy_buffer(raw); + hal::DynDevice::destroy_buffer(self.device.raw(), raw); } } } @@ -822,7 +815,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, @@ -831,7 +824,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), @@ -841,7 +833,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, @@ -900,12 +892,14 @@ 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())) }; + #[allow(clippy::single_range_in_vec_init)] + 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, .. @@ -924,20 +918,19 @@ 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) -> &A::Buffer { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynBuffer { + 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 raw = unsafe { ManuallyDrop::take(&mut self.raw) }; @@ -948,35 +941,35 @@ impl Drop for FlushedStagingBuffer { 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: A::SurfaceTexture, + raw: Box, parent_id: SurfaceId, }, } -impl TextureInner { - pub(crate) fn raw(&self) -> &A::Texture { +impl TextureInner { + pub(crate) fn raw(&self) -> &dyn hal::DynTexture { match self { - Self::Native { raw } => raw, - Self::Surface { raw, .. } => raw.borrow(), + Self::Native { raw } => raw.as_ref(), + Self::Surface { raw, .. } => raw.as_ref().borrow(), } } } #[derive(Debug)] -pub enum TextureClearMode { +pub enum TextureClearMode { BufferCopy, // View for clear via RenderPass for every subsurface (mip/layer/slice) RenderPass { - clear_views: SmallVec<[ManuallyDrop; 1]>, + clear_views: SmallVec<[ManuallyDrop>; 1]>, is_color: bool, }, Surface { - clear_view: ManuallyDrop, + clear_view: ManuallyDrop>, }, // 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) @@ -985,7 +978,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, @@ -995,7 +988,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: TextureClearMode, + pub(crate) clear_mode: TextureClearMode, pub(crate) views: Mutex>>>, pub(crate) bind_groups: Mutex>>>, } @@ -1003,11 +996,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 { @@ -1055,7 +1048,6 @@ impl Texture { impl Drop for Texture { fn drop(&mut self) { - use hal::Device; match self.clear_mode { TextureClearMode::Surface { ref mut clear_view, .. @@ -1094,20 +1086,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> { Some(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) .map(|t| t.raw()) @@ -1115,11 +1110,11 @@ impl Texture { } 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, - ) -> &'a A::TextureView { + ) -> &'a dyn hal::DynTextureView { match *clear_mode { TextureClearMode::BufferCopy => { panic!("Given texture is cleared with buffer copies, not render passes") @@ -1127,7 +1122,7 @@ impl Texture { TextureClearMode::None => { panic!("Given texture can't be cleared") } - TextureClearMode::Surface { ref clear_view, .. } => clear_view, + TextureClearMode::Surface { ref clear_view, .. } => clear_view.as_ref(), TextureClearMode::RenderPass { ref clear_views, .. } => { @@ -1138,7 +1133,7 @@ impl Texture { } else { mip_level * desc.size.depth_or_array_layers } + depth_or_layer; - &clear_views[index as usize] + clear_views[index as usize].as_ref() } } } @@ -1207,7 +1202,9 @@ impl Global { if let Ok(buffer) = hub.buffers.get(id) { let snatch_guard = buffer.device.snatchable_lock.read(); - let hal_buffer = buffer.raw(&snatch_guard); + let hal_buffer = buffer + .raw(&snatch_guard) + .and_then(|b| b.as_any().downcast_ref()); hal_buffer_callback(hal_buffer) } else { hal_buffer_callback(None) @@ -1229,6 +1226,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) @@ -1250,6 +1250,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) @@ -1285,7 +1288,10 @@ 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()) + .and_then(|device| device.as_any().downcast_ref()); hal_device_callback(hal_device) } @@ -1304,7 +1310,7 @@ impl Global { if let Ok(device) = hub.devices.get(id) { let fence = device.fence.read(); - hal_fence_callback(Some(&fence)) + hal_fence_callback(fence.as_any().downcast_ref()) } else { hal_fence_callback(None) } @@ -1346,7 +1352,11 @@ impl Global { if let Ok(cmd_buf) = hub.command_buffers.get(id.into_command_buffer_id()) { let mut cmd_buf_data = cmd_buf.data.lock(); let cmd_buf_data = cmd_buf_data.as_mut().unwrap(); - let cmd_buf_raw = cmd_buf_data.encoder.open().ok(); + let cmd_buf_raw = cmd_buf_data + .encoder + .open() + .ok() + .and_then(|encoder| encoder.as_any_mut().downcast_mut()); hal_command_encoder_callback(cmd_buf_raw) } else { hal_command_encoder_callback(None) @@ -1357,7 +1367,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>, @@ -1387,7 +1397,6 @@ impl Drop for DestroyedTexture { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_texture(raw); } } @@ -1553,7 +1562,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>, @@ -1573,7 +1582,6 @@ impl Drop for TextureView { if let Some(raw) = self.raw.take() { resource_log!("Destroy raw {}", self.error_ident()); unsafe { - use hal::Device; self.device.raw().destroy_texture_view(raw); } } @@ -1581,16 +1589,20 @@ impl Drop for TextureView { } 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())) } } @@ -1687,7 +1699,7 @@ pub struct SamplerDescriptor<'a> { #[derive(Debug)] pub struct Sampler { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, @@ -1704,15 +1716,14 @@ impl Drop for Sampler { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_sampler(raw); } } } impl Sampler { - pub(crate) fn raw(&self) -> &A::Sampler { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynSampler { + self.raw.as_ref() } } @@ -1783,7 +1794,7 @@ pub type QuerySetDescriptor<'a> = wgt::QuerySetDescriptor>; #[derive(Debug)] pub struct QuerySet { - pub(crate) raw: ManuallyDrop, + pub(crate) raw: ManuallyDrop>, pub(crate) device: Arc>, /// The `label` from the descriptor used to create the resource. pub(crate) label: String, @@ -1797,7 +1808,6 @@ impl Drop for QuerySet { // SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. let raw = unsafe { ManuallyDrop::take(&mut self.raw) }; unsafe { - use hal::Device; self.device.raw().destroy_query_set(raw); } } @@ -1810,8 +1820,8 @@ crate::impl_storage_item!(QuerySet); crate::impl_trackable!(QuerySet); impl QuerySet { - pub(crate) fn raw(&self) -> &A::QuerySet { - &self.raw + pub(crate) fn raw(&self) -> &dyn hal::DynQuerySet { + self.raw.as_ref() } } diff --git a/wgpu-core/src/track/buffer.rs b/wgpu-core/src/track/buffer.rs index 0f2bc8cef..ea670de35 100644 --- a/wgpu-core/src/track/buffer.rs +++ b/wgpu-core/src/track/buffer.rs @@ -284,7 +284,7 @@ impl BufferTracker { pub fn drain_transitions<'a, 'b: 'a>( &'b mut self, snatch_guard: &'a SnatchGuard<'a>, - ) -> impl Iterator> { + ) -> impl Iterator> { let buffer_barriers = self.temp.drain(..).map(|pending| { let buf = unsafe { self.metadata.get_resource_unchecked(pending.id as _) }; pending.into_hal(buf, snatch_guard) @@ -557,7 +557,7 @@ impl DeviceBufferTracker { &'a mut self, tracker: &'a BufferTracker, snatch_guard: &'b SnatchGuard<'b>, - ) -> impl Iterator> { + ) -> impl Iterator> { for index in tracker.metadata.owned_indices() { self.tracker_assert_in_bounds(index); diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index 4fccb24ab..a75092d8b 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -261,7 +261,7 @@ impl PendingTransition { self, buf: &'a resource::Buffer, snatch_guard: &'a SnatchGuard<'a>, - ) -> hal::BufferBarrier<'a, A::Buffer> { + ) -> hal::BufferBarrier<'a, dyn hal::DynBuffer> { let buffer = buf.raw(snatch_guard).expect("Buffer is destroyed"); hal::BufferBarrier { buffer, @@ -272,10 +272,10 @@ impl PendingTransition { impl PendingTransition { /// Produce the hal barrier corresponding to the transition. - pub fn into_hal<'a, T: hal::DynTexture + ?Sized>( + pub fn into_hal( self, - texture: &'a T, - ) -> hal::TextureBarrier<'a, T> { + texture: &dyn hal::DynTexture, + ) -> hal::TextureBarrier<'_, dyn hal::DynTexture> { // These showing up in a barrier is always a bug strict_assert_ne!(self.usage.start, hal::TextureUses::UNKNOWN); strict_assert_ne!(self.usage.end, hal::TextureUses::UNKNOWN); diff --git a/wgpu-core/src/track/texture.rs b/wgpu-core/src/track/texture.rs index f454c3e22..9b1152764 100644 --- a/wgpu-core/src/track/texture.rs +++ b/wgpu-core/src/track/texture.rs @@ -438,7 +438,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 @@ -754,7 +754,7 @@ impl DeviceTextureTracker { &'a mut self, tracker: &'a TextureTracker, snatch_guard: &'b SnatchGuard<'b>, - ) -> impl Iterator> { + ) -> impl Iterator> { for index in tracker.metadata.owned_indices() { self.tracker_assert_in_bounds(index); @@ -798,7 +798,7 @@ impl DeviceTextureTracker { &'a mut self, scope: &'a TextureUsageScope, snatch_guard: &'b SnatchGuard<'b>, - ) -> impl Iterator> { + ) -> impl Iterator> { for index in scope.metadata.owned_indices() { self.tracker_assert_in_bounds(index); diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 06632d68d..b787130ba 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -143,7 +143,7 @@ impl ContextWgpuCore { let descriptor = desc.map_label_and_view_formats(|l| l.map(Borrowed), |v| v.to_vec()); let (id, error) = unsafe { self.0 - .create_texture_from_hal::(hal_texture, device.id, &descriptor, None) + .create_texture_from_hal::(Box::new(hal_texture), device.id, &descriptor, None) }; if let Some(cause) = error { self.handle_error(