The big unraveling: core device now has a boxed DynDevice, ripple effects from there leading to boxing of almost all hal resources

This commit is contained in:
Andreas Reich 2024-07-11 00:35:36 +02:00
parent 5b9198fd43
commit 7c7e4164f1
24 changed files with 418 additions and 396 deletions

View File

@ -499,7 +499,7 @@ impl<A: HalApi> std::fmt::Display for ExclusivePipeline<A> {
/// Bind group layout. /// Bind group layout.
#[derive(Debug)] #[derive(Debug)]
pub struct BindGroupLayout<A: HalApi> { pub struct BindGroupLayout<A: HalApi> {
pub(crate) raw: ManuallyDrop<A::BindGroupLayout>, pub(crate) raw: ManuallyDrop<Box<dyn hal::DynBindGroupLayout>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
pub(crate) entries: bgl::EntryMap, pub(crate) entries: bgl::EntryMap,
/// It is very important that we know if the bind group comes from the BGL pool. /// It is very important that we know if the bind group comes from the BGL pool.
@ -525,7 +525,6 @@ impl<A: HalApi> Drop for BindGroupLayout<A> {
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. // 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) }; let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_bind_group_layout(raw); self.device.raw().destroy_bind_group_layout(raw);
} }
} }
@ -537,8 +536,8 @@ crate::impl_parent_device!(BindGroupLayout);
crate::impl_storage_item!(BindGroupLayout); crate::impl_storage_item!(BindGroupLayout);
impl<A: HalApi> BindGroupLayout<A> { impl<A: HalApi> BindGroupLayout<A> {
pub(crate) fn raw(&self) -> &A::BindGroupLayout { pub(crate) fn raw(&self) -> &dyn hal::DynBindGroupLayout {
&self.raw self.raw.as_ref()
} }
} }
@ -652,7 +651,7 @@ pub struct ResolvedPipelineLayoutDescriptor<'a, A: HalApi> {
#[derive(Debug)] #[derive(Debug)]
pub struct PipelineLayout<A: HalApi> { pub struct PipelineLayout<A: HalApi> {
pub(crate) raw: ManuallyDrop<A::PipelineLayout>, pub(crate) raw: ManuallyDrop<Box<dyn hal::DynPipelineLayout>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
pub(crate) label: String, pub(crate) label: String,
@ -666,15 +665,14 @@ impl<A: HalApi> Drop for PipelineLayout<A> {
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. // 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) }; let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_pipeline_layout(raw); self.device.raw().destroy_pipeline_layout(raw);
} }
} }
} }
impl<A: HalApi> PipelineLayout<A> { impl<A: HalApi> PipelineLayout<A> {
pub(crate) fn raw(&self) -> &A::PipelineLayout { pub(crate) fn raw(&self) -> &dyn hal::DynPipelineLayout {
&self.raw self.raw.as_ref()
} }
pub(crate) fn get_binding_maps(&self) -> ArrayVec<&bgl::EntryMap, { hal::MAX_BIND_GROUPS }> { 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)] #[derive(Debug)]
pub struct BindGroup<A: HalApi> { pub struct BindGroup<A: HalApi> {
pub(crate) raw: Snatchable<A::BindGroup>, pub(crate) raw: Snatchable<Box<dyn hal::DynBindGroup>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
pub(crate) layout: Arc<BindGroupLayout<A>>, pub(crate) layout: Arc<BindGroupLayout<A>>,
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
@ -909,7 +907,6 @@ impl<A: HalApi> Drop for BindGroup<A> {
if let Some(raw) = self.raw.take() { if let Some(raw) = self.raw.take() {
resource_log!("Destroy raw {}", self.error_ident()); resource_log!("Destroy raw {}", self.error_ident());
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_bind_group(raw); self.device.raw().destroy_bind_group(raw);
} }
} }
@ -920,7 +917,7 @@ impl<A: HalApi> BindGroup<A> {
pub(crate) fn try_raw<'a>( pub(crate) fn try_raw<'a>(
&'a self, &'a self,
guard: &'a SnatchGuard, 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 // Clippy insist on writing it this way. The idea is to return None
// if any of the raw buffer is not valid anymore. // if any of the raw buffer is not valid anymore.
for buffer in &self.used_buffer_ranges { for buffer in &self.used_buffer_ranges {
@ -932,6 +929,7 @@ impl<A: HalApi> BindGroup<A> {
self.raw self.raw
.get(guard) .get(guard)
.map(|raw| raw.as_ref())
.ok_or_else(|| DestroyedResourceError(self.error_ident())) .ok_or_else(|| DestroyedResourceError(self.error_ident()))
} }

View File

@ -1,6 +1,4 @@
use crate::hal_api::HalApi;
use crate::resource_log; use crate::resource_log;
use hal::Device as _;
use crate::lock::{rank, Mutex}; use crate::lock::{rank, Mutex};
@ -14,11 +12,11 @@ use crate::lock::{rank, Mutex};
/// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder
/// [ce]: hal::CommandEncoder /// [ce]: hal::CommandEncoder
/// [cb]: hal::Api::CommandBuffer /// [cb]: hal::Api::CommandBuffer
pub(crate) struct CommandAllocator<A: HalApi> { pub(crate) struct CommandAllocator {
free_encoders: Mutex<Vec<A::CommandEncoder>>, free_encoders: Mutex<Vec<Box<dyn hal::DynCommandEncoder>>>,
} }
impl<A: HalApi> CommandAllocator<A> { impl CommandAllocator {
pub(crate) fn new() -> Self { pub(crate) fn new() -> Self {
Self { Self {
free_encoders: Mutex::new(rank::COMMAND_ALLOCATOR_FREE_ENCODERS, Vec::new()), free_encoders: Mutex::new(rank::COMMAND_ALLOCATOR_FREE_ENCODERS, Vec::new()),
@ -33,9 +31,9 @@ impl<A: HalApi> CommandAllocator<A> {
/// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder
pub(crate) fn acquire_encoder( pub(crate) fn acquire_encoder(
&self, &self,
device: &A::Device, device: &dyn hal::DynDevice,
queue: &A::Queue, queue: &dyn hal::DynQueue,
) -> Result<A::CommandEncoder, hal::DeviceError> { ) -> Result<Box<dyn hal::DynCommandEncoder>, hal::DeviceError> {
let mut free_encoders = self.free_encoders.lock(); let mut free_encoders = self.free_encoders.lock();
match free_encoders.pop() { match free_encoders.pop() {
Some(encoder) => Ok(encoder), Some(encoder) => Ok(encoder),
@ -47,7 +45,7 @@ impl<A: HalApi> CommandAllocator<A> {
} }
/// Add `encoder` back to the free pool. /// Add `encoder` back to the free pool.
pub(crate) fn release_encoder(&self, encoder: A::CommandEncoder) { pub(crate) fn release_encoder(&self, encoder: Box<dyn hal::DynCommandEncoder>) {
let mut free_encoders = self.free_encoders.lock(); let mut free_encoders = self.free_encoders.lock();
free_encoders.push(encoder); free_encoders.push(encoder);
} }
@ -55,7 +53,7 @@ impl<A: HalApi> CommandAllocator<A> {
/// Free the pool of command encoders. /// Free the pool of command encoders.
/// ///
/// This is only called when the `Device` is dropped. /// 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(); let mut free_encoders = self.free_encoders.lock();
resource_log!("CommandAllocator::dispose encoders {}", free_encoders.len()); resource_log!("CommandAllocator::dispose encoders {}", free_encoders.len());
for cmd_encoder in free_encoders.drain(..) { for cmd_encoder in free_encoders.drain(..) {

View File

@ -104,8 +104,6 @@ use arrayvec::ArrayVec;
use std::{borrow::Cow, mem, num::NonZeroU32, ops::Range, sync::Arc}; use std::{borrow::Cow, mem, num::NonZeroU32, ops::Range, sync::Arc};
use thiserror::Error; use thiserror::Error;
use hal::CommandEncoder as _;
use super::{ use super::{
render_command::{ArcRenderCommand, RenderCommand}, render_command::{ArcRenderCommand, RenderCommand},
DrawKind, DrawKind,
@ -965,7 +963,7 @@ impl<A: HalApi> RenderBundle<A> {
/// The only failure condition is if some of the used buffers are destroyed. /// The only failure condition is if some of the used buffers are destroyed.
pub(super) unsafe fn execute( pub(super) unsafe fn execute(
&self, &self,
raw: &mut A::CommandEncoder, raw: &mut dyn hal::DynCommandEncoder,
snatch_guard: &SnatchGuard, snatch_guard: &SnatchGuard,
) -> Result<(), ExecutionError> { ) -> Result<(), ExecutionError> {
let mut offsets = self.base.dynamic_offsets.as_slice(); let mut offsets = self.base.dynamic_offsets.as_slice();
@ -1006,7 +1004,7 @@ impl<A: HalApi> RenderBundle<A> {
offset, offset,
size, size,
} => { } => {
let buffer: &A::Buffer = buffer.try_raw(snatch_guard)?; let buffer = buffer.try_raw(snatch_guard)?;
let bb = hal::BufferBinding { let bb = hal::BufferBinding {
buffer, buffer,
offset: *offset, offset: *offset,

View File

@ -19,7 +19,6 @@ use crate::{
track::{TextureSelector, TextureTrackerSetSingle}, track::{TextureSelector, TextureTrackerSetSingle},
}; };
use hal::CommandEncoder as _;
use thiserror::Error; use thiserror::Error;
use wgt::{math::align_to, BufferAddress, BufferUsages, ImageSubresourceRange, TextureAspect}; 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 dst_barrier = dst_pending.map(|pending| pending.into_hal(&dst_buffer, &snatch_guard));
let cmd_buf_raw = cmd_buf_data.encoder.open()?; let cmd_buf_raw = cmd_buf_data.encoder.open()?;
unsafe { 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); cmd_buf_raw.clear_buffer(dst_raw, offset..end_offset);
} }
Ok(()) Ok(())
@ -263,7 +262,7 @@ impl Global {
encoder, encoder,
&mut tracker.textures, &mut tracker.textures,
&device.alignments, &device.alignments,
&device.zero_buffer, device.zero_buffer.as_ref(),
&snatch_guard, &snatch_guard,
) )
} }
@ -272,10 +271,10 @@ impl Global {
pub(crate) fn clear_texture<A: HalApi, T: TextureTrackerSetSingle<A>>( pub(crate) fn clear_texture<A: HalApi, T: TextureTrackerSetSingle<A>>(
dst_texture: &Arc<Texture<A>>, dst_texture: &Arc<Texture<A>>,
range: TextureInitRange, range: TextureInitRange,
encoder: &mut A::CommandEncoder, encoder: &mut dyn hal::DynCommandEncoder,
texture_tracker: &mut T, texture_tracker: &mut T,
alignments: &hal::Alignments, alignments: &hal::Alignments,
zero_buffer: &A::Buffer, zero_buffer: &dyn hal::DynBuffer,
snatch_guard: &SnatchGuard<'_>, snatch_guard: &SnatchGuard<'_>,
) -> Result<(), ClearError> { ) -> Result<(), ClearError> {
let dst_raw = dst_texture.try_raw(snatch_guard)?; let dst_raw = dst_texture.try_raw(snatch_guard)?;
@ -316,14 +315,15 @@ pub(crate) fn clear_texture<A: HalApi, T: TextureTrackerSetSingle<A>>(
// change_replace_tracked whenever possible. // change_replace_tracked whenever possible.
let dst_barrier = texture_tracker let dst_barrier = texture_tracker
.set_single(dst_texture, selector, clear_usage) .set_single(dst_texture, selector, clear_usage)
.map(|pending| pending.into_hal(dst_raw)); .map(|pending| pending.into_hal(dst_raw))
.collect::<Vec<_>>();
unsafe { unsafe {
encoder.transition_textures(dst_barrier.into_iter()); encoder.transition_textures(&dst_barrier);
} }
// Record actual clearing // Record actual clearing
match dst_texture.clear_mode { match dst_texture.clear_mode {
TextureClearMode::BufferCopy => clear_texture_via_buffer_copies::<A>( TextureClearMode::BufferCopy => clear_texture_via_buffer_copies(
&dst_texture.desc, &dst_texture.desc,
alignments, alignments,
zero_buffer, zero_buffer,
@ -346,13 +346,13 @@ pub(crate) fn clear_texture<A: HalApi, T: TextureTrackerSetSingle<A>>(
Ok(()) Ok(())
} }
fn clear_texture_via_buffer_copies<A: HalApi>( fn clear_texture_via_buffer_copies(
texture_desc: &wgt::TextureDescriptor<(), Vec<wgt::TextureFormat>>, texture_desc: &wgt::TextureDescriptor<(), Vec<wgt::TextureFormat>>,
alignments: &hal::Alignments, 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, range: TextureInitRange,
encoder: &mut A::CommandEncoder, encoder: &mut dyn hal::DynCommandEncoder,
dst_raw: &A::Texture, dst_raw: &dyn hal::DynTexture,
) { ) {
assert!(!texture_desc.format.is_depth_stencil_format()); assert!(!texture_desc.format.is_depth_stencil_format());
@ -436,7 +436,7 @@ fn clear_texture_via_buffer_copies<A: HalApi>(
} }
unsafe { 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<A: HalApi>(
dst_texture: &Texture<A>, dst_texture: &Texture<A>,
range: TextureInitRange, range: TextureInitRange,
is_color: bool, is_color: bool,
encoder: &mut A::CommandEncoder, encoder: &mut dyn hal::DynCommandEncoder,
) { ) {
assert_eq!(dst_texture.desc.dimension, wgt::TextureDimension::D2); assert_eq!(dst_texture.desc.dimension, wgt::TextureDimension::D2);
@ -461,7 +461,7 @@ fn clear_texture_via_render_passes<A: HalApi>(
let (color_attachments, depth_stencil_attachment) = if is_color { let (color_attachments, depth_stencil_attachment) = if is_color {
color_attachments_tmp = [Some(hal::ColorAttachment { color_attachments_tmp = [Some(hal::ColorAttachment {
target: hal::Attachment { target: hal::Attachment {
view: Texture::get_clear_view( view: Texture::<A>::get_clear_view(
&dst_texture.clear_mode, &dst_texture.clear_mode,
&dst_texture.desc, &dst_texture.desc,
mip_level, mip_level,
@ -479,7 +479,7 @@ fn clear_texture_via_render_passes<A: HalApi>(
&[][..], &[][..],
Some(hal::DepthStencilAttachment { Some(hal::DepthStencilAttachment {
target: hal::Attachment { target: hal::Attachment {
view: Texture::get_clear_view( view: Texture::<A>::get_clear_view(
&dst_texture.clear_mode, &dst_texture.clear_mode,
&dst_texture.desc, &dst_texture.desc,
mip_level, mip_level,

View File

@ -26,8 +26,6 @@ use crate::{
Label, Label,
}; };
use hal::CommandEncoder as _;
use thiserror::Error; use thiserror::Error;
use wgt::{BufferAddress, DynamicOffset}; use wgt::{BufferAddress, DynamicOffset};
@ -212,7 +210,7 @@ struct State<'scope, 'snatch_guard, 'cmd_buf, 'raw_encoder, A: HalApi> {
device: &'cmd_buf Arc<Device<A>>, device: &'cmd_buf Arc<Device<A>>,
raw_encoder: &'raw_encoder mut A::CommandEncoder, raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder,
tracker: &'cmd_buf mut Tracker<A>, tracker: &'cmd_buf mut Tracker<A>,
buffer_memory_init_actions: &'cmd_buf mut Vec<BufferInitTrackerAction<A>>, buffer_memory_init_actions: &'cmd_buf mut Vec<BufferInitTrackerAction<A>>,
@ -485,40 +483,41 @@ impl Global {
state.tracker.buffers.set_size(indices.buffers.size()); state.tracker.buffers.set_size(indices.buffers.size());
state.tracker.textures.set_size(indices.textures.size()); state.tracker.textures.set_size(indices.textures.size());
let timestamp_writes = if let Some(tw) = timestamp_writes.take() { let timestamp_writes: Option<hal::PassTimestampWrites<'_, dyn hal::DynQuerySet>> =
tw.query_set if let Some(tw) = timestamp_writes.take() {
.same_device_as(cmd_buf) tw.query_set
.map_pass_err(pass_scope)?; .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 // Unlike in render passes we can't delay resetting the query sets since
// there is no auxiliary pass. // there is no auxiliary pass.
let range = if let (Some(index_a), Some(index_b)) = let range = if let (Some(index_a), Some(index_b)) =
(tw.beginning_of_pass_write_index, tw.end_of_pass_write_index) (tw.beginning_of_pass_write_index, tw.end_of_pass_write_index)
{ {
Some(index_a.min(index_b)..index_a.max(index_b) + 1) Some(index_a.min(index_b)..index_a.max(index_b) + 1)
} else { } else {
tw.beginning_of_pass_write_index tw.beginning_of_pass_write_index
.or(tw.end_of_pass_write_index) .or(tw.end_of_pass_write_index)
.map(|i| i..i + 1) .map(|i| i..i + 1)
}; };
// Range should always be Some, both values being None should lead to a validation error. // Range should always be Some, both values being None should lead to a validation error.
// But no point in erroring over that nuance here! // But no point in erroring over that nuance here!
if let Some(range) = range { if let Some(range) = range {
unsafe { unsafe {
state.raw_encoder.reset_queries(query_set.raw(), range); state.raw_encoder.reset_queries(query_set.raw(), range);
}
} }
}
Some(hal::PassTimestampWrites { Some(hal::PassTimestampWrites {
query_set: query_set.raw(), query_set: query_set.raw(),
beginning_of_pass_write_index: tw.beginning_of_pass_write_index, beginning_of_pass_write_index: tw.beginning_of_pass_write_index,
end_of_pass_write_index: tw.end_of_pass_write_index, end_of_pass_write_index: tw.end_of_pass_write_index,
}) })
} else { } else {
None None
}; };
let hal_desc = hal::ComputePassDescriptor { let hal_desc = hal::ComputePassDescriptor {
label: hal_label(base.label.as_deref(), self.instance.flags), label: hal_label(base.label.as_deref(), self.instance.flags),

View File

@ -1,7 +1,5 @@
use std::{collections::hash_map::Entry, ops::Range, sync::Arc, vec::Drain}; use std::{collections::hash_map::Entry, ops::Range, sync::Arc, vec::Drain};
use hal::CommandEncoder;
use crate::{ use crate::{
device::Device, device::Device,
hal_api::HalApi, hal_api::HalApi,
@ -140,7 +138,7 @@ pub(crate) fn fixup_discarded_surfaces<
InitIter: Iterator<Item = TextureSurfaceDiscard<A>>, InitIter: Iterator<Item = TextureSurfaceDiscard<A>>,
>( >(
inits: InitIter, inits: InitIter,
encoder: &mut A::CommandEncoder, encoder: &mut dyn hal::DynCommandEncoder,
texture_tracker: &mut TextureTracker<A>, texture_tracker: &mut TextureTracker<A>,
device: &Device<A>, device: &Device<A>,
snatch_guard: &SnatchGuard<'_>, snatch_guard: &SnatchGuard<'_>,
@ -155,7 +153,7 @@ pub(crate) fn fixup_discarded_surfaces<
encoder, encoder,
texture_tracker, texture_tracker,
&device.alignments, &device.alignments,
&device.zero_buffer, device.zero_buffer.as_ref(),
snatch_guard, snatch_guard,
) )
.unwrap(); .unwrap();
@ -233,7 +231,7 @@ impl<A: HalApi> BakedCommands<A> {
self.encoder.transition_buffers( self.encoder.transition_buffers(
transition transition
.map(|pending| pending.into_hal(&buffer, snatch_guard)) .map(|pending| pending.into_hal(&buffer, snatch_guard))
.into_iter(), .as_slice(),
); );
} }
@ -307,10 +305,10 @@ impl<A: HalApi> BakedCommands<A> {
let clear_result = clear_texture( let clear_result = clear_texture(
&texture_use.texture, &texture_use.texture,
range, range,
&mut self.encoder, self.encoder.as_mut(),
&mut device_tracker.textures, &mut device_tracker.textures,
&device.alignments, &device.alignments,
&device.zero_buffer, device.zero_buffer.as_ref(),
snatch_guard, snatch_guard,
); );

View File

@ -39,7 +39,6 @@ use crate::track::{DeviceTracker, Tracker, UsageScope};
use crate::LabelHelpers; use crate::LabelHelpers;
use crate::{api_log, global::Global, hal_api::HalApi, id, resource_log, Label}; use crate::{api_log, global::Global, hal_api::HalApi, id, resource_log, Label};
use hal::CommandEncoder as _;
use thiserror::Error; use thiserror::Error;
#[cfg(feature = "trace")] #[cfg(feature = "trace")]
@ -115,7 +114,7 @@ pub(crate) enum CommandEncoderStatus {
/// [rce]: hal::Api::CommandEncoder /// [rce]: hal::Api::CommandEncoder
/// [rcb]: hal::Api::CommandBuffer /// [rcb]: hal::Api::CommandBuffer
/// [`CommandEncoderId`]: crate::id::CommandEncoderId /// [`CommandEncoderId`]: crate::id::CommandEncoderId
pub(crate) struct CommandEncoder<A: HalApi> { pub(crate) struct CommandEncoder {
/// The underlying `wgpu_hal` [`CommandEncoder`]. /// The underlying `wgpu_hal` [`CommandEncoder`].
/// ///
/// Successfully executed command buffers' encoders are saved in a /// Successfully executed command buffers' encoders are saved in a
@ -123,7 +122,7 @@ pub(crate) struct CommandEncoder<A: HalApi> {
/// ///
/// [`CommandEncoder`]: hal::Api::CommandEncoder /// [`CommandEncoder`]: hal::Api::CommandEncoder
/// [`CommandAllocator`]: crate::command::CommandAllocator /// [`CommandAllocator`]: crate::command::CommandAllocator
raw: A::CommandEncoder, raw: Box<dyn hal::DynCommandEncoder>,
/// All the raw command buffers for our owning [`CommandBuffer`], in /// All the raw command buffers for our owning [`CommandBuffer`], in
/// submission order. /// submission order.
@ -136,7 +135,7 @@ pub(crate) struct CommandEncoder<A: HalApi> {
/// ///
/// [CE::ra]: hal::CommandEncoder::reset_all /// [CE::ra]: hal::CommandEncoder::reset_all
/// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder
list: Vec<A::CommandBuffer>, list: Vec<Box<dyn hal::DynCommandBuffer>>,
/// True if `raw` is in the "recording" state. /// True if `raw` is in the "recording" state.
/// ///
@ -150,7 +149,7 @@ pub(crate) struct CommandEncoder<A: HalApi> {
} }
//TODO: handle errors better //TODO: handle errors better
impl<A: HalApi> CommandEncoder<A> { impl CommandEncoder {
/// Finish the current command buffer, if any, and place it /// Finish the current command buffer, if any, and place it
/// at the second-to-last position in our list. /// at the second-to-last position in our list.
/// ///
@ -219,14 +218,14 @@ impl<A: HalApi> CommandEncoder<A> {
/// Begin recording a new command buffer, if we haven't already. /// Begin recording a new command buffer, if we haven't already.
/// ///
/// The underlying hal encoder is put in the "recording" state. /// 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 { if !self.is_open {
self.is_open = true; self.is_open = true;
let hal_label = self.hal_label.as_deref(); let hal_label = self.hal_label.as_deref();
unsafe { self.raw.begin_encoding(hal_label)? }; 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 /// Begin recording a new command buffer for a render pass, with
@ -242,8 +241,8 @@ impl<A: HalApi> CommandEncoder<A> {
} }
pub(crate) struct BakedCommands<A: HalApi> { pub(crate) struct BakedCommands<A: HalApi> {
pub(crate) encoder: A::CommandEncoder, pub(crate) encoder: Box<dyn hal::DynCommandEncoder>,
pub(crate) list: Vec<A::CommandBuffer>, pub(crate) list: Vec<Box<dyn hal::DynCommandBuffer>>,
pub(crate) trackers: Tracker<A>, pub(crate) trackers: Tracker<A>,
buffer_memory_init_actions: Vec<BufferInitTrackerAction<A>>, buffer_memory_init_actions: Vec<BufferInitTrackerAction<A>>,
texture_memory_actions: CommandBufferTextureMemoryActions<A>, texture_memory_actions: CommandBufferTextureMemoryActions<A>,
@ -255,7 +254,7 @@ pub struct CommandBufferMutable<A: HalApi> {
/// they belong to. /// they belong to.
/// ///
/// [`wgpu_hal::Api::CommandBuffer`]: hal::Api::CommandBuffer /// [`wgpu_hal::Api::CommandBuffer`]: hal::Api::CommandBuffer
pub(crate) encoder: CommandEncoder<A>, pub(crate) encoder: CommandEncoder,
/// The current state of this command buffer's encoder. /// The current state of this command buffer's encoder.
status: CommandEncoderStatus, status: CommandEncoderStatus,
@ -280,7 +279,7 @@ pub struct CommandBufferMutable<A: HalApi> {
impl<A: HalApi> CommandBufferMutable<A> { impl<A: HalApi> CommandBufferMutable<A> {
pub(crate) fn open_encoder_and_tracker( pub(crate) fn open_encoder_and_tracker(
&mut self, &mut self,
) -> Result<(&mut A::CommandEncoder, &mut Tracker<A>), DeviceError> { ) -> Result<(&mut dyn hal::DynCommandEncoder, &mut Tracker<A>), DeviceError> {
let encoder = self.encoder.open()?; let encoder = self.encoder.open()?;
let tracker = &mut self.trackers; let tracker = &mut self.trackers;
@ -329,17 +328,20 @@ impl<A: HalApi> Drop for CommandBuffer<A> {
} }
let mut baked = self.extract_baked_commands(); let mut baked = self.extract_baked_commands();
unsafe { unsafe {
baked.encoder.reset_all(baked.list.into_iter()); baked.encoder.reset_all(baked.list);
} }
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_command_encoder(baked.encoder); self.device.raw().destroy_command_encoder(baked.encoder);
} }
} }
} }
impl<A: HalApi> CommandBuffer<A> { impl<A: HalApi> CommandBuffer<A> {
pub(crate) fn new(encoder: A::CommandEncoder, device: &Arc<Device<A>>, label: &Label) -> Self { pub(crate) fn new(
encoder: Box<dyn hal::DynCommandEncoder>,
device: &Arc<Device<A>>,
label: &Label,
) -> Self {
CommandBuffer { CommandBuffer {
device: device.clone(), device: device.clone(),
support_clear_texture: device.features.contains(wgt::Features::CLEAR_TEXTURE), support_clear_texture: device.features.contains(wgt::Features::CLEAR_TEXTURE),
@ -370,7 +372,7 @@ impl<A: HalApi> CommandBuffer<A> {
} }
pub(crate) fn insert_barriers_from_tracker( pub(crate) fn insert_barriers_from_tracker(
raw: &mut A::CommandEncoder, raw: &mut dyn hal::DynCommandEncoder,
base: &mut Tracker<A>, base: &mut Tracker<A>,
head: &Tracker<A>, head: &Tracker<A>,
snatch_guard: &SnatchGuard, snatch_guard: &SnatchGuard,
@ -384,7 +386,7 @@ impl<A: HalApi> CommandBuffer<A> {
} }
pub(crate) fn insert_barriers_from_scope( pub(crate) fn insert_barriers_from_scope(
raw: &mut A::CommandEncoder, raw: &mut dyn hal::DynCommandEncoder,
base: &mut Tracker<A>, base: &mut Tracker<A>,
head: &UsageScope<A>, head: &UsageScope<A>,
snatch_guard: &SnatchGuard, snatch_guard: &SnatchGuard,
@ -398,27 +400,31 @@ impl<A: HalApi> CommandBuffer<A> {
} }
pub(crate) fn drain_barriers( pub(crate) fn drain_barriers(
raw: &mut A::CommandEncoder, raw: &mut dyn hal::DynCommandEncoder,
base: &mut Tracker<A>, base: &mut Tracker<A>,
snatch_guard: &SnatchGuard, snatch_guard: &SnatchGuard,
) { ) {
profiling::scope!("drain_barriers"); profiling::scope!("drain_barriers");
let buffer_barriers = base.buffers.drain_transitions(snatch_guard); let buffer_barriers = base
.buffers
.drain_transitions(snatch_guard)
.collect::<Vec<_>>();
let (transitions, textures) = base.textures.drain_transitions(snatch_guard); let (transitions, textures) = base.textures.drain_transitions(snatch_guard);
let texture_barriers = transitions let texture_barriers = transitions
.into_iter() .into_iter()
.enumerate() .enumerate()
.map(|(i, p)| p.into_hal(textures[i].unwrap().raw())); .map(|(i, p)| p.into_hal(textures[i].unwrap().raw()))
.collect::<Vec<_>>();
unsafe { unsafe {
raw.transition_buffers(buffer_barriers); raw.transition_buffers(&buffer_barriers);
raw.transition_textures(texture_barriers); raw.transition_textures(&texture_barriers);
} }
} }
pub(crate) fn insert_barriers_from_device_tracker( pub(crate) fn insert_barriers_from_device_tracker(
raw: &mut A::CommandEncoder, raw: &mut dyn hal::DynCommandEncoder,
base: &mut DeviceTracker<A>, base: &mut DeviceTracker<A>,
head: &Tracker<A>, head: &Tracker<A>,
snatch_guard: &SnatchGuard, snatch_guard: &SnatchGuard,
@ -427,15 +433,17 @@ impl<A: HalApi> CommandBuffer<A> {
let buffer_barriers = base let buffer_barriers = base
.buffers .buffers
.set_from_tracker_and_drain_transitions(&head.buffers, snatch_guard); .set_from_tracker_and_drain_transitions(&head.buffers, snatch_guard)
.collect::<Vec<_>>();
let texture_barriers = base let texture_barriers = base
.textures .textures
.set_from_tracker_and_drain_transitions(&head.textures, snatch_guard); .set_from_tracker_and_drain_transitions(&head.textures, snatch_guard)
.collect::<Vec<_>>();
unsafe { unsafe {
raw.transition_buffers(buffer_barriers); raw.transition_buffers(&buffer_barriers);
raw.transition_textures(texture_barriers); raw.transition_textures(&texture_barriers);
} }
} }
} }

View File

@ -1,5 +1,3 @@
use hal::CommandEncoder as _;
#[cfg(feature = "trace")] #[cfg(feature = "trace")]
use crate::device::trace::Command as TraceCommand; use crate::device::trace::Command as TraceCommand;
use crate::{ use crate::{
@ -44,7 +42,7 @@ impl<A: HalApi> QueryResetMap<A> {
std::mem::replace(&mut vec_pair.0[query as usize], true) 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() { for (_, (state, query_set)) in self.map.drain() {
debug_assert_eq!(state.len(), query_set.desc.count as usize); debug_assert_eq!(state.len(), query_set.desc.count as usize);
@ -199,7 +197,7 @@ impl<A: HalApi> QuerySet<A> {
pub(super) fn validate_and_write_timestamp( pub(super) fn validate_and_write_timestamp(
self: &Arc<Self>, self: &Arc<Self>,
raw_encoder: &mut A::CommandEncoder, raw_encoder: &mut dyn hal::DynCommandEncoder,
query_index: u32, query_index: u32,
reset_state: Option<&mut QueryResetMap<A>>, reset_state: Option<&mut QueryResetMap<A>>,
) -> Result<(), QueryUseError> { ) -> Result<(), QueryUseError> {
@ -220,7 +218,7 @@ impl<A: HalApi> QuerySet<A> {
pub(super) fn validate_and_begin_occlusion_query<A: HalApi>( pub(super) fn validate_and_begin_occlusion_query<A: HalApi>(
query_set: Arc<QuerySet<A>>, query_set: Arc<QuerySet<A>>,
raw_encoder: &mut A::CommandEncoder, raw_encoder: &mut dyn hal::DynCommandEncoder,
tracker: &mut StatelessTracker<QuerySet<A>>, tracker: &mut StatelessTracker<QuerySet<A>>,
query_index: u32, query_index: u32,
reset_state: Option<&mut QueryResetMap<A>>, reset_state: Option<&mut QueryResetMap<A>>,
@ -251,7 +249,7 @@ pub(super) fn validate_and_begin_occlusion_query<A: HalApi>(
} }
pub(super) fn end_occlusion_query<A: HalApi>( pub(super) fn end_occlusion_query<A: HalApi>(
raw_encoder: &mut A::CommandEncoder, raw_encoder: &mut dyn hal::DynCommandEncoder,
active_query: &mut Option<(Arc<QuerySet<A>>, u32)>, active_query: &mut Option<(Arc<QuerySet<A>>, u32)>,
) -> Result<(), QueryUseError> { ) -> Result<(), QueryUseError> {
if let Some((query_set, query_index)) = active_query.take() { if let Some((query_set, query_index)) = active_query.take() {
@ -264,7 +262,7 @@ pub(super) fn end_occlusion_query<A: HalApi>(
pub(super) fn validate_and_begin_pipeline_statistics_query<A: HalApi>( pub(super) fn validate_and_begin_pipeline_statistics_query<A: HalApi>(
query_set: Arc<QuerySet<A>>, query_set: Arc<QuerySet<A>>,
raw_encoder: &mut A::CommandEncoder, raw_encoder: &mut dyn hal::DynCommandEncoder,
tracker: &mut StatelessTracker<QuerySet<A>>, tracker: &mut StatelessTracker<QuerySet<A>>,
cmd_buf: &CommandBuffer<A>, cmd_buf: &CommandBuffer<A>,
query_index: u32, query_index: u32,
@ -302,7 +300,7 @@ pub(super) fn validate_and_begin_pipeline_statistics_query<A: HalApi>(
} }
pub(super) fn end_pipeline_statistics_query<A: HalApi>( pub(super) fn end_pipeline_statistics_query<A: HalApi>(
raw_encoder: &mut A::CommandEncoder, raw_encoder: &mut dyn hal::DynCommandEncoder,
active_query: &mut Option<(Arc<QuerySet<A>>, u32)>, active_query: &mut Option<(Arc<QuerySet<A>>, u32)>,
) -> Result<(), QueryUseError> { ) -> Result<(), QueryUseError> {
if let Some((query_set, query_index)) = active_query.take() { 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)?; let raw_dst_buffer = dst_buffer.try_raw(&snatch_guard)?;
unsafe { unsafe {
raw_encoder.transition_buffers(dst_barrier.into_iter()); raw_encoder.transition_buffers(dst_barrier.as_slice());
raw_encoder.copy_query_results( raw_encoder.copy_query_results(
query_set.raw(), query_set.raw(),
start_query..end_query, start_query..end_query,

View File

@ -34,7 +34,6 @@ use crate::{
}; };
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use hal::CommandEncoder as _;
use thiserror::Error; use thiserror::Error;
use wgt::{ use wgt::{
BufferAddress, BufferSize, BufferUsages, Color, DynamicOffset, IndexFormat, ShaderStages, 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<Device<A>>, device: &'cmd_buf Arc<Device<A>>,
raw_encoder: &'raw_encoder mut A::CommandEncoder, raw_encoder: &'raw_encoder mut dyn hal::DynCommandEncoder,
tracker: &'cmd_buf mut Tracker<A>, tracker: &'cmd_buf mut Tracker<A>,
buffer_memory_init_actions: &'cmd_buf mut Vec<BufferInitTrackerAction<A>>, buffer_memory_init_actions: &'cmd_buf mut Vec<BufferInitTrackerAction<A>>,
@ -826,7 +825,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> {
mut depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment<A>>, mut depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment<A>>,
mut timestamp_writes: Option<ArcPassTimestampWrites<A>>, mut timestamp_writes: Option<ArcPassTimestampWrites<A>>,
mut occlusion_query_set: Option<Arc<QuerySet<A>>>, mut occlusion_query_set: Option<Arc<QuerySet<A>>>,
encoder: &mut CommandEncoder<A>, encoder: &mut CommandEncoder,
trackers: &mut Tracker<A>, trackers: &mut Tracker<A>,
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>, texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
pending_query_resets: &mut QueryResetMap<A>, pending_query_resets: &mut QueryResetMap<A>,
@ -1255,7 +1254,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> {
fn finish( fn finish(
mut self, mut self,
raw: &mut A::CommandEncoder, raw: &mut dyn hal::DynCommandEncoder,
snatch_guard: &SnatchGuard, snatch_guard: &SnatchGuard,
) -> Result<(UsageScope<'d, A>, SurfacesInDiscardState<A>), RenderPassErrorInner> { ) -> Result<(UsageScope<'d, A>, SurfacesInDiscardState<A>), RenderPassErrorInner> {
profiling::scope!("RenderPassInfo::finish"); profiling::scope!("RenderPassInfo::finish");
@ -1298,7 +1297,7 @@ impl<'d, A: HalApi> RenderPassInfo<'d, A> {
hal::AttachmentOps::STORE, // clear depth 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"), label: Some("(wgpu internal) Zero init discarded depth/stencil aspect"),
extent: view.render_extent.unwrap(), extent: view.render_extent.unwrap(),
sample_count: view.samples, sample_count: view.samples,
@ -1632,8 +1631,6 @@ impl Global {
tracker.buffers.set_size(indices.buffers.size()); tracker.buffers.set_size(indices.buffers.size());
tracker.textures.set_size(indices.textures.size()); tracker.textures.set_size(indices.textures.size());
let raw = &mut encoder.raw;
let mut state = State { let mut state = State {
pipeline_flags: PipelineFlags::empty(), pipeline_flags: PipelineFlags::empty(),
binder: Binder::new(), binder: Binder::new(),
@ -1649,7 +1646,7 @@ impl Global {
snatch_guard, snatch_guard,
device, device,
raw_encoder: raw, raw_encoder: encoder.raw.as_mut(),
tracker, tracker,
buffer_memory_init_actions, buffer_memory_init_actions,
texture_memory_actions, texture_memory_actions,
@ -2179,7 +2176,7 @@ fn set_index_buffer<A: HalApi>(
size, size,
}; };
unsafe { unsafe {
state.raw_encoder.set_index_buffer(bb, index_format); hal::DynCommandEncoder::set_index_buffer(state.raw_encoder, bb, index_format);
} }
Ok(()) Ok(())
} }
@ -2244,7 +2241,7 @@ fn set_vertex_buffer<A: HalApi>(
size, size,
}; };
unsafe { unsafe {
state.raw_encoder.set_vertex_buffer(slot, bb); hal::DynCommandEncoder::set_vertex_buffer(state.raw_encoder, slot, bb);
} }
state.vertex.update_limits(); state.vertex.update_limits();
Ok(()) Ok(())

View File

@ -21,11 +21,10 @@ use crate::{
}; };
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use hal::CommandEncoder as _;
use thiserror::Error; use thiserror::Error;
use wgt::{BufferAddress, BufferUsages, Extent3d, TextureUsages}; use wgt::{BufferAddress, BufferUsages, Extent3d, TextureUsages};
use std::{iter, sync::Arc}; use std::sync::Arc;
use super::{memory_init::CommandBufferTextureMemoryActions, ClearError, CommandEncoder}; use super::{memory_init::CommandBufferTextureMemoryActions, ClearError, CommandEncoder};
@ -410,7 +409,7 @@ pub(crate) fn validate_texture_copy_range(
fn handle_texture_init<A: HalApi>( fn handle_texture_init<A: HalApi>(
init_kind: MemoryInitKind, init_kind: MemoryInitKind,
encoder: &mut CommandEncoder<A>, encoder: &mut CommandEncoder,
trackers: &mut Tracker<A>, trackers: &mut Tracker<A>,
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>, texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
device: &Device<A>, device: &Device<A>,
@ -445,7 +444,7 @@ fn handle_texture_init<A: HalApi>(
cmd_buf_raw, cmd_buf_raw,
&mut trackers.textures, &mut trackers.textures,
&device.alignments, &device.alignments,
&device.zero_buffer, device.zero_buffer.as_ref(),
snatch_guard, snatch_guard,
)?; )?;
} }
@ -459,7 +458,7 @@ fn handle_texture_init<A: HalApi>(
/// Ensure the source texture of a transfer is in the right initialization /// Ensure the source texture of a transfer is in the right initialization
/// state, and record the state for after the transfer operation. /// state, and record the state for after the transfer operation.
fn handle_src_texture_init<A: HalApi>( fn handle_src_texture_init<A: HalApi>(
encoder: &mut CommandEncoder<A>, encoder: &mut CommandEncoder,
trackers: &mut Tracker<A>, trackers: &mut Tracker<A>,
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>, texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
device: &Device<A>, device: &Device<A>,
@ -487,7 +486,7 @@ fn handle_src_texture_init<A: HalApi>(
/// Ensure the destination texture of a transfer is in the right initialization /// Ensure the destination texture of a transfer is in the right initialization
/// state, and record the state for after the transfer operation. /// state, and record the state for after the transfer operation.
fn handle_dst_texture_init<A: HalApi>( fn handle_dst_texture_init<A: HalApi>(
encoder: &mut CommandEncoder<A>, encoder: &mut CommandEncoder,
trackers: &mut Tracker<A>, trackers: &mut Tracker<A>,
texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>, texture_memory_actions: &mut CommandBufferTextureMemoryActions<A>,
device: &Device<A>, device: &Device<A>,
@ -687,9 +686,13 @@ impl Global {
size: wgt::BufferSize::new(size).unwrap(), size: wgt::BufferSize::new(size).unwrap(),
}; };
let cmd_buf_raw = cmd_buf_data.encoder.open()?; let cmd_buf_raw = cmd_buf_data.encoder.open()?;
let barriers = src_barrier
.into_iter()
.chain(dst_barrier)
.collect::<Vec<_>>();
unsafe { unsafe {
cmd_buf_raw.transition_buffers(src_barrier.into_iter().chain(dst_barrier)); cmd_buf_raw.transition_buffers(&barriers);
cmd_buf_raw.copy_buffer_to_buffer(src_raw, dst_raw, iter::once(region)); cmd_buf_raw.copy_buffer_to_buffer(src_raw, dst_raw, &[region]);
} }
Ok(()) Ok(())
} }
@ -801,7 +804,9 @@ impl Global {
dst_texture dst_texture
.check_usage(TextureUsages::COPY_DST) .check_usage(TextureUsages::COPY_DST)
.map_err(TransferError::MissingTextureUsage)?; .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::<Vec<_>>();
if !dst_base.aspect.is_one() { if !dst_base.aspect.is_one() {
return Err(TransferError::CopyAspectNotOne.into()); return Err(TransferError::CopyAspectNotOne.into());
@ -837,23 +842,25 @@ impl Global {
MemoryInitKind::NeedsInitializedMemory, MemoryInitKind::NeedsInitializedMemory,
)); ));
let regions = (0..array_layer_count).map(|rel_array_layer| { let regions = (0..array_layer_count)
let mut texture_base = dst_base.clone(); .map(|rel_array_layer| {
texture_base.array_layer += rel_array_layer; let mut texture_base = dst_base.clone();
let mut buffer_layout = source.layout; texture_base.array_layer += rel_array_layer;
buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; let mut buffer_layout = source.layout;
hal::BufferTextureCopy { buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer;
buffer_layout, hal::BufferTextureCopy {
texture_base, buffer_layout,
size: hal_copy_size, texture_base,
} size: hal_copy_size,
}); }
})
.collect::<Vec<_>>();
let cmd_buf_raw = encoder.open()?; let cmd_buf_raw = encoder.open()?;
unsafe { unsafe {
cmd_buf_raw.transition_textures(dst_barrier.into_iter()); cmd_buf_raw.transition_textures(&dst_barrier);
cmd_buf_raw.transition_buffers(src_barrier.into_iter()); cmd_buf_raw.transition_buffers(src_barrier.as_slice());
cmd_buf_raw.copy_buffer_to_texture(src_raw, dst_raw, regions); cmd_buf_raw.copy_buffer_to_texture(src_raw, dst_raw, &regions);
} }
Ok(()) Ok(())
} }
@ -956,7 +963,9 @@ impl Global {
} }
.into()); .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::<Vec<_>>();
let dst_buffer = hub let dst_buffer = hub
.buffers .buffers
@ -1009,26 +1018,28 @@ impl Global {
MemoryInitKind::ImplicitlyInitialized, MemoryInitKind::ImplicitlyInitialized,
)); ));
let regions = (0..array_layer_count).map(|rel_array_layer| { let regions = (0..array_layer_count)
let mut texture_base = src_base.clone(); .map(|rel_array_layer| {
texture_base.array_layer += rel_array_layer; let mut texture_base = src_base.clone();
let mut buffer_layout = destination.layout; texture_base.array_layer += rel_array_layer;
buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer; let mut buffer_layout = destination.layout;
hal::BufferTextureCopy { buffer_layout.offset += rel_array_layer as u64 * bytes_per_array_layer;
buffer_layout, hal::BufferTextureCopy {
texture_base, buffer_layout,
size: hal_copy_size, texture_base,
} size: hal_copy_size,
}); }
})
.collect::<Vec<_>>();
let cmd_buf_raw = encoder.open()?; let cmd_buf_raw = encoder.open()?;
unsafe { unsafe {
cmd_buf_raw.transition_buffers(dst_barrier.into_iter()); cmd_buf_raw.transition_buffers(dst_barrier.as_slice());
cmd_buf_raw.transition_textures(src_barrier.into_iter()); cmd_buf_raw.transition_textures(&src_barrier);
cmd_buf_raw.copy_texture_to_buffer( cmd_buf_raw.copy_texture_to_buffer(
src_raw, src_raw,
hal::TextureUses::COPY_SRC, hal::TextureUses::COPY_SRC,
dst_raw, dst_raw,
regions, &regions,
); );
} }
Ok(()) Ok(())
@ -1186,25 +1197,27 @@ impl Global {
height: src_copy_size.height.min(dst_copy_size.height), height: src_copy_size.height.min(dst_copy_size.height),
depth: src_copy_size.depth.min(dst_copy_size.depth), depth: src_copy_size.depth.min(dst_copy_size.depth),
}; };
let regions = (0..array_layer_count).map(|rel_array_layer| { let regions = (0..array_layer_count)
let mut src_base = src_tex_base.clone(); .map(|rel_array_layer| {
let mut dst_base = dst_tex_base.clone(); let mut src_base = src_tex_base.clone();
src_base.array_layer += rel_array_layer; let mut dst_base = dst_tex_base.clone();
dst_base.array_layer += rel_array_layer; src_base.array_layer += rel_array_layer;
hal::TextureCopy { dst_base.array_layer += rel_array_layer;
src_base, hal::TextureCopy {
dst_base, src_base,
size: hal_copy_size, dst_base,
} size: hal_copy_size,
}); }
})
.collect::<Vec<_>>();
let cmd_buf_raw = cmd_buf_data.encoder.open()?; let cmd_buf_raw = cmd_buf_data.encoder.open()?;
unsafe { unsafe {
cmd_buf_raw.transition_textures(barriers.into_iter()); cmd_buf_raw.transition_textures(&barriers);
cmd_buf_raw.copy_texture_to_texture( cmd_buf_raw.copy_texture_to_texture(
src_raw, src_raw,
hal::TextureUses::COPY_SRC, hal::TextureUses::COPY_SRC,
dst_raw, dst_raw,
regions, &regions,
); );
} }

View File

@ -24,8 +24,6 @@ use crate::{
Label, Label,
}; };
use hal::Device as _;
use wgt::{BufferAddress, TextureFormat}; use wgt::{BufferAddress, TextureFormat};
use std::{borrow::Cow, ptr::NonNull, sync::atomic::Ordering}; use std::{borrow::Cow, ptr::NonNull, sync::atomic::Ordering};
@ -282,10 +280,10 @@ impl Global {
.map_err(DeviceError::from)?; .map_err(DeviceError::from)?;
std::ptr::copy_nonoverlapping(data.as_ptr(), mapping.ptr.as_ptr(), data.len()); std::ptr::copy_nonoverlapping(data.as_ptr(), mapping.ptr.as_ptr(), data.len());
if !mapping.is_coherent { if !mapping.is_coherent {
device.raw().flush_mapped_ranges( #[allow(clippy::single_range_in_vec_init)]
raw_buf, device
std::iter::once(offset..offset + data.len() as u64), .raw()
); .flush_mapped_ranges(raw_buf, &[offset..offset + data.len() as u64]);
} }
device.raw().unmap_buffer(raw_buf); device.raw().unmap_buffer(raw_buf);
} }
@ -391,7 +389,7 @@ impl Global {
/// - `hal_texture` must be initialized /// - `hal_texture` must be initialized
pub unsafe fn create_texture_from_hal<A: HalApi>( pub unsafe fn create_texture_from_hal<A: HalApi>(
&self, &self,
hal_texture: A::Texture, hal_texture: Box<dyn hal::DynTexture>,
device_id: DeviceId, device_id: DeviceId,
desc: &resource::TextureDescriptor, desc: &resource::TextureDescriptor,
id_in: Option<id::TextureId>, id_in: Option<id::TextureId>,
@ -1995,7 +1993,7 @@ impl Global {
match unsafe { match unsafe {
A::surface_as_hal(surface) A::surface_as_hal(surface)
.unwrap() .unwrap()
.configure(device.raw(), &hal_config) .configure(device.raw().as_any().downcast_ref().unwrap(), &hal_config)
} { } {
Ok(()) => (), Ok(()) => (),
Err(error) => { Err(error) => {

View File

@ -268,7 +268,7 @@ impl<A: HalApi> LifetimeTracker<A> {
pub fn triage_submissions( pub fn triage_submissions(
&mut self, &mut self,
last_done: SubmissionIndex, last_done: SubmissionIndex,
command_allocator: &crate::command::CommandAllocator<A>, command_allocator: &crate::command::CommandAllocator,
) -> SmallVec<[SubmittedWorkDoneClosure; 1]> { ) -> SmallVec<[SubmittedWorkDoneClosure; 1]> {
profiling::scope!("triage_submissions"); profiling::scope!("triage_submissions");
@ -351,7 +351,7 @@ impl<A: HalApi> LifetimeTracker<A> {
#[must_use] #[must_use]
pub(crate) fn handle_mapping( pub(crate) fn handle_mapping(
&mut self, &mut self,
raw: &A::Device, raw: &dyn hal::DynDevice,
snatch_guard: &SnatchGuard, snatch_guard: &SnatchGuard,
) -> Vec<super::BufferMapPendingClosure> { ) -> Vec<super::BufferMapPendingClosure> {
if self.ready_to_map.is_empty() { if self.ready_to_map.is_empty() {

View File

@ -12,13 +12,12 @@ use crate::{
}; };
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use hal::Device as _;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::os::raw::c_char; use std::os::raw::c_char;
use thiserror::Error; use thiserror::Error;
use wgt::{BufferAddress, DeviceLostReason, TextureFormat}; use wgt::{BufferAddress, DeviceLostReason, TextureFormat};
use std::{iter, num::NonZeroU32}; use std::num::NonZeroU32;
pub mod any_device; pub mod any_device;
pub(crate) mod bgl; pub(crate) mod bgl;
@ -301,7 +300,7 @@ impl DeviceLostClosure {
} }
fn map_buffer<A: HalApi>( fn map_buffer<A: HalApi>(
raw: &A::Device, raw: &dyn hal::DynDevice,
buffer: &Buffer<A>, buffer: &Buffer<A>,
offset: BufferAddress, offset: BufferAddress,
size: BufferAddress, size: BufferAddress,
@ -315,8 +314,9 @@ fn map_buffer<A: HalApi>(
}; };
if !mapping.is_coherent && kind == HostMap::Read { if !mapping.is_coherent && kind == HostMap::Read {
#[allow(clippy::single_range_in_vec_init)]
unsafe { 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<A: HalApi>(
mapped[fill_range].fill(0); mapped[fill_range].fill(0);
if !mapping.is_coherent && kind == HostMap::Read { 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]) };
} }
} }

View File

@ -25,7 +25,6 @@ use crate::{
FastHashMap, SubmissionIndex, FastHashMap, SubmissionIndex,
}; };
use hal::{CommandEncoder as _, Device as _, Queue as _};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{ use std::{
@ -39,20 +38,20 @@ use thiserror::Error;
use super::Device; use super::Device;
pub struct Queue<A: HalApi> { pub struct Queue<A: HalApi> {
raw: ManuallyDrop<A::Queue>, raw: ManuallyDrop<Box<dyn hal::DynQueue>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
} }
impl<A: HalApi> Queue<A> { impl<A: HalApi> Queue<A> {
pub(crate) fn new(device: Arc<Device<A>>, raw: A::Queue) -> Self { pub(crate) fn new(device: Arc<Device<A>>, raw: Box<dyn hal::DynQueue>) -> Self {
Queue { Queue {
raw: ManuallyDrop::new(raw), raw: ManuallyDrop::new(raw),
device, device,
} }
} }
pub(crate) fn raw(&self) -> &A::Queue { pub(crate) fn raw(&self) -> &dyn hal::DynQueue {
&self.raw self.raw.as_ref()
} }
} }
@ -154,8 +153,8 @@ pub enum TempResource<A: HalApi> {
/// [`CommandBuffer`]: hal::Api::CommandBuffer /// [`CommandBuffer`]: hal::Api::CommandBuffer
/// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder /// [`wgpu_hal::CommandEncoder`]: hal::CommandEncoder
pub(crate) struct EncoderInFlight<A: HalApi> { pub(crate) struct EncoderInFlight<A: HalApi> {
raw: A::CommandEncoder, raw: Box<dyn hal::DynCommandEncoder>,
cmd_buffers: Vec<A::CommandBuffer>, cmd_buffers: Vec<Box<dyn hal::DynCommandBuffer>>,
pub(crate) trackers: Tracker<A>, pub(crate) trackers: Tracker<A>,
/// These are the buffers that have been tracked by `PendingWrites`. /// These are the buffers that have been tracked by `PendingWrites`.
@ -169,8 +168,8 @@ impl<A: HalApi> EncoderInFlight<A> {
/// ///
/// Return the command encoder, fully reset and ready to be /// Return the command encoder, fully reset and ready to be
/// reused. /// reused.
pub(crate) unsafe fn land(mut self) -> A::CommandEncoder { pub(crate) unsafe fn land(mut self) -> Box<dyn hal::DynCommandEncoder> {
unsafe { self.raw.reset_all(self.cmd_buffers.into_iter()) }; unsafe { self.raw.reset_all(self.cmd_buffers) };
{ {
// This involves actually decrementing the ref count of all command buffer // This involves actually decrementing the ref count of all command buffer
// resources, so can be _very_ expensive. // resources, so can be _very_ expensive.
@ -205,7 +204,7 @@ impl<A: HalApi> EncoderInFlight<A> {
/// All uses of [`StagingBuffer`]s end up here. /// All uses of [`StagingBuffer`]s end up here.
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct PendingWrites<A: HalApi> { pub(crate) struct PendingWrites<A: HalApi> {
pub command_encoder: A::CommandEncoder, pub command_encoder: Box<dyn hal::DynCommandEncoder>,
/// True if `command_encoder` is in the "recording" state, as /// True if `command_encoder` is in the "recording" state, as
/// described in the docs for the [`wgpu_hal::CommandEncoder`] /// described in the docs for the [`wgpu_hal::CommandEncoder`]
@ -220,7 +219,7 @@ pub(crate) struct PendingWrites<A: HalApi> {
} }
impl<A: HalApi> PendingWrites<A> { impl<A: HalApi> PendingWrites<A> {
pub fn new(command_encoder: A::CommandEncoder) -> Self { pub fn new(command_encoder: Box<dyn hal::DynCommandEncoder>) -> Self {
Self { Self {
command_encoder, command_encoder,
is_recording: false, is_recording: false,
@ -230,7 +229,7 @@ impl<A: HalApi> PendingWrites<A> {
} }
} }
pub fn dispose(mut self, device: &A::Device) { pub fn dispose(mut self, device: &dyn hal::DynDevice) {
unsafe { unsafe {
if self.is_recording { if self.is_recording {
self.command_encoder.discard_encoding(); self.command_encoder.discard_encoding();
@ -270,9 +269,9 @@ impl<A: HalApi> PendingWrites<A> {
fn pre_submit( fn pre_submit(
&mut self, &mut self,
command_allocator: &CommandAllocator<A>, command_allocator: &CommandAllocator,
device: &A::Device, device: &dyn hal::DynDevice,
queue: &A::Queue, queue: &dyn hal::DynQueue,
) -> Result<Option<EncoderInFlight<A>>, DeviceError> { ) -> Result<Option<EncoderInFlight<A>>, DeviceError> {
if self.is_recording { if self.is_recording {
let pending_buffers = mem::take(&mut self.dst_buffers); let pending_buffers = mem::take(&mut self.dst_buffers);
@ -298,7 +297,7 @@ impl<A: HalApi> PendingWrites<A> {
} }
} }
pub fn activate(&mut self) -> &mut A::CommandEncoder { pub fn activate(&mut self) -> &mut dyn hal::DynCommandEncoder {
if !self.is_recording { if !self.is_recording {
unsafe { unsafe {
self.command_encoder self.command_encoder
@ -307,7 +306,7 @@ impl<A: HalApi> PendingWrites<A> {
} }
self.is_recording = true; self.is_recording = true;
} }
&mut self.command_encoder self.command_encoder.as_mut()
} }
pub fn deactivate(&mut self) { pub fn deactivate(&mut self) {
@ -586,11 +585,12 @@ impl Global {
buffer: staging_buffer.raw(), buffer: staging_buffer.raw(),
usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, 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::<Vec<_>>();
let encoder = pending_writes.activate(); let encoder = pending_writes.activate();
unsafe { unsafe {
encoder.transition_buffers(barriers); encoder.transition_buffers(&barriers);
encoder.copy_buffer_to_buffer(staging_buffer.raw(), dst_raw, iter::once(region)); encoder.copy_buffer_to_buffer(staging_buffer.raw(), dst_raw, &[region]);
} }
pending_writes.insert_buffer(&dst); pending_writes.insert_buffer(&dst);
@ -723,7 +723,7 @@ impl Global {
encoder, encoder,
&mut trackers.textures, &mut trackers.textures,
&device.alignments, &device.alignments,
&device.zero_buffer, device.zero_buffer.as_ref(),
&device.snatchable_lock.read(), &device.snatchable_lock.read(),
) )
.map_err(QueueWriteError::from)?; .map_err(QueueWriteError::from)?;
@ -802,24 +802,26 @@ impl Global {
let staging_buffer = staging_buffer.flush(); let staging_buffer = staging_buffer.flush();
let regions = (0..array_layer_count).map(|array_layer_offset| { let regions = (0..array_layer_count)
let mut texture_base = dst_base.clone(); .map(|array_layer_offset| {
texture_base.array_layer += array_layer_offset; let mut texture_base = dst_base.clone();
hal::BufferTextureCopy { texture_base.array_layer += array_layer_offset;
buffer_layout: wgt::ImageDataLayout { hal::BufferTextureCopy {
offset: array_layer_offset as u64 buffer_layout: wgt::ImageDataLayout {
* rows_per_image as u64 offset: array_layer_offset as u64
* stage_bytes_per_row as u64, * rows_per_image as u64
bytes_per_row: Some(stage_bytes_per_row), * stage_bytes_per_row as u64,
rows_per_image: Some(rows_per_image), bytes_per_row: Some(stage_bytes_per_row),
}, rows_per_image: Some(rows_per_image),
texture_base, },
size: hal_copy_size, texture_base,
} size: hal_copy_size,
}); }
})
.collect::<Vec<_>>();
{ {
let barrier = hal::BufferBarrier { let buffer_barrier = hal::BufferBarrier {
buffer: staging_buffer.raw(), buffer: staging_buffer.raw(),
usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC,
}; };
@ -829,10 +831,14 @@ impl Global {
trackers trackers
.textures .textures
.set_single(&dst, selector, hal::TextureUses::COPY_DST); .set_single(&dst, selector, hal::TextureUses::COPY_DST);
let texture_barriers = transition
.map(|pending| pending.into_hal(dst_raw))
.collect::<Vec<_>>();
unsafe { unsafe {
encoder.transition_textures(transition.map(|pending| pending.into_hal(dst_raw))); encoder.transition_textures(&texture_barriers);
encoder.transition_buffers(iter::once(barrier)); encoder.transition_buffers(&[buffer_barrier]);
encoder.copy_buffer_to_texture(staging_buffer.raw(), dst_raw, regions); encoder.copy_buffer_to_texture(staging_buffer.raw(), dst_raw, &regions);
} }
} }
@ -990,7 +996,7 @@ impl Global {
encoder, encoder,
&mut trackers.textures, &mut trackers.textures,
&device.alignments, &device.alignments,
&device.zero_buffer, device.zero_buffer.as_ref(),
&device.snatchable_lock.read(), &device.snatchable_lock.read(),
) )
.map_err(QueueWriteError::from)?; .map_err(QueueWriteError::from)?;
@ -1185,7 +1191,7 @@ impl Global {
//Note: stateless trackers are not merged: //Note: stateless trackers are not merged:
// device already knows these resources exist. // device already knows these resources exist.
CommandBuffer::insert_barriers_from_device_tracker( CommandBuffer::insert_barriers_from_device_tracker(
&mut baked.encoder, baked.encoder.as_mut(),
&mut *trackers, &mut *trackers,
&baked.trackers, &baked.trackers,
&snatch_guard, &snatch_guard,
@ -1212,9 +1218,10 @@ impl Global {
.set_from_usage_scope_and_drain_transitions( .set_from_usage_scope_and_drain_transitions(
&used_surface_textures, &used_surface_textures,
&snatch_guard, &snatch_guard,
); )
.collect::<Vec<_>>();
let present = unsafe { let present = unsafe {
baked.encoder.transition_textures(texture_barriers); baked.encoder.transition_textures(&texture_barriers);
baked.encoder.end_encoding().unwrap() baked.encoder.end_encoding().unwrap()
}; };
baked.list.push(present); baked.list.push(present);
@ -1262,11 +1269,12 @@ impl Global {
.set_from_usage_scope_and_drain_transitions( .set_from_usage_scope_and_drain_transitions(
&used_surface_textures, &used_surface_textures,
&snatch_guard, &snatch_guard,
); )
.collect::<Vec<_>>();
unsafe { unsafe {
pending_writes pending_writes
.command_encoder .command_encoder
.transition_textures(texture_barriers); .transition_textures(&texture_barriers);
}; };
} }
} }
@ -1279,16 +1287,18 @@ impl Global {
let hal_command_buffers = active_executions let hal_command_buffers = active_executions
.iter() .iter()
.flat_map(|e| e.cmd_buffers.iter()) .flat_map(|e| e.cmd_buffers.iter().map(|b| b.as_ref()))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
{ {
let mut submit_surface_textures = 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() { for texture in submit_surface_textures_owned.values() {
let raw = match texture.inner.get(&snatch_guard) { let raw = match texture.inner.get(&snatch_guard) {
Some(TextureInner::Surface { raw, .. }) => raw, Some(TextureInner::Surface { raw, .. }) => raw.as_ref(),
_ => unreachable!(), _ => unreachable!(),
}; };
submit_surface_textures.push(raw); submit_surface_textures.push(raw);
@ -1300,7 +1310,7 @@ impl Global {
.submit( .submit(
&hal_command_buffers, &hal_command_buffers,
&submit_surface_textures, &submit_surface_textures,
(&mut fence, submit_index), (fence.as_mut(), submit_index),
) )
.map_err(DeviceError::from)?; .map_err(DeviceError::from)?;
} }

View File

@ -36,7 +36,6 @@ use crate::{
}; };
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use hal::{CommandEncoder as _, Device as _};
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
use smallvec::SmallVec; use smallvec::SmallVec;
@ -45,7 +44,6 @@ use wgt::{DeviceLostReason, TextureFormat, TextureSampleType, TextureViewDimensi
use std::{ use std::{
borrow::Cow, borrow::Cow,
iter,
mem::ManuallyDrop, mem::ManuallyDrop,
num::NonZeroU32, num::NonZeroU32,
sync::{ sync::{
@ -80,15 +78,15 @@ use super::{
/// When locking pending_writes please check that trackers is not locked /// When locking pending_writes please check that trackers is not locked
/// trackers should be locked only when needed for the shortest time possible /// trackers should be locked only when needed for the shortest time possible
pub struct Device<A: HalApi> { pub struct Device<A: HalApi> {
raw: ManuallyDrop<A::Device>, raw: ManuallyDrop<Box<dyn hal::DynDevice>>,
pub(crate) adapter: Arc<Adapter<A>>, pub(crate) adapter: Arc<Adapter<A>>,
pub(crate) queue: OnceCell<Weak<Queue<A>>>, pub(crate) queue: OnceCell<Weak<Queue<A>>>,
queue_to_drop: OnceCell<A::Queue>, queue_to_drop: OnceCell<Box<dyn hal::DynQueue>>,
pub(crate) zero_buffer: ManuallyDrop<A::Buffer>, pub(crate) zero_buffer: ManuallyDrop<Box<dyn hal::DynBuffer>>,
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
label: String, label: String,
pub(crate) command_allocator: command::CommandAllocator<A>, pub(crate) command_allocator: command::CommandAllocator,
/// The index of the last command submission that was attempted. /// The index of the last command submission that was attempted.
/// ///
@ -112,7 +110,7 @@ pub struct Device<A: HalApi> {
// NOTE: if both are needed, the `snatchable_lock` must be consistently acquired before the // NOTE: if both are needed, the `snatchable_lock` must be consistently acquired before the
// `fence` lock to avoid deadlocks. // `fence` lock to avoid deadlocks.
pub(crate) fence: RwLock<ManuallyDrop<A::Fence>>, pub(crate) fence: RwLock<ManuallyDrop<Box<dyn hal::DynFence>>>,
pub(crate) snatchable_lock: SnatchLock, pub(crate) snatchable_lock: SnatchLock,
/// Is this device valid? Valid is closely associated with "lose the device", /// Is this device valid? Valid is closely associated with "lose the device",
@ -177,8 +175,8 @@ impl<A: HalApi> Drop for Device<A> {
let pending_writes = unsafe { ManuallyDrop::take(&mut self.pending_writes.lock()) }; 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. // 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()) }; let fence = unsafe { ManuallyDrop::take(&mut self.fence.write()) };
pending_writes.dispose(&raw); pending_writes.dispose(raw.as_ref());
self.command_allocator.dispose(&raw); self.command_allocator.dispose(raw.as_ref());
unsafe { unsafe {
raw.destroy_buffer(zero_buffer); raw.destroy_buffer(zero_buffer);
raw.destroy_fence(fence); raw.destroy_fence(fence);
@ -197,8 +195,8 @@ pub enum CreateDeviceError {
} }
impl<A: HalApi> Device<A> { impl<A: HalApi> Device<A> {
pub(crate) fn raw(&self) -> &A::Device { pub(crate) fn raw(&self) -> &dyn hal::DynDevice {
&self.raw self.raw.as_ref()
} }
pub(crate) fn require_features(&self, feature: wgt::Features) -> Result<(), MissingFeatures> { pub(crate) fn require_features(&self, feature: wgt::Features) -> Result<(), MissingFeatures> {
if self.features.contains(feature) { if self.features.contains(feature) {
@ -222,8 +220,8 @@ impl<A: HalApi> Device<A> {
impl<A: HalApi> Device<A> { impl<A: HalApi> Device<A> {
pub(crate) fn new( pub(crate) fn new(
raw_device: A::Device, raw_device: Box<dyn hal::DynDevice>,
raw_queue: &A::Queue, raw_queue: &dyn hal::DynQueue,
adapter: &Arc<Adapter<A>>, adapter: &Arc<Adapter<A>>,
desc: &DeviceDescriptor, desc: &DeviceDescriptor,
trace_path: Option<&std::path::Path>, trace_path: Option<&std::path::Path>,
@ -238,7 +236,7 @@ impl<A: HalApi> Device<A> {
let command_allocator = command::CommandAllocator::new(); let command_allocator = command::CommandAllocator::new();
let pending_encoder = command_allocator let pending_encoder = command_allocator
.acquire_encoder(&raw_device, raw_queue) .acquire_encoder(raw_device.as_ref(), raw_queue)
.map_err(|_| CreateDeviceError::OutOfMemory)?; .map_err(|_| CreateDeviceError::OutOfMemory)?;
let mut pending_writes = PendingWrites::<A>::new(pending_encoder); let mut pending_writes = PendingWrites::<A>::new(pending_encoder);
@ -257,19 +255,19 @@ impl<A: HalApi> Device<A> {
unsafe { unsafe {
pending_writes pending_writes
.command_encoder .command_encoder
.transition_buffers(iter::once(hal::BufferBarrier { .transition_buffers(&[hal::BufferBarrier {
buffer: &zero_buffer, buffer: zero_buffer.as_ref(),
usage: hal::BufferUses::empty()..hal::BufferUses::COPY_DST, usage: hal::BufferUses::empty()..hal::BufferUses::COPY_DST,
})); }]);
pending_writes pending_writes
.command_encoder .command_encoder
.clear_buffer(&zero_buffer, 0..ZERO_BUFFER_SIZE); .clear_buffer(zero_buffer.as_ref(), 0..ZERO_BUFFER_SIZE);
pending_writes pending_writes
.command_encoder .command_encoder
.transition_buffers(iter::once(hal::BufferBarrier { .transition_buffers(&[hal::BufferBarrier {
buffer: &zero_buffer, buffer: zero_buffer.as_ref(),
usage: hal::BufferUses::COPY_DST..hal::BufferUses::COPY_SRC, usage: hal::BufferUses::COPY_DST..hal::BufferUses::COPY_SRC,
})); }]);
} }
let alignments = adapter.raw.capabilities.alignments.clone(); let alignments = adapter.raw.capabilities.alignments.clone();
@ -335,7 +333,7 @@ impl<A: HalApi> Device<A> {
} }
} }
pub(crate) fn release_queue(&self, queue: A::Queue) { pub(crate) fn release_queue(&self, queue: Box<dyn hal::DynQueue>) {
assert!(self.queue_to_drop.set(queue).is_ok()); assert!(self.queue_to_drop.set(queue).is_ok());
} }
@ -364,7 +362,6 @@ impl<A: HalApi> Device<A> {
resource_log!("Destroy raw {}", view.error_ident()); resource_log!("Destroy raw {}", view.error_ident());
unsafe { unsafe {
use hal::Device;
self.raw().destroy_texture_view(raw_view); self.raw().destroy_texture_view(raw_view);
} }
} }
@ -380,7 +377,6 @@ impl<A: HalApi> Device<A> {
resource_log!("Destroy raw {}", bind_group.error_ident()); resource_log!("Destroy raw {}", bind_group.error_ident());
unsafe { unsafe {
use hal::Device;
self.raw().destroy_bind_group(raw_bind_group); self.raw().destroy_bind_group(raw_bind_group);
} }
} }
@ -411,7 +407,7 @@ impl<A: HalApi> Device<A> {
/// return it to our callers.) /// return it to our callers.)
pub(crate) fn maintain<'this>( pub(crate) fn maintain<'this>(
&'this self, &'this self,
fence: crate::lock::RwLockReadGuard<ManuallyDrop<A::Fence>>, fence: crate::lock::RwLockReadGuard<ManuallyDrop<Box<dyn hal::DynFence>>>,
maintain: wgt::Maintain<crate::SubmissionIndex>, maintain: wgt::Maintain<crate::SubmissionIndex>,
snatch_guard: SnatchGuard, snatch_guard: SnatchGuard,
) -> Result<(UserClosures, bool), WaitIdleError> { ) -> Result<(UserClosures, bool), WaitIdleError> {
@ -440,7 +436,7 @@ impl<A: HalApi> Device<A> {
.load(Ordering::Acquire), .load(Ordering::Acquire),
wgt::Maintain::Poll => unsafe { wgt::Maintain::Poll => unsafe {
self.raw() self.raw()
.get_fence_value(&fence) .get_fence_value(fence.as_ref())
.map_err(DeviceError::from)? .map_err(DeviceError::from)?
}, },
}; };
@ -449,7 +445,7 @@ impl<A: HalApi> Device<A> {
if maintain.is_wait() { if maintain.is_wait() {
unsafe { unsafe {
self.raw() self.raw()
.wait(&fence, submission_index, CLEANUP_WAIT_MS) .wait(fence.as_ref(), submission_index, CLEANUP_WAIT_MS)
.map_err(DeviceError::from)? .map_err(DeviceError::from)?
}; };
} }
@ -654,7 +650,7 @@ impl<A: HalApi> Device<A> {
pub(crate) fn create_texture_from_hal( pub(crate) fn create_texture_from_hal(
self: &Arc<Self>, self: &Arc<Self>,
hal_texture: A::Texture, hal_texture: Box<dyn hal::DynTexture>,
desc: &resource::TextureDescriptor, desc: &resource::TextureDescriptor,
) -> Result<Arc<Texture<A>>, resource::CreateTextureError> { ) -> Result<Arc<Texture<A>>, resource::CreateTextureError> {
let format_features = self let format_features = self
@ -687,7 +683,7 @@ impl<A: HalApi> Device<A> {
desc: &resource::BufferDescriptor, desc: &resource::BufferDescriptor,
) -> Arc<Buffer<A>> { ) -> Arc<Buffer<A>> {
let buffer = Buffer { let buffer = Buffer {
raw: Snatchable::new(hal_buffer), raw: Snatchable::new(Box::new(hal_buffer)),
device: self.clone(), device: self.clone(),
usage: desc.usage, usage: desc.usage,
size: desc.size, size: desc.size,
@ -972,8 +968,10 @@ impl<A: HalApi> Device<A> {
}, },
}; };
clear_views.push(ManuallyDrop::new( clear_views.push(ManuallyDrop::new(
unsafe { self.raw().create_texture_view(&raw_texture, &desc) } unsafe {
.map_err(DeviceError::from)?, self.raw().create_texture_view(raw_texture.as_ref(), &desc)
}
.map_err(DeviceError::from)?,
)); ));
}; };
} }
@ -1889,7 +1887,8 @@ impl<A: HalApi> Device<A> {
used: &mut BindGroupStates<A>, used: &mut BindGroupStates<A>,
limits: &wgt::Limits, limits: &wgt::Limits,
snatch_guard: &'a SnatchGuard<'a>, snatch_guard: &'a SnatchGuard<'a>,
) -> Result<hal::BufferBinding<'a, A::Buffer>, binding_model::CreateBindGroupError> { ) -> Result<hal::BufferBinding<'a, dyn hal::DynBuffer>, binding_model::CreateBindGroupError>
{
use crate::binding_model::CreateBindGroupError as Error; use crate::binding_model::CreateBindGroupError as Error;
let (binding_ty, dynamic, min_size) = match decl.ty { let (binding_ty, dynamic, min_size) = match decl.ty {
@ -2021,7 +2020,7 @@ impl<A: HalApi> Device<A> {
binding: u32, binding: u32,
decl: &wgt::BindGroupLayoutEntry, decl: &wgt::BindGroupLayoutEntry,
sampler: &'a Arc<Sampler<A>>, sampler: &'a Arc<Sampler<A>>,
) -> Result<&'a A::Sampler, binding_model::CreateBindGroupError> { ) -> Result<&'a dyn hal::DynSampler, binding_model::CreateBindGroupError> {
use crate::binding_model::CreateBindGroupError as Error; use crate::binding_model::CreateBindGroupError as Error;
used.samplers.insert_single(sampler.clone()); used.samplers.insert_single(sampler.clone());
@ -2072,7 +2071,8 @@ impl<A: HalApi> Device<A> {
used: &mut BindGroupStates<A>, used: &mut BindGroupStates<A>,
used_texture_ranges: &mut Vec<TextureInitTrackerAction<A>>, used_texture_ranges: &mut Vec<TextureInitTrackerAction<A>>,
snatch_guard: &'a SnatchGuard<'a>, snatch_guard: &'a SnatchGuard<'a>,
) -> Result<hal::TextureBinding<'a, A::TextureView>, binding_model::CreateBindGroupError> { ) -> Result<hal::TextureBinding<'a, dyn hal::DynTextureView>, binding_model::CreateBindGroupError>
{
view.same_device(self)?; view.same_device(self)?;
let (pub_usage, internal_use) = self.texture_use_parameters( let (pub_usage, internal_use) = self.texture_use_parameters(
@ -2389,14 +2389,14 @@ impl<A: HalApi> Device<A> {
.unwrap(); .unwrap();
match (sample_type, compat_sample_type) { match (sample_type, compat_sample_type) {
(Tst::Uint, Tst::Uint) | (Tst::Uint, Tst::Uint) |
(Tst::Sint, Tst::Sint) | (Tst::Sint, Tst::Sint) |
(Tst::Depth, Tst::Depth) | (Tst::Depth, Tst::Depth) |
// if we expect non-filterable, accept anything float // if we expect non-filterable, accept anything float
(Tst::Float { filterable: false }, Tst::Float { .. }) | (Tst::Float { filterable: false }, Tst::Float { .. }) |
// if we expect filterable, require it // if we expect filterable, require it
(Tst::Float { filterable: true }, Tst::Float { filterable: true }) | (Tst::Float { filterable: true }, Tst::Float { filterable: true }) |
// if we expect non-filterable, also accept depth // if we expect non-filterable, also accept depth
(Tst::Float { filterable: false }, Tst::Depth) => {} (Tst::Float { filterable: false }, Tst::Depth) => {}
// if we expect filterable, also accept Float that is defined as // if we expect filterable, also accept Float that is defined as
// unfilterable if filterable feature is explicitly enabled (only hit // unfilterable if filterable feature is explicitly enabled (only hit
// if wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES is // if wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES is
@ -2999,7 +2999,7 @@ impl<A: HalApi> Device<A> {
break; break;
} else { } else {
return Err(pipeline::CreateRenderPipelineError return Err(pipeline::CreateRenderPipelineError
::BlendFactorOnUnsupportedTarget { factor, target: i as u32 }); ::BlendFactorOnUnsupportedTarget { factor, target: i as u32 });
} }
} }
} }
@ -3491,9 +3491,9 @@ impl<A: HalApi> Device<A> {
submission_index: crate::SubmissionIndex, submission_index: crate::SubmissionIndex,
) -> Result<(), DeviceError> { ) -> Result<(), DeviceError> {
let fence = self.fence.read(); 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 { 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); drop(fence);
let closures = self let closures = self
.lock_life() .lock_life()
@ -3622,7 +3622,7 @@ impl<A: HalApi> Device<A> {
pub(crate) fn destroy_command_buffer(&self, mut cmd_buf: command::CommandBuffer<A>) { pub(crate) fn destroy_command_buffer(&self, mut cmd_buf: command::CommandBuffer<A>) {
let mut baked = cmd_buf.extract_baked_commands(); let mut baked = cmd_buf.extract_baked_commands();
unsafe { unsafe {
baked.encoder.reset_all(baked.list.into_iter()); baked.encoder.reset_all(baked.list);
} }
unsafe { unsafe {
self.raw().destroy_command_encoder(baked.encoder); self.raw().destroy_command_encoder(baked.encoder);
@ -3637,7 +3637,8 @@ impl<A: HalApi> Device<A> {
.load(Ordering::Acquire); .load(Ordering::Acquire);
if let Err(error) = unsafe { if let Err(error) = unsafe {
let fence = self.fence.read(); 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}"); log::error!("failed to wait for the device: {error}");
} }

View File

@ -244,7 +244,8 @@ impl<A: HalApi> Hub<A> {
if let Some(device) = present.device.downcast_ref::<A>() { if let Some(device) = present.device.downcast_ref::<A>() {
let suf = A::surface_as_hal(surface); let suf = A::surface_as_hal(surface);
unsafe { unsafe {
suf.unwrap().unconfigure(device.raw()); suf.unwrap()
.unconfigure(device.raw().as_any().downcast_ref().unwrap());
} }
} }
} }

View File

@ -267,7 +267,7 @@ impl<A: HalApi> Adapter<A> {
api_log!("Adapter::create_device"); api_log!("Adapter::create_device");
if let Ok(device) = Device::new( if let Ok(device) = Device::new(
hal_device.device, Box::new(hal_device.device),
&hal_device.queue, &hal_device.queue,
self, self,
desc, desc,
@ -275,7 +275,7 @@ impl<A: HalApi> Adapter<A> {
instance_flags, instance_flags,
) { ) {
let device = Arc::new(device); 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); device.set_queue(&queue);
return Ok((device, queue)); return Ok((device, queue));
} }
@ -662,7 +662,7 @@ impl Global {
if let Some(surface) = surface { if let Some(surface) = surface {
if let Some(device) = present.device.downcast_ref::<A>() { if let Some(device) = present.device.downcast_ref::<A>() {
use hal::Surface; use hal::Surface;
unsafe { surface.unconfigure(device.raw()) }; unsafe { surface.unconfigure(device.raw().as_any().downcast_ref().unwrap()) };
} }
} }
} }

View File

@ -47,7 +47,7 @@ pub struct ShaderModuleDescriptor<'a> {
#[derive(Debug)] #[derive(Debug)]
pub struct ShaderModule<A: HalApi> { pub struct ShaderModule<A: HalApi> {
pub(crate) raw: ManuallyDrop<A::ShaderModule>, pub(crate) raw: ManuallyDrop<Box<dyn hal::DynShaderModule>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
pub(crate) interface: Option<validation::Interface>, pub(crate) interface: Option<validation::Interface>,
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
@ -60,7 +60,6 @@ impl<A: HalApi> Drop for ShaderModule<A> {
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. // 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) }; let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_shader_module(raw); self.device.raw().destroy_shader_module(raw);
} }
} }
@ -72,8 +71,8 @@ crate::impl_parent_device!(ShaderModule);
crate::impl_storage_item!(ShaderModule); crate::impl_storage_item!(ShaderModule);
impl<A: HalApi> ShaderModule<A> { impl<A: HalApi> ShaderModule<A> {
pub(crate) fn raw(&self) -> &A::ShaderModule { pub(crate) fn raw(&self) -> &dyn hal::DynShaderModule {
&self.raw self.raw.as_ref()
} }
pub(crate) fn finalize_entry_point_name( pub(crate) fn finalize_entry_point_name(
@ -242,7 +241,7 @@ pub enum CreateComputePipelineError {
#[derive(Debug)] #[derive(Debug)]
pub struct ComputePipeline<A: HalApi> { pub struct ComputePipeline<A: HalApi> {
pub(crate) raw: ManuallyDrop<A::ComputePipeline>, pub(crate) raw: ManuallyDrop<Box<dyn hal::DynComputePipeline>>,
pub(crate) layout: Arc<PipelineLayout<A>>, pub(crate) layout: Arc<PipelineLayout<A>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
pub(crate) _shader_module: Arc<ShaderModule<A>>, pub(crate) _shader_module: Arc<ShaderModule<A>>,
@ -258,7 +257,6 @@ impl<A: HalApi> Drop for ComputePipeline<A> {
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. // 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) }; let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_compute_pipeline(raw); self.device.raw().destroy_compute_pipeline(raw);
} }
} }
@ -271,8 +269,8 @@ crate::impl_storage_item!(ComputePipeline);
crate::impl_trackable!(ComputePipeline); crate::impl_trackable!(ComputePipeline);
impl<A: HalApi> ComputePipeline<A> { impl<A: HalApi> ComputePipeline<A> {
pub(crate) fn raw(&self) -> &A::ComputePipeline { pub(crate) fn raw(&self) -> &dyn hal::DynComputePipeline {
&self.raw self.raw.as_ref()
} }
} }
@ -301,7 +299,7 @@ impl From<hal::PipelineCacheError> for CreatePipelineCacheError {
#[derive(Debug)] #[derive(Debug)]
pub struct PipelineCache<A: HalApi> { pub struct PipelineCache<A: HalApi> {
pub(crate) raw: ManuallyDrop<A::PipelineCache>, pub(crate) raw: ManuallyDrop<Box<dyn hal::DynPipelineCache>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
pub(crate) label: String, pub(crate) label: String,
@ -313,7 +311,6 @@ impl<A: HalApi> Drop for PipelineCache<A> {
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. // 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) }; let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_pipeline_cache(raw); self.device.raw().destroy_pipeline_cache(raw);
} }
} }
@ -325,8 +322,8 @@ crate::impl_parent_device!(PipelineCache);
crate::impl_storage_item!(PipelineCache); crate::impl_storage_item!(PipelineCache);
impl<A: HalApi> PipelineCache<A> { impl<A: HalApi> PipelineCache<A> {
pub(crate) fn raw(&self) -> &A::PipelineCache { pub(crate) fn raw(&self) -> &dyn hal::DynPipelineCache {
&self.raw self.raw.as_ref()
} }
} }
@ -592,7 +589,7 @@ impl Default for VertexStep {
#[derive(Debug)] #[derive(Debug)]
pub struct RenderPipeline<A: HalApi> { pub struct RenderPipeline<A: HalApi> {
pub(crate) raw: ManuallyDrop<A::RenderPipeline>, pub(crate) raw: ManuallyDrop<Box<dyn hal::DynRenderPipeline>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
pub(crate) layout: Arc<PipelineLayout<A>>, pub(crate) layout: Arc<PipelineLayout<A>>,
pub(crate) _shader_modules: pub(crate) _shader_modules:
@ -613,7 +610,6 @@ impl<A: HalApi> Drop for RenderPipeline<A> {
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. // 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) }; let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_render_pipeline(raw); self.device.raw().destroy_render_pipeline(raw);
} }
} }
@ -626,7 +622,7 @@ crate::impl_storage_item!(RenderPipeline);
crate::impl_trackable!(RenderPipeline); crate::impl_trackable!(RenderPipeline);
impl<A: HalApi> RenderPipeline<A> { impl<A: HalApi> RenderPipeline<A> {
pub(crate) fn raw(&self) -> &A::RenderPipeline { pub(crate) fn raw(&self) -> &dyn hal::DynRenderPipeline {
&self.raw self.raw.as_ref()
} }
} }

View File

@ -9,7 +9,7 @@ When this texture is presented, we remove it from the device tracker as well as
extract it from the hub. extract it from the hub.
!*/ !*/
use std::{borrow::Borrow, mem::ManuallyDrop, sync::Arc}; use std::{mem::ManuallyDrop, sync::Arc};
#[cfg(feature = "trace")] #[cfg(feature = "trace")]
use crate::device::trace::Action; use crate::device::trace::Action;
@ -23,7 +23,6 @@ use crate::{
resource::{self, Trackable}, resource::{self, Trackable},
}; };
use hal::{Queue as _, Surface as _};
use thiserror::Error; use thiserror::Error;
use wgt::SurfaceStatus as Status; use wgt::SurfaceStatus as Status;
@ -156,9 +155,10 @@ impl Global {
let suf = A::surface_as_hal(surface.as_ref()); let suf = A::surface_as_hal(surface.as_ref());
let (texture_id, status) = match unsafe { let (texture_id, status) = match unsafe {
use hal::DynSurface;
suf.unwrap().acquire_texture( suf.unwrap().acquire_texture(
Some(std::time::Duration::from_millis(FRAME_TIMEOUT_MS as u64)), Some(std::time::Duration::from_millis(FRAME_TIMEOUT_MS as u64)),
&fence, fence.as_ref(),
) )
} { } {
Ok(Some(ast)) => { Ok(Some(ast)) => {
@ -195,11 +195,9 @@ impl Global {
range: wgt::ImageSubresourceRange::default(), range: wgt::ImageSubresourceRange::default(),
}; };
let clear_view = unsafe { let clear_view = unsafe {
hal::Device::create_texture_view( device
device.raw(), .raw()
ast.texture.borrow(), .create_texture_view(ast.texture.as_ref().borrow(), &clear_view_desc)
&clear_view_desc,
)
} }
.map_err(DeviceError::from)?; .map_err(DeviceError::from)?;
@ -386,6 +384,7 @@ impl Global {
match texture.inner.snatch(exclusive_snatch_guard).unwrap() { match texture.inner.snatch(exclusive_snatch_guard).unwrap() {
resource::TextureInner::Surface { raw, parent_id } => { resource::TextureInner::Surface { raw, parent_id } => {
if surface_id == parent_id { if surface_id == parent_id {
use hal::DynSurface;
unsafe { suf.unwrap().discard_texture(raw) }; unsafe { suf.unwrap().discard_texture(raw) };
} else { } else {
log::warn!("Surface texture is outdated"); log::warn!("Surface texture is outdated");

View File

@ -17,14 +17,12 @@ use crate::{
Label, LabelHelpers, Label, LabelHelpers,
}; };
use hal::CommandEncoder;
use smallvec::SmallVec; use smallvec::SmallVec;
use thiserror::Error; use thiserror::Error;
use std::{ use std::{
borrow::{Borrow, Cow}, borrow::{Borrow, Cow},
fmt::Debug, fmt::Debug,
iter,
mem::{self, ManuallyDrop}, mem::{self, ManuallyDrop},
ops::Range, ops::Range,
ptr::NonNull, ptr::NonNull,
@ -426,7 +424,7 @@ pub type BufferDescriptor<'a> = wgt::BufferDescriptor<Label<'a>>;
#[derive(Debug)] #[derive(Debug)]
pub struct Buffer<A: HalApi> { pub struct Buffer<A: HalApi> {
pub(crate) raw: Snatchable<A::Buffer>, pub(crate) raw: Snatchable<Box<dyn hal::DynBuffer>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
pub(crate) usage: wgt::BufferUsages, pub(crate) usage: wgt::BufferUsages,
pub(crate) size: wgt::BufferAddress, pub(crate) size: wgt::BufferAddress,
@ -443,7 +441,6 @@ impl<A: HalApi> Drop for Buffer<A> {
if let Some(raw) = self.raw.take() { if let Some(raw) = self.raw.take() {
resource_log!("Destroy raw {}", self.error_ident()); resource_log!("Destroy raw {}", self.error_ident());
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_buffer(raw); self.device.raw().destroy_buffer(raw);
} }
} }
@ -451,16 +448,17 @@ impl<A: HalApi> Drop for Buffer<A> {
} }
impl<A: HalApi> Buffer<A> { impl<A: HalApi> Buffer<A> {
pub(crate) fn raw<'a>(&'a self, guard: &'a SnatchGuard) -> Option<&'a A::Buffer> { pub(crate) fn raw<'a>(&'a self, guard: &'a SnatchGuard) -> Option<&'a dyn hal::DynBuffer> {
self.raw.get(guard) self.raw.get(guard).map(|b| b.as_ref())
} }
pub(crate) fn try_raw<'a>( pub(crate) fn try_raw<'a>(
&'a self, &'a self,
guard: &'a SnatchGuard, guard: &'a SnatchGuard,
) -> Result<&A::Buffer, DestroyedResourceError> { ) -> Result<&dyn hal::DynBuffer, DestroyedResourceError> {
self.raw self.raw
.get(guard) .get(guard)
.map(|raw| raw.as_ref())
.ok_or_else(|| DestroyedResourceError(self.error_ident())) .ok_or_else(|| DestroyedResourceError(self.error_ident()))
} }
@ -611,8 +609,6 @@ impl<A: HalApi> Buffer<A> {
self: &Arc<Self>, self: &Arc<Self>,
#[cfg(feature = "trace")] buffer_id: BufferId, #[cfg(feature = "trace")] buffer_id: BufferId,
) -> Result<Option<BufferMapPendingClosure>, BufferAccessError> { ) -> Result<Option<BufferMapPendingClosure>, BufferAccessError> {
use hal::Device;
let device = &self.device; let device = &self.device;
let snatch_guard = device.snatchable_lock.read(); let snatch_guard = device.snatchable_lock.read();
let raw_buf = self.try_raw(&snatch_guard)?; let raw_buf = self.try_raw(&snatch_guard)?;
@ -642,20 +638,18 @@ impl<A: HalApi> Buffer<A> {
buffer: staging_buffer.raw(), buffer: staging_buffer.raw(),
usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC, usage: hal::BufferUses::MAP_WRITE..hal::BufferUses::COPY_SRC,
}; };
let transition_dst = hal::BufferBarrier { let transition_dst = hal::BufferBarrier::<dyn hal::DynBuffer> {
buffer: raw_buf, buffer: raw_buf,
usage: hal::BufferUses::empty()..hal::BufferUses::COPY_DST, usage: hal::BufferUses::empty()..hal::BufferUses::COPY_DST,
}; };
let encoder = pending_writes.activate(); let encoder = pending_writes.activate();
unsafe { unsafe {
encoder.transition_buffers( encoder.transition_buffers(&[transition_src, transition_dst]);
iter::once(transition_src).chain(iter::once(transition_dst)),
);
if self.size > 0 { if self.size > 0 {
encoder.copy_buffer_to_buffer( encoder.copy_buffer_to_buffer(
staging_buffer.raw(), staging_buffer.raw(),
raw_buf, raw_buf,
region.into_iter(), region.as_slice(),
); );
} }
} }
@ -689,7 +683,7 @@ impl<A: HalApi> Buffer<A> {
}); });
} }
if !mapping.is_coherent { 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) }; 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. /// A buffer that has been marked as destroyed and is staged for actual deletion soon.
#[derive(Debug)] #[derive(Debug)]
pub struct DestroyedBuffer<A: HalApi> { pub struct DestroyedBuffer<A: HalApi> {
raw: ManuallyDrop<A::Buffer>, raw: ManuallyDrop<Box<dyn hal::DynBuffer>>,
device: Arc<Device<A>>, device: Arc<Device<A>>,
label: String, label: String,
bind_groups: Vec<Weak<BindGroup<A>>>, bind_groups: Vec<Weak<BindGroup<A>>>,
@ -790,8 +784,7 @@ impl<A: HalApi> Drop for DestroyedBuffer<A> {
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. // 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) }; let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe { unsafe {
use hal::Device; hal::DynDevice::destroy_buffer(self.device.raw(), raw);
self.device.raw().destroy_buffer(raw);
} }
} }
} }
@ -822,7 +815,7 @@ unsafe impl<A: HalApi> Sync for StagingBuffer<A> {}
/// [`Device::pending_writes`]: crate::device::Device /// [`Device::pending_writes`]: crate::device::Device
#[derive(Debug)] #[derive(Debug)]
pub struct StagingBuffer<A: HalApi> { pub struct StagingBuffer<A: HalApi> {
raw: A::Buffer, raw: Box<dyn hal::DynBuffer>,
device: Arc<Device<A>>, device: Arc<Device<A>>,
pub(crate) size: wgt::BufferSize, pub(crate) size: wgt::BufferSize,
is_coherent: bool, is_coherent: bool,
@ -831,7 +824,6 @@ pub struct StagingBuffer<A: HalApi> {
impl<A: HalApi> StagingBuffer<A> { impl<A: HalApi> StagingBuffer<A> {
pub(crate) fn new(device: &Arc<Device<A>>, size: wgt::BufferSize) -> Result<Self, DeviceError> { pub(crate) fn new(device: &Arc<Device<A>>, size: wgt::BufferSize) -> Result<Self, DeviceError> {
use hal::Device;
profiling::scope!("StagingBuffer::new"); profiling::scope!("StagingBuffer::new");
let stage_desc = hal::BufferDescriptor { let stage_desc = hal::BufferDescriptor {
label: crate::hal_label(Some("(wgpu internal) Staging"), device.instance_flags), label: crate::hal_label(Some("(wgpu internal) Staging"), device.instance_flags),
@ -841,7 +833,7 @@ impl<A: HalApi> StagingBuffer<A> {
}; };
let raw = unsafe { device.raw().create_buffer(&stage_desc)? }; 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 { let staging_buffer = StagingBuffer {
raw, raw,
@ -900,12 +892,14 @@ impl<A: HalApi> StagingBuffer<A> {
} }
pub(crate) fn flush(self) -> FlushedStagingBuffer<A> { pub(crate) fn flush(self) -> FlushedStagingBuffer<A> {
use hal::Device;
let device = self.device.raw(); let device = self.device.raw();
if !self.is_coherent { 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 { let StagingBuffer {
raw, device, size, .. raw, device, size, ..
@ -924,20 +918,19 @@ crate::impl_storage_item!(StagingBuffer);
#[derive(Debug)] #[derive(Debug)]
pub struct FlushedStagingBuffer<A: HalApi> { pub struct FlushedStagingBuffer<A: HalApi> {
raw: ManuallyDrop<A::Buffer>, raw: ManuallyDrop<Box<dyn hal::DynBuffer>>,
device: Arc<Device<A>>, device: Arc<Device<A>>,
pub(crate) size: wgt::BufferSize, pub(crate) size: wgt::BufferSize,
} }
impl<A: HalApi> FlushedStagingBuffer<A> { impl<A: HalApi> FlushedStagingBuffer<A> {
pub(crate) fn raw(&self) -> &A::Buffer { pub(crate) fn raw(&self) -> &dyn hal::DynBuffer {
&self.raw self.raw.as_ref()
} }
} }
impl<A: HalApi> Drop for FlushedStagingBuffer<A> { impl<A: HalApi> Drop for FlushedStagingBuffer<A> {
fn drop(&mut self) { fn drop(&mut self) {
use hal::Device;
resource_log!("Destroy raw StagingBuffer"); resource_log!("Destroy raw StagingBuffer");
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. // 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) }; let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
@ -948,35 +941,35 @@ impl<A: HalApi> Drop for FlushedStagingBuffer<A> {
pub type TextureDescriptor<'a> = wgt::TextureDescriptor<Label<'a>, Vec<wgt::TextureFormat>>; pub type TextureDescriptor<'a> = wgt::TextureDescriptor<Label<'a>, Vec<wgt::TextureFormat>>;
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum TextureInner<A: HalApi> { pub(crate) enum TextureInner {
Native { Native {
raw: A::Texture, raw: Box<dyn hal::DynTexture>,
}, },
Surface { Surface {
raw: A::SurfaceTexture, raw: Box<dyn hal::DynSurfaceTexture>,
parent_id: SurfaceId, parent_id: SurfaceId,
}, },
} }
impl<A: HalApi> TextureInner<A> { impl TextureInner {
pub(crate) fn raw(&self) -> &A::Texture { pub(crate) fn raw(&self) -> &dyn hal::DynTexture {
match self { match self {
Self::Native { raw } => raw, Self::Native { raw } => raw.as_ref(),
Self::Surface { raw, .. } => raw.borrow(), Self::Surface { raw, .. } => raw.as_ref().borrow(),
} }
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub enum TextureClearMode<A: HalApi> { pub enum TextureClearMode {
BufferCopy, BufferCopy,
// View for clear via RenderPass for every subsurface (mip/layer/slice) // View for clear via RenderPass for every subsurface (mip/layer/slice)
RenderPass { RenderPass {
clear_views: SmallVec<[ManuallyDrop<A::TextureView>; 1]>, clear_views: SmallVec<[ManuallyDrop<Box<dyn hal::DynTextureView>>; 1]>,
is_color: bool, is_color: bool,
}, },
Surface { Surface {
clear_view: ManuallyDrop<A::TextureView>, clear_view: ManuallyDrop<Box<dyn hal::DynTextureView>>,
}, },
// Texture can't be cleared, attempting to do so will cause panic. // 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) // (either because it is impossible for the type of texture or it is being destroyed)
@ -985,7 +978,7 @@ pub enum TextureClearMode<A: HalApi> {
#[derive(Debug)] #[derive(Debug)]
pub struct Texture<A: HalApi> { pub struct Texture<A: HalApi> {
pub(crate) inner: Snatchable<TextureInner<A>>, pub(crate) inner: Snatchable<TextureInner>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
pub(crate) desc: wgt::TextureDescriptor<(), Vec<wgt::TextureFormat>>, pub(crate) desc: wgt::TextureDescriptor<(), Vec<wgt::TextureFormat>>,
pub(crate) hal_usage: hal::TextureUses, pub(crate) hal_usage: hal::TextureUses,
@ -995,7 +988,7 @@ pub struct Texture<A: HalApi> {
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
pub(crate) label: String, pub(crate) label: String,
pub(crate) tracking_data: TrackingData, pub(crate) tracking_data: TrackingData,
pub(crate) clear_mode: TextureClearMode<A>, pub(crate) clear_mode: TextureClearMode,
pub(crate) views: Mutex<Vec<Weak<TextureView<A>>>>, pub(crate) views: Mutex<Vec<Weak<TextureView<A>>>>,
pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>, pub(crate) bind_groups: Mutex<Vec<Weak<BindGroup<A>>>>,
} }
@ -1003,11 +996,11 @@ pub struct Texture<A: HalApi> {
impl<A: HalApi> Texture<A> { impl<A: HalApi> Texture<A> {
pub(crate) fn new( pub(crate) fn new(
device: &Arc<Device<A>>, device: &Arc<Device<A>>,
inner: TextureInner<A>, inner: TextureInner,
hal_usage: hal::TextureUses, hal_usage: hal::TextureUses,
desc: &TextureDescriptor, desc: &TextureDescriptor,
format_features: wgt::TextureFormatFeatures, format_features: wgt::TextureFormatFeatures,
clear_mode: TextureClearMode<A>, clear_mode: TextureClearMode,
init: bool, init: bool,
) -> Self { ) -> Self {
Texture { Texture {
@ -1055,7 +1048,6 @@ impl<A: HalApi> Texture<A> {
impl<A: HalApi> Drop for Texture<A> { impl<A: HalApi> Drop for Texture<A> {
fn drop(&mut self) { fn drop(&mut self) {
use hal::Device;
match self.clear_mode { match self.clear_mode {
TextureClearMode::Surface { TextureClearMode::Surface {
ref mut clear_view, .. ref mut clear_view, ..
@ -1094,20 +1086,23 @@ impl<A: HalApi> Texture<A> {
pub(crate) fn try_inner<'a>( pub(crate) fn try_inner<'a>(
&'a self, &'a self,
guard: &'a SnatchGuard, guard: &'a SnatchGuard,
) -> Result<&'a TextureInner<A>, DestroyedResourceError> { ) -> Result<&'a TextureInner, DestroyedResourceError> {
self.inner self.inner
.get(guard) .get(guard)
.ok_or_else(|| DestroyedResourceError(self.error_ident())) .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()) Some(self.inner.get(snatch_guard)?.raw())
} }
pub(crate) fn try_raw<'a>( pub(crate) fn try_raw<'a>(
&'a self, &'a self,
guard: &'a SnatchGuard, guard: &'a SnatchGuard,
) -> Result<&'a A::Texture, DestroyedResourceError> { ) -> Result<&'a dyn hal::DynTexture, DestroyedResourceError> {
self.inner self.inner
.get(guard) .get(guard)
.map(|t| t.raw()) .map(|t| t.raw())
@ -1115,11 +1110,11 @@ impl<A: HalApi> Texture<A> {
} }
pub(crate) fn get_clear_view<'a>( pub(crate) fn get_clear_view<'a>(
clear_mode: &'a TextureClearMode<A>, clear_mode: &'a TextureClearMode,
desc: &'a wgt::TextureDescriptor<(), Vec<wgt::TextureFormat>>, desc: &'a wgt::TextureDescriptor<(), Vec<wgt::TextureFormat>>,
mip_level: u32, mip_level: u32,
depth_or_layer: u32, depth_or_layer: u32,
) -> &'a A::TextureView { ) -> &'a dyn hal::DynTextureView {
match *clear_mode { match *clear_mode {
TextureClearMode::BufferCopy => { TextureClearMode::BufferCopy => {
panic!("Given texture is cleared with buffer copies, not render passes") panic!("Given texture is cleared with buffer copies, not render passes")
@ -1127,7 +1122,7 @@ impl<A: HalApi> Texture<A> {
TextureClearMode::None => { TextureClearMode::None => {
panic!("Given texture can't be cleared") 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 { TextureClearMode::RenderPass {
ref clear_views, .. ref clear_views, ..
} => { } => {
@ -1138,7 +1133,7 @@ impl<A: HalApi> Texture<A> {
} else { } else {
mip_level * desc.size.depth_or_array_layers mip_level * desc.size.depth_or_array_layers
} + depth_or_layer; } + 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) { if let Ok(buffer) = hub.buffers.get(id) {
let snatch_guard = buffer.device.snatchable_lock.read(); 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) hal_buffer_callback(hal_buffer)
} else { } else {
hal_buffer_callback(None) hal_buffer_callback(None)
@ -1229,6 +1226,9 @@ impl Global {
if let Ok(texture) = hub.textures.get(id) { if let Ok(texture) = hub.textures.get(id) {
let snatch_guard = texture.device.snatchable_lock.read(); let snatch_guard = texture.device.snatchable_lock.read();
let hal_texture = texture.raw(&snatch_guard); 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) hal_texture_callback(hal_texture)
} else { } else {
hal_texture_callback(None) hal_texture_callback(None)
@ -1250,6 +1250,9 @@ impl Global {
if let Ok(texture_view) = hub.texture_views.get(id) { if let Ok(texture_view) = hub.texture_views.get(id) {
let snatch_guard = texture_view.device.snatchable_lock.read(); let snatch_guard = texture_view.device.snatchable_lock.read();
let hal_texture_view = texture_view.raw(&snatch_guard); 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) hal_texture_view_callback(hal_texture_view)
} else { } else {
hal_texture_view_callback(None) hal_texture_view_callback(None)
@ -1285,7 +1288,10 @@ impl Global {
let hub = A::hub(self); let hub = A::hub(self);
let device = hub.devices.get(id).ok(); 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) hal_device_callback(hal_device)
} }
@ -1304,7 +1310,7 @@ impl Global {
if let Ok(device) = hub.devices.get(id) { if let Ok(device) = hub.devices.get(id) {
let fence = device.fence.read(); let fence = device.fence.read();
hal_fence_callback(Some(&fence)) hal_fence_callback(fence.as_any().downcast_ref())
} else { } else {
hal_fence_callback(None) hal_fence_callback(None)
} }
@ -1346,7 +1352,11 @@ impl Global {
if let Ok(cmd_buf) = hub.command_buffers.get(id.into_command_buffer_id()) { if let Ok(cmd_buf) = hub.command_buffers.get(id.into_command_buffer_id()) {
let mut cmd_buf_data = cmd_buf.data.lock(); let mut cmd_buf_data = cmd_buf.data.lock();
let cmd_buf_data = cmd_buf_data.as_mut().unwrap(); 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) hal_command_encoder_callback(cmd_buf_raw)
} else { } else {
hal_command_encoder_callback(None) 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. /// A texture that has been marked as destroyed and is staged for actual deletion soon.
#[derive(Debug)] #[derive(Debug)]
pub struct DestroyedTexture<A: HalApi> { pub struct DestroyedTexture<A: HalApi> {
raw: ManuallyDrop<A::Texture>, raw: ManuallyDrop<Box<dyn hal::DynTexture>>,
views: Vec<Weak<TextureView<A>>>, views: Vec<Weak<TextureView<A>>>,
bind_groups: Vec<Weak<BindGroup<A>>>, bind_groups: Vec<Weak<BindGroup<A>>>,
device: Arc<Device<A>>, device: Arc<Device<A>>,
@ -1387,7 +1397,6 @@ impl<A: HalApi> Drop for DestroyedTexture<A> {
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. // 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) }; let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_texture(raw); self.device.raw().destroy_texture(raw);
} }
} }
@ -1553,7 +1562,7 @@ pub enum TextureViewNotRenderableReason {
#[derive(Debug)] #[derive(Debug)]
pub struct TextureView<A: HalApi> { pub struct TextureView<A: HalApi> {
pub(crate) raw: Snatchable<A::TextureView>, pub(crate) raw: Snatchable<Box<dyn hal::DynTextureView>>,
// if it's a surface texture - it's none // if it's a surface texture - it's none
pub(crate) parent: Arc<Texture<A>>, pub(crate) parent: Arc<Texture<A>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
@ -1573,7 +1582,6 @@ impl<A: HalApi> Drop for TextureView<A> {
if let Some(raw) = self.raw.take() { if let Some(raw) = self.raw.take() {
resource_log!("Destroy raw {}", self.error_ident()); resource_log!("Destroy raw {}", self.error_ident());
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_texture_view(raw); self.device.raw().destroy_texture_view(raw);
} }
} }
@ -1581,16 +1589,20 @@ impl<A: HalApi> Drop for TextureView<A> {
} }
impl<A: HalApi> TextureView<A> { impl<A: HalApi> TextureView<A> {
pub(crate) fn raw<'a>(&'a self, snatch_guard: &'a SnatchGuard) -> Option<&'a A::TextureView> { pub(crate) fn raw<'a>(
self.raw.get(snatch_guard) &'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>( pub(crate) fn try_raw<'a>(
&'a self, &'a self,
guard: &'a SnatchGuard, guard: &'a SnatchGuard,
) -> Result<&A::TextureView, DestroyedResourceError> { ) -> Result<&'a dyn hal::DynTextureView, DestroyedResourceError> {
self.raw self.raw
.get(guard) .get(guard)
.map(|it| it.as_ref())
.ok_or_else(|| DestroyedResourceError(self.error_ident())) .ok_or_else(|| DestroyedResourceError(self.error_ident()))
} }
} }
@ -1687,7 +1699,7 @@ pub struct SamplerDescriptor<'a> {
#[derive(Debug)] #[derive(Debug)]
pub struct Sampler<A: HalApi> { pub struct Sampler<A: HalApi> {
pub(crate) raw: ManuallyDrop<A::Sampler>, pub(crate) raw: ManuallyDrop<Box<dyn hal::DynSampler>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
pub(crate) label: String, pub(crate) label: String,
@ -1704,15 +1716,14 @@ impl<A: HalApi> Drop for Sampler<A> {
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. // 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) }; let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_sampler(raw); self.device.raw().destroy_sampler(raw);
} }
} }
} }
impl<A: HalApi> Sampler<A> { impl<A: HalApi> Sampler<A> {
pub(crate) fn raw(&self) -> &A::Sampler { pub(crate) fn raw(&self) -> &dyn hal::DynSampler {
&self.raw self.raw.as_ref()
} }
} }
@ -1783,7 +1794,7 @@ pub type QuerySetDescriptor<'a> = wgt::QuerySetDescriptor<Label<'a>>;
#[derive(Debug)] #[derive(Debug)]
pub struct QuerySet<A: HalApi> { pub struct QuerySet<A: HalApi> {
pub(crate) raw: ManuallyDrop<A::QuerySet>, pub(crate) raw: ManuallyDrop<Box<dyn hal::DynQuerySet>>,
pub(crate) device: Arc<Device<A>>, pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource. /// The `label` from the descriptor used to create the resource.
pub(crate) label: String, pub(crate) label: String,
@ -1797,7 +1808,6 @@ impl<A: HalApi> Drop for QuerySet<A> {
// SAFETY: We are in the Drop impl and we don't use self.raw anymore after this point. // 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) }; let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe { unsafe {
use hal::Device;
self.device.raw().destroy_query_set(raw); self.device.raw().destroy_query_set(raw);
} }
} }
@ -1810,8 +1820,8 @@ crate::impl_storage_item!(QuerySet);
crate::impl_trackable!(QuerySet); crate::impl_trackable!(QuerySet);
impl<A: HalApi> QuerySet<A> { impl<A: HalApi> QuerySet<A> {
pub(crate) fn raw(&self) -> &A::QuerySet { pub(crate) fn raw(&self) -> &dyn hal::DynQuerySet {
&self.raw self.raw.as_ref()
} }
} }

View File

@ -284,7 +284,7 @@ impl<A: HalApi> BufferTracker<A> {
pub fn drain_transitions<'a, 'b: 'a>( pub fn drain_transitions<'a, 'b: 'a>(
&'b mut self, &'b mut self,
snatch_guard: &'a SnatchGuard<'a>, snatch_guard: &'a SnatchGuard<'a>,
) -> impl Iterator<Item = BufferBarrier<'a, A::Buffer>> { ) -> impl Iterator<Item = BufferBarrier<'a, dyn hal::DynBuffer>> {
let buffer_barriers = self.temp.drain(..).map(|pending| { let buffer_barriers = self.temp.drain(..).map(|pending| {
let buf = unsafe { self.metadata.get_resource_unchecked(pending.id as _) }; let buf = unsafe { self.metadata.get_resource_unchecked(pending.id as _) };
pending.into_hal(buf, snatch_guard) pending.into_hal(buf, snatch_guard)
@ -557,7 +557,7 @@ impl<A: HalApi> DeviceBufferTracker<A> {
&'a mut self, &'a mut self,
tracker: &'a BufferTracker<A>, tracker: &'a BufferTracker<A>,
snatch_guard: &'b SnatchGuard<'b>, snatch_guard: &'b SnatchGuard<'b>,
) -> impl Iterator<Item = BufferBarrier<'a, A::Buffer>> { ) -> impl Iterator<Item = BufferBarrier<'a, dyn hal::DynBuffer>> {
for index in tracker.metadata.owned_indices() { for index in tracker.metadata.owned_indices() {
self.tracker_assert_in_bounds(index); self.tracker_assert_in_bounds(index);

View File

@ -261,7 +261,7 @@ impl PendingTransition<hal::BufferUses> {
self, self,
buf: &'a resource::Buffer<A>, buf: &'a resource::Buffer<A>,
snatch_guard: &'a SnatchGuard<'a>, 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"); let buffer = buf.raw(snatch_guard).expect("Buffer is destroyed");
hal::BufferBarrier { hal::BufferBarrier {
buffer, buffer,
@ -272,10 +272,10 @@ impl PendingTransition<hal::BufferUses> {
impl PendingTransition<hal::TextureUses> { impl PendingTransition<hal::TextureUses> {
/// Produce the hal barrier corresponding to the transition. /// Produce the hal barrier corresponding to the transition.
pub fn into_hal<'a, T: hal::DynTexture + ?Sized>( pub fn into_hal(
self, self,
texture: &'a T, texture: &dyn hal::DynTexture,
) -> hal::TextureBarrier<'a, T> { ) -> hal::TextureBarrier<'_, dyn hal::DynTexture> {
// These showing up in a barrier is always a bug // These showing up in a barrier is always a bug
strict_assert_ne!(self.usage.start, hal::TextureUses::UNKNOWN); strict_assert_ne!(self.usage.start, hal::TextureUses::UNKNOWN);
strict_assert_ne!(self.usage.end, hal::TextureUses::UNKNOWN); strict_assert_ne!(self.usage.end, hal::TextureUses::UNKNOWN);

View File

@ -438,7 +438,7 @@ impl<A: HalApi> TextureTracker<A> {
pub fn drain_transitions<'a>( pub fn drain_transitions<'a>(
&'a mut self, &'a mut self,
snatch_guard: &'a SnatchGuard<'a>, snatch_guard: &'a SnatchGuard<'a>,
) -> (PendingTransitionList, Vec<Option<&'a TextureInner<A>>>) { ) -> (PendingTransitionList, Vec<Option<&'a TextureInner>>) {
let mut textures = Vec::new(); let mut textures = Vec::new();
let transitions = self let transitions = self
.temp .temp
@ -754,7 +754,7 @@ impl<A: HalApi> DeviceTextureTracker<A> {
&'a mut self, &'a mut self,
tracker: &'a TextureTracker<A>, tracker: &'a TextureTracker<A>,
snatch_guard: &'b SnatchGuard<'b>, snatch_guard: &'b SnatchGuard<'b>,
) -> impl Iterator<Item = TextureBarrier<'a, A::Texture>> { ) -> impl Iterator<Item = TextureBarrier<'a, dyn hal::DynTexture>> {
for index in tracker.metadata.owned_indices() { for index in tracker.metadata.owned_indices() {
self.tracker_assert_in_bounds(index); self.tracker_assert_in_bounds(index);
@ -798,7 +798,7 @@ impl<A: HalApi> DeviceTextureTracker<A> {
&'a mut self, &'a mut self,
scope: &'a TextureUsageScope<A>, scope: &'a TextureUsageScope<A>,
snatch_guard: &'b SnatchGuard<'b>, snatch_guard: &'b SnatchGuard<'b>,
) -> impl Iterator<Item = TextureBarrier<'a, A::Texture>> { ) -> impl Iterator<Item = TextureBarrier<'a, dyn hal::DynTexture>> {
for index in scope.metadata.owned_indices() { for index in scope.metadata.owned_indices() {
self.tracker_assert_in_bounds(index); self.tracker_assert_in_bounds(index);

View File

@ -143,7 +143,7 @@ impl ContextWgpuCore {
let descriptor = desc.map_label_and_view_formats(|l| l.map(Borrowed), |v| v.to_vec()); let descriptor = desc.map_label_and_view_formats(|l| l.map(Borrowed), |v| v.to_vec());
let (id, error) = unsafe { let (id, error) = unsafe {
self.0 self.0
.create_texture_from_hal::<A>(hal_texture, device.id, &descriptor, None) .create_texture_from_hal::<A>(Box::new(hal_texture), device.id, &descriptor, None)
}; };
if let Some(cause) = error { if let Some(cause) = error {
self.handle_error( self.handle_error(