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.
#[derive(Debug)]
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) entries: bgl::EntryMap,
/// 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.
let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe {
use hal::Device;
self.device.raw().destroy_bind_group_layout(raw);
}
}
@ -537,8 +536,8 @@ crate::impl_parent_device!(BindGroupLayout);
crate::impl_storage_item!(BindGroupLayout);
impl<A: HalApi> BindGroupLayout<A> {
pub(crate) fn raw(&self) -> &A::BindGroupLayout {
&self.raw
pub(crate) fn raw(&self) -> &dyn hal::DynBindGroupLayout {
self.raw.as_ref()
}
}
@ -652,7 +651,7 @@ pub struct ResolvedPipelineLayoutDescriptor<'a, A: HalApi> {
#[derive(Debug)]
pub struct PipelineLayout<A: HalApi> {
pub(crate) raw: ManuallyDrop<A::PipelineLayout>,
pub(crate) raw: ManuallyDrop<Box<dyn hal::DynPipelineLayout>>,
pub(crate) device: Arc<Device<A>>,
/// The `label` from the descriptor used to create the resource.
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.
let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe {
use hal::Device;
self.device.raw().destroy_pipeline_layout(raw);
}
}
}
impl<A: HalApi> PipelineLayout<A> {
pub(crate) fn raw(&self) -> &A::PipelineLayout {
&self.raw
pub(crate) fn raw(&self) -> &dyn hal::DynPipelineLayout {
self.raw.as_ref()
}
pub(crate) fn get_binding_maps(&self) -> ArrayVec<&bgl::EntryMap, { hal::MAX_BIND_GROUPS }> {
@ -889,7 +887,7 @@ pub(crate) fn buffer_binding_type_alignment(
#[derive(Debug)]
pub struct BindGroup<A: HalApi> {
pub(crate) raw: Snatchable<A::BindGroup>,
pub(crate) raw: Snatchable<Box<dyn hal::DynBindGroup>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) layout: Arc<BindGroupLayout<A>>,
/// 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() {
resource_log!("Destroy raw {}", self.error_ident());
unsafe {
use hal::Device;
self.device.raw().destroy_bind_group(raw);
}
}
@ -920,7 +917,7 @@ impl<A: HalApi> BindGroup<A> {
pub(crate) fn try_raw<'a>(
&'a self,
guard: &'a SnatchGuard,
) -> Result<&A::BindGroup, DestroyedResourceError> {
) -> Result<&dyn hal::DynBindGroup, DestroyedResourceError> {
// Clippy insist on writing it this way. The idea is to return None
// if any of the raw buffer is not valid anymore.
for buffer in &self.used_buffer_ranges {
@ -932,6 +929,7 @@ impl<A: HalApi> BindGroup<A> {
self.raw
.get(guard)
.map(|raw| raw.as_ref())
.ok_or_else(|| DestroyedResourceError(self.error_ident()))
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -244,7 +244,8 @@ impl<A: HalApi> Hub<A> {
if let Some(device) = present.device.downcast_ref::<A>() {
let suf = A::surface_as_hal(surface);
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");
if let Ok(device) = Device::new(
hal_device.device,
Box::new(hal_device.device),
&hal_device.queue,
self,
desc,
@ -275,7 +275,7 @@ impl<A: HalApi> Adapter<A> {
instance_flags,
) {
let device = Arc::new(device);
let queue = Arc::new(Queue::new(device.clone(), hal_device.queue));
let queue = Arc::new(Queue::new(device.clone(), Box::new(hal_device.queue)));
device.set_queue(&queue);
return Ok((device, queue));
}
@ -662,7 +662,7 @@ impl Global {
if let Some(surface) = surface {
if let Some(device) = present.device.downcast_ref::<A>() {
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)]
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) interface: Option<validation::Interface>,
/// 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.
let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe {
use hal::Device;
self.device.raw().destroy_shader_module(raw);
}
}
@ -72,8 +71,8 @@ crate::impl_parent_device!(ShaderModule);
crate::impl_storage_item!(ShaderModule);
impl<A: HalApi> ShaderModule<A> {
pub(crate) fn raw(&self) -> &A::ShaderModule {
&self.raw
pub(crate) fn raw(&self) -> &dyn hal::DynShaderModule {
self.raw.as_ref()
}
pub(crate) fn finalize_entry_point_name(
@ -242,7 +241,7 @@ pub enum CreateComputePipelineError {
#[derive(Debug)]
pub struct ComputePipeline<A: HalApi> {
pub(crate) raw: ManuallyDrop<A::ComputePipeline>,
pub(crate) raw: ManuallyDrop<Box<dyn hal::DynComputePipeline>>,
pub(crate) layout: Arc<PipelineLayout<A>>,
pub(crate) device: Arc<Device<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.
let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe {
use hal::Device;
self.device.raw().destroy_compute_pipeline(raw);
}
}
@ -271,8 +269,8 @@ crate::impl_storage_item!(ComputePipeline);
crate::impl_trackable!(ComputePipeline);
impl<A: HalApi> ComputePipeline<A> {
pub(crate) fn raw(&self) -> &A::ComputePipeline {
&self.raw
pub(crate) fn raw(&self) -> &dyn hal::DynComputePipeline {
self.raw.as_ref()
}
}
@ -301,7 +299,7 @@ impl From<hal::PipelineCacheError> for CreatePipelineCacheError {
#[derive(Debug)]
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>>,
/// The `label` from the descriptor used to create the resource.
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.
let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe {
use hal::Device;
self.device.raw().destroy_pipeline_cache(raw);
}
}
@ -325,8 +322,8 @@ crate::impl_parent_device!(PipelineCache);
crate::impl_storage_item!(PipelineCache);
impl<A: HalApi> PipelineCache<A> {
pub(crate) fn raw(&self) -> &A::PipelineCache {
&self.raw
pub(crate) fn raw(&self) -> &dyn hal::DynPipelineCache {
self.raw.as_ref()
}
}
@ -592,7 +589,7 @@ impl Default for VertexStep {
#[derive(Debug)]
pub struct RenderPipeline<A: HalApi> {
pub(crate) raw: ManuallyDrop<A::RenderPipeline>,
pub(crate) raw: ManuallyDrop<Box<dyn hal::DynRenderPipeline>>,
pub(crate) device: Arc<Device<A>>,
pub(crate) layout: Arc<PipelineLayout<A>>,
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.
let raw = unsafe { ManuallyDrop::take(&mut self.raw) };
unsafe {
use hal::Device;
self.device.raw().destroy_render_pipeline(raw);
}
}
@ -626,7 +622,7 @@ crate::impl_storage_item!(RenderPipeline);
crate::impl_trackable!(RenderPipeline);
impl<A: HalApi> RenderPipeline<A> {
pub(crate) fn raw(&self) -> &A::RenderPipeline {
&self.raw
pub(crate) fn raw(&self) -> &dyn hal::DynRenderPipeline {
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.
!*/
use std::{borrow::Borrow, mem::ManuallyDrop, sync::Arc};
use std::{mem::ManuallyDrop, sync::Arc};
#[cfg(feature = "trace")]
use crate::device::trace::Action;
@ -23,7 +23,6 @@ use crate::{
resource::{self, Trackable},
};
use hal::{Queue as _, Surface as _};
use thiserror::Error;
use wgt::SurfaceStatus as Status;
@ -156,9 +155,10 @@ impl Global {
let suf = A::surface_as_hal(surface.as_ref());
let (texture_id, status) = match unsafe {
use hal::DynSurface;
suf.unwrap().acquire_texture(
Some(std::time::Duration::from_millis(FRAME_TIMEOUT_MS as u64)),
&fence,
fence.as_ref(),
)
} {
Ok(Some(ast)) => {
@ -195,11 +195,9 @@ impl Global {
range: wgt::ImageSubresourceRange::default(),
};
let clear_view = unsafe {
hal::Device::create_texture_view(
device.raw(),
ast.texture.borrow(),
&clear_view_desc,
)
device
.raw()
.create_texture_view(ast.texture.as_ref().borrow(), &clear_view_desc)
}
.map_err(DeviceError::from)?;
@ -386,6 +384,7 @@ impl Global {
match texture.inner.snatch(exclusive_snatch_guard).unwrap() {
resource::TextureInner::Surface { raw, parent_id } => {
if surface_id == parent_id {
use hal::DynSurface;
unsafe { suf.unwrap().discard_texture(raw) };
} else {
log::warn!("Surface texture is outdated");

View File

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

View File

@ -284,7 +284,7 @@ impl<A: HalApi> BufferTracker<A> {
pub fn drain_transitions<'a, 'b: 'a>(
&'b mut self,
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 buf = unsafe { self.metadata.get_resource_unchecked(pending.id as _) };
pending.into_hal(buf, snatch_guard)
@ -557,7 +557,7 @@ impl<A: HalApi> DeviceBufferTracker<A> {
&'a mut self,
tracker: &'a BufferTracker<A>,
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() {
self.tracker_assert_in_bounds(index);

View File

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

View File

@ -438,7 +438,7 @@ impl<A: HalApi> TextureTracker<A> {
pub fn drain_transitions<'a>(
&'a mut self,
snatch_guard: &'a SnatchGuard<'a>,
) -> (PendingTransitionList, Vec<Option<&'a TextureInner<A>>>) {
) -> (PendingTransitionList, Vec<Option<&'a TextureInner>>) {
let mut textures = Vec::new();
let transitions = self
.temp
@ -754,7 +754,7 @@ impl<A: HalApi> DeviceTextureTracker<A> {
&'a mut self,
tracker: &'a TextureTracker<A>,
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() {
self.tracker_assert_in_bounds(index);
@ -798,7 +798,7 @@ impl<A: HalApi> DeviceTextureTracker<A> {
&'a mut self,
scope: &'a TextureUsageScope<A>,
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() {
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 (id, error) = unsafe {
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 {
self.handle_error(